mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-07 02:39:48 +09:00
feat: add null hostkey for server
fix: skip gssapi tests in fips mode fix: skip gssapi_key_exchange_null test on ubuntu and tumbleweed fix: return early when rc != 0 to show error tests: replace int asserts by ssh return code asserts fix: add fatal error when hostkeys are not found and gssapi kex is not enabled ci: add comment linking gssapi null kex bug in ubuntu and tumbleweed fix: don't specify hostkeys in config instead of deleting files tests: assert kex method was null refactor: remove redundant include refactor: better error message fix: check null before accessing in gssapi.c fix: allow setting no hostkeys 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
fd1c3e8878
commit
c1aab9903f
@@ -2456,7 +2456,7 @@ pending:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to authenticate through the "gssapi-with-keyex" method.
|
||||
* @brief Try to authenticate through the "gssapi-keyex" method.
|
||||
*
|
||||
* @param[in] session The ssh session to use.
|
||||
*
|
||||
@@ -2503,7 +2503,7 @@ int ssh_userauth_gssapi_keyex(ssh_session session)
|
||||
} else if (rc == SSH_ERROR) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Authenticating with gssapi-with-keyex");
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Authenticating with gssapi-keyex");
|
||||
|
||||
session->auth.current_method = SSH_AUTH_METHOD_GSSAPI_KEYEX;
|
||||
session->auth.state = SSH_AUTH_STATE_NONE;
|
||||
|
||||
19
src/bind.c
19
src/bind.c
@@ -245,8 +245,13 @@ int ssh_bind_listen(ssh_bind sshbind)
|
||||
sshbind->ecdsa == NULL &&
|
||||
sshbind->ed25519 == NULL) {
|
||||
rc = ssh_bind_import_keys(sshbind);
|
||||
if (rc != SSH_OK) {
|
||||
return SSH_ERROR;
|
||||
if (rc == SSH_ERROR) {
|
||||
if (!sshbind->gssapi_key_exchange) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"No hostkeys found");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_DEBUG, "No hostkeys found: Using \"null\" hostkey algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,6 +472,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
|
||||
session->opts.gssapi_key_exchange = sshbind->gssapi_key_exchange;
|
||||
|
||||
if (sshbind->gssapi_key_exchange_algs != NULL) {
|
||||
SAFE_FREE(session->opts.gssapi_key_exchange_algs);
|
||||
session->opts.gssapi_key_exchange_algs = strdup(sshbind->gssapi_key_exchange_algs);
|
||||
if (session->opts.gssapi_key_exchange_algs == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
@@ -519,8 +525,13 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
|
||||
sshbind->ecdsa == NULL &&
|
||||
sshbind->ed25519 == NULL) {
|
||||
rc = ssh_bind_import_keys(sshbind);
|
||||
if (rc != SSH_OK) {
|
||||
return SSH_ERROR;
|
||||
if (rc == SSH_ERROR) {
|
||||
if (!sshbind->gssapi_key_exchange) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"No hostkeys found");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_DEBUG, "No hostkeys found: Using \"null\" hostkey algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
48
src/dh-gss.c
48
src/dh-gss.c
@@ -338,11 +338,6 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_dh_compute_shared_secret(crypto->dh_ctx,
|
||||
DH_SERVER_KEYPAIR, DH_CLIENT_KEYPAIR,
|
||||
&crypto->shared_secret);
|
||||
@@ -351,32 +346,39 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
|
||||
ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Also imports next_crypto->server_pubkey
|
||||
* Can give error when using null hostkey */
|
||||
ssh_get_key_params(session, &privkey, &digest);
|
||||
|
||||
rc = ssh_make_sessionid(session);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||
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;
|
||||
}
|
||||
if (strncmp(crypto->kex_methods[SSH_HOSTKEYS], "null", 4) != 0) {
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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,
|
||||
NULL, &server_pubkey);
|
||||
|
||||
@@ -727,6 +727,10 @@ ssh_gssapi_check_client_config(ssh_session session)
|
||||
|
||||
for (i = 0; i < supported->count; ++i){
|
||||
gssapi = calloc(1, sizeof(struct ssh_gssapi_struct));
|
||||
if (gssapi == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
gssapi->server_creds = GSS_C_NO_CREDENTIAL;
|
||||
gssapi->client_creds = GSS_C_NO_CREDENTIAL;
|
||||
gssapi->ctx = GSS_C_NO_CONTEXT;
|
||||
@@ -786,7 +790,7 @@ ssh_gssapi_check_client_config(ssh_session session)
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Supported mech %zu: %s", i, ptr);
|
||||
free(ptr);
|
||||
|
||||
/* If any one is configured then return successfully */
|
||||
/* If atleast one mechanism is configured then return successfully */
|
||||
ret = SSH_OK;
|
||||
|
||||
end:
|
||||
|
||||
20
src/kex.c
20
src/kex.c
@@ -811,7 +811,7 @@ int ssh_set_client_kex(ssh_session session)
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#ifdef WITH_GSSAPI
|
||||
if (session->opts.gssapi_key_exchange) {
|
||||
if (session->opts.gssapi_key_exchange && !ssh_fips_mode()) {
|
||||
char *gssapi_algs = NULL;
|
||||
|
||||
ok = ssh_gssapi_init(session);
|
||||
@@ -825,7 +825,7 @@ int ssh_set_client_kex(ssh_session session)
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
gssapi_algs = ssh_gssapi_kex_mechs(session, session->opts.gssapi_key_exchange_algs ? session->opts.gssapi_key_exchange_algs : GSSAPI_KEY_EXCHANGE_SUPPORTED);
|
||||
gssapi_algs = ssh_gssapi_kex_mechs(session, session->opts.gssapi_key_exchange_algs);
|
||||
if (gssapi_algs == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -1488,15 +1488,15 @@ int ssh_make_sessionid(ssh_session session)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (server_pubkey_blob == NULL && session->opts.gssapi_key_exchange) {
|
||||
ssh_string_free(server_pubkey_blob);
|
||||
server_pubkey_blob = ssh_string_new(0);
|
||||
}
|
||||
|
||||
if (session->server) {
|
||||
if (server_pubkey_blob == NULL && ssh_kex_is_gss(session->next_crypto)) {
|
||||
ssh_string_free(server_pubkey_blob);
|
||||
if (server_pubkey_blob == NULL) {
|
||||
if ((session->server && ssh_kex_is_gss(session->next_crypto)) ||
|
||||
session->opts.gssapi_key_exchange) {
|
||||
server_pubkey_blob = ssh_string_new(0);
|
||||
if (server_pubkey_blob == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
rc = SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -566,7 +566,7 @@ int ssh_options_set_algo(ssh_session session,
|
||||
* to the server (int, 0 = false).
|
||||
*
|
||||
* - SSH_OPTIONS_GSSAPI_KEY_EXCHANGE
|
||||
* Set to true to do GSSAPI key exchange (bool).
|
||||
* Set to true to allow GSSAPI key exchange (bool).
|
||||
*
|
||||
* - SSH_OPTIONS_GSSAPI_KEY_EXCHANGE_ALGS
|
||||
* Set the GSSAPI key exchange method to be used (const char *,
|
||||
@@ -1285,6 +1285,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
"GSSAPI key exchange algorithms not supported or invalid");
|
||||
return -1;
|
||||
}
|
||||
SAFE_FREE(session->opts.gssapi_key_exchange_algs);
|
||||
session->opts.gssapi_key_exchange_algs = ret;
|
||||
}
|
||||
break;
|
||||
|
||||
45
src/server.c
45
src/server.c
@@ -141,10 +141,6 @@ int server_set_kex(ssh_session session)
|
||||
",%s", ssh_key_type_to_char(keytype));
|
||||
}
|
||||
|
||||
if (strlen(hostkeys) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (session->opts.wanted_methods[SSH_HOSTKEYS]) {
|
||||
allowed = session->opts.wanted_methods[SSH_HOSTKEYS];
|
||||
} else {
|
||||
@@ -155,33 +151,34 @@ int server_set_kex(ssh_session session)
|
||||
}
|
||||
}
|
||||
|
||||
/* It is expected for the list of allowed hostkeys to be ordered by
|
||||
* preference */
|
||||
kept = ssh_find_all_matching(hostkeys[0] == ',' ? hostkeys + 1 : hostkeys,
|
||||
allowed);
|
||||
if (kept == NULL) {
|
||||
/* Nothing was allowed */
|
||||
return -1;
|
||||
}
|
||||
if (strlen(hostkeys) != 0) {
|
||||
/* It is expected for the list of allowed hostkeys to be ordered by
|
||||
* preference */
|
||||
kept = ssh_find_all_matching(hostkeys[0] == ',' ? hostkeys + 1 : hostkeys,
|
||||
allowed);
|
||||
if (kept == NULL) {
|
||||
/* Nothing was allowed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_options_set_algo(session,
|
||||
SSH_HOSTKEYS,
|
||||
kept,
|
||||
&session->opts.wanted_methods[SSH_HOSTKEYS]);
|
||||
SAFE_FREE(kept);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
rc = ssh_options_set_algo(session,
|
||||
SSH_HOSTKEYS,
|
||||
kept,
|
||||
&session->opts.wanted_methods[SSH_HOSTKEYS]);
|
||||
SAFE_FREE(kept);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_GSSAPI
|
||||
if (session->opts.gssapi_key_exchange) {
|
||||
if (session->opts.gssapi_key_exchange && !ssh_fips_mode()) {
|
||||
ok = ssh_gssapi_init(session);
|
||||
if (ok != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
gssapi_algs = ssh_gssapi_kex_mechs(session, session->opts.gssapi_key_exchange_algs ? session->opts.gssapi_key_exchange_algs : GSSAPI_KEY_EXCHANGE_SUPPORTED);
|
||||
gssapi_algs = ssh_gssapi_kex_mechs(session, session->opts.gssapi_key_exchange_algs);
|
||||
if (gssapi_algs == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -191,6 +188,10 @@ int server_set_kex(ssh_session session)
|
||||
session->opts.wanted_methods[SSH_KEX] =
|
||||
ssh_prefix_without_duplicates(ssh_kex_get_default_methods(SSH_KEX), gssapi_algs);
|
||||
|
||||
if (strlen(hostkeys) == 0) {
|
||||
session->opts.wanted_methods[SSH_HOSTKEYS] = strdup("null");
|
||||
}
|
||||
|
||||
SAFE_FREE(gssapi_algs);
|
||||
}
|
||||
#endif /* WITH_GSSAPI */
|
||||
|
||||
@@ -160,6 +160,13 @@ ssh_session ssh_new(void)
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef WITH_GSSAPI
|
||||
session->opts.gssapi_key_exchange_algs = strdup(GSSAPI_KEY_EXCHANGE_SUPPORTED);
|
||||
if (session->opts.gssapi_key_exchange_algs == NULL) {
|
||||
goto err;
|
||||
}
|
||||
#endif /* WITH_GSSAPI */
|
||||
|
||||
id = strdup("%d/id_ed25519");
|
||||
if (id == NULL) {
|
||||
goto err;
|
||||
|
||||
Reference in New Issue
Block a user