summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordtucker@openbsd.org <dtucker@openbsd.org>2020-06-26 05:02:03 +0000
committerDamien Miller <djm@mindrot.org>2020-06-26 15:24:27 +1000
commit74344c3ca42c3f53b00b025daf09ae7f6aa38076 (patch)
tree4952081cdbd6c6f3e6e891cd09a7688f003ea639
parentc9e24daac6324fcbdba171392c325bf9ccc3c768 (diff)
upstream: Defer creation of ~/.ssh by ssh(1) until we attempt to
write to it so we don't leave an empty .ssh directory when it's not needed. Use the same function to replace the code in ssh-keygen that does the same thing. bz#3156, ok djm@ OpenBSD-Commit-ID: 59c073b569be1a60f4de36f491a4339bc4ae870f
-rw-r--r--hostfile.c36
-rw-r--r--hostfile.h4
-rw-r--r--ssh-keygen.c21
-rw-r--r--ssh.c20
4 files changed, 44 insertions, 37 deletions
diff --git a/hostfile.c b/hostfile.c
index a91dbbd94..4b39def04 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.c,v 1.80 2020/05/13 09:52:41 djm Exp $ */ 1/* $OpenBSD: hostfile.c,v 1.81 2020/06/26 05:02:03 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -57,6 +57,7 @@
57#include "hostfile.h" 57#include "hostfile.h"
58#include "log.h" 58#include "log.h"
59#include "misc.h" 59#include "misc.h"
60#include "pathnames.h"
60#include "ssherr.h" 61#include "ssherr.h"
61#include "digest.h" 62#include "digest.h"
62#include "hmac.h" 63#include "hmac.h"
@@ -450,6 +451,38 @@ write_host_entry(FILE *f, const char *host, const char *ip,
450} 451}
451 452
452/* 453/*
454 * Create user ~/.ssh directory if it doesn't exist and we want to write to it.
455 * If notify is set, a message will be emitted if the directory is created.
456 */
457void
458hostfile_create_user_ssh_dir(const char *filename, int notify)
459{
460 char *dotsshdir = NULL, *p;
461 size_t len;
462 struct stat st;
463
464 if ((p = strrchr(filename, '/')) == NULL)
465 return;
466 len = p - filename;
467 dotsshdir = tilde_expand_filename("~/" _PATH_SSH_USER_DIR, getuid());
468 if ((strlen(dotsshdir) > len || strncmp(filename, dotsshdir, len) != 0
469 || stat(dotsshdir, &st)) == 0)
470 ; /* do nothing, path not in ~/.ssh or dir already exists */
471 else if (errno != ENOENT)
472 error("Could not stat %s: %s", dotsshdir, strerror(errno));
473 else {
474 ssh_selinux_setfscreatecon(dotsshdir);
475 if (mkdir(dotsshdir, 0700) == -1)
476 error("Could not create directory '%.200s' (%s).",
477 dotsshdir, strerror(errno));
478 else if (notify)
479 logit("Created directory '%s'.", dotsshdir);
480 ssh_selinux_setfscreatecon(NULL);
481 }
482 free(dotsshdir);
483}
484
485/*
453 * Appends an entry to the host file. Returns false if the entry could not 486 * Appends an entry to the host file. Returns false if the entry could not
454 * be appended. 487 * be appended.
455 */ 488 */
@@ -462,6 +495,7 @@ add_host_to_hostfile(const char *filename, const char *host,
462 495
463 if (key == NULL) 496 if (key == NULL)
464 return 1; /* XXX ? */ 497 return 1; /* XXX ? */
498 hostfile_create_user_ssh_dir(filename, 0);
465 f = fopen(filename, "a"); 499 f = fopen(filename, "a");
466 if (!f) 500 if (!f)
467 return 0; 501 return 0;
diff --git a/hostfile.h b/hostfile.h
index 49fcbb7e8..de8b677e3 100644
--- a/hostfile.h
+++ b/hostfile.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.h,v 1.25 2020/05/13 09:52:41 djm Exp $ */ 1/* $OpenBSD: hostfile.h,v 1.26 2020/06/26 05:02:03 dtucker Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -106,4 +106,6 @@ typedef int hostkeys_foreach_fn(struct hostkey_foreach_line *l, void *ctx);
106int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, 106int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
107 const char *host, const char *ip, u_int options); 107 const char *host, const char *ip, u_int options);
108 108
109void hostfile_create_user_ssh_dir(const char *, int);
110
109#endif 111#endif
diff --git a/ssh-keygen.c b/ssh-keygen.c
index bdc29e00a..7c6f11f40 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.412 2020/05/29 03:11:54 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.413 2020/06/26 05:02:03 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -3082,11 +3082,10 @@ usage(void)
3082int 3082int
3083main(int argc, char **argv) 3083main(int argc, char **argv)
3084{ 3084{
3085 char dotsshdir[PATH_MAX], comment[1024], *passphrase; 3085 char comment[1024], *passphrase;
3086 char *rr_hostname = NULL, *ep, *fp, *ra; 3086 char *rr_hostname = NULL, *ep, *fp, *ra;
3087 struct sshkey *private, *public; 3087 struct sshkey *private, *public;
3088 struct passwd *pw; 3088 struct passwd *pw;
3089 struct stat st;
3090 int r, opt, type; 3089 int r, opt, type;
3091 int change_passphrase = 0, change_comment = 0, show_cert = 0; 3090 int change_passphrase = 0, change_comment = 0, show_cert = 0;
3092 int find_host = 0, delete_host = 0, hash_hosts = 0; 3091 int find_host = 0, delete_host = 0, hash_hosts = 0;
@@ -3609,20 +3608,8 @@ main(int argc, char **argv)
3609 ask_filename(pw, "Enter file in which to save the key"); 3608 ask_filename(pw, "Enter file in which to save the key");
3610 3609
3611 /* Create ~/.ssh directory if it doesn't already exist. */ 3610 /* Create ~/.ssh directory if it doesn't already exist. */
3612 snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", 3611 hostfile_create_user_ssh_dir(identity_file, !quiet);
3613 pw->pw_dir, _PATH_SSH_USER_DIR); 3612
3614 if (strstr(identity_file, dotsshdir) != NULL) {
3615 if (stat(dotsshdir, &st) == -1) {
3616 if (errno != ENOENT) {
3617 error("Could not stat %s: %s", dotsshdir,
3618 strerror(errno));
3619 } else if (mkdir(dotsshdir, 0700) == -1) {
3620 error("Could not create directory '%s': %s",
3621 dotsshdir, strerror(errno));
3622 } else if (!quiet)
3623 printf("Created directory '%s'.\n", dotsshdir);
3624 }
3625 }
3626 /* If the file already exists, ask the user to confirm. */ 3613 /* If the file already exists, ask the user to confirm. */
3627 if (!confirm_overwrite(identity_file)) 3614 if (!confirm_overwrite(identity_file))
3628 exit(1); 3615 exit(1);
diff --git a/ssh.c b/ssh.c
index dfae0a73d..a767a1839 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.529 2020/06/05 03:15:26 dtucker Exp $ */ 1/* $OpenBSD: ssh.c,v 1.530 2020/06/26 05:02:03 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -645,7 +645,7 @@ main(int ac, char **av)
645 struct ssh *ssh = NULL; 645 struct ssh *ssh = NULL;
646 int i, r, opt, exit_status, use_syslog, direct, timeout_ms; 646 int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
647 int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; 647 int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0;
648 char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; 648 char *p, *cp, *line, *argv0, *logfile;
649 char cname[NI_MAXHOST]; 649 char cname[NI_MAXHOST];
650 struct stat st; 650 struct stat st;
651 struct passwd *pw; 651 struct passwd *pw;
@@ -1572,22 +1572,6 @@ main(int ac, char **av)
1572 } 1572 }
1573 } 1573 }
1574 1574
1575 /* Create ~/.ssh * directory if it doesn't already exist. */
1576 if (config == NULL) {
1577 r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
1578 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
1579 if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) == -1) {
1580#ifdef WITH_SELINUX
1581 ssh_selinux_setfscreatecon(buf);
1582#endif
1583 if (mkdir(buf, 0700) < 0)
1584 error("Could not create directory '%.200s'.",
1585 buf);
1586#ifdef WITH_SELINUX
1587 ssh_selinux_setfscreatecon(NULL);
1588#endif
1589 }
1590 }
1591 /* load options.identity_files */ 1575 /* load options.identity_files */
1592 load_public_identity_files(pw); 1576 load_public_identity_files(pw);
1593 1577