diff --git a/src/config.c b/src/config.c index 8270b3a9..41ba1054 100644 --- a/src/config.c +++ b/src/config.c @@ -548,6 +548,11 @@ ssh_config_make_absolute(ssh_session session, return out; } + /* paths starting with tilde are already absolute */ + if (path[0] == '~') { + return ssh_path_expand_tilde(path); + } + /* Parsing user config relative to home directory (generally ~/.ssh) */ if (session->opts.sshdir == NULL) { ssh_set_error_invalid(session); diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c index 261429a3..31dadae3 100644 --- a/tests/unittests/torture_config.c +++ b/tests/unittests/torture_config.c @@ -2,6 +2,11 @@ #define LIBSSH_STATIC +#ifndef _WIN32 +#define _POSIX_PTHREAD_SEMANTICS +#include +#endif + #include "torture.h" #include "libssh/options.h" #include "libssh/session.h" @@ -1710,6 +1715,27 @@ static void torture_config_make_absolute_int(void **state, bool no_sshdir_fails) { ssh_session session = *state; char *result = NULL; +#ifndef _WIN32 + char h[256]; + char *user; + char *home; + + user = getenv("USER"); + if (user == NULL) { + user = getenv("LOGNAME"); + } + + /* in certain CIs there no such variables */ + if (!user) { + struct passwd *pw = getpwuid(getuid()); + if (pw){ + user = pw->pw_name; + } + } + + home = getenv("HOME"); + assert_non_null(home); +#endif /* Absolute path already -- should not change in any case */ result = ssh_config_make_absolute(session, "/etc/ssh/ssh_config.d/*.conf", 1); @@ -1742,6 +1768,30 @@ static void torture_config_make_absolute_int(void **state, bool no_sshdir_fails) result = ssh_config_make_absolute(session, "my_config", 0); assert_string_equal(result, "/tmp/ssh/my_config"); free(result); + +#ifndef _WIN32 + /* Tilde expansion works only in user config */ + result = ssh_config_make_absolute(session, "~/.ssh/config.d/*.conf", 0); + snprintf(h, 256 - 1, "%s/.ssh/config.d/*.conf", home); + assert_string_equal(result, h); + free(result); + + snprintf(h, 256 - 1, "~%s/.ssh/config.d/*.conf", user); + result = ssh_config_make_absolute(session, h, 0); + snprintf(h, 256 - 1, "%s/.ssh/config.d/*.conf", home); + assert_string_equal(result, h); + free(result); + + /* in global config its just prefixed without expansion */ + result = ssh_config_make_absolute(session, "~/.ssh/config.d/*.conf", 1); + assert_string_equal(result, "/etc/ssh/~/.ssh/config.d/*.conf"); + free(result); + snprintf(h, 256 - 1, "~%s/.ssh/config.d/*.conf", user); + result = ssh_config_make_absolute(session, h, 1); + snprintf(h, 256 - 1, "/etc/ssh/~%s/.ssh/config.d/*.conf", user); + assert_string_equal(result, h); + free(result); +#endif } static void torture_config_make_absolute(void **state) diff --git a/tests/unittests/torture_misc.c b/tests/unittests/torture_misc.c index 6d6cf0a9..9e346ff8 100644 --- a/tests/unittests/torture_misc.c +++ b/tests/unittests/torture_misc.c @@ -4,8 +4,8 @@ #include #endif #include -#ifndef _WIN32 +#ifndef _WIN32 #define _POSIX_PTHREAD_SEMANTICS #include #endif