summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2008-07-22 19:45:18 +0000
committerColin Watson <cjwatson@debian.org>2008-07-22 19:45:18 +0000
commit137d76ba65883aa8143af1fcad83b57e7badef0c (patch)
treef426e804bb5248ceafedfab7bb78ae6e6752942c /ssh-keygen.c
parentdac7d049dad31f5f84d421d4eb628a7e13f977d7 (diff)
parentef94e5613d37bcbf880f21ee6094e4b1c7683a4c (diff)
* New upstream release (closes: #474301). Important changes not previously
backported to 4.7p1: - 4.9/4.9p1 (http://www.openssh.com/txt/release-4.9): + Added chroot(2) support for sshd(8), controlled by a new option "ChrootDirectory" (closes: #139047, LP: #24777). + Linked sftp-server(8) into sshd(8). The internal sftp server is used when the command "internal-sftp" is specified in a Subsystem or ForceCommand declaration. When used with ChrootDirectory, the internal sftp server requires no special configuration of files inside the chroot environment. + Added a protocol extension method "posix-rename@openssh.com" for sftp-server(8) to perform POSIX atomic rename() operations; sftp(1) prefers this if available (closes: #308561). + Removed the fixed limit of 100 file handles in sftp-server(8). + ssh(8) will now skip generation of SSH protocol 1 ephemeral server keys when in inetd mode and protocol 2 connections are negotiated. This speeds up protocol 2 connections to inetd-mode servers that also allow Protocol 1. + Accept the PermitRootLogin directive in a sshd_config(5) Match block. Allows for, e.g. permitting root only from the local network. + Reworked sftp(1) argument splitting and escaping to be more internally consistent (i.e. between sftp commands) and more consistent with sh(1). Please note that this will change the interpretation of some quoted strings, especially those with embedded backslash escape sequences. + Support "Banner=none" in sshd_config(5) to disable sending of a pre-login banner (e.g. in a Match block). + ssh(1) ProxyCommands are now executed with $SHELL rather than /bin/sh. + ssh(1)'s ConnectTimeout option is now applied to both the TCP connection and the SSH banner exchange (previously it just covered the TCP connection). This allows callers of ssh(1) to better detect and deal with stuck servers that accept a TCP connection but don't progress the protocol, and also makes ConnectTimeout useful for connections via a ProxyCommand. + scp(1) incorrectly reported "stalled" on slow copies (closes: #140828). + scp(1) date underflow for timestamps before epoch. + ssh(1) used the obsolete SIG DNS RRtype for host keys in DNS, instead of the current standard RRSIG. + Correctly drain ACKs when a sftp(1) upload write fails midway, avoids a fatal() exit from what should be a recoverable condition. + Fixed ssh-keygen(1) selective host key hashing (i.e. "ssh-keygen -HF hostname") to not include any IP address in the data to be hashed. + Make ssh(1) skip listening on the IPv6 wildcard address when a binding address of 0.0.0.0 is used against an old SSH server that does not support the RFC4254 syntax for wildcard bind addresses. + Enable IPV6_V6ONLY socket option on sshd(8) listen socket, as is already done for X11/TCP forwarding sockets (closes: #439661). + Fix FD leak that could hang a ssh(1) connection multiplexing master. + Make ssh(1) -q option documentation consistent with reality. + Fixed sshd(8) PAM support not calling pam_session_close(), or failing to call it with root privileges (closes: #372680). + Fix activation of OpenSSL engine support when requested in configure (LP: #119295). - 5.1/5.1p1 (http://www.openssh.com/txt/release-5.1): + Introduce experimental SSH Fingerprint ASCII Visualisation to ssh(1) and ssh-keygen(1). Visual fingerprint display is controlled by a new ssh_config(5) option "VisualHostKey". The intent is to render SSH host keys in a visual form that is amenable to easy recall and rejection of changed host keys. + sshd_config(5) now supports CIDR address/masklen matching in "Match address" blocks, with a fallback to classic wildcard matching. + sshd(8) now supports CIDR matching in ~/.ssh/authorized_keys from="..." restrictions, also with a fallback to classic wildcard matching. + Added an extended test mode (-T) to sshd(8) to request that it write its effective configuration to stdout and exit. Extended test mode also supports the specification of connection parameters (username, source address and hostname) to test the application of sshd_config(5) Match rules. + ssh(1) now prints the number of bytes transferred and the overall connection throughput for SSH protocol 2 sessions when in verbose mode (previously these statistics were displayed for protocol 1 connections only). + sftp-server(8) now supports extension methods statvfs@openssh.com and fstatvfs@openssh.com that implement statvfs(2)-like operations. + sftp(1) now has a "df" command to the sftp client that uses the statvfs@openssh.com to produce a df(1)-like display of filesystem space and inode utilisation (requires statvfs@openssh.com support on the server). + Added a MaxSessions option to sshd_config(5) to allow control of the number of multiplexed sessions supported over a single TCP connection. This allows increasing the number of allowed sessions above the previous default of 10, disabling connection multiplexing (MaxSessions=1) or disallowing login/shell/subsystem sessions entirely (MaxSessions=0). + Added a no-more-sessions@openssh.com global request extension that is sent from ssh(1) to sshd(8) when the client knows that it will never request another session (i.e. when session multiplexing is disabled). This allows a server to disallow further session requests and terminate the session in cases where the client has been hijacked. + ssh-keygen(1) now supports the use of the -l option in combination with -F to search for a host in ~/.ssh/known_hosts and display its fingerprint. + ssh-keyscan(1) now defaults to "rsa" (protocol 2) keys, instead of "rsa1". + Added an AllowAgentForwarding option to sshd_config(8) to control whether authentication agent forwarding is permitted. Note that this is a loose control, as a client may install their own unofficial forwarder. + ssh(1) and sshd(8): avoid unnecessary malloc/copy/free when receiving network data, resulting in a ~10% speedup. + ssh(1) and sshd(8) will now try additional addresses when connecting to a port forward destination whose DNS name resolves to more than one address. The previous behaviour was to try the only first address and give up if that failed. + ssh(1) and sshd(8) now support signalling that channels are half-closed for writing, through a channel protocol extension notification "eow@openssh.com". This allows propagation of closed file descriptors, so that commands such as "ssh -2 localhost od /bin/ls | true" do not send unnecessary data over the wire. + sshd(8): increased the default size of ssh protocol 1 ephemeral keys from 768 to 1024 bits. + When ssh(1) has been requested to fork after authentication ("ssh -f") with ExitOnForwardFailure enabled, delay the fork until after replies for any -R forwards have been seen. Allows for robust detection of -R forward failure when using -f. + "Match group" blocks in sshd_config(5) now support negation of groups. E.g. "Match group staff,!guests". + sftp(1) and sftp-server(8) now allow chmod-like operations to set set[ug]id/sticky bits. + The MaxAuthTries option is now permitted in sshd_config(5) match blocks. + Multiplexed ssh(1) sessions now support a subset of the ~ escapes that are available to a primary connection. + ssh(1) connection multiplexing will now fall back to creating a new connection in most error cases (closes: #352830). + Make ssh(1) deal more gracefully with channel requests that fail. Previously it would optimistically assume that requests would always succeed, which could cause hangs if they did not (e.g. when the server runs out of file descriptors). + ssh(1) now reports multiplexing errors via the multiplex slave's stderr where possible (subject to LogLevel in the mux master). + Prevent sshd(8) from erroneously applying public key restrictions leaned from ~/.ssh/authorized_keys to other authentication methods when public key authentication subsequently fails (LP: #161047). + Fixed an UMAC alignment problem that manifested on Itanium platforms.
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c97
1 files changed, 66 insertions, 31 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 04a9b939a..f7e284062 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.160 2007/01/21 01:41:54 stevesk Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.171 2008/07/13 21:22:52 sthen 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
@@ -21,6 +21,7 @@
21 21
22#include <openssl/evp.h> 22#include <openssl/evp.h>
23#include <openssl/pem.h> 23#include <openssl/pem.h>
24#include "openbsd-compat/openssl-compat.h"
24 25
25#include <errno.h> 26#include <errno.h>
26#include <fcntl.h> 27#include <fcntl.h>
@@ -71,6 +72,8 @@ int change_comment = 0;
71 72
72int quiet = 0; 73int quiet = 0;
73 74
75int log_level = SYSLOG_LEVEL_INFO;
76
74/* Flag indicating that we want to hash a known_hosts file */ 77/* Flag indicating that we want to hash a known_hosts file */
75int hash_hosts = 0; 78int hash_hosts = 0;
76/* Flag indicating that we want lookup a host in known_hosts file */ 79/* Flag indicating that we want lookup a host in known_hosts file */
@@ -141,8 +144,7 @@ ask_filename(struct passwd *pw, const char *prompt)
141 fprintf(stderr, "%s (%s): ", prompt, identity_file); 144 fprintf(stderr, "%s (%s): ", prompt, identity_file);
142 if (fgets(buf, sizeof(buf), stdin) == NULL) 145 if (fgets(buf, sizeof(buf), stdin) == NULL)
143 exit(1); 146 exit(1);
144 if (strchr(buf, '\n')) 147 buf[strcspn(buf, "\n")] = '\0';
145 *strchr(buf, '\n') = 0;
146 if (strcmp(buf, "") != 0) 148 if (strcmp(buf, "") != 0)
147 strlcpy(identity_file, buf, sizeof(identity_file)); 149 strlcpy(identity_file, buf, sizeof(identity_file));
148 have_identity = 1; 150 have_identity = 1;
@@ -504,8 +506,8 @@ do_fingerprint(struct passwd *pw)
504{ 506{
505 FILE *f; 507 FILE *f;
506 Key *public; 508 Key *public;
507 char *comment = NULL, *cp, *ep, line[16*1024], *fp; 509 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
508 int i, skip = 0, num = 1, invalid = 1; 510 int i, skip = 0, num = 0, invalid = 1;
509 enum fp_rep rep; 511 enum fp_rep rep;
510 enum fp_type fptype; 512 enum fp_type fptype;
511 struct stat st; 513 struct stat st;
@@ -522,9 +524,14 @@ do_fingerprint(struct passwd *pw)
522 public = key_load_public(identity_file, &comment); 524 public = key_load_public(identity_file, &comment);
523 if (public != NULL) { 525 if (public != NULL) {
524 fp = key_fingerprint(public, fptype, rep); 526 fp = key_fingerprint(public, fptype, rep);
525 printf("%u %s %s\n", key_size(public), fp, comment); 527 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
528 printf("%u %s %s (%s)\n", key_size(public), fp, comment,
529 key_type(public));
530 if (log_level >= SYSLOG_LEVEL_VERBOSE)
531 printf("%s\n", ra);
526 key_free(public); 532 key_free(public);
527 xfree(comment); 533 xfree(comment);
534 xfree(ra);
528 xfree(fp); 535 xfree(fp);
529 exit(0); 536 exit(0);
530 } 537 }
@@ -536,9 +543,9 @@ do_fingerprint(struct passwd *pw)
536 f = fopen(identity_file, "r"); 543 f = fopen(identity_file, "r");
537 if (f != NULL) { 544 if (f != NULL) {
538 while (fgets(line, sizeof(line), f)) { 545 while (fgets(line, sizeof(line), f)) {
539 i = strlen(line) - 1; 546 if ((cp = strchr(line, '\n')) == NULL) {
540 if (line[i] != '\n') { 547 error("line %d too long: %.40s...",
541 error("line %d too long: %.40s...", num, line); 548 num + 1, line);
542 skip = 1; 549 skip = 1;
543 continue; 550 continue;
544 } 551 }
@@ -547,7 +554,7 @@ do_fingerprint(struct passwd *pw)
547 skip = 0; 554 skip = 0;
548 continue; 555 continue;
549 } 556 }
550 line[i] = '\0'; 557 *cp = '\0';
551 558
552 /* Skip leading whitespace, empty and comment lines. */ 559 /* Skip leading whitespace, empty and comment lines. */
553 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 560 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@@ -582,8 +589,12 @@ do_fingerprint(struct passwd *pw)
582 } 589 }
583 comment = *cp ? cp : comment; 590 comment = *cp ? cp : comment;
584 fp = key_fingerprint(public, fptype, rep); 591 fp = key_fingerprint(public, fptype, rep);
585 printf("%u %s %s\n", key_size(public), fp, 592 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
586 comment ? comment : "no comment"); 593 printf("%u %s %s (%s)\n", key_size(public), fp,
594 comment ? comment : "no comment", key_type(public));
595 if (log_level >= SYSLOG_LEVEL_VERBOSE)
596 printf("%s\n", ra);
597 xfree(ra);
587 xfree(fp); 598 xfree(fp);
588 key_free(public); 599 key_free(public);
589 invalid = 0; 600 invalid = 0;
@@ -598,14 +609,31 @@ do_fingerprint(struct passwd *pw)
598} 609}
599 610
600static void 611static void
601print_host(FILE *f, char *name, Key *public, int hash) 612print_host(FILE *f, const char *name, Key *public, int hash)
602{ 613{
603 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 614 if (print_fingerprint) {
604 fatal("hash_host failed"); 615 enum fp_rep rep;
605 fprintf(f, "%s ", name); 616 enum fp_type fptype;
606 if (!key_write(public, f)) 617 char *fp, *ra;
607 fatal("key_write failed"); 618
608 fprintf(f, "\n"); 619 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
620 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
621 fp = key_fingerprint(public, fptype, rep);
622 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
623 printf("%u %s %s (%s)\n", key_size(public), fp, name,
624 key_type(public));
625 if (log_level >= SYSLOG_LEVEL_VERBOSE)
626 printf("%s\n", ra);
627 xfree(ra);
628 xfree(fp);
629 } else {
630 if (hash && (name = host_hash(name, NULL, 0)) == NULL)
631 fatal("hash_host failed");
632 fprintf(f, "%s ", name);
633 if (!key_write(public, f))
634 fatal("key_write failed");
635 fprintf(f, "\n");
636 }
609} 637}
610 638
611static void 639static void
@@ -615,7 +643,7 @@ do_known_hosts(struct passwd *pw, const char *name)
615 Key *public; 643 Key *public;
616 char *cp, *cp2, *kp, *kp2; 644 char *cp, *cp2, *kp, *kp2;
617 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; 645 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
618 int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; 646 int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
619 647
620 if (!have_identity) { 648 if (!have_identity) {
621 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 649 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@@ -650,19 +678,18 @@ do_known_hosts(struct passwd *pw, const char *name)
650 } 678 }
651 679
652 while (fgets(line, sizeof(line), in)) { 680 while (fgets(line, sizeof(line), in)) {
653 num++; 681 if ((cp = strchr(line, '\n')) == NULL) {
654 i = strlen(line) - 1; 682 error("line %d too long: %.40s...", num + 1, line);
655 if (line[i] != '\n') {
656 error("line %d too long: %.40s...", num, line);
657 skip = 1; 683 skip = 1;
658 invalid = 1; 684 invalid = 1;
659 continue; 685 continue;
660 } 686 }
687 num++;
661 if (skip) { 688 if (skip) {
662 skip = 0; 689 skip = 0;
663 continue; 690 continue;
664 } 691 }
665 line[i] = '\0'; 692 *cp = '\0';
666 693
667 /* Skip leading whitespace, empty and comment lines. */ 694 /* Skip leading whitespace, empty and comment lines. */
668 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 695 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@@ -726,7 +753,8 @@ do_known_hosts(struct passwd *pw, const char *name)
726 printf("# Host %s found: " 753 printf("# Host %s found: "
727 "line %d type %s\n", name, 754 "line %d type %s\n", name,
728 num, key_type(public)); 755 num, key_type(public));
729 print_host(out, cp, public, hash_hosts); 756 print_host(out, name, public,
757 hash_hosts);
730 } 758 }
731 if (delete_host && !c) 759 if (delete_host && !c)
732 print_host(out, cp, public, 0); 760 print_host(out, cp, public, 0);
@@ -750,7 +778,7 @@ do_known_hosts(struct passwd *pw, const char *name)
750 fclose(in); 778 fclose(in);
751 779
752 if (invalid) { 780 if (invalid) {
753 fprintf(stderr, "%s is not a valid known_host file.\n", 781 fprintf(stderr, "%s is not a valid known_hosts file.\n",
754 identity_file); 782 identity_file);
755 if (inplace) { 783 if (inplace) {
756 fprintf(stderr, "Not replacing existing known_hosts " 784 fprintf(stderr, "Not replacing existing known_hosts "
@@ -962,8 +990,7 @@ do_change_comment(struct passwd *pw)
962 key_free(private); 990 key_free(private);
963 exit(1); 991 exit(1);
964 } 992 }
965 if (strchr(new_comment, '\n')) 993 new_comment[strcspn(new_comment, "\n")] = '\0';
966 *strchr(new_comment, '\n') = 0;
967 } 994 }
968 995
969 /* Save the file using the new passphrase. */ 996 /* Save the file using the new passphrase. */
@@ -1006,7 +1033,7 @@ do_change_comment(struct passwd *pw)
1006static void 1033static void
1007usage(void) 1034usage(void)
1008{ 1035{
1009 fprintf(stderr, "Usage: %s [options]\n", __progname); 1036 fprintf(stderr, "usage: %s [options]\n", __progname);
1010 fprintf(stderr, "Options:\n"); 1037 fprintf(stderr, "Options:\n");
1011 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); 1038 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n");
1012 fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); 1039 fprintf(stderr, " -B Show bubblebabble digest of key file.\n");
@@ -1059,7 +1086,6 @@ main(int argc, char **argv)
1059 int opt, type, fd, download = 0; 1086 int opt, type, fd, download = 0;
1060 u_int32_t memory = 0, generator_wanted = 0, trials = 100; 1087 u_int32_t memory = 0, generator_wanted = 0, trials = 100;
1061 int do_gen_candidates = 0, do_screen_candidates = 0; 1088 int do_gen_candidates = 0, do_screen_candidates = 0;
1062 int log_level = SYSLOG_LEVEL_INFO;
1063 BIGNUM *start = NULL; 1089 BIGNUM *start = NULL;
1064 FILE *f; 1090 FILE *f;
1065 const char *errstr; 1091 const char *errstr;
@@ -1232,6 +1258,10 @@ main(int argc, char **argv)
1232 printf("Can only have one of -p and -c.\n"); 1258 printf("Can only have one of -p and -c.\n");
1233 usage(); 1259 usage();
1234 } 1260 }
1261 if (print_fingerprint && (delete_host || hash_hosts)) {
1262 printf("Cannot use -l with -D or -R.\n");
1263 usage();
1264 }
1235 if (delete_host || hash_hosts || find_host) 1265 if (delete_host || hash_hosts || find_host)
1236 do_known_hosts(pw, rr_hostname); 1266 do_known_hosts(pw, rr_hostname);
1237 if (print_fingerprint || print_bubblebabble) 1267 if (print_fingerprint || print_bubblebabble)
@@ -1436,10 +1466,15 @@ passphrase_again:
1436 1466
1437 if (!quiet) { 1467 if (!quiet) {
1438 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 1468 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
1469 char *ra = key_fingerprint(public, SSH_FP_MD5,
1470 SSH_FP_RANDOMART);
1439 printf("Your public key has been saved in %s.\n", 1471 printf("Your public key has been saved in %s.\n",
1440 identity_file); 1472 identity_file);
1441 printf("The key fingerprint is:\n"); 1473 printf("The key fingerprint is:\n");
1442 printf("%s %s\n", fp, comment); 1474 printf("%s %s\n", fp, comment);
1475 printf("The key's randomart image is:\n");
1476 printf("%s\n", ra);
1477 xfree(ra);
1443 xfree(fp); 1478 xfree(fp);
1444 } 1479 }
1445 1480