From 3d68b80a847b5e8e4b0b5805c73d0543a56b28e6 Mon Sep 17 00:00:00 2001 From: Aanand Kainth Date: Sun, 11 Feb 2024 22:26:40 -0800 Subject: [PATCH] use backslash for paths displayed on Windows --- pathnames.h | 34 +++++++++++++++++++++------------- ssh-add.c | 2 +- ssh-keygen.c | 2 +- ssh.c | 2 +- sshconnect.c | 15 +++++++++++---- 5 files changed, 35 insertions(+), 20 deletions(-) diff --git a/pathnames.h b/pathnames.h index 6c07f7989166..7bc038774509 100644 --- a/pathnames.h +++ b/pathnames.h @@ -12,6 +12,14 @@ * called by a name other than "ssh" or "Secure Shell". */ +#ifdef WINDOWS +#define _PATH_SEPARATOR "\\" +#define HOME_ENV_VAR "USERPROFILE" +#else +#define _PATH_SEPARATOR "/" +#define HOME_ENV_VAR "HOME" +#endif + #define ETCDIR "/etc" #ifndef SSHDIR @@ -64,21 +72,21 @@ * readable by anyone except the user him/herself, though this does not * contain anything particularly secret. */ -#define _PATH_SSH_USER_HOSTFILE "~/" _PATH_SSH_USER_DIR "/known_hosts" +#define _PATH_SSH_USER_HOSTFILE "~" _PATH_SEPARATOR _PATH_SSH_USER_DIR _PATH_SEPARATOR "known_hosts" /* backward compat for protocol 2 */ -#define _PATH_SSH_USER_HOSTFILE2 "~/" _PATH_SSH_USER_DIR "/known_hosts2" +#define _PATH_SSH_USER_HOSTFILE2 "~" _PATH_SEPARATOR _PATH_SSH_USER_DIR _PATH_SEPARATOR "/known_hosts2" /* * Name of the default file containing client-side authentication key. This * file should only be readable by the user him/herself. */ -#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa" -#define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa" -#define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa" -#define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519" -#define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss" -#define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk" -#define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR "/id_ed25519_sk" +#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR _PATH_SEPARATOR "id_dsa" +#define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR _PATH_SEPARATOR "id_ecdsa" +#define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR _PATH_SEPARATOR "id_rsa" +#define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR _PATH_SEPARATOR "id_ed25519" +#define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR _PATH_SEPARATOR "id_xmss" +#define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR _PATH_SEPARATOR "id_ecdsa_sk" +#define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR _PATH_SEPARATOR "id_ed25519_sk" /* * Configuration file in user's home directory. This file need not be @@ -86,7 +94,7 @@ * particularly secret. If the user's home directory resides on an NFS * volume where root is mapped to nobody, this may need to be world-readable. */ -#define _PATH_SSH_USER_CONFFILE _PATH_SSH_USER_DIR "/config" +#define _PATH_SSH_USER_CONFFILE _PATH_SSH_USER_DIR _PATH_SEPARATOR "config" /* * File containing a list of those rsa keys that permit logging in as this @@ -96,10 +104,10 @@ * may need to be world-readable. (This file is read by the daemon which is * running as root.) */ -#define _PATH_SSH_USER_PERMITTED_KEYS _PATH_SSH_USER_DIR "/authorized_keys" +#define _PATH_SSH_USER_PERMITTED_KEYS _PATH_SSH_USER_DIR _PATH_SEPARATOR "authorized_keys" /* backward compat for protocol v2 */ -#define _PATH_SSH_USER_PERMITTED_KEYS2 _PATH_SSH_USER_DIR "/authorized_keys2" +#define _PATH_SSH_USER_PERMITTED_KEYS2 _PATH_SSH_USER_DIR _PATH_SEPARATOR "authorized_keys2" /* * Per-user and system-wide ssh "rc" files. These files are executed with @@ -107,7 +115,7 @@ * passed "proto cookie" as arguments if X11 forwarding with spoofing is in * use. xauth will be run if neither of these exists. */ -#define _PATH_SSH_USER_RC _PATH_SSH_USER_DIR "/rc" +#define _PATH_SSH_USER_RC _PATH_SSH_USER_DIR _PATH_SEPARATOR "rc" #define _PATH_SSH_SYSTEM_RC SSHDIR "/sshrc" /* diff --git a/ssh-add.c b/ssh-add.c index 41884d687e20..8b6208076de8 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1044,7 +1044,7 @@ main(int argc, char **argv) } for (i = 0; default_files[i]; i++) { - snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir, + snprintf(buf, sizeof(buf), "%s" _PATH_SEPARATOR "%s", pw->pw_dir, default_files[i]); if (stat(buf, &st) == -1) continue; diff --git a/ssh-keygen.c b/ssh-keygen.c index 2188133023f3..dda0d2a8146b 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -297,7 +297,7 @@ ask_filename(struct passwd *pw, const char *prompt) } } snprintf(identity_file, sizeof(identity_file), - "%s/%s", pw->pw_dir, name); + "%s" _PATH_SEPARATOR "%s", pw->pw_dir, name); printf("%s (%s): ", prompt, identity_file); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) diff --git a/ssh.c b/ssh.c index 745188234c89..d679cc12511b 100644 --- a/ssh.c +++ b/ssh.c @@ -572,7 +572,7 @@ process_config_files(const char *host_name, struct passwd *pw, int final_pass, fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { - r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, + r = snprintf(buf, sizeof buf, "%s" _PATH_SEPARATOR "%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) (void)read_config_file(buf, pw, host, host_name, diff --git a/sshconnect.c b/sshconnect.c index 5902d9b2676a..44292b52be40 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -72,6 +72,7 @@ #include "ssherr.h" #include "authfd.h" #include "kex.h" +#include "pathnames.h" struct sshkey *previous_host_key = NULL; @@ -735,9 +736,11 @@ try_tilde_unexpand(const char *path) char *home, *ret = NULL; size_t l; +#ifndef WINDOWS if (*path != '/') return xstrdup(path); - if ((home = getenv("HOME")) == NULL || (l = strlen(home)) == 0) +#endif // !WINDOWS + if ((home = getenv(HOME_ENV_VAR)) == NULL || (l = strlen(home)) == 0) return xstrdup(path); if (strncmp(path, home, l) != 0) return xstrdup(path); @@ -745,12 +748,16 @@ try_tilde_unexpand(const char *path) * ensure we have matched on a path boundary: either the $HOME that * we just compared ends with a '/' or the next character of the path * must be a '/'. + * + * *_PATH_SEPARATOR is used to obtain the char '/' from the path + * separator string. When compiled for Windows, this will be '\\' + * instead. */ - if (home[l - 1] != '/' && path[l] != '/') + if (home[l - 1] != *_PATH_SEPARATOR && path[l] != *_PATH_SEPARATOR) return xstrdup(path); - if (path[l] == '/') + if (path[l] == *_PATH_SEPARATOR) l++; - xasprintf(&ret, "~/%s", path + l); + xasprintf(&ret, "~" _PATH_SEPARATOR "%s", path + l); return ret; }