reformat: functions related to pubkey authentication

Signed-off-by: Abdallah Alhadad <abdallahselhdad@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Abdallah Alhadad
2025-03-15 14:15:27 +02:00
parent bf2b8954e8
commit 1f76cc0c6a
2 changed files with 307 additions and 282 deletions

View File

@@ -508,29 +508,31 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
switch(session->pending_call_state) { switch (session->pending_call_state) {
case SSH_PENDING_CALL_NONE: case SSH_PENDING_CALL_NONE:
break; break;
case SSH_PENDING_CALL_AUTH_OFFER_PUBKEY: case SSH_PENDING_CALL_AUTH_OFFER_PUBKEY:
goto pending; goto pending;
default: default:
ssh_set_error(session, ssh_set_error(session,
SSH_FATAL, SSH_FATAL,
"Wrong state (%d) during pending SSH call", "Wrong state (%d) during pending SSH call",
session->pending_call_state); session->pending_call_state);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
/* Check if the given public key algorithm is allowed */ /* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type); sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
if (sig_type_c == NULL) { if (sig_type_c == NULL) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"Invalid key type (unknown)"); "Invalid key type (unknown)");
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
rc = ssh_key_algorithm_allowed(session, sig_type_c); rc = ssh_key_algorithm_allowed(session, sig_type_c);
if (!rc) { if (!rc) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by" "The key algorithm '%s' is not allowed to be used by"
" PUBLICKEY_ACCEPTED_TYPES configuration option", " PUBLICKEY_ACCEPTED_TYPES configuration option",
sig_type_c); sig_type_c);
@@ -538,9 +540,12 @@ int ssh_userauth_try_publickey(ssh_session session,
} }
allowed = ssh_key_size_allowed(session, pubkey); allowed = ssh_key_size_allowed(session, pubkey);
if (!allowed) { if (!allowed) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"The '%s' key type of size %d is not allowed by " "The '%s' key type of size %d is not allowed by "
"RSA_MIN_SIZE", sig_type_c, ssh_key_size(pubkey)); "RSA_MIN_SIZE",
sig_type_c,
ssh_key_size(pubkey));
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
@@ -559,15 +564,16 @@ int ssh_userauth_try_publickey(ssh_session session,
SSH_LOG(SSH_LOG_TRACE, "Trying signature type %s", sig_type_c); SSH_LOG(SSH_LOG_TRACE, "Trying signature type %s", sig_type_c);
/* request */ /* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", rc = ssh_buffer_pack(session->out_buffer,
SSH2_MSG_USERAUTH_REQUEST, "bsssbsS",
username ? username : session->opts.username, SSH2_MSG_USERAUTH_REQUEST,
"ssh-connection", username ? username : session->opts.username,
"publickey", "ssh-connection",
0, /* private key ? */ "publickey",
sig_type_c, /* algo */ 0, /* private key ? */
pubkey_s /* public key */ sig_type_c, /* algo */
); pubkey_s /* public key */
);
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
} }
@@ -640,16 +646,17 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
switch(session->pending_call_state) { switch (session->pending_call_state) {
case SSH_PENDING_CALL_NONE: case SSH_PENDING_CALL_NONE:
break; break;
case SSH_PENDING_CALL_AUTH_PUBKEY: case SSH_PENDING_CALL_AUTH_PUBKEY:
goto pending; goto pending;
default: default:
ssh_set_error(session, ssh_set_error(
SSH_FATAL, session,
"Bad call during pending SSH call in ssh_userauth_try_publickey"); SSH_FATAL,
return SSH_AUTH_ERROR; "Bad call during pending SSH call in ssh_userauth_try_publickey");
return SSH_AUTH_ERROR;
} }
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */ /* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
@@ -658,13 +665,15 @@ int ssh_userauth_publickey(ssh_session session,
/* Check if the given public key algorithm is allowed */ /* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, key_type); sig_type_c = ssh_key_get_signature_algorithm(session, key_type);
if (sig_type_c == NULL) { if (sig_type_c == NULL) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"Invalid key type (unknown)"); "Invalid key type (unknown)");
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
rc = ssh_key_algorithm_allowed(session, sig_type_c); rc = ssh_key_algorithm_allowed(session, sig_type_c);
if (!rc) { if (!rc) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by" "The key algorithm '%s' is not allowed to be used by"
" PUBLICKEY_ACCEPTED_TYPES configuration option", " PUBLICKEY_ACCEPTED_TYPES configuration option",
sig_type_c); sig_type_c);
@@ -672,9 +681,12 @@ int ssh_userauth_publickey(ssh_session session,
} }
allowed = ssh_key_size_allowed(session, privkey); allowed = ssh_key_size_allowed(session, privkey);
if (!allowed) { if (!allowed) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"The '%s' key type of size %d is not allowed by " "The '%s' key type of size %d is not allowed by "
"RSA_MIN_SIZE", sig_type_c, ssh_key_size(privkey)); "RSA_MIN_SIZE",
sig_type_c,
ssh_key_size(privkey));
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
@@ -693,15 +705,16 @@ int ssh_userauth_publickey(ssh_session session,
SSH_LOG(SSH_LOG_TRACE, "Sending signature type %s", sig_type_c); SSH_LOG(SSH_LOG_TRACE, "Sending signature type %s", sig_type_c);
/* request */ /* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", rc = ssh_buffer_pack(session->out_buffer,
SSH2_MSG_USERAUTH_REQUEST, "bsssbsS",
username ? username : session->opts.username, SSH2_MSG_USERAUTH_REQUEST,
"ssh-connection", username ? username : session->opts.username,
"publickey", "ssh-connection",
1, /* private key */ "publickey",
sig_type_c, /* algo */ 1, /* private key */
str /* public key or cert */ sig_type_c, /* algo */
); str /* public key or cert */
);
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
} }
@@ -785,14 +798,16 @@ static int ssh_userauth_agent_publickey(ssh_session session,
/* Check if the given public key algorithm is allowed */ /* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type); sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
if (sig_type_c == NULL) { if (sig_type_c == NULL) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"Invalid key type (unknown)"); "Invalid key type (unknown)");
SSH_STRING_FREE(pubkey_s); SSH_STRING_FREE(pubkey_s);
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
rc = ssh_key_algorithm_allowed(session, sig_type_c); rc = ssh_key_algorithm_allowed(session, sig_type_c);
if (!rc) { if (!rc) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by" "The key algorithm '%s' is not allowed to be used by"
" PUBLICKEY_ACCEPTED_TYPES configuration option", " PUBLICKEY_ACCEPTED_TYPES configuration option",
sig_type_c); sig_type_c);
@@ -801,23 +816,27 @@ static int ssh_userauth_agent_publickey(ssh_session session,
} }
allowed = ssh_key_size_allowed(session, pubkey); allowed = ssh_key_size_allowed(session, pubkey);
if (!allowed) { if (!allowed) {
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
SSH_REQUEST_DENIED,
"The '%s' key type of size %d is not allowed by " "The '%s' key type of size %d is not allowed by "
"RSA_MIN_SIZE", sig_type_c, ssh_key_size(pubkey)); "RSA_MIN_SIZE",
sig_type_c,
ssh_key_size(pubkey));
SSH_STRING_FREE(pubkey_s); SSH_STRING_FREE(pubkey_s);
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
/* request */ /* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", rc = ssh_buffer_pack(session->out_buffer,
"bsssbsS",
SSH2_MSG_USERAUTH_REQUEST, SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username, username ? username : session->opts.username,
"ssh-connection", "ssh-connection",
"publickey", "publickey",
1, /* private key */ 1, /* private key */
sig_type_c, /* algo */ sig_type_c, /* algo */
pubkey_s /* public key */ pubkey_s /* public key */
); );
SSH_STRING_FREE(pubkey_s); SSH_STRING_FREE(pubkey_s);
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
@@ -879,7 +898,7 @@ void ssh_agent_state_free(void *data)
if (state) { if (state) {
SSH_STRING_FREE_CHAR(state->comment); SSH_STRING_FREE_CHAR(state->comment);
ssh_key_free(state->pubkey); ssh_key_free(state->pubkey);
free (state); free(state);
} }
} }
@@ -905,8 +924,7 @@ void ssh_agent_state_free(void *data)
* authentication. The username should only be set with ssh_options_set() only * authentication. The username should only be set with ssh_options_set() only
* before you connect to the server. * before you connect to the server.
*/ */
int ssh_userauth_agent(ssh_session session, int ssh_userauth_agent(ssh_session session, const char *username)
const char *username)
{ {
int rc = SSH_AUTH_ERROR; int rc = SSH_AUTH_ERROR;
struct ssh_agent_state_struct *state = NULL; struct ssh_agent_state_struct *state = NULL;

View File

@@ -737,7 +737,7 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
{ {
struct ssh_crypto_struct *crypto = NULL; struct ssh_crypto_struct *crypto = NULL;
ssh_buffer buffer; ssh_buffer buffer;
ssh_string str=NULL; ssh_string str = NULL;
int rc; int rc;
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN); crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
@@ -758,14 +758,15 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
rc = ssh_buffer_pack(buffer, rc = ssh_buffer_pack(buffer,
"dPbsssbsS", "dPbsssbsS",
crypto->session_id_len, /* session ID string */ crypto->session_id_len, /* session ID string */
crypto->session_id_len, crypto->session_id, crypto->session_id_len,
crypto->session_id,
SSH2_MSG_USERAUTH_REQUEST, /* type */ SSH2_MSG_USERAUTH_REQUEST, /* type */
msg->auth_request.username, msg->auth_request.username,
service, service,
"publickey", /* method */ "publickey", /* method */
1, /* has to be signed (true) */ 1, /* has to be signed (true) */
ssh_string_get_char(algo), /* pubkey algorithm */ ssh_string_get_char(algo), /* pubkey algorithm */
str); /* public key as a blob */ str); /* public key as a blob */
SSH_STRING_FREE(str); SSH_STRING_FREE(str);
if (rc != SSH_OK) { if (rc != SSH_OK) {
@@ -783,263 +784,269 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
* @brief Handle a SSH_MSG_MSG_USERAUTH_REQUEST packet and queue a * @brief Handle a SSH_MSG_MSG_USERAUTH_REQUEST packet and queue a
* SSH Message * SSH Message
*/ */
SSH_PACKET_CALLBACK(ssh_packet_userauth_request){ SSH_PACKET_CALLBACK(ssh_packet_userauth_request)
ssh_message msg = NULL; {
ssh_signature sig = NULL; ssh_message msg = NULL;
char *service = NULL; ssh_signature sig = NULL;
char *method = NULL; char *service = NULL;
int cmp; char *method = NULL;
int rc; int cmp;
int rc;
(void)user; (void)user;
(void)type; (void)type;
msg = ssh_message_new(session); msg = ssh_message_new(session);
if (msg == NULL) { if (msg == NULL) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
goto error;
}
msg->type = SSH_REQUEST_AUTH;
rc = ssh_buffer_unpack(packet,
"sss",
&msg->auth_request.username,
&service,
&method);
if (rc != SSH_OK) {
goto error;
}
SSH_LOG(SSH_LOG_PACKET,
"Auth request for service %s, method %s for user '%s'",
service, method,
msg->auth_request.username);
cmp = strcmp(service, "ssh-connection");
if (cmp != 0) {
SSH_LOG(SSH_LOG_TRACE,
"Invalid service request: %s",
service);
goto end;
}
if (strcmp(method, "none") == 0) {
msg->auth_request.method = SSH_AUTH_METHOD_NONE;
goto end;
}
if (strcmp(method, "password") == 0) {
uint8_t tmp;
msg->auth_request.method = SSH_AUTH_METHOD_PASSWORD;
rc = ssh_buffer_unpack(packet, "bs", &tmp, &msg->auth_request.password);
if (rc != SSH_OK) {
goto error;
}
goto end;
}
if (strcmp(method, "keyboard-interactive") == 0) {
ssh_string lang = NULL;
ssh_string submethods = NULL;
msg->auth_request.method = SSH_AUTH_METHOD_INTERACTIVE;
lang = ssh_buffer_get_ssh_string(packet);
if (lang == NULL) {
goto error;
}
/* from the RFC 4256
* 3.1. Initial Exchange
* "The language tag is deprecated and SHOULD be the empty string."
*/
SSH_STRING_FREE(lang);
submethods = ssh_buffer_get_ssh_string(packet);
if (submethods == NULL) {
goto error;
}
/* from the RFC 4256
* 3.1. Initial Exchange
* "One possible implementation strategy of the submethods field on the
* server is that, unless the user may use multiple different
* submethods, the server ignores this field."
*/
SSH_STRING_FREE(submethods);
goto end;
}
if (strcmp(method, "publickey") == 0) {
ssh_string algo = NULL;
ssh_string pubkey_blob = NULL;
uint8_t has_sign;
msg->auth_request.method = SSH_AUTH_METHOD_PUBLICKEY;
SAFE_FREE(method);
rc = ssh_buffer_unpack(packet, "bSS",
&has_sign,
&algo,
&pubkey_blob
);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_pki_import_pubkey_blob(pubkey_blob, &msg->auth_request.pubkey);
SSH_STRING_FREE(pubkey_blob);
pubkey_blob = NULL;
if (rc < 0) {
SSH_STRING_FREE(algo);
algo = NULL;
goto error; goto error;
} }
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_NONE; msg->type = SSH_REQUEST_AUTH;
msg->auth_request.sigtype = strdup(ssh_string_get_char(algo)); rc = ssh_buffer_unpack(packet,
if (msg->auth_request.sigtype == NULL) { "sss",
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR; &msg->auth_request.username,
SSH_STRING_FREE(algo); &service,
algo = NULL; &method);
if (rc != SSH_OK) {
goto error; goto error;
} }
// has a valid signature ? SSH_LOG(SSH_LOG_PACKET,
if(has_sign) { "Auth request for service %s, method %s for user '%s'",
ssh_string sig_blob = NULL; service,
ssh_buffer digest = NULL; method,
msg->auth_request.username);
sig_blob = ssh_buffer_get_ssh_string(packet); cmp = strcmp(service, "ssh-connection");
if(sig_blob == NULL) { if (cmp != 0) {
SSH_LOG(SSH_LOG_PACKET, "Invalid signature packet from peer"); SSH_LOG(SSH_LOG_TRACE, "Invalid service request: %s", service);
goto end;
}
if (strcmp(method, "none") == 0) {
msg->auth_request.method = SSH_AUTH_METHOD_NONE;
goto end;
}
if (strcmp(method, "password") == 0) {
uint8_t tmp;
msg->auth_request.method = SSH_AUTH_METHOD_PASSWORD;
rc = ssh_buffer_unpack(packet, "bs", &tmp, &msg->auth_request.password);
if (rc != SSH_OK) {
goto error;
}
goto end;
}
if (strcmp(method, "keyboard-interactive") == 0) {
ssh_string lang = NULL;
ssh_string submethods = NULL;
msg->auth_request.method = SSH_AUTH_METHOD_INTERACTIVE;
lang = ssh_buffer_get_ssh_string(packet);
if (lang == NULL) {
goto error;
}
/* from the RFC 4256
* 3.1. Initial Exchange
* "The language tag is deprecated and SHOULD be the empty string."
*/
SSH_STRING_FREE(lang);
submethods = ssh_buffer_get_ssh_string(packet);
if (submethods == NULL) {
goto error;
}
/* from the RFC 4256
* 3.1. Initial Exchange
* "One possible implementation strategy of the submethods field on the
* server is that, unless the user may use multiple different
* submethods, the server ignores this field."
*/
SSH_STRING_FREE(submethods);
goto end;
}
if (strcmp(method, "publickey") == 0) {
ssh_string algo = NULL;
ssh_string pubkey_blob = NULL;
uint8_t has_sign;
msg->auth_request.method = SSH_AUTH_METHOD_PUBLICKEY;
SAFE_FREE(method);
rc = ssh_buffer_unpack(packet, "bSS", &has_sign, &algo, &pubkey_blob);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_pki_import_pubkey_blob(pubkey_blob, &msg->auth_request.pubkey);
SSH_STRING_FREE(pubkey_blob);
pubkey_blob = NULL;
if (rc < 0) {
SSH_STRING_FREE(algo);
algo = NULL;
goto error;
}
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_NONE;
msg->auth_request.sigtype = strdup(ssh_string_get_char(algo));
if (msg->auth_request.sigtype == NULL) {
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR; msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR;
SSH_STRING_FREE(algo); SSH_STRING_FREE(algo);
algo = NULL; algo = NULL;
goto error; goto error;
} }
digest = ssh_msg_userauth_build_digest(session, msg, service, algo); // has a valid signature ?
SSH_STRING_FREE(algo); if (has_sign) {
algo = NULL; ssh_string sig_blob = NULL;
if (digest == NULL) { ssh_buffer digest = NULL;
SSH_STRING_FREE(sig_blob);
SSH_LOG(SSH_LOG_PACKET, "Failed to get digest");
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG;
goto error;
}
rc = ssh_pki_import_signature_blob(sig_blob, sig_blob = ssh_buffer_get_ssh_string(packet);
msg->auth_request.pubkey, if (sig_blob == NULL) {
&sig); SSH_LOG(SSH_LOG_PACKET, "Invalid signature packet from peer");
if (rc == SSH_OK) { msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR;
/* Check if the signature from client matches server preferences */ SSH_STRING_FREE(algo);
if (session->opts.pubkey_accepted_types) { algo = NULL;
cmp = match_group(session->opts.pubkey_accepted_types, goto error;
sig->type_c); }
if (cmp != 1) {
ssh_set_error(session, digest = ssh_msg_userauth_build_digest(session, msg, service, algo);
SSH_STRING_FREE(algo);
algo = NULL;
if (digest == NULL) {
SSH_STRING_FREE(sig_blob);
SSH_LOG(SSH_LOG_PACKET, "Failed to get digest");
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG;
goto error;
}
rc = ssh_pki_import_signature_blob(sig_blob,
msg->auth_request.pubkey,
&sig);
if (rc == SSH_OK) {
/* Check if the signature from client matches server preferences
*/
if (session->opts.pubkey_accepted_types) {
cmp = match_group(session->opts.pubkey_accepted_types,
sig->type_c);
if (cmp != 1) {
ssh_set_error(
session,
SSH_FATAL, SSH_FATAL,
"Public key from client (%s) doesn't match server " "Public key from client (%s) doesn't match server "
"preference (%s)", "preference (%s)",
sig->type_c, sig->type_c,
session->opts.pubkey_accepted_types); session->opts.pubkey_accepted_types);
rc = SSH_ERROR; rc = SSH_ERROR;
}
}
if (rc == SSH_OK) {
rc = ssh_pki_signature_verify(session,
sig,
msg->auth_request.pubkey,
ssh_buffer_get(digest),
ssh_buffer_get_len(digest));
} }
} }
SSH_STRING_FREE(sig_blob);
if (rc == SSH_OK) { SSH_BUFFER_FREE(digest);
rc = ssh_pki_signature_verify(session, ssh_signature_free(sig);
sig, if (rc < 0) {
msg->auth_request.pubkey, SSH_LOG(SSH_LOG_PACKET,
ssh_buffer_get(digest), "Received an invalid signature from peer");
ssh_buffer_get_len(digest)); msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG;
goto error;
} }
SSH_LOG(SSH_LOG_PACKET, "Valid signature received");
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_VALID;
} }
SSH_STRING_FREE(sig_blob); SSH_STRING_FREE(algo);
SSH_BUFFER_FREE(digest); goto end;
ssh_signature_free(sig); }
if (rc < 0) { #ifdef WITH_GSSAPI
SSH_LOG( if (strcmp(method, "gssapi-with-mic") == 0) {
SSH_LOG_PACKET, uint32_t n_oid;
"Received an invalid signature from peer"); ssh_string *oids;
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG; ssh_string oid;
char *hexa;
int i;
ssh_buffer_get_u32(packet, &n_oid);
n_oid = ntohl(n_oid);
if (n_oid > 100) {
ssh_set_error(
session,
SSH_FATAL,
"USERAUTH_REQUEST: gssapi-with-mic OID count too big (%d)",
n_oid);
goto error; goto error;
} }
SSH_LOG(SSH_LOG_PACKET, "gssapi: %d OIDs", n_oid);
oids = calloc(n_oid, sizeof(ssh_string));
if (oids == NULL) {
ssh_set_error_oom(session);
goto error;
}
for (i = 0; i < (int)n_oid; ++i) {
oid = ssh_buffer_get_ssh_string(packet);
if (oid == NULL) {
for (i = i - 1; i >= 0; --i) {
SAFE_FREE(oids[i]);
}
SAFE_FREE(oids);
ssh_set_error(session,
SSH_LOG_PACKET,
"USERAUTH_REQUEST: gssapi-with-mic missing OID");
goto error;
}
oids[i] = oid;
if (session->common.log_verbosity >= SSH_LOG_PACKET) {
hexa = ssh_get_hexa(ssh_string_data(oid), ssh_string_len(oid));
SSH_LOG(SSH_LOG_PACKET, "gssapi: OID %d: %s", i, hexa);
SAFE_FREE(hexa);
}
}
ssh_gssapi_handle_userauth(session,
msg->auth_request.username,
n_oid,
oids);
SSH_LOG(SSH_LOG_PACKET, "Valid signature received"); for (i = 0; i < (int)n_oid; ++i) {
SAFE_FREE(oids[i]);
}
SAFE_FREE(oids);
/* bypass the message queue thing */
SAFE_FREE(service);
SAFE_FREE(method);
SSH_MESSAGE_FREE(msg);
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_VALID; return SSH_PACKET_USED;
} }
SSH_STRING_FREE(algo);
goto end;
}
#ifdef WITH_GSSAPI
if (strcmp(method, "gssapi-with-mic") == 0) {
uint32_t n_oid;
ssh_string *oids;
ssh_string oid;
char *hexa;
int i;
ssh_buffer_get_u32(packet, &n_oid);
n_oid=ntohl(n_oid);
if(n_oid > 100){
ssh_set_error(session, SSH_FATAL, "USERAUTH_REQUEST: gssapi-with-mic OID count too big (%d)",n_oid);
goto error;
}
SSH_LOG(SSH_LOG_PACKET, "gssapi: %d OIDs", n_oid);
oids = calloc(n_oid, sizeof(ssh_string));
if (oids == NULL){
ssh_set_error_oom(session);
goto error;
}
for (i=0;i<(int) n_oid;++i){
oid=ssh_buffer_get_ssh_string(packet);
if(oid == NULL){
for(i=i-1;i>=0;--i){
SAFE_FREE(oids[i]);
}
SAFE_FREE(oids);
ssh_set_error(session, SSH_LOG_PACKET, "USERAUTH_REQUEST: gssapi-with-mic missing OID");
goto error;
}
oids[i] = oid;
if(session->common.log_verbosity >= SSH_LOG_PACKET){
hexa = ssh_get_hexa(ssh_string_data(oid), ssh_string_len(oid));
SSH_LOG(SSH_LOG_PACKET,"gssapi: OID %d: %s",i, hexa);
SAFE_FREE(hexa);
}
}
ssh_gssapi_handle_userauth(session, msg->auth_request.username, n_oid, oids);
for(i=0;i<(int)n_oid;++i){
SAFE_FREE(oids[i]);
}
SAFE_FREE(oids);
/* bypass the message queue thing */
SAFE_FREE(service);
SAFE_FREE(method);
SSH_MESSAGE_FREE(msg);
return SSH_PACKET_USED;
}
#endif #endif
msg->auth_request.method = SSH_AUTH_METHOD_UNKNOWN; msg->auth_request.method = SSH_AUTH_METHOD_UNKNOWN;
SAFE_FREE(method); SAFE_FREE(method);
goto end; goto end;
error: error:
SAFE_FREE(service); SAFE_FREE(service);
SAFE_FREE(method); SAFE_FREE(method);
SSH_MESSAGE_FREE(msg); SSH_MESSAGE_FREE(msg);
return SSH_PACKET_USED; return SSH_PACKET_USED;
end: end:
SAFE_FREE(service); SAFE_FREE(service);
SAFE_FREE(method); SAFE_FREE(method);
ssh_message_queue(session,msg); ssh_message_queue(session, msg);
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
#endif /* WITH_SERVER */ #endif /* WITH_SERVER */