auth: Cleanup memory leak when using SSH agent
In Cockpit we've seen this memory leak: at 0x4C2A9C7: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x5B76B03: ssh_userauth_agent (auth.c:778) by 0x40DD5A: cockpit_ssh_authenticate (cockpitsshtransport.c:327) BUG: https://red.libssh.org/issues/208 Signed-off-by: Stef Walter <stefw@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
родитель
aa5c7c3b0c
Коммит
ffe8b98cc2
@ -361,5 +361,7 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
|
||||
|
||||
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)
|
||||
|
||||
void ssh_agent_state_free(void *data);
|
||||
|
||||
#endif /* _LIBSSH_PRIV_H */
|
||||
/* vim: set ts=4 sw=4 et cindent: */
|
||||
|
27
src/auth.c
27
src/auth.c
@ -745,6 +745,15 @@ struct ssh_agent_state_struct {
|
||||
char *comment;
|
||||
};
|
||||
|
||||
/* Internal function */
|
||||
void ssh_agent_state_free(void *data) {
|
||||
struct ssh_agent_state_struct *state = data;
|
||||
if (state) {
|
||||
ssh_string_free_char(state->comment);
|
||||
ssh_key_free(state->pubkey);
|
||||
free (state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to do public key authentication with ssh agent.
|
||||
@ -805,9 +814,8 @@ int ssh_userauth_agent(ssh_session session,
|
||||
state->state == SSH_AGENT_STATE_PUBKEY){
|
||||
rc = ssh_userauth_try_publickey(session, username, state->pubkey);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
ssh_string_free_char(state->comment);
|
||||
ssh_key_free(state->pubkey);
|
||||
SAFE_FREE(session->agent_state);
|
||||
ssh_agent_state_free (state);
|
||||
session->agent_state = NULL;
|
||||
return rc;
|
||||
} else if (rc == SSH_AUTH_AGAIN) {
|
||||
state->state = SSH_AGENT_STATE_PUBKEY;
|
||||
@ -816,6 +824,7 @@ int ssh_userauth_agent(ssh_session session,
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"Public key of %s refused by server", state->comment);
|
||||
ssh_string_free_char(state->comment);
|
||||
state->comment = NULL;
|
||||
ssh_key_free(state->pubkey);
|
||||
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
|
||||
state->state = SSH_AGENT_STATE_NONE;
|
||||
@ -831,23 +840,27 @@ int ssh_userauth_agent(ssh_session session,
|
||||
if (rc == SSH_AUTH_AGAIN)
|
||||
return rc;
|
||||
ssh_string_free_char(state->comment);
|
||||
ssh_key_free(state->pubkey);
|
||||
state->comment = NULL;
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
SAFE_FREE(session->agent_state);
|
||||
ssh_agent_state_free (session->agent_state);
|
||||
session->agent_state = NULL;
|
||||
return rc;
|
||||
} else if (rc != SSH_AUTH_SUCCESS) {
|
||||
SSH_LOG(SSH_LOG_INFO,
|
||||
"Server accepted public key but refused the signature");
|
||||
ssh_key_free(state->pubkey);
|
||||
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
|
||||
state->state = SSH_AGENT_STATE_NONE;
|
||||
continue;
|
||||
}
|
||||
SAFE_FREE(session->agent_state);
|
||||
ssh_agent_state_free (session->agent_state);
|
||||
session->agent_state = NULL;
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(session->agent_state);
|
||||
ssh_agent_state_free (session->agent_state);
|
||||
session->agent_state = NULL;
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
@ -261,6 +261,9 @@ void ssh_free(ssh_session session) {
|
||||
ssh_list_free(session->opts.identity);
|
||||
}
|
||||
|
||||
ssh_agent_state_free (session->agent_state);
|
||||
session->agent_state = NULL;
|
||||
|
||||
SAFE_FREE(session->auth_auto_state);
|
||||
SAFE_FREE(session->serverbanner);
|
||||
SAFE_FREE(session->clientbanner);
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user