fix: correct pubkey auth response, strncpy warning, and NUL byte validation

- auth_pubkey: return SSH_AUTH_SUCCESS for key offers instead of
  SSH_AUTH_PARTIAL, which incorrectly signals partial authentication
- command history: replace strncpy with snprintf to eliminate
  -Wstringop-truncation warning on GCC
- utf8_is_valid_sequence: reject NUL byte (0x00) in single-byte
  validation to prevent C string truncation attacks

Closes #34
This commit is contained in:
m1ngsama 2026-04-19 18:13:01 +08:00
parent c7fa162bff
commit 6781aff538
2 changed files with 8 additions and 8 deletions

View file

@ -1109,9 +1109,8 @@ static void execute_command(client_t *client) {
(max_hist - 1) * sizeof(client->command_history[0])); (max_hist - 1) * sizeof(client->command_history[0]));
client->command_history_count = max_hist - 1; client->command_history_count = max_hist - 1;
} }
strncpy(client->command_history[client->command_history_count], snprintf(client->command_history[client->command_history_count],
cmd, sizeof(client->command_history[0]) - 1); sizeof(client->command_history[0]), "%s", cmd);
client->command_history[client->command_history_count][sizeof(client->command_history[0]) - 1] = '\0';
client->command_history_count++; client->command_history_count++;
client->command_history_pos = client->command_history_count; client->command_history_pos = client->command_history_count;
} }
@ -1740,10 +1739,11 @@ static int auth_pubkey(ssh_session session, const char *user,
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
/* Only accept after the signature has been verified by libssh. /* SSH_PUBLICKEY_STATE_NONE = key offer (no signature yet).
* SSH_PUBLICKEY_STATE_NONE is just a key offer no proof of possession. */ * Return SUCCESS to tell libssh "I accept this key, verify the signature."
* SSH_PUBLICKEY_STATE_VALID = signature verified by libssh. */
if (signature_state != SSH_PUBLICKEY_STATE_VALID) { if (signature_state != SSH_PUBLICKEY_STATE_VALID) {
return SSH_AUTH_PARTIAL; return SSH_AUTH_SUCCESS;
} }
ctx->auth_success = true; ctx->auth_success = true;

View file

@ -193,9 +193,9 @@ bool utf8_is_valid_sequence(const char *bytes, int len) {
uint32_t codepoint = 0; uint32_t codepoint = 0;
switch (len) { switch (len) {
case 1: case 1:
/* 0xxxxxxx - valid range: 0x00-0x7F */ /* 0xxxxxxx - valid range: 0x01-0x7F (reject NUL) */
codepoint = b[0]; codepoint = b[0];
if (codepoint > 0x7F) return false; if (codepoint == 0 || codepoint > 0x7F) return false;
break; break;
case 2: case 2:
/* 110xxxxx 10xxxxxx - valid range: 0x80-0x7FF */ /* 110xxxxx 10xxxxxx - valid range: 0x80-0x7FF */