Bugzilla – Attachment 3220 Details for
Bug 2950
Store user runtime files in /run/user/ rather than in /tmp/
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
proposed patch
openssh-run-user.patch (text/plain), 9.93 KB, created by
Jakub Jelen
on 2019-01-05 03:22:37 AEDT
(
hide
)
Description:
proposed patch
Filename:
MIME Type:
Creator:
Jakub Jelen
Created:
2019-01-05 03:22:37 AEDT
Size:
9.93 KB
patch
obsolete
>diff --git a/auth-krb5.c b/auth-krb5.c >index 3096f1c8..d71879d1 100644 >--- a/auth-krb5.c >+++ b/auth-krb5.c >@@ -45,6 +45,8 @@ > #include "uidswap.h" > #include "hostfile.h" > #include "auth.h" >+#include "channels.h" >+#include "session.h" > > #ifdef KRB5 > #include <errno.h> >@@ -241,11 +243,14 @@ krb5_cleanup_proc(Authctxt *authctxt) > krb5_error_code > ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { > int tmpfd, ret, oerrno; >- char ccname[40]; >+ char ccname[PATH_MAX] = {0}; >+ char *path; > mode_t old_umask; > >+ path = session_get_runtime_directory(); > ret = snprintf(ccname, sizeof(ccname), >- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); >+ "FILE:%s/krb5cc_%d_XXXXXXXXXX", path, geteuid()); >+ free(path); > if (ret < 0 || (size_t)ret >= sizeof(ccname)) > return ENOMEM; > >diff --git a/auth-pam.c b/auth-pam.c >index d67324e1..1942442a 100644 >--- a/auth-pam.c >+++ b/auth-pam.c >@@ -1356,4 +1356,36 @@ sshpam_set_maxtries_reached(int reached) > options.kbd_interactive_authentication = 0; > options.challenge_response_authentication = 0; > } >+ >+#define RUNTIME_SUBDIR "/openssh" >+ >+char * >+sshpam_get_runtime_directory(void) >+{ >+ int r; >+ const char *v = NULL; >+ >+ if (!options.use_pam || sshpam_handle == NULL) >+ return NULL; >+ >+ v = pam_getenv(sshpam_handle, "XDG_RUNTIME_DIR"); >+ if (v && *v != '\0') { >+ char *s = NULL; >+ struct stat st; >+ >+ r = asprintf(&s, "%s"RUNTIME_SUBDIR, v); >+ if (r > 0) { >+ r = stat(s, &st); >+ if (r < 0 && errno == ENOENT) { >+ r = mkdir(s, 0700); >+ if (r == 0) >+ return s; >+ } else if (r == 0) { >+ return s; >+ } >+ free(s); >+ } >+ } >+ return NULL; >+} > #endif /* USE_PAM */ >diff --git a/auth-pam.h b/auth-pam.h >index 41986074..08cae699 100644 >--- a/auth-pam.h >+++ b/auth-pam.h >@@ -43,5 +43,6 @@ int sshpam_auth_passwd(Authctxt *, const char *); > int sshpam_get_maxtries_reached(void); > void sshpam_set_maxtries_reached(int); > int is_pam_session_open(void); >+char *sshpam_get_runtime_directory(void); > > #endif /* USE_PAM */ >diff --git a/clientloop.c b/clientloop.c >index 8d312cda..6e161bfd 100644 >--- a/clientloop.c >+++ b/clientloop.c >@@ -284,6 +284,7 @@ client_x11_get_proto(struct ssh *ssh, const char *display, > static char proto[512], data[512]; > FILE *f; > int got_data = 0, generated = 0, do_unlink = 0, r; >+ int remove_xauthdir = 1; > struct stat st; > u_int now, x11_timeout_real; > >@@ -327,19 +328,18 @@ client_x11_get_proto(struct ssh *ssh, const char *display, > * ssh's willingness to forward X11 connections to > * avoid nasty fail-open behaviour in the X server. > */ >- mktemp_proto(xauthdir, sizeof(xauthdir)); >- if (mkdtemp(xauthdir) == NULL) { >- error("%s: mkdtemp: %s", >- __func__, strerror(errno)); >- return -1; >- } >+ if (create_private_runtime_directory(xauthdir, >+ sizeof(xauthdir), &remove_xauthdir) != 0) >+ error("%s: Failed to create runtime directory", >+ __func__); > do_unlink = 1; > if ((r = snprintf(xauthfile, sizeof(xauthfile), > "%s/xauthfile", xauthdir)) < 0 || > (size_t)r >= sizeof(xauthfile)) { > error("%s: xauthfile path too long", __func__); > unlink(xauthfile); >- rmdir(xauthdir); >+ if (remove_xauthdir) >+ rmdir(xauthdir); > return -1; > } > >@@ -405,7 +405,8 @@ client_x11_get_proto(struct ssh *ssh, const char *display, > > if (do_unlink) { > unlink(xauthfile); >- rmdir(xauthdir); >+ if (remove_xauthdir) >+ rmdir(xauthdir); > } > > /* Don't fall back to fake X11 data for untrusted forwarding */ >diff --git a/misc.c b/misc.c >index bfd786ef..0d0b99a8 100644 >--- a/misc.c >+++ b/misc.c >@@ -1468,6 +1468,49 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len) > monotime_tv(&bw->bwstart); > } > >+#define RUNTIME_SUBDIR "/openssh" >+ >+/* Creates private runtime directory in the dir argument. It is either >+ * a under $XDG_RUNTIME_DIRECTORY or under /tmp, which needs to be removed >+ * when it is no longer needed (the second argument). >+ */ >+int >+create_private_runtime_directory(char *dir, size_t len, int *need_rm) >+{ >+ int r; >+ const char *v = NULL; >+ >+ if (need_rm == NULL) >+ return -1; >+ >+ *need_rm = 0; >+ >+ v = getenv("XDG_RUNTIME_DIR"); >+ if (v && *v != '\0') { >+ struct stat st; >+ >+ r = snprintf(dir, len, "%s"RUNTIME_SUBDIR, v); >+ if (r > 0) { >+ r = stat(dir, &st); >+ if (r < 0 && errno == ENOENT) { >+ r = mkdir(dir, 0700); >+ if (r == 0) { >+ return 0; >+ } >+ } else if (r == 0) { >+ return 0; >+ } >+ } >+ } >+ mktemp_proto(dir, len); >+ if (mkdtemp(dir) == NULL) { >+ perror("mkdtemp: private socket directory"); >+ exit(1); >+ } >+ *need_rm = 1; >+ return 0; >+} >+ > /* Make a template filename for mk[sd]temp() */ > void > mktemp_proto(char *s, size_t len) >@@ -1475,7 +1518,8 @@ mktemp_proto(char *s, size_t len) > const char *tmpdir; > int r; > >- if ((tmpdir = getenv("TMPDIR")) != NULL) { >+ tmpdir = getenv("TMPDIR"); >+ if (tmpdir && *tmpdir != '\0') { > r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); > if (r > 0 && (size_t)r < len) > return; >diff --git a/misc.h b/misc.h >index 47177d83..0c388624 100644 >--- a/misc.h >+++ b/misc.h >@@ -151,6 +151,8 @@ int parse_ipqos(const char *); > const char *iptos2str(int); > void mktemp_proto(char *, size_t); > >+int create_private_runtime_directory(char *dir, size_t len, int *need_rm); >+ > void child_set_env(char ***envp, u_int *envsizep, const char *name, > const char *value); > >diff --git a/session.c b/session.c >index d2e2fbd7..3c1c69f4 100644 >--- a/session.c >+++ b/session.c >@@ -170,6 +170,7 @@ static char *auth_info_file = NULL; > /* Name and directory of socket for authentication agent forwarding. */ > static char *auth_sock_name = NULL; > static char *auth_sock_dir = NULL; >+int remove_auth_sock_dir = 1; > > /* removes the agent forwarding socket */ > >@@ -179,8 +180,13 @@ auth_sock_cleanup_proc(struct passwd *pw) > if (auth_sock_name != NULL) { > temporarily_use_uid(pw); > unlink(auth_sock_name); >- rmdir(auth_sock_dir); >+ free(auth_sock_name); > auth_sock_name = NULL; >+ >+ if (remove_auth_sock_dir) >+ rmdir(auth_sock_dir); >+ free(auth_sock_dir); >+ auth_sock_dir = NULL; > restore_uid(); > } > } >@@ -189,6 +195,7 @@ static int > auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) > { > Channel *nc; >+ char *path; > int sock = -1; > > if (auth_sock_name != NULL) { >@@ -199,17 +206,25 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) > /* Temporarily drop privileged uid for mkdir/bind. */ > temporarily_use_uid(pw); > >- /* Allocate a buffer for the socket name, and format the name. */ >- auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX"); >- >- /* Create private directory for socket */ >- if (mkdtemp(auth_sock_dir) == NULL) { >- packet_send_debug("Agent forwarding disabled: " >- "mkdtemp() failed: %.100s", strerror(errno)); >- restore_uid(); >- free(auth_sock_dir); >- auth_sock_dir = NULL; >- goto authsock_err; >+ path = session_get_runtime_directory(); >+ if (strcmp(path, "/tmp") == 0) { >+ /* Allocate a buffer for the socket name, and format the name. */ >+ auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX"); >+ >+ /* Create private directory for socket */ >+ if (mkdtemp(auth_sock_dir) == NULL) { >+ packet_send_debug("Agent forwarding disabled: " >+ "mkdtemp() failed: %.100s", strerror(errno)); >+ restore_uid(); >+ free(auth_sock_dir); >+ auth_sock_dir = NULL; >+ goto authsock_err; >+ } >+ free(path); >+ } else { >+ /* This is already private directory */ >+ auth_sock_dir = path; >+ remove_auth_sock_dir = 0; > } > > xasprintf(&auth_sock_name, "%s/agent.%ld", >@@ -236,7 +251,8 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) > authsock_err: > free(auth_sock_name); > if (auth_sock_dir != NULL) { >- rmdir(auth_sock_dir); >+ if (remove_auth_sock_dir) >+ rmdir(auth_sock_dir); > free(auth_sock_dir); > } > if (sock != -1) >@@ -259,16 +275,34 @@ display_loginmsg(void) > sshbuf_reset(loginmsg); > } > >+char * >+session_get_runtime_directory(void) >+{ >+ char *auth_info_file = NULL; >+ >+#ifdef USE_PAM >+ auth_info_file = sshpam_get_runtime_directory(); >+ if (auth_info_file != NULL) >+ return auth_info_file; >+#endif /* USE_PAM */ >+ return xstrdup("/tmp"); >+} >+ >+#define SSH_AUTH_TEMPLATE "sshauth.XXXXXXXXXXXXXXX" >+ > static void > prepare_auth_info_file(struct passwd *pw, struct sshbuf *info) > { > int fd = -1, success = 0; >+ char *path = NULL; > > if (!options.expose_userauth_info || info == NULL) > return; > > temporarily_use_uid(pw); >- auth_info_file = xstrdup("/tmp/sshauth.XXXXXXXXXXXXXXX"); >+ path = session_get_runtime_directory(); >+ xasprintf(&auth_info_file, "%s/" SSH_AUTH_TEMPLATE, path); >+ free(path); > if ((fd = mkstemp(auth_info_file)) == -1) { > error("%s: mkstemp: %s", __func__, strerror(errno)); > goto out; >diff --git a/session.h b/session.h >index ce59dabd..63f1e06b 100644 >--- a/session.h >+++ b/session.h >@@ -80,5 +80,6 @@ void session_close(struct ssh *, Session *); > void do_setusercontext(struct passwd *); > > const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); >+char *session_get_runtime_directory(void); > > #endif >diff --git a/ssh-agent.c b/ssh-agent.c >index 6baebc31..9b11f43c 100644 >--- a/ssh-agent.c >+++ b/ssh-agent.c >@@ -143,6 +143,7 @@ pid_t cleanup_pid = 0; > /* pathname and directory for AUTH_SOCKET */ > char socket_name[PATH_MAX]; > char socket_dir[PATH_MAX]; >+int remove_socket_dir = 1; > > /* PKCS#11 path whitelist */ > static char *pkcs11_whitelist; >@@ -1016,7 +1017,7 @@ cleanup_socket(void) > debug("%s: cleanup", __func__); > if (socket_name[0]) > unlink(socket_name); >- if (socket_dir[0]) >+ if (socket_dir[0] && remove_socket_dir) > rmdir(socket_dir); > } > >@@ -1203,11 +1204,10 @@ main(int ac, char **av) > > if (agentsocket == NULL) { > /* Create private directory for agent socket */ >- mktemp_proto(socket_dir, sizeof(socket_dir)); >- if (mkdtemp(socket_dir) == NULL) { >- perror("mkdtemp: private socket dir"); >- exit(1); >- } >+ if (create_private_runtime_directory(socket_dir, >+ sizeof(socket_dir), &remove_socket_dir) != 0) >+ fatal("%s: Failed to create private runtime directory", >+ __progname); > snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, > (long)parent_pid); > } else {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2950
: 3220