mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-07-31 00:03:07 +03:00
auth: Add ssh_userauth_publickey_auto_get_current_identity()
Signed-off-by: Marius Vollmer <mvollmer@redhat.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
026879e9f0
commit
abc88c025c
@ -757,6 +757,8 @@ LIBSSH_API int ssh_userauth_publickey(ssh_session session,
|
|||||||
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
||||||
const char *username);
|
const char *username);
|
||||||
#endif
|
#endif
|
||||||
|
LIBSSH_API int ssh_userauth_publickey_auto_get_current_identity(ssh_session session,
|
||||||
|
char** value);
|
||||||
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
||||||
const char *username,
|
const char *username,
|
||||||
const char *passphrase);
|
const char *passphrase);
|
||||||
|
49
src/auth.c
49
src/auth.c
@ -975,6 +975,55 @@ struct ssh_auth_auto_state_struct {
|
|||||||
ssh_key pubkey;
|
ssh_key pubkey;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the identity that is currenly being processed by
|
||||||
|
* ssh_userauth_publickey_auto()
|
||||||
|
*
|
||||||
|
* This is meant to be used by a callback that happens as part of the
|
||||||
|
* execution of ssh_userauth_publickey_auto(). The auth_function
|
||||||
|
* callback might want to know which key a passphrase is needed for,
|
||||||
|
* for example.
|
||||||
|
*
|
||||||
|
* @param[in] session The SSH session.
|
||||||
|
*
|
||||||
|
* @param[out] value The value to get into. As a char**, space will be
|
||||||
|
* allocated by the function for the value, it is
|
||||||
|
* your responsibility to free the memory using
|
||||||
|
* ssh_string_free_char().
|
||||||
|
*
|
||||||
|
* @return SSH_OK on success, SSH_ERROR on error.
|
||||||
|
*/
|
||||||
|
int ssh_userauth_publickey_auto_get_current_identity(ssh_session session,
|
||||||
|
char** value)
|
||||||
|
{
|
||||||
|
const char *id = NULL;
|
||||||
|
|
||||||
|
if (session == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == NULL) {
|
||||||
|
ssh_set_error_invalid(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->auth.auto_state != NULL && session->auth.auto_state->it != NULL) {
|
||||||
|
id = session->auth.auto_state->it->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = strdup(id);
|
||||||
|
if (*value == NULL) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tries to automatically authenticate with public key and "none"
|
* @brief Tries to automatically authenticate with public key and "none"
|
||||||
*
|
*
|
||||||
|
@ -402,6 +402,7 @@ LIBSSH_4_5_0 # Released
|
|||||||
ssh_userauth_pubkey;
|
ssh_userauth_pubkey;
|
||||||
ssh_userauth_publickey;
|
ssh_userauth_publickey;
|
||||||
ssh_userauth_publickey_auto;
|
ssh_userauth_publickey_auto;
|
||||||
|
ssh_userauth_publickey_auto_get_current_identity;
|
||||||
ssh_userauth_try_publickey;
|
ssh_userauth_try_publickey;
|
||||||
ssh_version;
|
ssh_version;
|
||||||
ssh_write_knownhost;
|
ssh_write_knownhost;
|
||||||
|
@ -208,6 +208,9 @@ if (CLIENT_TESTING OR SERVER_TESTING)
|
|||||||
# Give bob some keys
|
# Give bob some keys
|
||||||
file(COPY keys/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
file(COPY keys/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
file(COPY keys/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
file(COPY keys/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
|
# Same as id_rsa, protected with passphrase "secret"
|
||||||
|
file(COPY keys/id_rsa_protected DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
|
file(COPY keys/id_rsa_protected.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
file(COPY keys/id_ecdsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
file(COPY keys/id_ecdsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
file(COPY keys/id_ecdsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
file(COPY keys/id_ecdsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
file(COPY keys/id_ed25519 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
file(COPY keys/id_ed25519 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
|
@ -281,6 +281,96 @@ static void torture_auth_autopubkey(void **state) {
|
|||||||
assert_int_equal(rc, SSH_AUTH_SUCCESS);
|
assert_int_equal(rc, SSH_AUTH_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct torture_auth_autopubkey_protected_data {
|
||||||
|
ssh_session session;
|
||||||
|
int n_calls;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
torture_auth_autopubkey_protected_auth_function (const char *prompt, char *buf, size_t len,
|
||||||
|
int echo, int verify, void *userdata)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char *id, *expected_id;
|
||||||
|
struct torture_auth_autopubkey_protected_data *data = userdata;
|
||||||
|
|
||||||
|
assert_true(prompt != NULL);
|
||||||
|
assert_int_equal(echo, 0);
|
||||||
|
assert_int_equal(verify, 0);
|
||||||
|
|
||||||
|
expected_id = ssh_path_expand_escape(data->session, "%d/id_rsa_protected");
|
||||||
|
assert_true(expected_id != NULL);
|
||||||
|
|
||||||
|
rc = ssh_userauth_publickey_auto_get_current_identity(data->session, &id);
|
||||||
|
assert_int_equal(rc, SSH_OK);
|
||||||
|
|
||||||
|
assert_string_equal(expected_id, id);
|
||||||
|
|
||||||
|
ssh_string_free_char(id);
|
||||||
|
ssh_string_free_char(expected_id);
|
||||||
|
|
||||||
|
data->n_calls += 1;
|
||||||
|
strncpy(buf, "secret", len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_auth_autopubkey_protected(void **state) {
|
||||||
|
struct torture_state *s = *state;
|
||||||
|
ssh_session session = s->ssh.session;
|
||||||
|
char *id;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
struct torture_auth_autopubkey_protected_data data = {
|
||||||
|
.session = session,
|
||||||
|
.n_calls = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ssh_callbacks_struct callbacks = {
|
||||||
|
.userdata = &data,
|
||||||
|
.auth_function = torture_auth_autopubkey_protected_auth_function
|
||||||
|
};
|
||||||
|
|
||||||
|
/* no session pointer */
|
||||||
|
rc = ssh_userauth_publickey_auto_get_current_identity(NULL, &id);
|
||||||
|
assert_int_equal(rc, SSH_ERROR);
|
||||||
|
|
||||||
|
/* no result pointer */
|
||||||
|
rc = ssh_userauth_publickey_auto_get_current_identity(session, NULL);
|
||||||
|
assert_int_equal(rc, SSH_ERROR);
|
||||||
|
|
||||||
|
/* no auto auth going on */
|
||||||
|
rc = ssh_userauth_publickey_auto_get_current_identity(session, &id);
|
||||||
|
assert_int_equal(rc, SSH_ERROR);
|
||||||
|
|
||||||
|
ssh_callbacks_init(&callbacks);
|
||||||
|
ssh_set_callbacks(session, &callbacks);
|
||||||
|
|
||||||
|
/* Authenticate as alice with bob his pubkey */
|
||||||
|
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
|
||||||
|
assert_int_equal(rc, SSH_OK);
|
||||||
|
|
||||||
|
/* Try id_rsa_protected first.
|
||||||
|
*/
|
||||||
|
rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, "%d/id_rsa_protected");
|
||||||
|
assert_int_equal(rc, SSH_OK);
|
||||||
|
|
||||||
|
rc = ssh_connect(session);
|
||||||
|
assert_int_equal(rc, SSH_OK);
|
||||||
|
|
||||||
|
rc = ssh_userauth_none(session,NULL);
|
||||||
|
/* This request should return a SSH_REQUEST_DENIED error */
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||||
|
}
|
||||||
|
rc = ssh_userauth_list(session, NULL);
|
||||||
|
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||||
|
|
||||||
|
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
||||||
|
assert_int_equal(rc, SSH_AUTH_SUCCESS);
|
||||||
|
|
||||||
|
assert_int_equal (data.n_calls, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void torture_auth_autopubkey_nonblocking(void **state) {
|
static void torture_auth_autopubkey_nonblocking(void **state) {
|
||||||
struct torture_state *s = *state;
|
struct torture_state *s = *state;
|
||||||
ssh_session session = s->ssh.session;
|
ssh_session session = s->ssh.session;
|
||||||
@ -918,6 +1008,9 @@ int torture_run_tests(void) {
|
|||||||
cmocka_unit_test_setup_teardown(torture_auth_autopubkey,
|
cmocka_unit_test_setup_teardown(torture_auth_autopubkey,
|
||||||
pubkey_setup,
|
pubkey_setup,
|
||||||
session_teardown),
|
session_teardown),
|
||||||
|
cmocka_unit_test_setup_teardown(torture_auth_autopubkey_protected,
|
||||||
|
pubkey_setup,
|
||||||
|
session_teardown),
|
||||||
cmocka_unit_test_setup_teardown(torture_auth_autopubkey_nonblocking,
|
cmocka_unit_test_setup_teardown(torture_auth_autopubkey_nonblocking,
|
||||||
pubkey_setup,
|
pubkey_setup,
|
||||||
session_teardown),
|
session_teardown),
|
||||||
|
28
tests/keys/id_rsa_protected
Normal file
28
tests/keys/id_rsa_protected
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
Wa+ehGaw==
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
1
tests/keys/id_rsa_protected.pub
Normal file
1
tests/keys/id_rsa_protected.pub
Normal file
@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCz98jP4bLz1eNSFd5s2rauzUrREkRlcNt9yh9vXcRIMn19Jt35GUJQzqL5+gRVXbfFZ1qd2zYGSfva0aKclp0iA5ZT6SjGn6BGa0ksT842IAolCpErd44k0EfoC33o0yongbC/nobhbry4+APBRVDBUhzoRzpHKmLPsMT5L76BK8FAhVRC3teQ9xc7I3nO6PmoOFkziXpXs6D0taPj/YgXlpy8qN8gyl6qaen3PoFNhlC25BTpvVW4RiFfK8zouQzCd2xUaHjqQMoyZFCHIDwDqq8sCWIwyrzyTmBHgB4l5OeoNH9DXbQjo8ypg2XpMtOTz8qic448NH9dcZveIXrv asn@krikkit.cryptomilk.site
|
Reference in New Issue
Block a user