mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-10 10:26:47 +09:00
feat: add SSH2_MSG_KEXGSS_HOSTKEY support to client and server
Signed-off-by: Gauravsingh Sisodia <xaerru@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Jakub Jelen
parent
9044fcdb52
commit
d730b40b91
@@ -30,6 +30,7 @@ int ssh_client_gss_dh_init(ssh_session session);
|
|||||||
void ssh_server_gss_dh_init(ssh_session session);
|
void ssh_server_gss_dh_init(ssh_session session);
|
||||||
int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet);
|
int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet);
|
||||||
void ssh_client_gss_dh_remove_callbacks(ssh_session session);
|
void ssh_client_gss_dh_remove_callbacks(ssh_session session);
|
||||||
|
void ssh_client_gss_dh_remove_callback_hostkey(ssh_session session);
|
||||||
|
|
||||||
#endif /* WITH_GSSAPI */
|
#endif /* WITH_GSSAPI */
|
||||||
#endif /* DH_GSS_H_ */
|
#endif /* DH_GSS_H_ */
|
||||||
|
|||||||
72
src/dh-gss.c
72
src/dh-gss.c
@@ -49,6 +49,19 @@ static struct ssh_packet_callbacks_struct ssh_gss_dh_client_callbacks = {
|
|||||||
.user = NULL
|
.user = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_client_gss_dh_hostkey);
|
||||||
|
|
||||||
|
static ssh_packet_callback gss_dh_client_callback_hostkey[]= {
|
||||||
|
ssh_packet_client_gss_dh_hostkey
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ssh_packet_callbacks_struct ssh_gss_dh_client_callback_hostkey = {
|
||||||
|
.start = SSH2_MSG_KEXGSS_HOSTKEY,
|
||||||
|
.n_callbacks = 1,
|
||||||
|
.callbacks = gss_dh_client_callback_hostkey,
|
||||||
|
.user = NULL
|
||||||
|
};
|
||||||
|
|
||||||
/** @internal
|
/** @internal
|
||||||
* @brief Starts gssapi key exchange
|
* @brief Starts gssapi key exchange
|
||||||
*/
|
*/
|
||||||
@@ -131,6 +144,7 @@ int ssh_client_gss_dh_init(ssh_session session){
|
|||||||
|
|
||||||
/* register the packet callbacks */
|
/* register the packet callbacks */
|
||||||
ssh_packet_set_callbacks(session, &ssh_gss_dh_client_callbacks);
|
ssh_packet_set_callbacks(session, &ssh_gss_dh_client_callbacks);
|
||||||
|
ssh_packet_set_callbacks(session, &ssh_gss_dh_client_callback_hostkey);
|
||||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||||
|
|
||||||
rc = ssh_packet_send(session);
|
rc = ssh_packet_send(session);
|
||||||
@@ -148,6 +162,11 @@ void ssh_client_gss_dh_remove_callbacks(ssh_session session)
|
|||||||
ssh_packet_remove_callbacks(session, &ssh_gss_dh_client_callbacks);
|
ssh_packet_remove_callbacks(session, &ssh_gss_dh_client_callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ssh_client_gss_dh_remove_callback_hostkey(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_packet_remove_callbacks(session, &ssh_gss_dh_client_callback_hostkey);
|
||||||
|
}
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_client_gss_dh_reply){
|
SSH_PACKET_CALLBACK(ssh_packet_client_gss_dh_reply){
|
||||||
struct ssh_crypto_struct *crypto=session->next_crypto;
|
struct ssh_crypto_struct *crypto=session->next_crypto;
|
||||||
ssh_string pubkey_blob = NULL, mic = NULL, otoken = NULL;
|
ssh_string pubkey_blob = NULL, mic = NULL, otoken = NULL;
|
||||||
@@ -211,6 +230,35 @@ error:
|
|||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_client_gss_dh_hostkey) {
|
||||||
|
ssh_string pubkey_blob = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
(void)type;
|
||||||
|
(void)user;
|
||||||
|
|
||||||
|
ssh_client_gss_dh_remove_callback_hostkey(session);
|
||||||
|
|
||||||
|
rc = ssh_buffer_unpack(packet,
|
||||||
|
"S",
|
||||||
|
&pubkey_blob);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Invalid SSH2_MSG_KEXGSS_HOSTKEY packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||||
|
SSH_STRING_FREE(pubkey_blob);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
error:
|
||||||
|
ssh_dh_cleanup(session->next_crypto);
|
||||||
|
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
|
|
||||||
@@ -256,6 +304,7 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
|
|||||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||||
ssh_string otoken = NULL;
|
ssh_string otoken = NULL;
|
||||||
|
ssh_string server_pubkey_blob = NULL;
|
||||||
OM_uint32 maj_stat, min_stat;
|
OM_uint32 maj_stat, min_stat;
|
||||||
gss_name_t client_name = GSS_C_NO_NAME;
|
gss_name_t client_name = GSS_C_NO_NAME;
|
||||||
OM_uint32 ret_flags=0;
|
OM_uint32 ret_flags=0;
|
||||||
@@ -307,6 +356,28 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
|
|||||||
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = ssh_dh_get_next_server_publickey_blob(session, &server_pubkey_blob);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
rc = ssh_buffer_pack(session->out_buffer,
|
||||||
|
"bS",
|
||||||
|
SSH2_MSG_KEXGSS_HOSTKEY,
|
||||||
|
server_pubkey_blob);
|
||||||
|
if(rc != SSH_OK) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
ssh_buffer_reinit(session->out_buffer);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
SSH_LOG(SSH_LOG_DEBUG, "Sent SSH2_MSG_KEXGSS_HOSTKEY");
|
||||||
|
SSH_STRING_FREE(server_pubkey_blob);
|
||||||
|
|
||||||
rc = ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
|
rc = ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
|
||||||
NULL, &server_pubkey);
|
NULL, &server_pubkey);
|
||||||
if (rc != SSH_OK){
|
if (rc != SSH_OK){
|
||||||
@@ -414,6 +485,7 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
|
|||||||
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
error:
|
error:
|
||||||
|
SSH_STRING_FREE(server_pubkey_blob);
|
||||||
#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
bignum_safe_free(server_pubkey);
|
bignum_safe_free(server_pubkey);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1480,7 +1480,7 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->server) {
|
if (session->server) {
|
||||||
if (ssh_kex_is_gss(session->next_crypto)) {
|
if (server_pubkey_blob == NULL && ssh_kex_is_gss(session->next_crypto)) {
|
||||||
ssh_string_free(server_pubkey_blob);
|
ssh_string_free(server_pubkey_blob);
|
||||||
server_pubkey_blob = ssh_string_new(0);
|
server_pubkey_blob = ssh_string_new(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user