diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 56ea8f1b..aa7b9ef1 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -432,6 +432,7 @@ enum ssh_options_e { SSH_OPTIONS_ADDRESS_FAMILY, SSH_OPTIONS_GSSAPI_KEY_EXCHANGE, SSH_OPTIONS_GSSAPI_KEY_EXCHANGE_ALGS, + SSH_OPTIONS_NEXT_IDENTITY, }; enum { diff --git a/include/libssh/session.h b/include/libssh/session.h index 85868da0..da39df2a 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -246,6 +246,7 @@ struct ssh_session_struct { struct { struct ssh_list *identity; struct ssh_list *identity_non_exp; + struct ssh_iterator *identity_it; struct ssh_list *certificate; struct ssh_list *certificate_non_exp; struct ssh_list *proxy_jumps; diff --git a/src/options.c b/src/options.c index a19a8293..8125903f 100644 --- a/src/options.c +++ b/src/options.c @@ -1561,7 +1561,16 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) { * - SSH_OPTIONS_IDENTITY: * Get the first identity file name (const char *).\n * \n - * By default id_rsa, id_ecdsa and id_ed25519 files are used. + * By default `id_rsa`, `id_ecdsa`, `id_ed25519`, `id_ecdsa_sk` + * and `id_ed25519_sk` (when SK support is built in) files are + * used. + * + * - SSH_OPTIONS_NEXT_IDENTITY: + * Get the next identity file name (const char *).\n + * \n + * Repeat calls to get all key paths. SSH_EOF is returned when + * the end of list is reached. Another call will start another + * iteration over the same list. * * - SSH_OPTIONS_PROXYCOMMAND: * Get the proxycommand necessary to log into the @@ -1657,6 +1666,30 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value) break; } + case SSH_OPTIONS_NEXT_IDENTITY: { + if (session->opts.identity_it != NULL) { + /* Move to the next item */ + session->opts.identity_it = session->opts.identity_it->next; + if (session->opts.identity_it == NULL) { + *value = NULL; + return SSH_EOF; + } + } else { + /* Get iterator from opts */ + struct ssh_iterator *it = NULL; + it = ssh_list_get_iterator(session->opts.identity); + if (it == NULL) { + it = ssh_list_get_iterator(session->opts.identity_non_exp); + } + if (it == NULL) { + return SSH_ERROR; + } + session->opts.identity_it = it; + } + src = ssh_iterator_value(char *, session->opts.identity_it); + break; + } + case SSH_OPTIONS_PROXYCOMMAND: src = session->opts.ProxyCommand; break;