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>
Этот коммит содержится в:
родитель
026879e9f0
Коммит
abc88c025c
@ -757,6 +757,8 @@ LIBSSH_API int ssh_userauth_publickey(ssh_session session,
|
||||
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
||||
const char *username);
|
||||
#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,
|
||||
const char *username,
|
||||
const char *passphrase);
|
||||
|
49
src/auth.c
49
src/auth.c
@ -975,6 +975,55 @@ struct ssh_auth_auto_state_struct {
|
||||
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"
|
||||
*
|
||||
|
@ -402,6 +402,7 @@ LIBSSH_4_5_0 # Released
|
||||
ssh_userauth_pubkey;
|
||||
ssh_userauth_publickey;
|
||||
ssh_userauth_publickey_auto;
|
||||
ssh_userauth_publickey_auto_get_current_identity;
|
||||
ssh_userauth_try_publickey;
|
||||
ssh_version;
|
||||
ssh_write_knownhost;
|
||||
|
@ -208,6 +208,9 @@ if (CLIENT_TESTING OR SERVER_TESTING)
|
||||
# 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.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.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)
|
||||
|
@ -281,6 +281,96 @@ static void torture_auth_autopubkey(void **state) {
|
||||
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) {
|
||||
struct torture_state *s = *state;
|
||||
ssh_session session = s->ssh.session;
|
||||
@ -918,6 +1008,9 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test_setup_teardown(torture_auth_autopubkey,
|
||||
pubkey_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_auth_autopubkey_protected,
|
||||
pubkey_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_auth_autopubkey_nonblocking,
|
||||
pubkey_setup,
|
||||
session_teardown),
|
||||
|
28
tests/keys/id_rsa_protected
Обычный файл
28
tests/keys/id_rsa_protected
Обычный файл
@ -0,0 +1,28 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBjmItEMS
|
||||
YKDxy/7xvsZY+uAAAAEAAAAAEAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQCz98jP4bLz
|
||||
1eNSFd5s2rauzUrREkRlcNt9yh9vXcRIMn19Jt35GUJQzqL5+gRVXbfFZ1qd2zYGSfva0a
|
||||
Kclp0iA5ZT6SjGn6BGa0ksT842IAolCpErd44k0EfoC33o0yongbC/nobhbry4+APBRVDB
|
||||
UhzoRzpHKmLPsMT5L76BK8FAhVRC3teQ9xc7I3nO6PmoOFkziXpXs6D0taPj/YgXlpy8qN
|
||||
8gyl6qaen3PoFNhlC25BTpvVW4RiFfK8zouQzCd2xUaHjqQMoyZFCHIDwDqq8sCWIwyrzy
|
||||
TmBHgB4l5OeoNH9DXbQjo8ypg2XpMtOTz8qic448NH9dcZveIXrvAAADwCLre52Jer2DTQ
|
||||
TJi91b/xNm5NRuW9366ZdoOC5NdWtbQFk4YJmdImEDo8k1t3Re24rVNxLMQwHwZX4ZLISl
|
||||
/e49RtSd6TDP44FkQF4NgtCjLUdmEWRTQj0mtENGto+wdLpL25HkmmI5WGrQU9SufVhhvj
|
||||
TxKi6ediSXIXEA5bSrWNvUaw084TT3ZfP9g98/6wr9tAYL1jVfTFUabvZzCR6+wRVoJIVc
|
||||
/+uN1bubj+IdOzYSm9Dhj4kUlK+KvI4GtouCzjuEZosjvn0ino3du1vgyT7SPdjmDxtIds
|
||||
YI7YiB1Xy3QcWdWFk+SoXhDizf9pupo2r1+G50GoBuXg2ELdsKBLXtxQ9bh37JyAcLzagq
|
||||
iVMCJjk3XMZvNXhdELRqLeWyhQ7U1BCtUBatbem0VsH6hQZ/pHReX2We8/GAUQkh4ZN8U2
|
||||
lkta9v5cb7XaBm49JjzIa3WeOS+tFHIUAWqd7MQ4f2FCTMhBssLAM7EJDOUXyo6938pa75
|
||||
+LvdLZRUycE8d/PWG9SuFWSe4CJJrRlBQqPEwx9OPtKNNKgsXIGVKAFLXe+nJ4z6RXTR3R
|
||||
IGe0uaf8v9Jra5j22rq/dbQG1fP1fZNcCnIZQQo6olLaoyQmGCboC8CiCz1PNTsC1+r4pB
|
||||
oaRiCx5/qLF6EXQ03mdEqL1L/R+KMDa2+Ncw2hCSRU3GBby4wXmSqFsboRy5uxJB5sK0Ut
|
||||
sI3FW48k9zijiqVpdysRkalVVSQj8ymTG9LbjjEEmE7qxRf2dZCEnS/iPFUIu7iO9ISiOm
|
||||
4ThpROBspNyHMXKFR6mKArJX1vIwjehlaLAXA3UMY9PEFRDrWQcbatGWj4f/L6e3Tq+n7a
|
||||
t0djAgKlh40IvVL+Xf+Bsv8vUr7HAbKnOxpX69nEShiJqR5YWlEPXba+JCOjryE2ycoRB6
|
||||
d2d0SgDlB1M04uUmv2sy2Kw/CcSNHPLKGiYqqv8DAZ4GiKH2rI4oWvH9z2uRuQni98/Gw1
|
||||
1D5/QwJOHpqrUnVat4JXPBeTqiHYYtbTtqJLeIPX+Dsa6tbdjEOVgx2FkH3104xMwJyUKb
|
||||
Ccip4AbWsTwfM4GVPnJE6WCBcXC5WR6AOzuEEDQjhyzLs5K7RVb7irfhHa4Vs1/2LvxnRT
|
||||
dmTzdv/mhUNqS9RIPmFttfsSveDqY0P6WOn+K6FcCHQjpFJ3pK08glD+Sx4cbFv3lUQLfw
|
||||
hsjL0P+p+M+gTqeJ1kb2z87fiS03mHMV15lmb7nzoqyeJLIukV1jidWdGxf0efnQfmUVfX
|
||||
Wa+ehGaw==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
1
tests/keys/id_rsa_protected.pub
Обычный файл
1
tests/keys/id_rsa_protected.pub
Обычный файл
@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCz98jP4bLz1eNSFd5s2rauzUrREkRlcNt9yh9vXcRIMn19Jt35GUJQzqL5+gRVXbfFZ1qd2zYGSfva0aKclp0iA5ZT6SjGn6BGa0ksT842IAolCpErd44k0EfoC33o0yongbC/nobhbry4+APBRVDBUhzoRzpHKmLPsMT5L76BK8FAhVRC3teQ9xc7I3nO6PmoOFkziXpXs6D0taPj/YgXlpy8qN8gyl6qaen3PoFNhlC25BTpvVW4RiFfK8zouQzCd2xUaHjqQMoyZFCHIDwDqq8sCWIwyrzyTmBHgB4l5OeoNH9DXbQjo8ypg2XpMtOTz8qic448NH9dcZveIXrv asn@krikkit.cryptomilk.site
|
Загрузка…
x
Ссылка в новой задаче
Block a user