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:
committed by
Jakub Jelen
parent
435f1549f1
commit
1ff893c914
@@ -209,6 +209,7 @@ struct ssh_session_struct {
|
|||||||
#endif
|
#endif
|
||||||
struct {
|
struct {
|
||||||
struct ssh_list *identity;
|
struct ssh_list *identity;
|
||||||
|
struct ssh_list *identity_non_exp;
|
||||||
char *username;
|
char *username;
|
||||||
char *host;
|
char *host;
|
||||||
char *bindaddr; /* bind the client to an ip addr */
|
char *bindaddr; /* bind the client to an ip addr */
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
* @brief Duplicate the options of a session structure.
|
* @brief Duplicate the options of a session structure.
|
||||||
*
|
*
|
||||||
* If you make several sessions with the same options this is useful. You
|
* 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.
|
* @param src The session to use to copy the options.
|
||||||
*
|
*
|
||||||
@@ -61,13 +61,14 @@
|
|||||||
*
|
*
|
||||||
* @returns 0 on success, -1 on error with errno set.
|
* @returns 0 on success, -1 on error with errno set.
|
||||||
*
|
*
|
||||||
* @see ssh_session_connect()
|
* @see ssh_connect()
|
||||||
* @see ssh_free()
|
* @see ssh_free()
|
||||||
*/
|
*/
|
||||||
int ssh_options_copy(ssh_session src, ssh_session *dest)
|
int ssh_options_copy(ssh_session src, ssh_session *dest)
|
||||||
{
|
{
|
||||||
ssh_session new;
|
ssh_session new;
|
||||||
struct ssh_iterator *it = NULL;
|
struct ssh_iterator *it = NULL;
|
||||||
|
struct ssh_list *list = NULL;
|
||||||
char *id = NULL;
|
char *id = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -105,14 +106,15 @@ int ssh_options_copy(ssh_session src, ssh_session *dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the default identities */
|
/* 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 != NULL;
|
||||||
id = ssh_list_pop_head(char *, new->opts.identity)) {
|
id = ssh_list_pop_head(char *, new->opts.identity_non_exp)) {
|
||||||
SAFE_FREE(id);
|
SAFE_FREE(id);
|
||||||
}
|
}
|
||||||
/* Copy the new identities from the source list */
|
/* Copy the new identities from the source list */
|
||||||
if (src->opts.identity != NULL) {
|
list = new->opts.identity_non_exp;
|
||||||
it = ssh_list_get_iterator(src->opts.identity);
|
it = ssh_list_get_iterator(src->opts.identity_non_exp);
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
while (it) {
|
while (it) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -122,7 +124,7 @@ int ssh_options_copy(ssh_session src, ssh_session *dest)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ssh_list_append(new->opts.identity, id);
|
rc = ssh_list_append(list, id);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
free(id);
|
free(id);
|
||||||
ssh_free(new);
|
ssh_free(new);
|
||||||
@@ -130,6 +132,10 @@ int ssh_options_copy(ssh_session src, ssh_session *dest)
|
|||||||
}
|
}
|
||||||
it = it->next;
|
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) {
|
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
|
* Add a new identity file (const char *, format string) to
|
||||||
* the identity list.\n
|
* the identity list.\n
|
||||||
* \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
|
* \n
|
||||||
* The identity used to authenticate with public key will be
|
* The identity used to authenticate with public key will be
|
||||||
* prepended to the list.
|
* prepended to the list.
|
||||||
@@ -705,7 +711,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
|||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
return -1;
|
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) {
|
if (rc < 0) {
|
||||||
free(q);
|
free(q);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1216,7 +1226,7 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
|
|||||||
* - SSH_OPTIONS_IDENTITY:
|
* - SSH_OPTIONS_IDENTITY:
|
||||||
* Get the first identity file name (const char *).\n
|
* Get the first identity file name (const char *).\n
|
||||||
* \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:
|
* - SSH_OPTIONS_PROXYCOMMAND:
|
||||||
* Get the proxycommand necessary to log into the
|
* 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;
|
break;
|
||||||
}
|
}
|
||||||
case SSH_OPTIONS_IDENTITY: {
|
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) {
|
if (it == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1555,7 +1569,6 @@ out:
|
|||||||
|
|
||||||
int ssh_options_apply(ssh_session session)
|
int ssh_options_apply(ssh_session session)
|
||||||
{
|
{
|
||||||
struct ssh_iterator *it;
|
|
||||||
char *tmp;
|
char *tmp;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -1600,15 +1613,17 @@ int ssh_options_apply(ssh_session session)
|
|||||||
size_t plen = strlen(session->opts.ProxyCommand) +
|
size_t plen = strlen(session->opts.ProxyCommand) +
|
||||||
5 /* strlen("exec ") */;
|
5 /* strlen("exec ") */;
|
||||||
|
|
||||||
p = malloc(plen + 1 /* \0 */);
|
if (strncmp(session->opts.ProxyCommand, "exec ", 5) != 0) {
|
||||||
if (p == NULL) {
|
p = malloc(plen + 1 /* \0 */);
|
||||||
return -1;
|
if (p == NULL) {
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand);
|
rc = snprintf(p, plen + 1, "exec %s", session->opts.ProxyCommand);
|
||||||
if ((size_t)rc != plen) {
|
if ((size_t)rc != plen) {
|
||||||
free(p);
|
free(p);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = ssh_path_expand_escape(session, p);
|
tmp = ssh_path_expand_escape(session, p);
|
||||||
@@ -1620,24 +1635,33 @@ int ssh_options_apply(ssh_session session)
|
|||||||
session->opts.ProxyCommand = tmp;
|
session->opts.ProxyCommand = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = ssh_list_get_iterator(session->opts.identity);
|
for (tmp = ssh_list_pop_head(char *, session->opts.identity_non_exp);
|
||||||
it != NULL;
|
tmp != NULL;
|
||||||
it = it->next) {
|
tmp = ssh_list_pop_head(char *, session->opts.identity_non_exp)) {
|
||||||
char *id = (char *) it->data;
|
char *id = tmp;
|
||||||
if (strncmp(id, "pkcs11:", 6) == 0) {
|
if (strncmp(id, "pkcs11:", 6) != 0) {
|
||||||
/* PKCS#11 URIs are using percent-encoding so we can not mix
|
/* PKCS#11 URIs are using percent-encoding so we can not mix
|
||||||
* it with ssh expansion of ssh escape characters.
|
* 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;
|
return -1;
|
||||||
}
|
}
|
||||||
free(id);
|
|
||||||
it->data = tmp;
|
|
||||||
}
|
}
|
||||||
|
session->opts.exp_flags |= SSH_OPT_EXP_FLAG_IDENTITY;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,13 +119,17 @@ ssh_session ssh_new(void)
|
|||||||
if (session->opts.identity == NULL) {
|
if (session->opts.identity == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
session->opts.identity_non_exp = ssh_list_new();
|
||||||
|
if (session->opts.identity_non_exp == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
id = strdup("%d/id_ed25519");
|
id = strdup("%d/id_ed25519");
|
||||||
if (id == NULL) {
|
if (id == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ssh_list_append(session->opts.identity, id);
|
rc = ssh_list_append(session->opts.identity_non_exp, id);
|
||||||
if (rc == SSH_ERROR) {
|
if (rc == SSH_ERROR) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -135,7 +139,7 @@ ssh_session ssh_new(void)
|
|||||||
if (id == NULL) {
|
if (id == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
rc = ssh_list_append(session->opts.identity, id);
|
rc = ssh_list_append(session->opts.identity_non_exp, id);
|
||||||
if (rc == SSH_ERROR) {
|
if (rc == SSH_ERROR) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -145,7 +149,7 @@ ssh_session ssh_new(void)
|
|||||||
if (id == NULL) {
|
if (id == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
rc = ssh_list_append(session->opts.identity, id);
|
rc = ssh_list_append(session->opts.identity_non_exp, id);
|
||||||
if (rc == SSH_ERROR) {
|
if (rc == SSH_ERROR) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -155,7 +159,7 @@ ssh_session ssh_new(void)
|
|||||||
if (id == NULL) {
|
if (id == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
rc = ssh_list_append(session->opts.identity, id);
|
rc = ssh_list_append(session->opts.identity_non_exp, id);
|
||||||
if (rc == SSH_ERROR) {
|
if (rc == SSH_ERROR) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -285,6 +289,17 @@ void ssh_free(ssh_session session)
|
|||||||
ssh_list_free(session->opts.identity);
|
ssh_list_free(session->opts.identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session->opts.identity_non_exp) {
|
||||||
|
char *id;
|
||||||
|
|
||||||
|
for (id = ssh_list_pop_head(char *, session->opts.identity_non_exp);
|
||||||
|
id != NULL;
|
||||||
|
id = ssh_list_pop_head(char *, session->opts.identity_non_exp)) {
|
||||||
|
SAFE_FREE(id);
|
||||||
|
}
|
||||||
|
ssh_list_free(session->opts.identity_non_exp);
|
||||||
|
}
|
||||||
|
|
||||||
while ((b = ssh_list_pop_head(struct ssh_buffer_struct *,
|
while ((b = ssh_list_pop_head(struct ssh_buffer_struct *,
|
||||||
session->out_queue)) != NULL) {
|
session->out_queue)) != NULL) {
|
||||||
SSH_BUFFER_FREE(b);
|
SSH_BUFFER_FREE(b);
|
||||||
|
|||||||
Reference in New Issue
Block a user