1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-29 01:03:57 +03:00

Add a placehohlder for non-expanded identities

Expanding a string twice could lead to unwanted behaviour.
This solution creates a ssh_list (`opts.identites_non_exp`) to store the strings
before expansion and by using ssh_apply it moves the string to the
`opts.identities`. This way the expanded strings are separated.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Norbert Pocs
2022-11-16 10:40:38 +01:00
committed by Jakub Jelen
parent 435f1549f1
commit 1ff893c914
3 changed files with 75 additions and 35 deletions

View File

@@ -52,7 +52,7 @@
* @brief Duplicate the options of a session structure.
*
* If you make several sessions with the same options this is useful. You
* cannot use twice the same option structure in ssh_session_connect.
* cannot use twice the same option structure in ssh_connect.
*
* @param src The session to use to copy the options.
*
@@ -61,13 +61,14 @@
*
* @returns 0 on success, -1 on error with errno set.
*
* @see ssh_session_connect()
* @see ssh_connect()
* @see ssh_free()
*/
int ssh_options_copy(ssh_session src, ssh_session *dest)
{
ssh_session new;
struct ssh_iterator *it = NULL;
struct ssh_list *list = NULL;
char *id = NULL;
int i;
@@ -105,14 +106,15 @@ int ssh_options_copy(ssh_session src, ssh_session *dest)
}
/* Remove the default identities */
for (id = ssh_list_pop_head(char *, new->opts.identity);
for (id = ssh_list_pop_head(char *, new->opts.identity_non_exp);
id != NULL;
id = ssh_list_pop_head(char *, new->opts.identity)) {
id = ssh_list_pop_head(char *, new->opts.identity_non_exp)) {
SAFE_FREE(id);
}
/* Copy the new identities from the source list */
if (src->opts.identity != NULL) {
it = ssh_list_get_iterator(src->opts.identity);
list = new->opts.identity_non_exp;
it = ssh_list_get_iterator(src->opts.identity_non_exp);
for (i = 0; i < 2; i++) {
while (it) {
int rc;
@@ -122,7 +124,7 @@ int ssh_options_copy(ssh_session src, ssh_session *dest)
return -1;
}
rc = ssh_list_append(new->opts.identity, id);
rc = ssh_list_append(list, id);
if (rc < 0) {
free(id);
ssh_free(new);
@@ -130,6 +132,10 @@ int ssh_options_copy(ssh_session src, ssh_session *dest)
}
it = it->next;
}
/* copy the identity list if there is any already */
list = new->opts.identity;
it = ssh_list_get_iterator(src->opts.identity);
}
if (src->opts.sshdir != NULL) {
@@ -331,7 +337,7 @@ int ssh_options_set_algo(ssh_session session,
* Add a new identity file (const char *, format string) to
* the identity list.\n
* \n
* By default identity, id_dsa and id_rsa are checked.\n
* By default id_rsa, id_ecdsa and id_ed25519 files are used.\n
* \n
* The identity used to authenticate with public key will be
* prepended to the list.
@@ -705,7 +711,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
if (q == NULL) {
return -1;
}
rc = ssh_list_prepend(session->opts.identity, q);
if (session->opts.exp_flags & SSH_OPT_EXP_FLAG_IDENTITY) {
rc = ssh_list_append(session->opts.identity_non_exp, q);
} else {
rc = ssh_list_prepend(session->opts.identity_non_exp, q);
}
if (rc < 0) {
free(q);
return -1;
@@ -1216,7 +1226,7 @@ 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 identity, id_dsa and id_rsa are checked.
* By default id_rsa, id_ecdsa and id_ed25519 files are used.
*
* - SSH_OPTIONS_PROXYCOMMAND:
* Get the proxycommand necessary to log into the
@@ -1260,7 +1270,11 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value)
break;
}
case SSH_OPTIONS_IDENTITY: {
struct ssh_iterator *it = ssh_list_get_iterator(session->opts.identity);
struct ssh_iterator *it;
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;
}
@@ -1555,7 +1569,6 @@ out:
int ssh_options_apply(ssh_session session)
{
struct ssh_iterator *it;
char *tmp;
int rc;
@@ -1600,15 +1613,17 @@ int ssh_options_apply(ssh_session session)
size_t plen = strlen(session->opts.ProxyCommand) +
5 /* strlen("exec ") */;
p = malloc(plen + 1 /* \0 */);
if (p == NULL) {
return -1;
}
if (strncmp(session->opts.ProxyCommand, "exec ", 5) != 0) {
p = malloc(plen + 1 /* \0 */);
if (p == NULL) {
return -1;
}
rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand);
if ((size_t)rc != plen) {
free(p);
return -1;
rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand);
if ((size_t)rc != plen) {
free(p);
return -1;
}
}
tmp = ssh_path_expand_escape(session, p);
@@ -1620,24 +1635,33 @@ int ssh_options_apply(ssh_session session)
session->opts.ProxyCommand = tmp;
}
for (it = ssh_list_get_iterator(session->opts.identity);
it != NULL;
it = it->next) {
char *id = (char *) it->data;
if (strncmp(id, "pkcs11:", 6) == 0) {
for (tmp = ssh_list_pop_head(char *, session->opts.identity_non_exp);
tmp != NULL;
tmp = ssh_list_pop_head(char *, session->opts.identity_non_exp)) {
char *id = tmp;
if (strncmp(id, "pkcs11:", 6) != 0) {
/* PKCS#11 URIs are using percent-encoding so we can not mix
* it with ssh expansion of ssh escape characters.
* Skip these identities now, before we will have PKCS#11 support
*/
continue;
tmp = ssh_path_expand_escape(session, id);
if (tmp == NULL) {
return -1;
}
free(id);
}
tmp = ssh_path_expand_escape(session, id);
if (tmp == NULL) {
/* use append to keep the order at first call and use prepend
* to put anything that comes on the nth calls to the beginning */
if (session->opts.exp_flags & SSH_OPT_EXP_FLAG_IDENTITY) {
rc = ssh_list_prepend(session->opts.identity, tmp);
} else {
rc = ssh_list_append(session->opts.identity, tmp);
}
if (rc != SSH_OK) {
return -1;
}
free(id);
it->data = tmp;
}
session->opts.exp_flags |= SSH_OPT_EXP_FLAG_IDENTITY;
return 0;
}