From ea43742e77ca5a14b625ebf073ba696b75cd7330 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 2 Oct 2009 11:49:03 +1000 Subject: pull in 5.3 release changes from branch: 20090926 - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] [contrib/suse/openssh.spec] Update for release - (djm) [README] update relnotes URL - (djm) [packet.c] Restore EWOULDBLOCK handling that got lost somewhere - (djm) Release 5.3p1 --- ChangeLog | 7 +++++++ README | 4 ++-- contrib/caldera/openssh.spec | 6 +++--- contrib/redhat/openssh.spec | 2 +- contrib/suse/openssh.spec | 2 +- packet.c | 9 ++++++--- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83664dc3d..b2df66023 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20090926 + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update for release + - (djm) [README] update relnotes URL + - (djm) [packet.c] Restore EWOULDBLOCK handling that got lost somewhere + - (djm) Release 5.3p1 + 20090911 - (dtucker) [configure.ac] Change the -lresolv check so it works on Mac OS X 10.6 (which doesn't have BIND8_COMPAT and thus uses res_9_query). Patch diff --git a/README b/README index 9de00c093..16666518a 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-5.2 for the release notes. +See http://www.openssh.com/txt/release-5.3 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html @@ -62,4 +62,4 @@ References - [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 [7] http://www.openssh.com/faq.html -$Id: README,v 1.70 2009/02/23 00:11:57 djm Exp $ +$Id: README,v 1.71 2009/10/02 01:49:03 djm Exp $ diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec index 42dbcfeeb..9ced32faf 100644 --- a/contrib/caldera/openssh.spec +++ b/contrib/caldera/openssh.spec @@ -17,11 +17,11 @@ #old cvs stuff. please update before use. may be deprecated. %define use_stable 1 %if %{use_stable} - %define version 5.2p1 + %define version 5.3p1 %define cvs %{nil} %define release 1 %else - %define version 5.2p1 + %define version 5.3p1 %define cvs cvs20050315 %define release 0r1 %endif @@ -358,4 +358,4 @@ fi * Mon Jan 01 1998 ... Template Version: 1.31 -$Id: openssh.spec,v 1.66 2009/02/21 07:03:05 djm Exp $ +$Id: openssh.spec,v 1.67 2009/10/02 01:49:05 djm Exp $ diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 10bdc1989..680906cf3 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 5.2p1 +%define ver 5.3p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 62f43e137..12661eeae 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 5.2p1 +Version: 5.3p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/packet.c b/packet.c index 600e015fb..994e35b6d 100644 --- a/packet.c +++ b/packet.c @@ -1070,7 +1070,8 @@ packet_read_seqnr(u_int32_t *seqnr_p) if ((ret = select(active_state->connection_in + 1, setp, NULL, NULL, timeoutp)) >= 0) break; - if (errno != EAGAIN && errno != EINTR) + if (errno != EAGAIN && errno != EINTR && + errno != EWOULDBLOCK) break; if (active_state->packet_timeout_ms == -1) continue; @@ -1643,7 +1644,8 @@ packet_write_poll(void) len = roaming_write(active_state->connection_out, buffer_ptr(&active_state->output), len, &cont); if (len == -1) { - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK) return; fatal("Write failed: %.100s", strerror(errno)); } @@ -1685,7 +1687,8 @@ packet_write_wait(void) if ((ret = select(active_state->connection_out + 1, NULL, setp, NULL, timeoutp)) >= 0) break; - if (errno != EAGAIN && errno != EINTR) + if (errno != EAGAIN && errno != EINTR && + errno != EWOULDBLOCK) break; if (active_state->packet_timeout_ms == -1) continue; -- cgit v1.2.3 From 350666d30069c163c0dc1fa2503740b9d970ecc8 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 2 Oct 2009 11:50:55 +1000 Subject: - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. spotted by des AT des.no --- ChangeLog | 4 ++++ Makefile.in | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2df66023..2278830f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091002 + - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. + spotted by des AT des.no + 20090926 - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] [contrib/suse/openssh.spec] Update for release diff --git a/Makefile.in b/Makefile.in index c5ecd5b39..da66311d0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.300 2009/08/28 00:47:38 djm Exp $ +# $Id: Makefile.in,v 1.301 2009/10/02 01:50:55 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -153,7 +153,7 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o +ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o -- cgit v1.2.3 From 46bbbe3326d69a84d94caca656c40a4521c10c45 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:21:48 +1100 Subject: - djm@cvs.openbsd.org 2009/08/12 00:13:00 [sftp.c sftp.1] support most of scp(1)'s commandline arguments in sftp(1), as a first step towards making sftp(1) a drop-in replacement for scp(1). One conflicting option (-P) has not been changed, pending further discussion. Patch from carlosvsilvapt@gmail.com as part of his work in the Google Summer of Code --- ChangeLog | 11 +++++++++++ sftp.1 | 31 ++++++++++++++++++++++++++++--- sftp.c | 57 ++++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 75 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2278830f3..e417906e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +20091007 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2009/08/12 00:13:00 + [sftp.c sftp.1] + support most of scp(1)'s commandline arguments in sftp(1), as a first + step towards making sftp(1) a drop-in replacement for scp(1). + One conflicting option (-P) has not been changed, pending further + discussion. + Patch from carlosvsilvapt@gmail.com as part of his work in the + Google Summer of Code + 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. spotted by des AT des.no diff --git a/sftp.1 b/sftp.1 index 37ccb3a38..d7df8bbee 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.69 2008/12/09 15:35:00 sobrado Exp $ +.\" $OpenBSD: sftp.1,v 1.70 2009/08/12 00:13:00 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: December 9 2008 $ +.Dd $Mdocdate: August 12 2009 $ .Dt SFTP 1 .Os .Sh NAME @@ -31,10 +31,12 @@ .Sh SYNOPSIS .Nm sftp .Bk -words -.Op Fl 1Cv +.Op Fl 1246Cqv .Op Fl B Ar buffer_size .Op Fl b Ar batchfile +.Op Fl c Ar cipher .Op Fl F Ar ssh_config +.Op Fl i Ar identity_path .Op Fl o Ar ssh_option .Op Fl P Ar sftp_server_path .Op Fl R Ar num_requests @@ -87,6 +89,16 @@ The options are as follows: .Bl -tag -width Ds .It Fl 1 Specify the use of protocol version 1. +.It Fl 2 +Specify the use of protocol version 2. +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. .It Fl B Ar buffer_size Specify the size of the buffer that .Nm @@ -120,6 +132,10 @@ prefixing the command with a .Sq \- character (for example, .Ic -rm /tmp/blah* ) . +.It Fl c Ar cipher +Selects the cipher to use for encrypting the data transfers. +This option is directly passed to +.Xr ssh 1 . .It Fl C Enables compression (via ssh's .Fl C @@ -130,6 +146,11 @@ per-user configuration file for .Xr ssh 1 . This option is directly passed to .Xr ssh 1 . +.It Fl i Ar identity_file +Selects the file from which the identity (private key) for public key +authentication is read. +This option is directly passed to +.Xr ssh 1 . .It Fl o Ar ssh_option Can be used to pass options to .Nm ssh @@ -199,6 +220,10 @@ Connect directly to a local sftp server (rather than via .Xr ssh 1 ) . This option may be useful in debugging the client and server. +.It Fl q +Quiet mode: disables the progress meter as well as warning and +diagnostic messages from +.Xr ssh 1 . .It Fl R Ar num_requests Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed diff --git a/sftp.c b/sftp.c index 66bd111b1..798a72edb 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.107 2009/02/02 11:15:14 dtucker Exp $ */ +/* $OpenBSD: sftp.c,v 1.108 2009/08/12 00:13:00 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1668,12 +1668,14 @@ usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config]\n" - " [-o ssh_option] [-P sftp_server_path] [-R num_requests]\n" - " [-S program] [-s subsystem | sftp_server] host\n" + "usage: %s [-1246Cqv] [-B buffer_size] [-b batchfile] [-c cipher]\n" + " [-F ssh_config] [-i identify_file] [-o ssh_option]\n" + " [-P sftp_server_path] [-R num_requests] [-S program]\n" + " [-s subsystem | sftp_server] host\n" " %s [user@]host[:file ...]\n" " %s [user@]host[:dir[/]]\n" - " %s -b batchfile [user@]host\n", __progname, __progname, __progname, __progname); + " %s -b batchfile [user@]host\n", + __progname, __progname, __progname, __progname); exit(1); } @@ -1705,10 +1707,24 @@ main(int argc, char **argv) ll = SYSLOG_LEVEL_INFO; infile = stdin; - while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) { + while ((ch = getopt(argc, argv, "1246hqvCc:i:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { + /* Passed through to ssh(1) */ + case '4': + case '6': case 'C': - addargs(&args, "-C"); + addargs(&args, "-%c", ch); + break; + /* Passed through to ssh(1) with argument */ + case 'F': + case 'c': + case 'i': + case 'o': + addargs(&args, "-%c%s", ch, optarg); + break; + case 'q': + showprogress = 0; + addargs(&args, "-%c", ch); break; case 'v': if (debug_level < 3) { @@ -1717,21 +1733,18 @@ main(int argc, char **argv) } debug_level++; break; - case 'F': - case 'o': - addargs(&args, "-%c%s", ch, optarg); - break; case '1': sshver = 1; if (sftp_server == NULL) sftp_server = _PATH_SFTP_SERVER; break; - case 's': - sftp_server = optarg; + case '2': + sshver = 2; break; - case 'S': - ssh_program = optarg; - replacearg(&args, 0, "%s", ssh_program); + case 'B': + copy_buffer_len = strtol(optarg, &cp, 10); + if (copy_buffer_len == 0 || *cp != '\0') + fatal("Invalid buffer size \"%s\"", optarg); break; case 'b': if (batchmode) @@ -1748,17 +1761,19 @@ main(int argc, char **argv) case 'P': sftp_direct = optarg; break; - case 'B': - copy_buffer_len = strtol(optarg, &cp, 10); - if (copy_buffer_len == 0 || *cp != '\0') - fatal("Invalid buffer size \"%s\"", optarg); - break; case 'R': num_requests = strtol(optarg, &cp, 10); if (num_requests == 0 || *cp != '\0') fatal("Invalid number of requests \"%s\"", optarg); break; + case 's': + sftp_server = optarg; + break; + case 'S': + ssh_program = optarg; + replacearg(&args, 0, "%s", ssh_program); + break; case 'h': default: usage(); -- cgit v1.2.3 From adba1ba51474d43e708de2b986c36199fa8f167e Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:22:20 +1100 Subject: - jmc@cvs.openbsd.org 2009/08/12 06:31:42 [sftp.1] sort options; --- ChangeLog | 3 +++ sftp.1 | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e417906e2..7c305d7d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,9 @@ discussion. Patch from carlosvsilvapt@gmail.com as part of his work in the Google Summer of Code + - jmc@cvs.openbsd.org 2009/08/12 06:31:42 + [sftp.1] + sort options; 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp.1 b/sftp.1 index d7df8bbee..d47ab1573 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.70 2009/08/12 00:13:00 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.71 2009/08/12 06:31:42 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -132,14 +132,14 @@ prefixing the command with a .Sq \- character (for example, .Ic -rm /tmp/blah* ) . -.It Fl c Ar cipher -Selects the cipher to use for encrypting the data transfers. -This option is directly passed to -.Xr ssh 1 . .It Fl C Enables compression (via ssh's .Fl C flag). +.It Fl c Ar cipher +Selects the cipher to use for encrypting the data transfers. +This option is directly passed to +.Xr ssh 1 . .It Fl F Ar ssh_config Specifies an alternative per-user configuration file for -- cgit v1.2.3 From 282b4026cb5c5a229e2c5b33e4ad3ac31fcf3189 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:23:06 +1100 Subject: - djm@cvs.openbsd.org 2009/08/13 01:11:19 [sftp.1 sftp.c] Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path", add "-P port" to match scp(1). Fortunately, the -P option is only really used by our regression scripts. part of larger patch from carlosvsilvapt@gmail.com for his Google Summer of Code work; ok deraadt markus --- ChangeLog | 7 +++++++ sftp.1 | 19 +++++++++++-------- sftp.c | 10 +++++++--- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c305d7d6..46f5e9cfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,13 @@ - jmc@cvs.openbsd.org 2009/08/12 06:31:42 [sftp.1] sort options; + - djm@cvs.openbsd.org 2009/08/13 01:11:19 + [sftp.1 sftp.c] + Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path", + add "-P port" to match scp(1). Fortunately, the -P option is only really + used by our regression scripts. + part of larger patch from carlosvsilvapt@gmail.com for his Google Summer + of Code work; ok deraadt markus 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp.1 b/sftp.1 index d47ab1573..6cec52ae1 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.71 2009/08/12 06:31:42 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.72 2009/08/13 01:11:19 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 12 2009 $ +.Dd $Mdocdate: August 13 2009 $ .Dt SFTP 1 .Os .Sh NAME @@ -35,10 +35,11 @@ .Op Fl B Ar buffer_size .Op Fl b Ar batchfile .Op Fl c Ar cipher +.Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config .Op Fl i Ar identity_path .Op Fl o Ar ssh_option -.Op Fl P Ar sftp_server_path +.Op Fl P Ar port .Op Fl R Ar num_requests .Op Fl S Ar program .Op Fl s Ar subsystem | sftp_server @@ -140,6 +141,11 @@ flag). Selects the cipher to use for encrypting the data transfers. This option is directly passed to .Xr ssh 1 . +.It Fl D Ar sftp_server_path +Connect directly to a local sftp server +(rather than via +.Xr ssh 1 ) . +This option may be useful in debugging the client and server. .It Fl F Ar ssh_config Specifies an alternative per-user configuration file for @@ -215,11 +221,8 @@ For full details of the options listed below, and their possible values, see .It UserKnownHostsFile .It VerifyHostKeyDNS .El -.It Fl P Ar sftp_server_path -Connect directly to a local sftp server -(rather than via -.Xr ssh 1 ) . -This option may be useful in debugging the client and server. +.It Fl P Ar port +Specifies the port to connect to on the remote host. .It Fl q Quiet mode: disables the progress meter as well as warning and diagnostic messages from diff --git a/sftp.c b/sftp.c index 798a72edb..4c1d55389 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.108 2009/08/12 00:13:00 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.109 2009/08/13 01:11:19 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1707,7 +1707,8 @@ main(int argc, char **argv) ll = SYSLOG_LEVEL_INFO; infile = stdin; - while ((ch = getopt(argc, argv, "1246hqvCc:i:o:s:S:b:B:F:P:R:")) != -1) { + while ((ch = getopt(argc, argv, + "1246hqvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { /* Passed through to ssh(1) */ case '4': @@ -1726,6 +1727,9 @@ main(int argc, char **argv) showprogress = 0; addargs(&args, "-%c", ch); break; + case 'P': + addargs(&args, "-oPort %s", optarg); + break; case 'v': if (debug_level < 3) { addargs(&args, "-v"); @@ -1758,7 +1762,7 @@ main(int argc, char **argv) batchmode = 1; addargs(&args, "-obatchmode yes"); break; - case 'P': + case 'D': sftp_direct = optarg; break; case 'R': -- cgit v1.2.3 From c07138e6f6a9173d0315cceb123e3bc4abbd1528 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:23:44 +1100 Subject: - jmc@cvs.openbsd.org 2009/08/13 13:39:54 [sftp.1 sftp.c] sync synopsis and usage(); --- ChangeLog | 3 +++ sftp.1 | 4 ++-- sftp.c | 8 +++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46f5e9cfa..9afa9e820 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,9 @@ used by our regression scripts. part of larger patch from carlosvsilvapt@gmail.com for his Google Summer of Code work; ok deraadt markus + - jmc@cvs.openbsd.org 2009/08/13 13:39:54 + [sftp.1 sftp.c] + sync synopsis and usage(); 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp.1 b/sftp.1 index 6cec52ae1..fcd1d240a 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.72 2009/08/13 01:11:19 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.73 2009/08/13 13:39:54 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -37,7 +37,7 @@ .Op Fl c Ar cipher .Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config -.Op Fl i Ar identity_path +.Op Fl i Ar identity_file .Op Fl o Ar ssh_option .Op Fl P Ar port .Op Fl R Ar num_requests diff --git a/sftp.c b/sftp.c index 4c1d55389..0123fd72c 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.109 2009/08/13 01:11:19 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.110 2009/08/13 13:39:54 jmc Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1669,8 +1669,10 @@ usage(void) fprintf(stderr, "usage: %s [-1246Cqv] [-B buffer_size] [-b batchfile] [-c cipher]\n" - " [-F ssh_config] [-i identify_file] [-o ssh_option]\n" - " [-P sftp_server_path] [-R num_requests] [-S program]\n" + " [-D sftp_server_path] [-F ssh_config] " + "[-i identity_file]\n" + " [-o ssh_option] [-P port] [-R num_requests] " + "[-S program]\n" " [-s subsystem | sftp_server] host\n" " %s [user@]host[:file ...]\n" " %s [user@]host[:dir[/]]\n" -- cgit v1.2.3 From c22f090a2f4ac309d1d44a6bbafdefb1e8de532a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:24:19 +1100 Subject: - djm@cvs.openbsd.org 2009/08/14 18:17:49 [sftp-client.c] make the "get_handle: ..." error messages vaguely useful by allowing callers to specify their own error message strings. --- ChangeLog | 4 ++++ sftp-client.c | 39 +++++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9afa9e820..5b4737632 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,10 @@ - jmc@cvs.openbsd.org 2009/08/13 13:39:54 [sftp.1 sftp.c] sync synopsis and usage(); + - djm@cvs.openbsd.org 2009/08/14 18:17:49 + [sftp-client.c] + make the "get_handle: ..." error messages vaguely useful by allowing + callers to specify their own error message strings. 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp-client.c b/sftp-client.c index 0990b7912..14c172d2f 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.87 2009/06/22 05:39:28 dtucker Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.88 2009/08/14 18:17:49 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -74,6 +74,10 @@ struct sftp_conn { u_int exts; }; +static char * +get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) + __attribute__((format(printf, 4, 5))); + static void send_msg(int fd, Buffer *m) { @@ -179,11 +183,18 @@ get_status(int fd, u_int expected_id) } static char * -get_handle(int fd, u_int expected_id, u_int *len) +get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) { Buffer msg; u_int type, id; - char *handle; + char *handle, errmsg[256]; + va_list args; + int status; + + va_start(args, errfmt); + if (errfmt != NULL) + vsnprintf(errmsg, sizeof(errmsg), errfmt, args); + va_end(args); buffer_init(&msg); get_msg(fd, &msg); @@ -191,16 +202,17 @@ get_handle(int fd, u_int expected_id, u_int *len) id = buffer_get_int(&msg); if (id != expected_id) - fatal("ID mismatch (%u != %u)", id, expected_id); + fatal("%s: ID mismatch (%u != %u)", + errfmt == NULL ? __func__ : errmsg, id, expected_id); if (type == SSH2_FXP_STATUS) { - int status = buffer_get_int(&msg); - - error("Couldn't get handle: %s", fx2txt(status)); + status = buffer_get_int(&msg); + if (errfmt != NULL) + error("%s: %s", errmsg, fx2txt(status)); buffer_free(&msg); return(NULL); } else if (type != SSH2_FXP_HANDLE) - fatal("Expected SSH2_FXP_HANDLE(%u) packet, got %u", - SSH2_FXP_HANDLE, type); + fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u", + errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type); handle = buffer_get_string(&msg, len); buffer_free(&msg); @@ -418,7 +430,8 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, buffer_clear(&msg); - handle = get_handle(conn->fd_in, id, &handle_len); + handle = get_handle(conn->fd_in, id, &handle_len, + "remote readdir(\"%s\")", path); if (handle == NULL) return(-1); @@ -951,7 +964,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, send_msg(conn->fd_out, &msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); - handle = get_handle(conn->fd_in, id, &handle_len); + handle = get_handle(conn->fd_in, id, &handle_len, + "remote open(\"%s\")", remote_path); if (handle == NULL) { buffer_free(&msg); return(-1); @@ -1195,7 +1209,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, buffer_clear(&msg); - handle = get_handle(conn->fd_in, id, &handle_len); + handle = get_handle(conn->fd_in, id, &handle_len, + "remote open(\"%s\")", remote_path); if (handle == NULL) { close(local_fd); buffer_free(&msg); -- cgit v1.2.3 From e54a036219434260f8efd86c8c110141994fcfa1 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:35:32 +1100 Subject: - fgsch@cvs.openbsd.org 2009/08/15 18:56:34 [auth.h] remove unused define. markus@ ok. (Id sync only, Portable still uses this.) --- ChangeLog | 4 ++++ auth.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5b4737632..e94fba2fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,10 @@ [sftp-client.c] make the "get_handle: ..." error messages vaguely useful by allowing callers to specify their own error message strings. + - fgsch@cvs.openbsd.org 2009/08/15 18:56:34 + [auth.h] + remove unused define. markus@ ok. + (Id sync only, Portable still uses this.) 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/auth.h b/auth.h index 3a70f4421..bebfb672d 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.62 2008/11/04 08:22:12 djm Exp $ */ +/* $OpenBSD: auth.h,v 1.63 2009/08/15 18:56:34 fgsch Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. -- cgit v1.2.3 From 1477ea162c05c09b4b5ebc19ac588fbf469349dc Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:36:05 +1100 Subject: - dtucker@cvs.openbsd.org 2009/08/16 23:29:26 [sshd_config.5] Add PubkeyAuthentication to the list allowed in a Match block (bz #1577) --- ChangeLog | 3 +++ sshd_config.5 | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e94fba2fd..60eae3a42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,9 @@ [auth.h] remove unused define. markus@ ok. (Id sync only, Portable still uses this.) + - dtucker@cvs.openbsd.org 2009/08/16 23:29:26 + [sshd_config.5] + Add PubkeyAuthentication to the list allowed in a Match block (bz #1577) 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sshd_config.5 b/sshd_config.5 index 588aed56e..54a4480fe 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.106 2009/04/21 15:13:17 stevesk Exp $ -.Dd $Mdocdate: April 21 2009 $ +.\" $OpenBSD: sshd_config.5,v 1.107 2009/08/16 23:29:26 dtucker Exp $ +.Dd $Mdocdate: August 16 2009 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -614,6 +614,7 @@ Available keywords are .Cm PermitEmptyPasswords , .Cm PermitOpen , .Cm PermitRootLogin , +.Cm PubkeyAuthentication , .Cm RhostsRSAAuthentication , .Cm RSAAuthentication , .Cm X11DisplayOffset , -- cgit v1.2.3 From 1b0dd175377c86abb7f3a3da2e9b1a89f36c7a1a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:37:48 +1100 Subject: - djm@cvs.openbsd.org 2009/08/18 18:36:21 [sftp-client.h sftp.1 sftp-client.c sftp.c] recursive transfer support for get/put and on the commandline work mostly by carlosvsilvapt@gmail.com for the Google Summer of Code with some tweaks by me; "go for it" deraadt@ --- ChangeLog | 5 ++ sftp-client.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- sftp-client.h | 21 ++++- sftp.1 | 44 ++++++++-- sftp.c | 219 +++++++++++++++++++++++++------------------------ 5 files changed, 423 insertions(+), 126 deletions(-) diff --git a/ChangeLog b/ChangeLog index 60eae3a42..2fedeccbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,11 @@ - dtucker@cvs.openbsd.org 2009/08/16 23:29:26 [sshd_config.5] Add PubkeyAuthentication to the list allowed in a Match block (bz #1577) + - djm@cvs.openbsd.org 2009/08/18 18:36:21 + [sftp-client.h sftp.1 sftp-client.c sftp.c] + recursive transfer support for get/put and on the commandline + work mostly by carlosvsilvapt@gmail.com for the Google Summer of Code + with some tweaks by me; "go for it" deraadt@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp-client.c b/sftp-client.c index 14c172d2f..cc4a5b15b 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.88 2009/08/14 18:17:49 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.89 2009/08/18 18:36:20 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -36,6 +36,7 @@ #endif #include +#include #include #include #include @@ -61,6 +62,9 @@ extern int showprogress; /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 +/* Maximum depth to descend in directory trees */ +#define MAX_DIR_DEPTH 64 + struct sftp_conn { int fd_in; int fd_out; @@ -497,6 +501,17 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, if (printflag) printf("%s\n", longname); + /* + * Directory entries should never contain '/' + * These can be used to attack recursive ops + * (e.g. send '../../../../etc/passwd') + */ + if (strchr(filename, '/') != NULL) { + error("Server sent suspect path \"%s\" " + "during readdir of \"%s\"", filename, path); + goto next; + } + if (dir) { *dir = xrealloc(*dir, ents + 2, sizeof(**dir)); (*dir)[ents] = xmalloc(sizeof(***dir)); @@ -505,7 +520,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, memcpy(&(*dir)[ents]->a, a, sizeof(*a)); (*dir)[++ents] = NULL; } - + next: xfree(filename); xfree(longname); } @@ -560,7 +575,7 @@ do_rm(struct sftp_conn *conn, char *path) } int -do_mkdir(struct sftp_conn *conn, char *path, Attrib *a) +do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) { u_int status, id; @@ -569,7 +584,7 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a) strlen(path), a); status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) + if (status != SSH2_FX_OK && printflag) error("Couldn't create directory: %s", fx2txt(status)); return(status); @@ -908,9 +923,9 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, int do_download(struct sftp_conn *conn, char *remote_path, char *local_path, - int pflag) + Attrib *a, int pflag) { - Attrib junk, *a; + Attrib junk; Buffer msg; char *handle; int local_fd, status = 0, write_error; @@ -929,9 +944,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, TAILQ_INIT(&requests); - a = do_stat(conn, remote_path, 0); - if (a == NULL) - return(-1); + if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL) + return -1; /* Do not preserve set[ug]id here, as we do not preserve ownership */ if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) @@ -1146,6 +1160,114 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, return(status); } +static int +download_dir_internal(struct sftp_conn *conn, char *src, char *dst, + Attrib *dirattrib, int pflag, int printflag, int depth) +{ + int i, ret = 0; + SFTP_DIRENT **dir_entries; + char *filename, *new_src, *new_dst; + mode_t mode = 0777; + + if (depth >= MAX_DIR_DEPTH) { + error("Maximum directory depth exceeded: %d levels", depth); + return -1; + } + + if (dirattrib == NULL && + (dirattrib = do_stat(conn, src, 1)) == NULL) { + error("Unable to stat remote directory \"%s\"", src); + return -1; + } + if (!S_ISDIR(dirattrib->perm)) { + error("\"%s\" is not a directory", src); + return -1; + } + if (printflag) + printf("Retrieving %s\n", src); + + if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) + mode = dirattrib->perm & 01777; + else { + debug("Server did not send permissions for " + "directory \"%s\"", dst); + } + + if (mkdir(dst, mode) == -1 && errno != EEXIST) { + error("mkdir %s: %s", dst, strerror(errno)); + return -1; + } + + if (do_readdir(conn, src, &dir_entries) == -1) { + error("%s: Failed to get directory contents", src); + return -1; + } + + for (i = 0; dir_entries[i] != NULL && !interrupted; i++) { + filename = dir_entries[i]->filename; + + new_dst = path_append(dst, filename); + new_src = path_append(src, filename); + + if (S_ISDIR(dir_entries[i]->a.perm)) { + if (strcmp(filename, ".") == 0 || + strcmp(filename, "..") == 0) + continue; + if (download_dir_internal(conn, new_src, new_dst, + &(dir_entries[i]->a), pflag, printflag, + depth + 1) == -1) + ret = -1; + } else if (S_ISREG(dir_entries[i]->a.perm) ) { + if (do_download(conn, new_src, new_dst, + &(dir_entries[i]->a), pflag) == -1) { + error("Download of file %s to %s failed", + new_src, new_dst); + ret = -1; + } + } else + logit("%s: not a regular file\n", new_src); + + xfree(new_dst); + xfree(new_src); + } + + if (pflag) { + if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + struct timeval tv[2]; + tv[0].tv_sec = dirattrib->atime; + tv[1].tv_sec = dirattrib->mtime; + tv[0].tv_usec = tv[1].tv_usec = 0; + if (utimes(dst, tv) == -1) + error("Can't set times on \"%s\": %s", + dst, strerror(errno)); + } else + debug("Server did not send times for directory " + "\"%s\"", dst); + } + + free_sftp_dirents(dir_entries); + + return ret; +} + +int +download_dir(struct sftp_conn *conn, char *src, char *dst, + Attrib *dirattrib, int pflag, int printflag) +{ + char *src_canon; + int ret; + + if ((src_canon = do_realpath(conn, src)) == NULL) { + error("Unable to canonicalise path \"%s\"", src); + return -1; + } + + ret = download_dir_internal(conn, src_canon, dst, + dirattrib, pflag, printflag, 0); + xfree(src_canon); + return ret; +} + int do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, int pflag) @@ -1328,3 +1450,123 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, return status; } + +static int +upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, + int pflag, int printflag, int depth) +{ + int ret = 0, status; + DIR *dirp; + struct dirent *dp; + char *filename, *new_src, *new_dst; + struct stat sb; + Attrib a; + + if (depth >= MAX_DIR_DEPTH) { + error("Maximum directory depth exceeded: %d levels", depth); + return -1; + } + + if (stat(src, &sb) == -1) { + error("Couldn't stat directory \"%s\": %s", + src, strerror(errno)); + return -1; + } + if (!S_ISDIR(sb.st_mode)) { + error("\"%s\" is not a directory", src); + return -1; + } + if (printflag) + printf("Entering %s\n", src); + + attrib_clear(&a); + stat_to_attrib(&sb, &a); + a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; + a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; + a.perm &= 01777; + if (!pflag) + a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; + + status = do_mkdir(conn, dst, &a, 0); + /* + * we lack a portable status for errno EEXIST, + * so if we get a SSH2_FX_FAILURE back we must check + * if it was created successfully. + */ + if (status != SSH2_FX_OK) { + if (status != SSH2_FX_FAILURE) + return -1; + if (do_stat(conn, dst, 0) == NULL) + return -1; + } + + if ((dirp = opendir(src)) == NULL) { + error("Failed to open dir \"%s\": %s", src, strerror(errno)); + return -1; + } + + while (((dp = readdir(dirp)) != NULL) && !interrupted) { + if (dp->d_ino == 0) + continue; + filename = dp->d_name; + new_dst = path_append(dst, filename); + new_src = path_append(src, filename); + + if (S_ISDIR(DTTOIF(dp->d_type))) { + if (strcmp(filename, ".") == 0 || + strcmp(filename, "..") == 0) + continue; + + if (upload_dir_internal(conn, new_src, new_dst, + pflag, depth + 1, printflag) == -1) + ret = -1; + } else if (S_ISREG(DTTOIF(dp->d_type)) ) { + if (do_upload(conn, new_src, new_dst, pflag) == -1) { + error("Uploading of file %s to %s failed!", + new_src, new_dst); + ret = -1; + } + } else + logit("%s: not a regular file\n", filename); + xfree(new_dst); + xfree(new_src); + } + + do_setstat(conn, dst, &a); + + (void) closedir(dirp); + return ret; +} + +int +upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, + int pflag) +{ + char *dst_canon; + int ret; + + if ((dst_canon = do_realpath(conn, dst)) == NULL) { + error("Unable to canonicalise path \"%s\"", dst); + return -1; + } + + ret = upload_dir_internal(conn, src, dst_canon, pflag, printflag, 0); + xfree(dst_canon); + return ret; +} + +char * +path_append(char *p1, char *p2) +{ + char *ret; + size_t len = strlen(p1) + strlen(p2) + 2; + + ret = xmalloc(len); + strlcpy(ret, p1, len); + if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/') + strlcat(ret, "/", len); + strlcat(ret, p2, len); + + return(ret); +} + diff --git a/sftp-client.h b/sftp-client.h index edb46790f..1d08c4049 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.17 2008/06/08 20:15:29 dtucker Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.18 2009/08/18 18:36:20 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller @@ -68,7 +68,7 @@ void free_sftp_dirents(SFTP_DIRENT **); int do_rm(struct sftp_conn *, char *); /* Create directory 'path' */ -int do_mkdir(struct sftp_conn *, char *, Attrib *); +int do_mkdir(struct sftp_conn *, char *, Attrib *, int); /* Remove directory 'path' */ int do_rmdir(struct sftp_conn *, char *); @@ -103,7 +103,13 @@ int do_symlink(struct sftp_conn *, char *, char *); * Download 'remote_path' to 'local_path'. Preserve permissions and times * if 'pflag' is set */ -int do_download(struct sftp_conn *, char *, char *, int); +int do_download(struct sftp_conn *, char *, char *, Attrib *, int); + +/* + * Recursively download 'remote_directory' to 'local_directory'. Preserve + * times if 'pflag' is set + */ +int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int); /* * Upload 'local_path' to 'remote_path'. Preserve permissions and times @@ -111,4 +117,13 @@ int do_download(struct sftp_conn *, char *, char *, int); */ int do_upload(struct sftp_conn *, char *, char *, int); +/* + * Recursively upload 'local_directory' to 'remote_directory'. Preserve + * times if 'pflag' is set + */ +int upload_dir(struct sftp_conn *, char *, char *, int, int); + +/* Concatenate paths, taking care of slashes. Caller must free result. */ +char *path_append(char *, char *); + #endif diff --git a/sftp.1 b/sftp.1 index fcd1d240a..21dc5d8d6 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.73 2009/08/13 13:39:54 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.74 2009/08/18 18:36:20 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 13 2009 $ +.Dd $Mdocdate: August 18 2009 $ .Dt SFTP 1 .Os .Sh NAME @@ -31,7 +31,7 @@ .Sh SYNOPSIS .Nm sftp .Bk -words -.Op Fl 1246Cqv +.Op Fl 1246Cpqrv .Op Fl B Ar buffer_size .Op Fl b Ar batchfile .Op Fl c Ar cipher @@ -223,6 +223,9 @@ For full details of the options listed below, and their possible values, see .El .It Fl P Ar port Specifies the port to connect to on the remote host. +.It Fl p +Preserves modification times, access times, and modes from the +original files transferred. .It Fl q Quiet mode: disables the progress meter as well as warning and diagnostic messages from @@ -232,6 +235,11 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. The default is 64 outstanding requests. +.It Fl r +Recursively copy entire directories when uploading and downloading. +Note that +.Nm +does not follow symbolic links encountered in the tree traversal. .It Fl S Ar program Name of the .Ar program @@ -322,7 +330,7 @@ extension. Quit .Nm sftp . .It Xo Ic get -.Op Fl P +.Op Fl Ppr .Ar remote-path .Op Ar local-path .Xc @@ -341,10 +349,20 @@ If it does and is specified, then .Ar local-path must specify a directory. -If the -.Fl P +.Pp +If ether the +.Fl Ppr +or +.Fl p flag is specified, then full file permissions and access times are copied too. +.Pp +If the +.Fl r +flag is specified then directories will be copied recursively. +Note that +.Nm +does not follow symbolic links when performing recursive transfers. .It Ic help Display help text. .It Ic lcd Ar path @@ -440,10 +458,20 @@ If it does and is specified, then .Ar remote-path must specify a directory. -If the +.Pp +If ether the .Fl P -flag is specified, then the file's full permission and access time are +or +.Fl p +flag is specified, then full file permissions and access times are copied too. +.Pp +If the +.Fl r +flag is specified then directories will be copied recursively. +Note that +.Nm +does not follow symbolic links when performing recursive transfers. .It Ic pwd Display remote working directory. .It Ic quit diff --git a/sftp.c b/sftp.c index 0123fd72c..75b16b27e 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.110 2009/08/13 13:39:54 jmc Exp $ */ +/* $OpenBSD: sftp.c,v 1.111 2009/08/18 18:36:21 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -35,6 +35,9 @@ #ifdef HAVE_PATHS_H # include #endif +#ifdef HAVE_LIBGEN_H +#include +#endif #ifdef USE_LIBEDIT #include #else @@ -83,6 +86,12 @@ static pid_t sshpid = -1; /* This is set to 0 if the progressmeter is not desired. */ int showprogress = 1; +/* When this option is set, we always recursively download/upload directories */ +int global_rflag = 0; + +/* When this option is set, the file transfers will always preserve times */ +int global_pflag = 0; + /* SIGINT received during command processing */ volatile sig_atomic_t interrupted = 0; @@ -216,7 +225,7 @@ help(void) "df [-hi] [path] Display statistics for current directory or\n" " filesystem containing 'path'\n" "exit Quit sftp\n" - "get [-P] remote-path [local-path] Download file\n" + "get [-Pr] remote-path [local-path] Download file\n" "help Display this help text\n" "lcd path Change local directory to 'path'\n" "lls [ls-options [path]] Display local directory listing\n" @@ -227,7 +236,7 @@ help(void) "lumask umask Set local umask to 'umask'\n" "mkdir path Create remote directory\n" "progress Toggle display of progress meter\n" - "put [-P] local-path [remote-path] Upload file\n" + "put [-Pr] local-path [remote-path] Upload file\n" "pwd Display remote working directory\n" "quit Quit sftp\n" "rename oldpath newpath Rename remote file\n" @@ -313,21 +322,6 @@ path_strip(char *path, char *strip) return (xstrdup(path)); } -static char * -path_append(char *p1, char *p2) -{ - char *ret; - size_t len = strlen(p1) + strlen(p2) + 2; - - ret = xmalloc(len); - strlcpy(ret, p1, len); - if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/') - strlcat(ret, "/", len); - strlcat(ret, p2, len); - - return(ret); -} - static char * make_absolute(char *p, char *pwd) { @@ -343,27 +337,8 @@ make_absolute(char *p, char *pwd) } static int -infer_path(const char *p, char **ifp) -{ - char *cp; - - cp = strrchr(p, '/'); - if (cp == NULL) { - *ifp = xstrdup(p); - return(0); - } - - if (!cp[1]) { - error("Invalid path"); - return(-1); - } - - *ifp = xstrdup(cp + 1); - return(0); -} - -static int -parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag) +parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag, + int *rflag) { extern int opterr, optind, optopt, optreset; int ch; @@ -371,13 +346,17 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag) optind = optreset = 1; opterr = 0; - *pflag = 0; - while ((ch = getopt(argc, argv, "Pp")) != -1) { + *rflag = *pflag = 0; + while ((ch = getopt(argc, argv, "PpRr")) != -1) { switch (ch) { case 'p': case 'P': *pflag = 1; break; + case 'r': + case 'R': + *rflag = 1; + break; default: error("%s: Invalid flag -%c", cmd, optopt); return -1; @@ -489,62 +468,79 @@ remote_is_dir(struct sftp_conn *conn, char *path) return(S_ISDIR(a->perm)); } +/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ +static int +pathname_is_dir(char *pathname) +{ + size_t l = strlen(pathname); + + return l > 0 && pathname[l - 1] == '/'; +} + static int -process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) +process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, + int pflag, int rflag) { char *abs_src = NULL; char *abs_dst = NULL; - char *tmp; glob_t g; - int err = 0; - int i; + char *filename, *tmp=NULL; + int i, err = 0; abs_src = xstrdup(src); abs_src = make_absolute(abs_src, pwd); - memset(&g, 0, sizeof(g)); + debug3("Looking up %s", abs_src); - if (remote_glob(conn, abs_src, 0, NULL, &g)) { + if (remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) { error("File \"%s\" not found.", abs_src); err = -1; goto out; } - /* If multiple matches, dst must be a directory or unspecified */ - if (g.gl_matchc > 1 && dst && !is_dir(dst)) { - error("Multiple files match, but \"%s\" is not a directory", - dst); + /* + * If multiple matches then dst must be a directory or + * unspecified. + */ + if (g.gl_matchc > 1 && dst != NULL && !is_dir(dst)) { + error("Multiple source paths, but destination " + "\"%s\" is not a directory", dst); err = -1; goto out; } for (i = 0; g.gl_pathv[i] && !interrupted; i++) { - if (infer_path(g.gl_pathv[i], &tmp)) { + tmp = xstrdup(g.gl_pathv[i]); + if ((filename = basename(tmp)) == NULL) { + error("basename %s: %s", tmp, strerror(errno)); + xfree(tmp); err = -1; goto out; } if (g.gl_matchc == 1 && dst) { - /* If directory specified, append filename */ - xfree(tmp); if (is_dir(dst)) { - if (infer_path(g.gl_pathv[0], &tmp)) { - err = 1; - goto out; - } - abs_dst = path_append(dst, tmp); - xfree(tmp); - } else + abs_dst = path_append(dst, filename); + } else { abs_dst = xstrdup(dst); + } } else if (dst) { - abs_dst = path_append(dst, tmp); - xfree(tmp); - } else - abs_dst = tmp; + abs_dst = path_append(dst, filename); + } else { + abs_dst = xstrdup(filename); + } + xfree(tmp); printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); - if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1) - err = -1; + if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { + if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, + pflag || global_pflag, 1) == -1) + err = -1; + } else { + if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, + pflag || global_pflag) == -1) + err = -1; + } xfree(abs_dst); abs_dst = NULL; } @@ -556,14 +552,15 @@ out: } static int -process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) +process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, + int pflag, int rflag) { char *tmp_dst = NULL; char *abs_dst = NULL; - char *tmp; + char *tmp = NULL, *filename = NULL; glob_t g; int err = 0; - int i; + int i, dst_is_dir = 1; struct stat sb; if (dst) { @@ -573,16 +570,20 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) memset(&g, 0, sizeof(g)); debug3("Looking up %s", src); - if (glob(src, GLOB_NOCHECK, NULL, &g)) { + if (glob(src, GLOB_NOCHECK | GLOB_MARK, NULL, &g)) { error("File \"%s\" not found.", src); err = -1; goto out; } + /* If we aren't fetching to pwd then stash this status for later */ + if (tmp_dst != NULL) + dst_is_dir = remote_is_dir(conn, tmp_dst); + /* If multiple matches, dst may be directory or unspecified */ - if (g.gl_matchc > 1 && tmp_dst && !remote_is_dir(conn, tmp_dst)) { - error("Multiple files match, but \"%s\" is not a directory", - tmp_dst); + if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) { + error("Multiple paths match, but destination " + "\"%s\" is not a directory", tmp_dst); err = -1; goto out; } @@ -593,38 +594,38 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) error("stat %s: %s", g.gl_pathv[i], strerror(errno)); continue; } - - if (!S_ISREG(sb.st_mode)) { - error("skipping non-regular file %s", - g.gl_pathv[i]); - continue; - } - if (infer_path(g.gl_pathv[i], &tmp)) { + + tmp = xstrdup(g.gl_pathv[i]); + if ((filename = basename(tmp)) == NULL) { + error("basename %s: %s", tmp, strerror(errno)); + xfree(tmp); err = -1; goto out; } if (g.gl_matchc == 1 && tmp_dst) { /* If directory specified, append filename */ - if (remote_is_dir(conn, tmp_dst)) { - if (infer_path(g.gl_pathv[0], &tmp)) { - err = 1; - goto out; - } - abs_dst = path_append(tmp_dst, tmp); - xfree(tmp); - } else + if (dst_is_dir) + abs_dst = path_append(tmp_dst, filename); + else abs_dst = xstrdup(tmp_dst); - } else if (tmp_dst) { - abs_dst = path_append(tmp_dst, tmp); - xfree(tmp); - } else - abs_dst = make_absolute(tmp, pwd); + abs_dst = path_append(tmp_dst, filename); + } else { + abs_dst = make_absolute(xstrdup(filename), pwd); + } + xfree(tmp); printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); - if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1) - err = -1; + if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { + if (upload_dir(conn, g.gl_pathv[i], abs_dst, + pflag || global_pflag, 1) == -1) + err = -1; + } else { + if (do_upload(conn, g.gl_pathv[i], abs_dst, + pflag || global_pflag) == -1) + err = -1; + } } out: @@ -1065,7 +1066,7 @@ makeargv(const char *arg, int *argcp) } static int -parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag, +parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, int *hflag, unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; @@ -1109,13 +1110,13 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag, } /* Get arguments and parse flags */ - *lflag = *pflag = *hflag = *n_arg = 0; + *lflag = *pflag = *rflag = *hflag = *n_arg = 0; *path1 = *path2 = NULL; optidx = 1; switch (cmdnum) { case I_GET: case I_PUT: - if ((optidx = parse_getput_flags(cmd, argv, argc, pflag)) == -1) + if ((optidx = parse_getput_flags(cmd, argv, argc, pflag, rflag)) == -1) return -1; /* Get first pathname (mandatory) */ if (argc - optidx < 1) { @@ -1235,7 +1236,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; - int pflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i; + int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i; unsigned long n_arg = 0; Attrib a, *aa; char path_buf[MAXPATHLEN]; @@ -1243,7 +1244,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, glob_t g; path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg, + cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, &n_arg, &path1, &path2); if (iflag != 0) @@ -1261,10 +1262,10 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, err = -1; break; case I_GET: - err = process_get(conn, path1, path2, *pwd, pflag); + err = process_get(conn, path1, path2, *pwd, pflag, rflag); break; case I_PUT: - err = process_put(conn, path1, path2, *pwd, pflag); + err = process_put(conn, path1, path2, *pwd, pflag, rflag); break; case I_RENAME: path1 = make_absolute(path1, *pwd); @@ -1290,7 +1291,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, attrib_clear(&a); a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; a.perm = 0777; - err = do_mkdir(conn, path1, &a); + err = do_mkdir(conn, path1, &a, 1); break; case I_RMDIR: path1 = make_absolute(path1, *pwd); @@ -1668,7 +1669,7 @@ usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-1246Cqv] [-B buffer_size] [-b batchfile] [-c cipher]\n" + "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" " [-D sftp_server_path] [-F ssh_config] " "[-i identity_file]\n" " [-o ssh_option] [-P port] [-R num_requests] " @@ -1710,7 +1711,7 @@ main(int argc, char **argv) infile = stdin; while ((ch = getopt(argc, argv, - "1246hqvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) { + "1246hqrvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { /* Passed through to ssh(1) */ case '4': @@ -1764,9 +1765,15 @@ main(int argc, char **argv) batchmode = 1; addargs(&args, "-obatchmode yes"); break; + case 'p': + global_pflag = 1; + break; case 'D': sftp_direct = optarg; break; + case 'r': + global_rflag = 1; + break; case 'R': num_requests = strtol(optarg, &cp, 10); if (num_requests == 0 || *cp != '\0') -- cgit v1.2.3 From 05016b2f9983e5489ae6e4dc810f22cc46415f55 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:38:23 +1100 Subject: - djm@cvs.openbsd.org 2009/08/18 21:15:59 [sftp.1] fix "get" command usage, spotted by jmc@ --- ChangeLog | 3 +++ sftp.1 | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2fedeccbd..f9243d28c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,6 +37,9 @@ recursive transfer support for get/put and on the commandline work mostly by carlosvsilvapt@gmail.com for the Google Summer of Code with some tweaks by me; "go for it" deraadt@ + - djm@cvs.openbsd.org 2009/08/18 21:15:59 + [sftp.1] + fix "get" command usage, spotted by jmc@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp.1 b/sftp.1 index 21dc5d8d6..1066ea478 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.74 2009/08/18 18:36:20 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.75 2009/08/18 21:15:59 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -351,7 +351,7 @@ is specified, then must specify a directory. .Pp If ether the -.Fl Ppr +.Fl P or .Fl p flag is specified, then full file permissions and access times are @@ -440,7 +440,7 @@ Create remote directory specified by .It Ic progress Toggle display of progress meter. .It Xo Ic put -.Op Fl P +.Op Fl Ppr .Ar local-path .Op Ar remote-path .Xc -- cgit v1.2.3 From b3b40a8b95b3fc8ca952f0958b966a99f78b2ef2 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:39:09 +1100 Subject: - jmc@cvs.openbsd.org 2009/08/19 04:56:03 [sftp.1] ether -> either; --- ChangeLog | 3 +++ sftp.1 | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9243d28c..d2d6862cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,9 @@ - djm@cvs.openbsd.org 2009/08/18 21:15:59 [sftp.1] fix "get" command usage, spotted by jmc@ + - jmc@cvs.openbsd.org 2009/08/19 04:56:03 + [sftp.1] + ether -> either; 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp.1 b/sftp.1 index 1066ea478..d1db0d6dd 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.75 2009/08/18 21:15:59 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.76 2009/08/19 04:56:03 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 18 2009 $ +.Dd $Mdocdate: August 19 2009 $ .Dt SFTP 1 .Os .Sh NAME @@ -350,7 +350,7 @@ is specified, then .Ar local-path must specify a directory. .Pp -If ether the +If either the .Fl P or .Fl p -- cgit v1.2.3 From 8ec4fd8e3cf5eaf4791d422df1137ecacebc2a34 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:39:57 +1100 Subject: - dtucker@cvs.openbsd.org 2009/08/20 23:54:28 [mux.c] subsystem_flag is defined in ssh.c so it's extern; ok djm --- ChangeLog | 3 +++ mux.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2d6862cb..c5ce2aed4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,9 @@ - jmc@cvs.openbsd.org 2009/08/19 04:56:03 [sftp.1] ether -> either; + - dtucker@cvs.openbsd.org 2009/08/20 23:54:28 + [mux.c] + subsystem_flag is defined in ssh.c so it's extern; ok djm 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/mux.c b/mux.c index 79f83768b..fac43a71f 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.7 2008/06/13 17:21:20 dtucker Exp $ */ +/* $OpenBSD: mux.c,v 1.8 2009/08/20 23:54:28 dtucker Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -85,7 +85,7 @@ extern int tty_flag; extern Options options; extern int stdin_null_flag; extern char *host; -int subsystem_flag; +extern int subsystem_flag; extern Buffer command; /* Context for session open confirmation callback */ -- cgit v1.2.3 From 7dc4850ce85a676ede0c070db6e46e022bd852fe Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:44:42 +1100 Subject: - djm@cvs.openbsd.org 2009/08/27 17:28:52 [sftp-server.c] allow setting an explicit umask on the commandline to override whatever default the user has. bz#1229; ok dtucker@ deraadt@ markus@ --- ChangeLog | 4 ++++ sftp-server.c | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c5ce2aed4..9ebb19e00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -46,6 +46,10 @@ - dtucker@cvs.openbsd.org 2009/08/20 23:54:28 [mux.c] subsystem_flag is defined in ssh.c so it's extern; ok djm + - djm@cvs.openbsd.org 2009/08/27 17:28:52 + [sftp-server.c] + allow setting an explicit umask on the commandline to override whatever + default the user has. bz#1229; ok dtucker@ deraadt@ markus@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp-server.c b/sftp-server.c index d984e6049..d144001bb 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.85 2009/04/14 16:33:42 stevesk Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.86 2009/08/27 17:28:52 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1322,7 +1322,8 @@ sftp_server_usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-he] [-l log_level] [-f log_facility]\n", __progname); + "usage: %s [-he] [-l log_level] [-f log_facility] [-u umask]\n", + __progname); exit(1); } @@ -1334,6 +1335,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; char *cp, buf[4*4096]; + const char *errmsg; + mode_t mask; extern char *optarg; extern char *__progname; @@ -1341,7 +1344,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); - while (!skipargs && (ch = getopt(argc, argv, "f:l:che")) != -1) { + while (!skipargs && (ch = getopt(argc, argv, "f:l:u:che")) != -1) { switch (ch) { case 'c': /* @@ -1363,6 +1366,13 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) if (log_facility == SYSLOG_FACILITY_NOT_SET) error("Invalid log facility \"%s\"", optarg); break; + case 'u': + mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); + if (cp != NULL) + fatal("Invalid umask \"%s\": %s", + optarg, errmsg); + (void)umask(mask); + break; case 'h': default: sftp_server_usage(); -- cgit v1.2.3 From 9bcd25b78b8764ab27cd807f267ff5d82720a0cf Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:45:48 +1100 Subject: - djm@cvs.openbsd.org 2009/08/27 17:33:49 [ssh-keygen.c] force use of correct hash function for random-art signature display as it was inheriting the wrong one when bubblebabble signatures were activated; bz#1611 report and patch from fwojcik+openssh AT besh.com; ok markus@ --- ChangeLog | 6 ++++++ ssh-keygen.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ebb19e00..f27d043ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,6 +50,12 @@ [sftp-server.c] allow setting an explicit umask on the commandline to override whatever default the user has. bz#1229; ok dtucker@ deraadt@ markus@ + - djm@cvs.openbsd.org 2009/08/27 17:33:49 + [ssh-keygen.c] + force use of correct hash function for random-art signature display + as it was inheriting the wrong one when bubblebabble signatures were + activated; bz#1611 report and patch from fwojcik+openssh AT besh.com; + ok markus@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/ssh-keygen.c b/ssh-keygen.c index da5db9845..4f90ac5c1 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.174 2009/06/22 05:39:28 dtucker Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.175 2009/08/27 17:33:49 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -524,7 +524,7 @@ do_fingerprint(struct passwd *pw) public = key_load_public(identity_file, &comment); if (public != NULL) { fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART); + ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, comment, key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -589,7 +589,7 @@ do_fingerprint(struct passwd *pw) } comment = *cp ? cp : comment; fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART); + ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, comment ? comment : "no comment", key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -619,7 +619,7 @@ print_host(FILE *f, const char *name, Key *public, int hash) fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART); + ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, name, key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) -- cgit v1.2.3 From 6b286a46821fa230258f1da82d0e013cfe3bf685 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:46:21 +1100 Subject: - djm@cvs.openbsd.org 2009/08/27 17:43:00 [sftp-server.8] allow setting an explicit umask on the commandline to override whatever default the user has. bz#1229; ok dtucker@ deraadt@ markus@ --- ChangeLog | 4 ++++ sftp-server.8 | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f27d043ee..183733fcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -56,6 +56,10 @@ as it was inheriting the wrong one when bubblebabble signatures were activated; bz#1611 report and patch from fwojcik+openssh AT besh.com; ok markus@ + - djm@cvs.openbsd.org 2009/08/27 17:43:00 + [sftp-server.8] + allow setting an explicit umask on the commandline to override whatever + default the user has. bz#1229; ok dtucker@ deraadt@ markus@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp-server.8 b/sftp-server.8 index 372b0770e..0f7963e27 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.15 2009/03/26 08:38:39 sobrado Exp $ +.\" $OpenBSD: sftp-server.8,v 1.16 2009/08/27 17:43:00 djm Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: March 26 2009 $ +.Dd $Mdocdate: August 27 2009 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -32,6 +32,7 @@ .Nm sftp-server .Op Fl f Ar log_facility .Op Fl l Ar log_level +.Op Fl u Ar umask .Sh DESCRIPTION .Nm is a program that speaks the server side of SFTP protocol @@ -71,6 +72,11 @@ performs on behalf of the client. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. +.It Fl u Ar umask +Sets an explicit +.Xr umask 2 +to be applied to newly-created files and directories, instead of the +user's default mask. .El .Pp For logging to work, -- cgit v1.2.3 From 893d73549d7cfa277434bf0113688a5a14055408 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:47:02 +1100 Subject: - djm@cvs.openbsd.org 2009/08/27 17:44:52 [authfd.c ssh-add.c authfd.h] Do not fall back to adding keys without contraints (ssh-add -c / -t ...) when the agent refuses the constrained add request. This was a useful migration measure back in 2002 when constraints were new, but just adds risk now. bz #1612, report and patch from dkg AT fifthhorseman.net; ok markus@ --- ChangeLog | 7 +++++++ authfd.c | 8 +------- authfd.h | 3 +-- ssh-add.c | 5 +---- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 183733fcb..971225fa8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -60,6 +60,13 @@ [sftp-server.8] allow setting an explicit umask on the commandline to override whatever default the user has. bz#1229; ok dtucker@ deraadt@ markus@ + - djm@cvs.openbsd.org 2009/08/27 17:44:52 + [authfd.c ssh-add.c authfd.h] + Do not fall back to adding keys without contraints (ssh-add -c / -t ...) + when the agent refuses the constrained add request. This was a useful + migration measure back in 2002 when constraints were new, but just + adds risk now. + bz #1612, report and patch from dkg AT fifthhorseman.net; ok markus@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/authfd.c b/authfd.c index 61faad123..78a53c7a6 100644 --- a/authfd.c +++ b/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.80 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: authfd.c,v 1.81 2009/08/27 17:44:52 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -545,12 +545,6 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, return decode_reply(type); } -int -ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) -{ - return ssh_add_identity_constrained(auth, key, comment, 0, 0); -} - /* * Removes an identity from the authentication server. This call is not * meant to be used by normal applications. diff --git a/authfd.h b/authfd.h index 3da256112..2582a27aa 100644 --- a/authfd.h +++ b/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.36 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: authfd.h,v 1.37 2009/08/27 17:44:52 djm Exp $ */ /* * Author: Tatu Ylonen @@ -75,7 +75,6 @@ void ssh_close_authentication_connection(AuthenticationConnection *); int ssh_get_num_identities(AuthenticationConnection *, int); Key *ssh_get_first_identity(AuthenticationConnection *, char **, int); Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); -int ssh_add_identity(AuthenticationConnection *, Key *, const char *); int ssh_add_identity_constrained(AuthenticationConnection *, Key *, const char *, u_int, u_int); int ssh_remove_identity(AuthenticationConnection *, Key *); diff --git a/ssh-add.c b/ssh-add.c index 7a43282f2..084478d78 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.90 2007/09/09 11:38:01 sobrado Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.91 2009/08/27 17:44:52 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -195,9 +195,6 @@ add_file(AuthenticationConnection *ac, const char *filename) if (confirm != 0) fprintf(stderr, "The user has to confirm each use of the key\n"); - } else if (ssh_add_identity(ac, private, comment)) { - fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); - ret = 0; } else { fprintf(stderr, "Could not add identity: %s\n", filename); } -- cgit v1.2.3 From 30359e19ecd93a494493501a8eacb4f7d36b2e3f Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:47:24 +1100 Subject: - djm@cvs.openbsd.org 2009/08/31 20:56:02 [sftp-server.c] check correct variable for error message, spotted by martynas@ --- ChangeLog | 3 +++ sftp-server.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 971225fa8..a57890ebd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -67,6 +67,9 @@ migration measure back in 2002 when constraints were new, but just adds risk now. bz #1612, report and patch from dkg AT fifthhorseman.net; ok markus@ + - djm@cvs.openbsd.org 2009/08/31 20:56:02 + [sftp-server.c] + check correct variable for error message, spotted by martynas@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp-server.c b/sftp-server.c index d144001bb..66c0c1d5f 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.86 2009/08/27 17:28:52 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.87 2009/08/31 20:56:02 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1368,7 +1368,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) break; case 'u': mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); - if (cp != NULL) + if (errmsg != NULL) fatal("Invalid umask \"%s\": %s", optarg, errmsg); (void)umask(mask); -- cgit v1.2.3 From 7bee06ab3b84c9f141666cc47abb349067551ef6 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:47:47 +1100 Subject: - djm@cvs.openbsd.org 2009/08/31 21:01:29 [sftp-server.8] document -e and -h; prodded by jmc@ --- ChangeLog | 3 +++ sftp-server.8 | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a57890ebd..5fbca0934 100644 --- a/ChangeLog +++ b/ChangeLog @@ -70,6 +70,9 @@ - djm@cvs.openbsd.org 2009/08/31 20:56:02 [sftp-server.c] check correct variable for error message, spotted by martynas@ + - djm@cvs.openbsd.org 2009/08/31 21:01:29 + [sftp-server.8] + document -e and -h; prodded by jmc@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp-server.8 b/sftp-server.8 index 0f7963e27..ee73c345b 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.16 2009/08/27 17:43:00 djm Exp $ +.\" $OpenBSD: sftp-server.8,v 1.17 2009/08/31 21:01:29 djm Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 27 2009 $ +.Dd $Mdocdate: August 31 2009 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -30,6 +30,7 @@ .Nd SFTP server subsystem .Sh SYNOPSIS .Nm sftp-server +.Op Fl eh .Op Fl f Ar log_facility .Op Fl l Ar log_level .Op Fl u Ar umask @@ -55,12 +56,20 @@ for more information. .Pp Valid options are: .Bl -tag -width Ds +.It Fl e +Causes +.Nm +to print logging information to stderr instead of syslog for debugging. .It Fl f Ar log_facility Specifies the facility code that is used when logging messages from .Nm . The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. +.It Fl h +Displays +.Nm +usage information. .It Fl l Ar log_level Specifies which messages will be logged by .Nm . -- cgit v1.2.3 From 72473c6b09b61b5ea2a7bda7728062b89a46b394 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 09:01:03 +1100 Subject: - djm@cvs.openbsd.org 2009/09/01 14:43:17 [ssh-agent.c] fix a race condition in ssh-agent that could result in a wedged or spinning agent: don't read off the end of the allocated fd_sets, and don't issue blocking read/write on agent sockets - just fall back to select() on retriable read/write errors. bz#1633 reported and tested by "noodle10000 AT googlemail.com"; ok dtucker@ markus@ --- ChangeLog | 7 +++++++ ssh-agent.c | 36 +++++++++++++++--------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5fbca0934..e961d1a2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -73,6 +73,13 @@ - djm@cvs.openbsd.org 2009/08/31 21:01:29 [sftp-server.8] document -e and -h; prodded by jmc@ + - djm@cvs.openbsd.org 2009/09/01 14:43:17 + [ssh-agent.c] + fix a race condition in ssh-agent that could result in a wedged or + spinning agent: don't read off the end of the allocated fd_sets, and + don't issue blocking read/write on agent sockets - just fall back to + select() on retriable read/write errors. bz#1633 reported and tested + by "noodle10000 AT googlemail.com"; ok dtucker@ markus@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/ssh-agent.c b/ssh-agent.c index f77dea3a6..df3a87d9a 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.162 2009/09/01 14:43:17 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -919,11 +919,11 @@ after_select(fd_set *readset, fd_set *writeset) socklen_t slen; char buf[1024]; int len, sock; - u_int i; + u_int i, orig_alloc; uid_t euid; gid_t egid; - for (i = 0; i < sockets_alloc; i++) + for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++) switch (sockets[i].type) { case AUTH_UNUSED: break; @@ -956,16 +956,13 @@ after_select(fd_set *readset, fd_set *writeset) case AUTH_CONNECTION: if (buffer_len(&sockets[i].output) > 0 && FD_ISSET(sockets[i].fd, writeset)) { - do { - len = write(sockets[i].fd, - buffer_ptr(&sockets[i].output), - buffer_len(&sockets[i].output)); - if (len == -1 && (errno == EAGAIN || - errno == EINTR || - errno == EWOULDBLOCK)) - continue; - break; - } while (1); + len = write(sockets[i].fd, + buffer_ptr(&sockets[i].output), + buffer_len(&sockets[i].output)); + if (len == -1 && (errno == EAGAIN || + errno == EWOULDBLOCK || + errno == EINTR)) + continue; if (len <= 0) { close_socket(&sockets[i]); break; @@ -973,14 +970,11 @@ after_select(fd_set *readset, fd_set *writeset) buffer_consume(&sockets[i].output, len); } if (FD_ISSET(sockets[i].fd, readset)) { - do { - len = read(sockets[i].fd, buf, sizeof(buf)); - if (len == -1 && (errno == EAGAIN || - errno == EINTR || - errno == EWOULDBLOCK)) - continue; - break; - } while (1); + len = read(sockets[i].fd, buf, sizeof(buf)); + if (len == -1 && (errno == EAGAIN || + errno == EWOULDBLOCK || + errno == EINTR)) + continue; if (len <= 0) { close_socket(&sockets[i]); break; -- cgit v1.2.3 From 759cb2a49aefe2757ec7b023024881f5d00efef5 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 09:01:50 +1100 Subject: - grunk@cvs.openbsd.org 2009/10/01 11:37:33 [dh.c] fix a cast ok djm@ markus@ --- ChangeLog | 4 ++++ dh.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e961d1a2f..f2233fb9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -80,6 +80,10 @@ don't issue blocking read/write on agent sockets - just fall back to select() on retriable read/write errors. bz#1633 reported and tested by "noodle10000 AT googlemail.com"; ok dtucker@ markus@ + - grunk@cvs.openbsd.org 2009/10/01 11:37:33 + [dh.c] + fix a cast + ok djm@ markus@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/dh.c b/dh.c index b76605325..b9029d867 100644 --- a/dh.c +++ b/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.47 2008/06/26 09:19:39 djm Exp $ */ +/* $OpenBSD: dh.c,v 1.48 2009/10/01 11:37:33 grunk Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * @@ -83,7 +83,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) goto fail; strsize = strsep(&cp, " "); /* size */ if (cp == NULL || *strsize == '\0' || - (dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || + (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || errstr) goto fail; /* The whole group is one bit larger */ -- cgit v1.2.3 From 695ed397a5216189629aa717d03d72ad21cdee1a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 09:02:18 +1100 Subject: - djm@cvs.openbsd.org 2009/10/06 04:46:40 [session.c] bz#1596: fflush(NULL) before exec() to ensure that everying (motd in particular) has made it out before the streams go away. --- ChangeLog | 4 ++++ session.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f2233fb9b..0914bf05b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -84,6 +84,10 @@ [dh.c] fix a cast ok djm@ markus@ + - djm@cvs.openbsd.org 2009/10/06 04:46:40 + [session.c] + bz#1596: fflush(NULL) before exec() to ensure that everying (motd + in particular) has made it out before the streams go away. 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/session.c b/session.c index f4a363543..d55419fbd 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.246 2009/04/17 19:23:06 stevesk Exp $ */ +/* $OpenBSD: session.c,v 1.247 2009/10/06 04:46:40 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1799,6 +1799,8 @@ do_child(Session *s, const char *command) exit(sftp_server_main(i, argv, s->pw)); } + fflush(NULL); + if (options.use_login) { launch_login(pw, hostname); /* NEVERREACHED */ -- cgit v1.2.3 From 7023d161d86211fa6a4c7dfacdad37a53f468512 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 10:30:06 +1100 Subject: - djm@cvs.openbsd.org 2008/12/07 22:17:48 [regress/addrmatch.sh] match string "passwordauthentication" only at start of line, not anywhere in sshd -T output --- ChangeLog | 4 ++++ regress/addrmatch.sh | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0914bf05b..826db9eaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -88,6 +88,10 @@ [session.c] bz#1596: fflush(NULL) before exec() to ensure that everying (motd in particular) has made it out before the streams go away. + - djm@cvs.openbsd.org 2008/12/07 22:17:48 + [regress/addrmatch.sh] + match string "passwordauthentication" only at start of line, not anywhere + in sshd -T output 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/regress/addrmatch.sh b/regress/addrmatch.sh index a258f7bb4..cbff82e5c 100644 --- a/regress/addrmatch.sh +++ b/regress/addrmatch.sh @@ -1,4 +1,4 @@ -# $OpenBSD: addrmatch.sh,v 1.1 2008/06/10 05:23:32 dtucker Exp $ +# $OpenBSD: addrmatch.sh,v 1.2 2008/12/07 22:17:48 djm Exp $ # Placed in the Public Domain. tid="address match" @@ -12,7 +12,7 @@ run_trial() verbose "test $descr for $user $addr $host" result=`${SSHD} -f $OBJ/sshd_proxy -T \ -C user=${user},addr=${addr},host=${host} | \ - awk '/passwordauthentication/ {print $2}'` + awk '/^passwordauthentication/ {print $2}'` if [ "$result" != "$expected" ]; then fail "failed for $user $addr $host: expected $expected, got $result" fi -- cgit v1.2.3 From 798855358538931da4f3d7ee6a111b3b4fbd338c Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 10:30:57 +1100 Subject: - dtucker@cvs.openbsd.org 2009/05/05 07:51:36 [regress/multiplex.sh] Always specify ssh_config for multiplex tests: prevents breakage caused by options in ~/.ssh/config. From Dan Peterson. --- ChangeLog | 4 ++++ regress/multiplex.sh | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 826db9eaa..eeeb5e365 100644 --- a/ChangeLog +++ b/ChangeLog @@ -92,6 +92,10 @@ [regress/addrmatch.sh] match string "passwordauthentication" only at start of line, not anywhere in sshd -T output + - dtucker@cvs.openbsd.org 2009/05/05 07:51:36 + [regress/multiplex.sh] + Always specify ssh_config for multiplex tests: prevents breakage caused + by options in ~/.ssh/config. From Dan Peterson. 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/regress/multiplex.sh b/regress/multiplex.sh index 4fba7b5ac..8a98a6e54 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh @@ -1,4 +1,4 @@ -# $OpenBSD: multiplex.sh,v 1.11 2005/04/25 09:54:09 dtucker Exp $ +# $OpenBSD: multiplex.sh,v 1.12 2009/05/05 07:51:36 dtucker Exp $ # Placed in the Public Domain. CTL=/tmp/openssh.regress.ctl-sock.$$ @@ -26,7 +26,7 @@ sleep 5 verbose "test $tid: envpass" trace "env passing over multiplexed connection" -_XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF' +_XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF' test X"$_XXX_TEST" = X"blah" EOF if [ $? -ne 0 ]; then @@ -36,26 +36,26 @@ fi verbose "test $tid: transfer" rm -f ${COPY} trace "ssh transfer over multiplexed connection and check result" -${SSH} -S$CTL otherhost cat ${DATA} > ${COPY} +${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY} test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}" rm -f ${COPY} trace "ssh transfer over multiplexed connection and check result" -${SSH} -S $CTL otherhost cat ${DATA} > ${COPY} +${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY} test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}" rm -f ${COPY} trace "sftp transfer over multiplexed connection and check result" echo "get ${DATA} ${COPY}" | \ - ${SFTP} -S ${SSH} -oControlPath=$CTL otherhost >$LOG 2>&1 + ${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >$LOG 2>&1 test -f ${COPY} || fail "sftp: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}" rm -f ${COPY} trace "scp transfer over multiplexed connection and check result" -${SCP} -S ${SSH} -oControlPath=$CTL otherhost:${DATA} ${COPY} >$LOG 2>&1 +${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >$LOG 2>&1 test -f ${COPY} || fail "scp: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" @@ -64,7 +64,7 @@ rm -f ${COPY} for s in 0 1 4 5 44; do trace "exit status $s over multiplexed connection" verbose "test $tid: status $s" - ${SSH} -S $CTL otherhost exit $s + ${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s r=$? if [ $r -ne $s ]; then fail "exit code mismatch for protocol $p: $r != $s" @@ -72,7 +72,7 @@ for s in 0 1 4 5 44; do # same with early close of stdout/err trace "exit status $s with early close over multiplexed connection" - ${SSH} -S $CTL -n otherhost \ + ${SSH} -F $OBJ/ssh_config -S $CTL -n otherhost \ exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' r=$? if [ $r -ne $s ]; then @@ -81,10 +81,10 @@ for s in 0 1 4 5 44; do done trace "test check command" -${SSH} -S $CTL -Ocheck otherhost || fail "check command failed" +${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost || fail "check command failed" trace "test exit command" -${SSH} -S $CTL -Oexit otherhost || fail "send exit command failed" +${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost || fail "send exit command failed" # Wait for master to exit sleep 2 -- cgit v1.2.3 From 287b9329c5fc2e1a177f9608209a35a6c5bf852a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 10:31:56 +1100 Subject: - djm@cvs.openbsd.org 2009/08/13 00:57:17 [regress/Makefile] regression test for port number parsing. written as part of the a2port change that went into 5.2 but I forgot to commit it at the time... --- ChangeLog | 4 ++++ regress/Makefile | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index eeeb5e365..838372197 100644 --- a/ChangeLog +++ b/ChangeLog @@ -96,6 +96,10 @@ [regress/multiplex.sh] Always specify ssh_config for multiplex tests: prevents breakage caused by options in ~/.ssh/config. From Dan Peterson. + - djm@cvs.openbsd.org 2009/08/13 00:57:17 + [regress/Makefile] + regression test for port number parsing. written as part of the a2port + change that went into 5.2 but I forgot to commit it at the time... 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/regress/Makefile b/regress/Makefile index 3b8ea245b..7d4e2ab4e 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.48 2008/06/28 13:57:25 djm Exp $ +# $OpenBSD: Makefile,v 1.49 2009/08/13 00:57:17 djm Exp $ REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec tests: $(REGRESS_TARGETS) @@ -50,7 +50,8 @@ LTESTS= connect \ cfgmatch \ addrmatch \ localcommand \ - forcecommand + forcecommand \ + portnum INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp -- cgit v1.2.3 From ed6b0c5fc21807ff771a499fd042a24f963f7291 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 10:43:57 +1100 Subject: - djm@cvs.openbsd.org 2009/08/13 01:11:55 [sftp-batch.sh sftp-badcmds.sh sftp.sh sftp-cmds.sh sftp-glob.sh] date: 2009/08/13 01:11:19; author: djm; state: Exp; lines: +10 -7 Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path", add "-P port" to match scp(1). Fortunately, the -P option is only really used by our regression scripts. part of larger patch from carlosvsilvapt@gmail.com for his Google Summer of Code work; ok deraadt markus --- ChangeLog | 8 ++++++ regress/sftp-badcmds.sh | 16 +++++------ regress/sftp-batch.sh | 10 +++---- regress/sftp-cmds.sh | 73 +++++++++++++++++++++++++------------------------ regress/sftp-glob.sh | 4 +-- regress/sftp.sh | 6 ++-- 6 files changed, 63 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index 838372197..4df4b4951 100644 --- a/ChangeLog +++ b/ChangeLog @@ -100,6 +100,14 @@ [regress/Makefile] regression test for port number parsing. written as part of the a2port change that went into 5.2 but I forgot to commit it at the time... + - djm@cvs.openbsd.org 2009/08/13 01:11:55 + [sftp-batch.sh sftp-badcmds.sh sftp.sh sftp-cmds.sh sftp-glob.sh] + date: 2009/08/13 01:11:19; author: djm; state: Exp; lines: +10 -7 + Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path", + add "-P port" to match scp(1). Fortunately, the -P option is only really + used by our regression scripts. + part of larger patch from carlosvsilvapt@gmail.com for his Google Summer + of Code work; ok deraadt markus 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/regress/sftp-badcmds.sh b/regress/sftp-badcmds.sh index b48b1cb01..08009f26b 100644 --- a/regress/sftp-badcmds.sh +++ b/regress/sftp-badcmds.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sftp-badcmds.sh,v 1.3 2008/03/24 21:46:54 djm Exp $ +# $OpenBSD: sftp-badcmds.sh,v 1.4 2009/08/13 01:11:55 djm Exp $ # Placed in the Public Domain. tid="sftp invalid commands" @@ -13,13 +13,13 @@ rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd rm -f ${COPY} verbose "$tid: get nonexistent" -echo "get $NONEXIST $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "get $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get nonexistent failed" test -f ${COPY} && fail "existing copy after get nonexistent" rm -f ${COPY}.dd/* verbose "$tid: glob get to nonexistent directory" -echo "get /bin/l* $NONEXIST" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "get /bin/l* $NONEXIST" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get nonexistent failed" for x in $GLOBFILES; do test -f ${COPY}.dd/$x && fail "existing copy after get nonexistent" @@ -27,13 +27,13 @@ done rm -f ${COPY} verbose "$tid: put nonexistent" -echo "put $NONEXIST $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "put $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put nonexistent failed" test -f ${COPY} && fail "existing copy after put nonexistent" rm -f ${COPY}.dd/* verbose "$tid: glob put to nonexistent directory" -echo "put /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "put /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put nonexistent failed" for x in $GLOBFILES; do test -f ${COPY}.dd/$x && fail "existing copy after nonexistent" @@ -41,7 +41,7 @@ done rm -f ${COPY} verbose "$tid: rename nonexistent" -echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rename nonexist failed" test -f ${COPY}.1 && fail "file exists after rename nonexistent" @@ -49,7 +49,7 @@ rm -rf ${COPY} ${COPY}.dd cp $DATA $COPY mkdir ${COPY}.dd verbose "$tid: rename target exists (directory)" -echo "rename $COPY ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "rename $COPY ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rename target exists (directory) failed" test -f ${COPY} || fail "oldname missing after rename target exists (directory)" test -d ${COPY}.dd || fail "newname missing after rename target exists (directory)" @@ -59,7 +59,7 @@ rm -f ${COPY}.dd/* rm -rf ${COPY} cp ${DATA2} ${COPY} verbose "$tid: glob put files to local file" -echo "put /bin/l* $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 +echo "put /bin/l* $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 cmp ${DATA2} ${COPY} || fail "put successed when it should have failed" rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd diff --git a/regress/sftp-batch.sh b/regress/sftp-batch.sh index 365c47cfc..a51ef0782 100644 --- a/regress/sftp-batch.sh +++ b/regress/sftp-batch.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sftp-batch.sh,v 1.3 2004/01/13 09:49:06 djm Exp $ +# $OpenBSD: sftp-batch.sh,v 1.4 2009/08/13 01:11:55 djm Exp $ # Placed in the Public Domain. tid="sftp batchfile" @@ -37,19 +37,19 @@ cat << EOF > ${BATCH}.fail.2 EOF verbose "$tid: good commands" -${SFTP} -b ${BATCH}.pass.1 -P ${SFTPSERVER} >/dev/null 2>&1 \ +${SFTP} -b ${BATCH}.pass.1 -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "good commands failed" verbose "$tid: bad commands" -${SFTP} -b ${BATCH}.fail.1 -P ${SFTPSERVER} >/dev/null 2>&1 \ +${SFTP} -b ${BATCH}.fail.1 -D ${SFTPSERVER} >/dev/null 2>&1 \ && fail "bad commands succeeded" verbose "$tid: comments and blanks" -${SFTP} -b ${BATCH}.pass.2 -P ${SFTPSERVER} >/dev/null 2>&1 \ +${SFTP} -b ${BATCH}.pass.2 -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "comments & blanks failed" verbose "$tid: junk command" -${SFTP} -b ${BATCH}.fail.2 -P ${SFTPSERVER} >/dev/null 2>&1 \ +${SFTP} -b ${BATCH}.fail.2 -D ${SFTPSERVER} >/dev/null 2>&1 \ && fail "junk command succeeded" rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* diff --git a/regress/sftp-cmds.sh b/regress/sftp-cmds.sh index 3b453c5e8..c4d6ae2de 100644 --- a/regress/sftp-cmds.sh +++ b/regress/sftp-cmds.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sftp-cmds.sh,v 1.9 2007/12/12 05:04:03 djm Exp $ +# $OpenBSD: sftp-cmds.sh,v 1.10 2009/08/13 01:11:55 djm Exp $ # Placed in the Public Domain. # XXX - TODO: @@ -40,56 +40,56 @@ SPACECOPY_ARG="${COPY}\ this\ has\ spaces.txt" # File with glob metacharacters GLOBMETACOPY="${COPY} [metachar].txt" -rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 ${BATCH}.* mkdir ${COPY}.dd verbose "$tid: lls" -(echo "lcd ${OBJ}" ; echo "lls") | ${SFTP} -P ${SFTPSERVER} 2>&1 | \ +(echo "lcd ${OBJ}" ; echo "lls") | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ grep copy.dd >/dev/null 2>&1 || fail "lls failed" verbose "$tid: lls w/path" -echo "lls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} 2>&1 | \ +echo "lls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ grep copy.dd >/dev/null 2>&1 || fail "lls w/path failed" verbose "$tid: ls" -echo "ls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "ls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "ls failed" # XXX always successful verbose "$tid: shell" -echo "!echo hi there" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "!echo hi there" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "shell failed" # XXX always successful verbose "$tid: pwd" -echo "pwd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "pwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "pwd failed" # XXX always successful verbose "$tid: lpwd" -echo "lpwd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "lpwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "lpwd failed" # XXX always successful verbose "$tid: quit" -echo "quit" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "quit" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "quit failed" # XXX always successful verbose "$tid: help" -echo "help" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "help" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "help failed" # XXX always successful rm -f ${COPY} verbose "$tid: get" -echo "get $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "get $DATA $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY} || fail "corrupted copy after get" rm -f ${COPY} verbose "$tid: get quoted" -echo "get \"$DATA\" $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "get \"$DATA\" $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY} || fail "corrupted copy after get" @@ -97,8 +97,8 @@ if [ "$os" != "cygwin" ]; then rm -f ${QUOTECOPY} cp $DATA ${QUOTECOPY} verbose "$tid: get filename with quotes" -echo "get \"$QUOTECOPY_ARG\" ${COPY}" | \ - ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" +echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes" rm -f ${QUOTECOPY} ${COPY} fi @@ -106,7 +106,7 @@ fi rm -f "$SPACECOPY" ${COPY} cp $DATA "$SPACECOPY" verbose "$tid: get filename with spaces" -echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp ${COPY} "$SPACECOPY" || fail "corrupted copy after get with spaces" @@ -114,19 +114,19 @@ rm -f "$GLOBMETACOPY" ${COPY} cp $DATA "$GLOBMETACOPY" verbose "$tid: get filename with glob metacharacters" echo "get \"${GLOBMETACOPY}\" ${COPY}" | \ - ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed" + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed" cmp ${COPY} "$GLOBMETACOPY" || \ fail "corrupted copy after get with glob metacharacters" rm -f ${COPY}.dd/* verbose "$tid: get to directory" -echo "get $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "get $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after get" rm -f ${COPY}.dd/* verbose "$tid: glob get to directory" -echo "get /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "get /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" @@ -134,13 +134,13 @@ done rm -f ${COPY}.dd/* verbose "$tid: get to local dir" -(echo "lcd ${COPY}.dd"; echo "get $DATA" ) | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +(echo "lcd ${COPY}.dd"; echo "get $DATA" ) | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after get" rm -f ${COPY}.dd/* verbose "$tid: glob get to local dir" -(echo "lcd ${COPY}.dd"; echo "get /bin/l*") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +(echo "lcd ${COPY}.dd"; echo "get /bin/l*") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" @@ -149,32 +149,32 @@ done rm -f ${COPY} verbose "$tid: put" echo "put $DATA $COPY" | \ - ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" cmp $DATA ${COPY} || fail "corrupted copy after put" if [ "$os" != "cygwin" ]; then rm -f ${QUOTECOPY} verbose "$tid: put filename with quotes" echo "put $DATA \"$QUOTECOPY_ARG\"" | \ - ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes" fi rm -f "$SPACECOPY" verbose "$tid: put filename with spaces" echo "put $DATA ${SPACECOPY_ARG}" | \ - ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" cmp $DATA "$SPACECOPY" || fail "corrupted copy after put with spaces" rm -f ${COPY}.dd/* verbose "$tid: put to directory" -echo "put $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "put $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put" rm -f ${COPY}.dd/* verbose "$tid: glob put to directory" -echo "put /bin/l? ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "put /bin/l? ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" @@ -182,60 +182,61 @@ done rm -f ${COPY}.dd/* verbose "$tid: put to local dir" -(echo "cd ${COPY}.dd"; echo "put $DATA") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +(echo "cd ${COPY}.dd"; echo "put $DATA") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put" rm -f ${COPY}.dd/* verbose "$tid: glob put to local dir" -(echo "cd ${COPY}.dd"; echo "put /bin/l?") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +(echo "cd ${COPY}.dd"; echo "put /bin/l?") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" done verbose "$tid: rename" -echo "rename $COPY ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "rename $COPY ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rename failed" test -f ${COPY}.1 || fail "missing file after rename" cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename" verbose "$tid: rename directory" echo "rename ${COPY}.dd ${COPY}.dd2" | \ - ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || \ + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || \ fail "rename directory failed" test -d ${COPY}.dd && fail "oldname exists after rename directory" test -d ${COPY}.dd2 || fail "missing newname after rename directory" verbose "$tid: ln" -echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" +echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" test -h ${COPY}.2 || fail "missing file after ln" verbose "$tid: mkdir" -echo "mkdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "mkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "mkdir failed" test -d ${COPY}.dd || fail "missing directory after mkdir" # XXX do more here verbose "$tid: chdir" -echo "chdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "chdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "chdir failed" verbose "$tid: rmdir" -echo "rmdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "rmdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rmdir failed" test -d ${COPY}.1 && fail "present directory after rmdir" verbose "$tid: lmkdir" -echo "lmkdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "lmkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "lmkdir failed" test -d ${COPY}.dd || fail "missing directory after lmkdir" # XXX do more here verbose "$tid: lchdir" -echo "lchdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ +echo "lchdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "lchdir failed" -rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 ${BATCH}.* rm -rf ${QUOTECOPY} "$SPACECOPY" "$GLOBMETACOPY" + diff --git a/regress/sftp-glob.sh b/regress/sftp-glob.sh index 60116a748..72bb17d75 100644 --- a/regress/sftp-glob.sh +++ b/regress/sftp-glob.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sftp-glob.sh,v 1.3 2007/10/26 05:30:01 djm Exp $ +# $OpenBSD: sftp-glob.sh,v 1.4 2009/08/13 01:11:55 djm Exp $ # Placed in the Public Domain. tid="sftp glob" @@ -10,7 +10,7 @@ sftp_ls() { unexpected=$4 verbose "$tid: $errtag" printf "ls -l %s" "${target}" | \ - ${SFTP} -b - -P ${SFTPSERVER} 2>/dev/null | \ + ${SFTP} -b - -D ${SFTPSERVER} 2>/dev/null | \ grep -v "^sftp>" > ${RESULTS} if [ $? -ne 0 ]; then fail "$errtag failed" diff --git a/regress/sftp.sh b/regress/sftp.sh index 0e22f8f6b..f84fa6f4e 100644 --- a/regress/sftp.sh +++ b/regress/sftp.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sftp.sh,v 1.2 2002/03/27 22:39:52 markus Exp $ +# $OpenBSD: sftp.sh,v 1.3 2009/08/13 01:11:55 djm Exp $ # Placed in the Public Domain. tid="basic sftp put/get" @@ -19,8 +19,8 @@ REQUESTS="1 2 10" for B in ${BUFFERSIZE}; do for R in ${REQUESTS}; do verbose "test $tid: buffer_size $B num_requests $R" - rm -f ${COPY}.1 ${COPY}.2 - ${SFTP} -P ${SFTPSERVER} -B $B -R $R -b $SFTPCMDFILE \ + rm -f ${COPY}.1 ${COPY}.2 + ${SFTP} -D ${SFTPSERVER} -B $B -R $R -b $SFTPCMDFILE \ > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then -- cgit v1.2.3 From c863895e0ab7f9430402736e953e62dae46be458 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 10:46:29 +1100 Subject: - djm@cvs.openbsd.org 2009/08/20 18:43:07 [ssh-com-sftp.sh] fix one sftp -D ... => sftp -P ... conversion that I missed; from Carlos Silva for Google Summer of Code --- ChangeLog | 4 ++++ regress/ssh-com-sftp.sh | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4df4b4951..bcaae4fef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -108,6 +108,10 @@ used by our regression scripts. part of larger patch from carlosvsilvapt@gmail.com for his Google Summer of Code work; ok deraadt markus + - djm@cvs.openbsd.org 2009/08/20 18:43:07 + [ssh-com-sftp.sh] + fix one sftp -D ... => sftp -P ... conversion that I missed; from Carlos + Silva for Google Summer of Code 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/regress/ssh-com-sftp.sh b/regress/ssh-com-sftp.sh index 936b4cca7..be6f4e0dc 100644 --- a/regress/ssh-com-sftp.sh +++ b/regress/ssh-com-sftp.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com-sftp.sh,v 1.5 2004/02/24 17:06:52 markus Exp $ +# $OpenBSD: ssh-com-sftp.sh,v 1.6 2009/08/20 18:43:07 djm Exp $ # Placed in the Public Domain. tid="basic sftp put/get with ssh.com server" @@ -51,7 +51,7 @@ for v in ${VERSIONS}; do for R in ${REQUESTS}; do verbose "test $tid: buffer_size $B num_requests $R" rm -f ${COPY}.1 ${COPY}.2 - ${SFTP} -P ${server} -B $B -R $R -b $SFTPCMDFILE \ + ${SFTP} -D ${server} -B $B -R $R -b $SFTPCMDFILE \ > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then -- cgit v1.2.3 From b707a243822f28d07702ce4fc2c1d6cf305bc631 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 10:54:31 +1100 Subject: - dtucker@cvs.openbsd.org 2009/10/06 23:51:49 [regress/ssh2putty.sh] Add OpenBSD tag to make syncs easier --- ChangeLog | 8 ++++++-- regress/ssh2putty.sh | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bcaae4fef..824bca846 100644 --- a/ChangeLog +++ b/ChangeLog @@ -101,7 +101,8 @@ regression test for port number parsing. written as part of the a2port change that went into 5.2 but I forgot to commit it at the time... - djm@cvs.openbsd.org 2009/08/13 01:11:55 - [sftp-batch.sh sftp-badcmds.sh sftp.sh sftp-cmds.sh sftp-glob.sh] + [regress/sftp-batch.sh regress/sftp-badcmds.sh regress/sftp.sh + regress/sftp-cmds.sh regres/sftp-glob.sh] date: 2009/08/13 01:11:19; author: djm; state: Exp; lines: +10 -7 Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path", add "-P port" to match scp(1). Fortunately, the -P option is only really @@ -109,9 +110,12 @@ part of larger patch from carlosvsilvapt@gmail.com for his Google Summer of Code work; ok deraadt markus - djm@cvs.openbsd.org 2009/08/20 18:43:07 - [ssh-com-sftp.sh] + [regress/ssh-com-sftp.sh] fix one sftp -D ... => sftp -P ... conversion that I missed; from Carlos Silva for Google Summer of Code + - dtucker@cvs.openbsd.org 2009/10/06 23:51:49 + [regress/ssh2putty.sh] + Add OpenBSD tag to make syncs easier 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/regress/ssh2putty.sh b/regress/ssh2putty.sh index dfdeeff4a..5d9de1cd7 100755 --- a/regress/ssh2putty.sh +++ b/regress/ssh2putty.sh @@ -1,4 +1,5 @@ #!/bin/sh +# $OpenBSD: ssh2putty.sh,v 1.1 2009/10/06 23:51:49 dtucker Exp $ if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then echo "Usage: ssh2putty hostname port ssh-private-key" -- cgit v1.2.3 From b99c6e14990e56eaac0b7afa8303a27bb20fc6d3 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 10:58:40 +1100 Subject: fix id --- regress/ssh2putty.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regress/ssh2putty.sh b/regress/ssh2putty.sh index 5d9de1cd7..691db1690 100755 --- a/regress/ssh2putty.sh +++ b/regress/ssh2putty.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: ssh2putty.sh,v 1.1 2009/10/06 23:51:49 dtucker Exp $ +# $OpenBSD: ssh2putty.sh,v 1.2 2009/10/06 23:51:49 dtucker Exp $ if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then echo "Usage: ssh2putty hostname port ssh-private-key" -- cgit v1.2.3 From a25ab018459dc366061ac98086705c561b856a19 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 11:00:58 +1100 Subject: - (dtucker) [regress/portnum.sh] Import new test. --- ChangeLog | 1 + regress/portnum.sh | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 regress/portnum.sh diff --git a/ChangeLog b/ChangeLog index 824bca846..e6a21cf7a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -116,6 +116,7 @@ - dtucker@cvs.openbsd.org 2009/10/06 23:51:49 [regress/ssh2putty.sh] Add OpenBSD tag to make syncs easier + - (dtucker) [regress/portnum.sh] Import new test. 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/regress/portnum.sh b/regress/portnum.sh new file mode 100644 index 000000000..82abbc9f0 --- /dev/null +++ b/regress/portnum.sh @@ -0,0 +1,32 @@ +# $OpenBSD: portnum.sh,v 1.1 2009/08/13 00:57:17 djm Exp $ +# Placed in the Public Domain. + +tid="port number parsing" + +badport() { + port=$1 + verbose "$tid: invalid port $port" + if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then + fail "$tid accepted invalid port $port" + fi +} +goodport() { + port=$1 + verbose "$tid: valid port $port" + if ! ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then + fail "$tid rejected valid port $port" + fi +} + +badport 0 +badport 65536 +badport 131073 +badport 2000blah +badport blah2000 + +goodport 1 +goodport 22 +goodport 2222 +goodport 22222 +goodport 65535 + -- cgit v1.2.3 From 4adeac764e110e12ab481dc72c7c67dbf4b7110a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 15:49:48 +1100 Subject: - (dtucker) [configure.ac sftp-client.c] DOTTIF is in fs/ffs/dir.h on at least dragonflybsd. --- ChangeLog | 2 ++ configure.ac | 11 +++++++++-- sftp-client.c | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6a21cf7a..3a7315b25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -117,6 +117,8 @@ [regress/ssh2putty.sh] Add OpenBSD tag to make syncs easier - (dtucker) [regress/portnum.sh] Import new test. + - (dtucker) [configure.ac sftp-client.c] DOTTIF is in fs/ffs/dir.h on at + least dragonflybsd. 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/configure.ac b/configure.ac index ea9f1bb56..759047f10 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.427 2009/09/11 04:56:08 dtucker Exp $ +# $Id: configure.ac,v 1.428 2009/10/07 04:49:48 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.427 $) +AC_REVISION($Revision: 1.428 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1130,6 +1130,13 @@ int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));} ] ) +AC_CHECK_DECL(DTTOIF, + AC_DEFINE(DTTOIF_IN_FS_FFS_DIR_H, 1 , [DTTOIF macro in fs/ffs/dir.h]), , + [ +#include +#include + ]) + AC_MSG_CHECKING([for /proc/pid/fd directory]) if test -d "/proc/$$/fd" ; then AC_DEFINE(HAVE_PROC_PID, 1, [Define if you have /proc/$pid/fd]) diff --git a/sftp-client.c b/sftp-client.c index cc4a5b15b..b49e81b91 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -37,6 +37,9 @@ #include #include +#ifdef DTTOIF_IN_FS_FFS_DIR_H +# include +#endif #include #include #include -- cgit v1.2.3 From 538738d861cefb25d78615b1c299d7b618db870c Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 18:56:10 +1100 Subject: - (dtucker) d_type is not mandated by POSIX, so add fallback code using stat(), needed on at least cygwin. --- ChangeLog | 4 +++- configure.ac | 6 ++++-- sftp-client.c | 18 ++++++++++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a7315b25..df6fba7aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -117,8 +117,10 @@ [regress/ssh2putty.sh] Add OpenBSD tag to make syncs easier - (dtucker) [regress/portnum.sh] Import new test. - - (dtucker) [configure.ac sftp-client.c] DOTTIF is in fs/ffs/dir.h on at + - (dtucker) [configure.ac sftp-client.c] DTOTIF is in fs/ffs/dir.h on at least dragonflybsd. + - (dtucker) d_type is not mandated by POSIX, so add fallback code using + stat(), needed on at least cygwin. 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/configure.ac b/configure.ac index 759047f10..80db43af1 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.428 2009/10/07 04:49:48 dtucker Exp $ +# $Id: configure.ac,v 1.429 2009/10/07 07:56:10 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.428 $) +AC_REVISION($Revision: 1.429 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1137,6 +1137,8 @@ AC_CHECK_DECL(DTTOIF, #include ]) +AC_CHECK_MEMBERS([struct dirent.d_type],,, [#include ]) + AC_MSG_CHECKING([for /proc/pid/fd directory]) if test -d "/proc/$$/fd" ; then AC_DEFINE(HAVE_PROC_PID, 1, [Define if you have /proc/$pid/fd]) diff --git a/sftp-client.c b/sftp-client.c index b49e81b91..a9c895a0d 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1454,6 +1454,20 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, return status; } +static mode_t +dirent_to_mode(struct dirent *dp) +{ +#if defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DTTOIF) + return DTTOIF(dp->d_type); +#else + struct stat sb; + + if (stat(dp->d_name, &sb) == -1) + return 0; + return sb.st_mode; +#endif +} + static int upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int pflag, int printflag, int depth) @@ -1515,7 +1529,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, new_dst = path_append(dst, filename); new_src = path_append(src, filename); - if (S_ISDIR(DTTOIF(dp->d_type))) { + if (S_ISDIR(dirent_to_mode(dp))) { if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; @@ -1523,7 +1537,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, if (upload_dir_internal(conn, new_src, new_dst, pflag, depth + 1, printflag) == -1) ret = -1; - } else if (S_ISREG(DTTOIF(dp->d_type)) ) { + } else if (S_ISREG(dirent_to_mode(dp))) { if (do_upload(conn, new_src, new_dst, pflag) == -1) { error("Uploading of file %s to %s failed!", new_src, new_dst); -- cgit v1.2.3 From c182d993762f86fbdf9e54dd5b0e3e3d229ebc13 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 11 Oct 2009 21:50:20 +1100 Subject: - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for dirent d_type and DTTOIF as we've switched OpenBSD to the more portable lstat. --- ChangeLog | 5 +++++ configure.ac | 13 ++----------- sftp-client.c | 21 ++------------------- 3 files changed, 9 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index df6fba7aa..85446e312 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +20091011 + - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for + dirent d_type and DTTOIF as we've switched OpenBSD to the more portable + lstat. + 20091007 - (dtucker) OpenBSD CVS Sync - djm@cvs.openbsd.org 2009/08/12 00:13:00 diff --git a/configure.ac b/configure.ac index 80db43af1..0447bd62d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.429 2009/10/07 07:56:10 dtucker Exp $ +# $Id: configure.ac,v 1.430 2009/10/11 10:50:20 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.429 $) +AC_REVISION($Revision: 1.430 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1130,15 +1130,6 @@ int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));} ] ) -AC_CHECK_DECL(DTTOIF, - AC_DEFINE(DTTOIF_IN_FS_FFS_DIR_H, 1 , [DTTOIF macro in fs/ffs/dir.h]), , - [ -#include -#include - ]) - -AC_CHECK_MEMBERS([struct dirent.d_type],,, [#include ]) - AC_MSG_CHECKING([for /proc/pid/fd directory]) if test -d "/proc/$$/fd" ; then AC_DEFINE(HAVE_PROC_PID, 1, [Define if you have /proc/$pid/fd]) diff --git a/sftp-client.c b/sftp-client.c index a9c895a0d..cc4a5b15b 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -37,9 +37,6 @@ #include #include -#ifdef DTTOIF_IN_FS_FFS_DIR_H -# include -#endif #include #include #include @@ -1454,20 +1451,6 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, return status; } -static mode_t -dirent_to_mode(struct dirent *dp) -{ -#if defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DTTOIF) - return DTTOIF(dp->d_type); -#else - struct stat sb; - - if (stat(dp->d_name, &sb) == -1) - return 0; - return sb.st_mode; -#endif -} - static int upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int pflag, int printflag, int depth) @@ -1529,7 +1512,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, new_dst = path_append(dst, filename); new_src = path_append(src, filename); - if (S_ISDIR(dirent_to_mode(dp))) { + if (S_ISDIR(DTTOIF(dp->d_type))) { if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; @@ -1537,7 +1520,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, if (upload_dir_internal(conn, new_src, new_dst, pflag, depth + 1, printflag) == -1) ret = -1; - } else if (S_ISREG(dirent_to_mode(dp))) { + } else if (S_ISREG(DTTOIF(dp->d_type)) ) { if (do_upload(conn, new_src, new_dst, pflag) == -1) { error("Uploading of file %s to %s failed!", new_src, new_dst); -- cgit v1.2.3 From bad5076bb5d5587cf8b889cd9ce495c39282786b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 11 Oct 2009 21:51:08 +1100 Subject: - (dtucker) OpenBSD CVS Sync - markus@cvs.openbsd.org 2009/10/08 14:03:41 [sshd_config readconf.c ssh_config.5 servconf.c sshd_config.5] disable protocol 1 by default (after a transition period of about 10 years) ok deraadt --- ChangeLog | 5 +++++ readconf.c | 4 ++-- servconf.c | 4 ++-- ssh_config.5 | 14 ++++++++------ sshd_config | 8 +++----- sshd_config.5 | 6 +++--- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 85446e312..23bc18b67 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,11 @@ - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for dirent d_type and DTTOIF as we've switched OpenBSD to the more portable lstat. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2009/10/08 14:03:41 + [sshd_config readconf.c ssh_config.5 servconf.c sshd_config.5] + disable protocol 1 by default (after a transition period of about 10 years) + ok deraadt 20091007 - (dtucker) OpenBSD CVS Sync diff --git a/readconf.c b/readconf.c index 0bf5d7cb4..4a16974b8 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.177 2009/06/27 09:35:06 andreas Exp $ */ +/* $OpenBSD: readconf.c,v 1.178 2009/10/08 14:03:41 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1142,7 +1142,7 @@ fill_default_options(Options * options) /* options->macs, default set in myproposals.h */ /* options->hostkeyalgorithms, default set in myproposals.h */ if (options->protocol == SSH_PROTO_UNKNOWN) - options->protocol = SSH_PROTO_1|SSH_PROTO_2; + options->protocol = SSH_PROTO_2; if (options->num_identity_files == 0) { if (options->protocol & SSH_PROTO_1) { len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; diff --git a/servconf.c b/servconf.c index b51b86a8f..c2e5cc6f4 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.195 2009/04/14 21:10:54 jj Exp $ */ +/* $OpenBSD: servconf.c,v 1.196 2009/10/08 14:03:41 markus Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -139,7 +139,7 @@ fill_default_server_options(ServerOptions *options) /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) - options->protocol = SSH_PROTO_1|SSH_PROTO_2; + options->protocol = SSH_PROTO_2; if (options->num_host_key_files == 0) { /* fill default hostkeys for protocols */ if (options->protocol & SSH_PROTO_1) diff --git a/ssh_config.5 b/ssh_config.5 index ea9a20b23..82c2a30b0 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.119 2009/02/22 23:50:57 djm Exp $ -.Dd $Mdocdate: February 22 2009 $ +.\" $OpenBSD: ssh_config.5,v 1.120 2009/10/08 14:03:41 markus Exp $ +.Dd $Mdocdate: October 8 2009 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -730,11 +730,13 @@ The possible values are and .Sq 2 . Multiple versions must be comma-separated. -The default is -.Dq 2,1 . -This means that ssh -tries version 2 and falls back to version 1 +When this option is set to +.Dq 2,1 +.Nm ssh +will try version 2 and fall back to version 1 if version 2 is not available. +The default is +.Dq 2 . .It Cm ProxyCommand Specifies the command to use to connect to the server. The command diff --git a/sshd_config b/sshd_config index 1b53a0efb..72fbae37b 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $ +# $OpenBSD: sshd_config,v 1.81 2009/10/08 14:03:41 markus Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -15,10 +15,8 @@ #ListenAddress 0.0.0.0 #ListenAddress :: -# Disable legacy (protocol version 1) support in the server for new -# installations. In future the default will change to require explicit -# activation of protocol 1 -Protocol 2 +# The default requires explicit activation of protocol 1 +#Protocol 2 # HostKey for protocol version 1 #HostKey /etc/ssh/ssh_host_key diff --git a/sshd_config.5 b/sshd_config.5 index 54a4480fe..00ac82a34 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.107 2009/08/16 23:29:26 dtucker Exp $ -.Dd $Mdocdate: August 16 2009 $ +.\" $OpenBSD: sshd_config.5,v 1.108 2009/10/08 14:03:41 markus Exp $ +.Dd $Mdocdate: October 8 2009 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -793,7 +793,7 @@ and .Sq 2 . Multiple versions must be comma-separated. The default is -.Dq 2,1 . +.Dq 2 . Note that the order of the protocol list does not indicate preference, because the client selects among multiple protocol versions offered by the server. -- cgit v1.2.3 From 7a4a76579e5321f52b773fc84f7bbe0f07adc5f2 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 11 Oct 2009 21:51:40 +1100 Subject: - jmc@cvs.openbsd.org 2009/10/08 20:42:12 [sshd_config.5 ssh_config.5 sshd.8 ssh.1] some tweaks now that protocol 1 is not offered by default; ok markus --- ChangeLog | 3 +++ ssh.1 | 16 +++++++--------- ssh_config.5 | 6 +++--- sshd.8 | 6 +++--- sshd_config.5 | 4 ++-- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23bc18b67..495c0968c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,9 @@ [sshd_config readconf.c ssh_config.5 servconf.c sshd_config.5] disable protocol 1 by default (after a transition period of about 10 years) ok deraadt + - jmc@cvs.openbsd.org 2009/10/08 20:42:12 + [sshd_config.5 ssh_config.5 sshd.8 ssh.1] + some tweaks now that protocol 1 is not offered by default; ok markus 20091007 - (dtucker) OpenBSD CVS Sync diff --git a/ssh.1 b/ssh.1 index 6c6271ee4..8c3d32aaf 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.283 2009/03/19 15:15:09 jmc Exp $ -.Dd $Mdocdate: March 19 2009 $ +.\" $OpenBSD: ssh.1,v 1.284 2009/10/08 20:42:12 jmc Exp $ +.Dd $Mdocdate: October 8 2009 $ .Dt SSH 1 .Os .Sh NAME @@ -666,20 +666,18 @@ exits with the exit status of the remote command or with 255 if an error occurred. .Sh AUTHENTICATION The OpenSSH SSH client supports SSH protocols 1 and 2. -Protocol 2 is the default, with -.Nm -falling back to protocol 1 if it detects protocol 2 is unsupported. -These settings may be altered using the +The default is to use protocol 2 only, +though this can be changed via the .Cm Protocol option in -.Xr ssh_config 5 , -or enforced using the +.Xr ssh_config 5 +or the .Fl 1 and .Fl 2 options (see above). Both protocols support similar authentication methods, -but protocol 2 is preferred since +but protocol 2 is the default since it provides additional mechanisms for confidentiality (the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) and integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160). diff --git a/ssh_config.5 b/ssh_config.5 index 82c2a30b0..89f3896e6 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.120 2009/10/08 14:03:41 markus Exp $ +.\" $OpenBSD: ssh_config.5,v 1.121 2009/10/08 20:42:13 jmc Exp $ .Dd $Mdocdate: October 8 2009 $ .Dt SSH_CONFIG 5 .Os @@ -731,12 +731,12 @@ and .Sq 2 . Multiple versions must be comma-separated. When this option is set to -.Dq 2,1 +.Dq 2,1 .Nm ssh will try version 2 and fall back to version 1 if version 2 is not available. The default is -.Dq 2 . +.Sq 2 . .It Cm ProxyCommand Specifies the command to use to connect to the server. The command diff --git a/sshd.8 b/sshd.8 index 111d491d9..7878d9f06 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.248 2009/03/26 08:38:39 sobrado Exp $ -.Dd $Mdocdate: March 26 2009 $ +.\" $OpenBSD: sshd.8,v 1.249 2009/10/08 20:42:13 jmc Exp $ +.Dd $Mdocdate: October 8 2009 $ .Dt SSHD 8 .Os .Sh NAME @@ -260,7 +260,7 @@ or .El .Sh AUTHENTICATION The OpenSSH SSH daemon supports SSH protocols 1 and 2. -Both protocols are supported by default, +The default is to use protocol 2 only, though this can be changed via the .Cm Protocol option in diff --git a/sshd_config.5 b/sshd_config.5 index 00ac82a34..4b3793d13 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.108 2009/10/08 14:03:41 markus Exp $ +.\" $OpenBSD: sshd_config.5,v 1.109 2009/10/08 20:42:13 jmc Exp $ .Dd $Mdocdate: October 8 2009 $ .Dt SSHD_CONFIG 5 .Os @@ -793,7 +793,7 @@ and .Sq 2 . Multiple versions must be comma-separated. The default is -.Dq 2 . +.Sq 2 . Note that the order of the protocol list does not indicate preference, because the client selects among multiple protocol versions offered by the server. -- cgit v1.2.3 From 438b47320cf075fa51aa0e840882998c24db176b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 11 Oct 2009 21:52:10 +1100 Subject: - dtucker@cvs.openbsd.org 2009/10/11 10:41:26 [sftp-client.c] d_type isn't portable so use lstat to get dirent modes. Suggested by and "looks sane" deraadt@ --- ChangeLog | 4 ++++ sftp-client.c | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 495c0968c..41bf68e7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,10 @@ - jmc@cvs.openbsd.org 2009/10/08 20:42:12 [sshd_config.5 ssh_config.5 sshd.8 ssh.1] some tweaks now that protocol 1 is not offered by default; ok markus + - dtucker@cvs.openbsd.org 2009/10/11 10:41:26 + [sftp-client.c] + d_type isn't portable so use lstat to get dirent modes. Suggested by and + "looks sane" deraadt@ 20091007 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-client.c b/sftp-client.c index cc4a5b15b..6124c0f40 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.89 2009/08/18 18:36:20 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.90 2009/10/11 10:41:26 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1512,7 +1512,11 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, new_dst = path_append(dst, filename); new_src = path_append(src, filename); - if (S_ISDIR(DTTOIF(dp->d_type))) { + if (lstat(new_src, &sb) == -1) { + logit("%s: lstat failed: %s", filename, + strerror(errno)); + ret = -1; + } else if (S_ISDIR(sb.st_mode)) { if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; @@ -1520,7 +1524,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, if (upload_dir_internal(conn, new_src, new_dst, pflag, depth + 1, printflag) == -1) ret = -1; - } else if (S_ISREG(DTTOIF(dp->d_type)) ) { + } else if (S_ISREG(sb.st_mode)) { if (do_upload(conn, new_src, new_dst, pflag) == -1) { error("Uploading of file %s to %s failed!", new_src, new_dst); -- cgit v1.2.3 From e23a79cbed41a3d10533a9d5caefdcee058a066b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 12 Oct 2009 09:37:22 +1100 Subject: - markus@cvs.openbsd.org 2009/10/08 18:04:27 [regress/test-exec.sh] re-enable protocol v1 for the tests. --- ChangeLog | 3 +++ regress/test-exec.sh | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 41bf68e7c..918a48da1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,9 @@ [sftp-client.c] d_type isn't portable so use lstat to get dirent modes. Suggested by and "looks sane" deraadt@ + - markus@cvs.openbsd.org 2009/10/08 18:04:27 + [regress/test-exec.sh] + re-enable protocol v1 for the tests. 20091007 - (dtucker) OpenBSD CVS Sync diff --git a/regress/test-exec.sh b/regress/test-exec.sh index b54448912..804a29696 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.35 2008/06/28 13:57:25 djm Exp $ +# $OpenBSD: test-exec.sh,v 1.36 2009/10/08 18:04:27 markus Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -222,6 +222,7 @@ trap fatal 3 2 cat << EOF > $OBJ/sshd_config StrictModes no Port $PORT + Protocol 2,1 AddressFamily inet ListenAddress 127.0.0.1 #ListenAddress ::1 @@ -247,6 +248,7 @@ echo 'StrictModes no' >> $OBJ/sshd_proxy # create client config cat << EOF > $OBJ/ssh_config Host * + Protocol 2,1 Hostname 127.0.0.1 HostKeyAlias localhost-with-alias Port $PORT -- cgit v1.2.3 From 1b118881b8f71a84458e42de07708c863f70093f Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:40:32 +1100 Subject: - (dtucker) OpenBSD CVS Sync - djm@cvs.openbsd.org 2009/10/11 23:03:15 [hostfile.c] mention the host name that we are looking for in check_host_in_hostfile() --- ChangeLog | 6 ++++++ hostfile.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 918a48da1..16f45c8ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20091024 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2009/10/11 23:03:15 + [hostfile.c] + mention the host name that we are looking for in check_host_in_hostfile() + 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for dirent d_type and DTTOIF as we've switched OpenBSD to the more portable diff --git a/hostfile.c b/hostfile.c index 2cceb352a..cd28bf446 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.45 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: hostfile.c,v 1.46 2009/10/11 23:03:15 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -204,7 +204,7 @@ check_host_in_hostfile_by_key_or_type(const char *filename, char *cp, *cp2, *hashed_host; HostStatus end_return; - debug3("check_host_in_hostfile: filename %s", filename); + debug3("check_host_in_hostfile: host %s filename %s", host, filename); /* Open the file containing the list of known hosts. */ f = fopen(filename, "r"); -- cgit v1.2.3 From 49b7e235455bf20227877624f8c60c34a6e78458 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:41:05 +1100 Subject: - sobrado@cvs.openbsd.org 2009/10/17 12:10:39 [sftp-server.c] sort flags. --- ChangeLog | 3 +++ sftp-server.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16f45c8ff..67839e275 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ - djm@cvs.openbsd.org 2009/10/11 23:03:15 [hostfile.c] mention the host name that we are looking for in check_host_in_hostfile() + - sobrado@cvs.openbsd.org 2009/10/17 12:10:39 + [sftp-server.c] + sort flags. 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/sftp-server.c b/sftp-server.c index 66c0c1d5f..20a601f99 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.87 2009/08/31 20:56:02 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.88 2009/10/17 12:10:39 sobrado Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1322,7 +1322,7 @@ sftp_server_usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-he] [-l log_level] [-f log_facility] [-u umask]\n", + "usage: %s [-eh] [-f log_facility] [-l log_level] [-u umask]\n", __progname); exit(1); } -- cgit v1.2.3 From ae69e1d010ddf367fdd8ecf7f006c54cfe3f9728 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:41:34 +1100 Subject: - sobrado@cvs.openbsd.org 2009/10/22 12:35:53 [ssh.1 ssh-agent.1 ssh-add.1] use the UNIX-related macros (.At and .Ux) where appropriate. ok jmc@ --- ChangeLog | 4 ++++ ssh-add.1 | 9 +++++---- ssh-agent.1 | 16 ++++++++++------ ssh.1 | 9 +++++---- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67839e275..ef05cbe35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,10 @@ - sobrado@cvs.openbsd.org 2009/10/17 12:10:39 [sftp-server.c] sort flags. + - sobrado@cvs.openbsd.org 2009/10/22 12:35:53 + [ssh.1 ssh-agent.1 ssh-add.1] + use the UNIX-related macros (.At and .Ux) where appropriate. + ok jmc@ 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/ssh-add.1 b/ssh-add.1 index 005041b68..c484e94a0 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.46 2007/06/12 13:41:03 jmc Exp $ +.\" $OpenBSD: ssh-add.1,v 1.47 2009/10/22 12:35:53 sobrado Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 12 2007 $ +.Dd $Mdocdate: October 22 2009 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -148,8 +148,9 @@ may be necessary to redirect the input from .Pa /dev/null to make this work.) .It Ev SSH_AUTH_SOCK -Identifies the path of a unix-domain socket used to communicate with the -agent. +Identifies the path of a +.Ux +domain socket used to communicate with the agent. .El .Sh FILES .Bl -tag -width Ds diff --git a/ssh-agent.1 b/ssh-agent.1 index 533cd6f6b..bbae4af92 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.47 2009/03/26 08:38:39 sobrado Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.48 2009/10/22 12:35:53 sobrado Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: March 26 2009 $ +.Dd $Mdocdate: October 22 2009 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -67,7 +67,9 @@ machines using The options are as follows: .Bl -tag -width Ds .It Fl a Ar bind_address -Bind the agent to the unix-domain socket +Bind the agent to the +.Ux +domain socket .Ar bind_address . The default is .Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . @@ -162,8 +164,9 @@ Instead, operations that require a private key will be performed by the agent, and the result will be returned to the requester. This way, private keys are not exposed to clients using the agent. .Pp -A unix-domain socket is created -and the name of this socket is stored in the +A +.Ux +domain socket is created and the name of this socket is stored in the .Ev SSH_AUTH_SOCK environment variable. @@ -186,7 +189,8 @@ Contains the protocol version 2 DSA authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. .It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt -Unix-domain sockets used to contain the connection to the +.Ux +domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. diff --git a/ssh.1 b/ssh.1 index 8c3d32aaf..9aca407a5 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.284 2009/10/08 20:42:12 jmc Exp $ -.Dd $Mdocdate: October 8 2009 $ +.\" $OpenBSD: ssh.1,v 1.285 2009/10/22 12:35:53 sobrado Exp $ +.Dd $Mdocdate: October 22 2009 $ .Dt SSH 1 .Os .Sh NAME @@ -132,8 +132,9 @@ This can also be specified on a per-host basis in a configuration file. .Pp Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host -(for the agent's Unix-domain socket) -can access the local agent through the forwarded connection. +(for the agent's +.Ux +domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. -- cgit v1.2.3 From 98c9aec30e75ba890ed36227793e1e5ea6a23d45 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:42:44 +1100 Subject: - sobrado@cvs.openbsd.org 2009/10/22 15:02:12 [ssh-agent.1 ssh-add.1 ssh.1] write UNIX-domain in a more consistent way; while here, replace a few remaining ".Tn UNIX" macros with ".Ux" ones. pointed out by ratchov@, thanks! ok jmc@ --- ChangeLog | 6 ++++++ ssh-add.1 | 6 +++--- ssh-agent.1 | 15 +++++++-------- ssh.1 | 6 +++--- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef05cbe35..34351d474 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,12 @@ [ssh.1 ssh-agent.1 ssh-add.1] use the UNIX-related macros (.At and .Ux) where appropriate. ok jmc@ + - sobrado@cvs.openbsd.org 2009/10/22 15:02:12 + [ssh-agent.1 ssh-add.1 ssh.1] + write UNIX-domain in a more consistent way; while here, replace a + few remaining ".Tn UNIX" macros with ".Ux" ones. + pointed out by ratchov@, thanks! + ok jmc@ 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/ssh-add.1 b/ssh-add.1 index c484e94a0..ee9a00ff0 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.47 2009/10/22 12:35:53 sobrado Exp $ +.\" $OpenBSD: ssh-add.1,v 1.48 2009/10/22 15:02:12 sobrado Exp $ .\" .\" -*- nroff -*- .\" @@ -149,8 +149,8 @@ may be necessary to redirect the input from to make this work.) .It Ev SSH_AUTH_SOCK Identifies the path of a -.Ux -domain socket used to communicate with the agent. +.Ux Ns -domain +socket used to communicate with the agent. .El .Sh FILES .Bl -tag -width Ds diff --git a/ssh-agent.1 b/ssh-agent.1 index bbae4af92..acc115bd4 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.48 2009/10/22 12:35:53 sobrado Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.49 2009/10/22 15:02:12 sobrado Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -68,8 +68,8 @@ The options are as follows: .Bl -tag -width Ds .It Fl a Ar bind_address Bind the agent to the -.Ux -domain socket +.Ux Ns -domain +socket .Ar bind_address . The default is .Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . @@ -165,8 +165,8 @@ by the agent, and the result will be returned to the requester. This way, private keys are not exposed to clients using the agent. .Pp A -.Ux -domain socket is created and the name of this socket is stored in the +.Ux Ns -domain +socket is created and the name of this socket is stored in the .Ev SSH_AUTH_SOCK environment variable. @@ -189,9 +189,8 @@ Contains the protocol version 2 DSA authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. .It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt -.Ux -domain sockets used to contain the connection to the -authentication agent. +.Ux Ns -domain +sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. .El diff --git a/ssh.1 b/ssh.1 index 9aca407a5..7e7f64e46 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.285 2009/10/22 12:35:53 sobrado Exp $ +.\" $OpenBSD: ssh.1,v 1.286 2009/10/22 15:02:12 sobrado Exp $ .Dd $Mdocdate: October 22 2009 $ .Dt SSH 1 .Os @@ -133,8 +133,8 @@ This can also be specified on a per-host basis in a configuration file. Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent's -.Ux -domain socket) can access the local agent through the forwarded connection. +.Ux Ns -domain +socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. -- cgit v1.2.3 From dfb9b716500f777563a8f6f36072210fea167530 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:46:43 +1100 Subject: - djm@cvs.openbsd.org 2009/10/22 22:26:13 [authfile.c] switch from 3DES to AES-128 for encryption of passphrase-protected SSH protocol 2 private keys; ok several --- ChangeLog | 4 ++++ authfile.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34351d474..5ec1345c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,10 @@ few remaining ".Tn UNIX" macros with ".Ux" ones. pointed out by ratchov@, thanks! ok jmc@ + - djm@cvs.openbsd.org 2009/10/22 22:26:13 + [authfile.c] + switch from 3DES to AES-128 for encryption of passphrase-protected + SSH protocol 2 private keys; ok several 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/authfile.c b/authfile.c index 735c64780..22df6c64b 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.76 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: authfile.c,v 1.77 2009/10/22 22:26:13 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -184,7 +184,7 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase, int success = 0; int len = strlen(_passphrase); u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; - const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; + const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; if (len > 0 && len <= 4) { error("passphrase too short: have %d bytes, need > 4", len); -- cgit v1.2.3 From 2f29a8caba867a2b0c32772de705657de726dcca Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:47:58 +1100 Subject: - djm@cvs.openbsd.org 2009/10/23 01:57:11 [sshconnect2.c] disallow a hostile server from checking jpake auth by sending an out-of-sequence success message. (doesn't affect code enabled by default) --- ChangeLog | 4 ++++ sshconnect2.c | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5ec1345c3..53dcc62fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,10 @@ [authfile.c] switch from 3DES to AES-128 for encryption of passphrase-protected SSH protocol 2 private keys; ok several + - djm@cvs.openbsd.org 2009/10/23 01:57:11 + [sshconnect2.c] + disallow a hostile server from checking jpake auth by sending an + out-of-sequence success message. (doesn't affect code enabled by default) 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/sshconnect2.c b/sshconnect2.c index 260c6307a..1e0e9d5e1 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.171 2009/03/05 07:18:19 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.172 2009/10/23 01:57:11 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -210,6 +210,7 @@ struct Authmethod { }; void input_userauth_success(int, u_int32_t, void *); +void input_userauth_success_unexpected(int, u_int32_t, void *); void input_userauth_failure(int, u_int32_t, void *); void input_userauth_banner(int, u_int32_t, void *); void input_userauth_error(int, u_int32_t, void *); @@ -427,12 +428,15 @@ void input_userauth_success(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; + if (authctxt == NULL) fatal("input_userauth_success: no authentication context"); if (authctxt->authlist) { xfree(authctxt->authlist); authctxt->authlist = NULL; } + if (authctxt->method != NULL && authctxt->method->cleanup != NULL) + authctxt->method->cleanup(authctxt); if (authctxt->methoddata) { xfree(authctxt->methoddata); authctxt->methoddata = NULL; @@ -440,6 +444,18 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt) authctxt->success = 1; /* break out */ } +void +input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + + if (authctxt == NULL) + fatal("%s: no authentication context", __func__); + + fatal("Unexpected authentication success during %s.", + authctxt->method->name); +} + /* ARGSUSED */ void input_userauth_failure(int type, u_int32_t seq, void *ctxt) @@ -1709,6 +1725,8 @@ userauth_jpake(Authctxt *authctxt) /* Expect step 1 packet from peer */ dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, input_userauth_jpake_server_step1); + dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, + &input_userauth_success_unexpected); return 1; } @@ -1721,6 +1739,7 @@ userauth_jpake_cleanup(Authctxt *authctxt) jpake_free(authctxt->methoddata); authctxt->methoddata = NULL; } + dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); } #endif /* JPAKE */ -- cgit v1.2.3 From 199ee6ff0727cd339c246b6b859a0ded14b366a4 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:50:17 +1100 Subject: - dtucker@cvs.openbsd.org 2009/10/24 00:48:34 [ssh-keygen.1] ssh-keygen now uses AES-128 for private keys --- ChangeLog | 3 +++ ssh-keygen.1 | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53dcc62fd..449aeed31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,9 @@ [sshconnect2.c] disallow a hostile server from checking jpake auth by sending an out-of-sequence success message. (doesn't affect code enabled by default) + - dtucker@cvs.openbsd.org 2009/10/24 00:48:34 + [ssh-keygen.1] + ssh-keygen now uses AES-128 for private keys 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 3596cc174..9e59c16f7 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.79 2008/07/24 23:55:30 sthen Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.80 2009/10/24 00:48:34 dtucker Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: July 24 2008 $ +.Dd $Mdocdate: October 24 2009 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -393,7 +393,7 @@ Contains the protocol version 1 RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file using 3DES. +used to encrypt the private part of this file using 128-bit AES. This file is not automatically accessed by .Nm but it is offered as the default file for the private key. @@ -411,7 +411,7 @@ Contains the protocol version 2 DSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file using 3DES. +used to encrypt the private part of this file using 128-bit AES. This file is not automatically accessed by .Nm but it is offered as the default file for the private key. @@ -429,7 +429,7 @@ Contains the protocol version 2 RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file using 3DES. +used to encrypt the private part of this file using 128-bit AES. This file is not automatically accessed by .Nm but it is offered as the default file for the private key. -- cgit v1.2.3 From 6ac91a7c83a7343e9fdf24c2857b301b50e21a9c Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:52:42 +1100 Subject: - (dtucker) [mdoc2man.awk] Teach it to understand the .Ux macro. --- ChangeLog | 1 + mdoc2man.awk | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 449aeed31..1b06168ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,7 @@ - dtucker@cvs.openbsd.org 2009/10/24 00:48:34 [ssh-keygen.1] ssh-keygen now uses AES-128 for private keys + - (dtucker) [mdoc2man.awk] Teach it to understand the .Ux macro. 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/mdoc2man.awk b/mdoc2man.awk index 9d1126769..80e8d5ffa 100644 --- a/mdoc2man.awk +++ b/mdoc2man.awk @@ -1,6 +1,6 @@ #!/usr/bin/awk # -# $Id: mdoc2man.awk,v 1.8 2007/06/05 10:01:16 dtucker Exp $ +# $Id: mdoc2man.awk,v 1.9 2009/10/24 00:52:42 dtucker Exp $ # # Version history: # v4+ Adapted for OpenSSH Portable (see cvs Id and history) @@ -149,6 +149,9 @@ function add(str) { } else if(match(words[w],"^Dt$")) { id=wtail() next + } else if(match(words[w],"^Ux$")) { + add("UNIX") + skip=1 } else if(match(words[w],"^Ox$")) { add("OpenBSD") skip=1 -- cgit v1.2.3 From 4d6656b1030c2090f8769ce9cce0a9e5dd135945 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 15:04:12 +1100 Subject: - (dtucker) [session.c openbsd-compat/port-linux.{c,h}] Bug #1637: if selinux is enabled set the security context to "sftpd_t" before running the internal sftp server Based on a patch from jchadima at redhat. --- ChangeLog | 3 +++ openbsd-compat/port-linux.c | 37 ++++++++++++++++++++++++++++++++++++- openbsd-compat/port-linux.h | 3 ++- session.c | 3 +++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b06168ae..37c928182 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,9 @@ [ssh-keygen.1] ssh-keygen now uses AES-128 for private keys - (dtucker) [mdoc2man.awk] Teach it to understand the .Ux macro. + - (dtucker) [session.c openbsd-compat/port-linux.{c,h}] Bug #1637: if selinux + is enabled set the security context to "sftpd_t" before running the + internal sftp server Based on a patch from jchadima at redhat. 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index ad262758e..88c601e20 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -1,4 +1,4 @@ -/* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker Exp $ */ +/* $Id: port-linux.c,v 1.6 2009/10/24 04:04:13 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh @@ -29,6 +29,7 @@ #ifdef WITH_SELINUX #include "log.h" +#include "xmalloc.h" #include "port-linux.h" #include @@ -168,4 +169,38 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) freecon(user_ctx); debug3("%s: done", __func__); } + +void +ssh_selinux_change_context(const char *newname) +{ + int len, newlen; + char *oldctx, *newctx, *cx; + + if (!ssh_selinux_enabled()) + return; + + if (getcon((security_context_t *)&oldctx) < 0) { + logit("%s: getcon failed with %s", __func__, strerror (errno)); + return; + } + if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) == + NULL) { + logit ("%s: unparseable context %s", __func__, oldctx); + return; + } + + newlen = strlen(oldctx) + strlen(newname) + 1; + newctx = xmalloc(newlen); + len = cx - oldctx + 1; + memcpy(newctx, oldctx, len); + strlcpy(newctx + len, newname, newlen - len); + if ((cx = index(cx + 1, ':'))) + strlcat(newctx, cx, newlen); + debug3("%s: setting context from '%s' to '%s'", __func__, oldctx, + newctx); + if (setcon(newctx) < 0) + logit("%s: setcon failed with %s", __func__, strerror (errno)); + xfree(oldctx); + xfree(newctx); +} #endif /* WITH_SELINUX */ diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 5cd39bf83..6ad4a49f6 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -1,4 +1,4 @@ -/* $Id: port-linux.h,v 1.2 2008/03/26 20:27:21 dtucker Exp $ */ +/* $Id: port-linux.h,v 1.3 2009/10/24 04:04:13 dtucker Exp $ */ /* * Copyright (c) 2006 Damien Miller @@ -23,6 +23,7 @@ int ssh_selinux_enabled(void); void ssh_selinux_setup_pty(char *, const char *); void ssh_selinux_setup_exec_context(char *); +void ssh_selinux_change_context(const char *); #endif #endif /* ! _PORT_LINUX_H */ diff --git a/session.c b/session.c index d55419fbd..78192314a 100644 --- a/session.c +++ b/session.c @@ -1796,6 +1796,9 @@ do_child(Session *s, const char *command) argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; +#ifdef WITH_SELINUX + ssh_selinux_change_context("sftpd_t"); +#endif exit(sftp_server_main(i, argv, s->pw)); } -- cgit v1.2.3 From e89ed1cfcae65705b48d3741873d8ab1f76a6cf7 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Thu, 5 Nov 2009 20:43:16 +1100 Subject: - (dtucker) [authfile.c] Add OpenSSL compat header so this still builds with older versions of OpenSSL. --- ChangeLog | 4 ++++ authfile.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 37c928182..1bdeea275 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091105 + - (dtucker) [authfile.c] Add OpenSSL compat header so this still builds with + older versions of OpenSSL. + 20091024 - (dtucker) OpenBSD CVS Sync - djm@cvs.openbsd.org 2009/10/11 23:03:15 diff --git a/authfile.c b/authfile.c index 22df6c64b..fc12c00c7 100644 --- a/authfile.c +++ b/authfile.c @@ -47,6 +47,9 @@ #include #include +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + #include #include #include -- cgit v1.2.3 From df6578bb4df17210f792c3bc98a72bed473e7e11 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 7 Nov 2009 16:03:14 +1100 Subject: - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private keys when built with OpenSSL versions that don't do AES. --- ChangeLog | 4 ++++ authfile.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1bdeea275..9a17b25ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091107 + - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private + keys when built with OpenSSL versions that don't do AES. + 20091105 - (dtucker) [authfile.c] Add OpenSSL compat header so this still builds with older versions of OpenSSL. diff --git a/authfile.c b/authfile.c index fc12c00c7..3fbe11b0e 100644 --- a/authfile.c +++ b/authfile.c @@ -187,7 +187,11 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase, int success = 0; int len = strlen(_passphrase); u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; +#if (OPENSSL_VERSION_NUMBER < 0x00907000L) + const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; +#else const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; +#endif if (len > 0 && len <= 4) { error("passphrase too short: have %d bytes, need > 4", len); -- cgit v1.2.3 From 04ee0f8f12ff3a1227439c5f67623547d7a5bd11 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 18 Nov 2009 17:48:30 +1100 Subject: - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only() report and fix from jan.kratochvil AT redhat.com --- ChangeLog | 6 ++++++ channels.c | 11 ++++------- misc.c | 11 +++++++++++ misc.h | 1 + sshd.c | 10 ++-------- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a17b25ae..c2e6cadc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20091107 + - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to + set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify + setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only() + report and fix from jan.kratochvil AT redhat.com + 20091107 - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private keys when built with OpenSSL versions that don't do AES. diff --git a/channels.c b/channels.c index e8b8aa07e..22e7f628b 100644 --- a/channels.c +++ b/channels.c @@ -2577,6 +2577,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, } channel_set_reuseaddr(sock); + if (ai->ai_family == AF_INET6) + sock_set_v6only(sock); debug("Local forwarding listening on %s port %s.", ntop, strport); @@ -3108,13 +3110,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, continue; } } -#ifdef IPV6_V6ONLY - if (ai->ai_family == AF_INET6) { - int on = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) - error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); - } -#endif + if (ai->ai_family == AF_INET6) + sock_set_v6only(sock); if (x11_use_localhost) channel_set_reuseaddr(sock); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { diff --git a/misc.c b/misc.c index 143dbf0e2..4dc152310 100644 --- a/misc.c +++ b/misc.c @@ -849,3 +849,14 @@ ms_to_timeval(struct timeval *tv, int ms) tv->tv_usec = (ms % 1000) * 1000; } +void +sock_set_v6only(int s) +{ +#ifdef IPV6_V6ONLY + int on = 1; + + debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) + error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); +#endif +} diff --git a/misc.h b/misc.h index 5da170d2f..e26b0aaff 100644 --- a/misc.h +++ b/misc.h @@ -35,6 +35,7 @@ char *tohex(const void *, size_t); void sanitise_stdfd(void); void ms_subtract_diff(struct timeval *, int *); void ms_to_timeval(struct timeval *, int); +void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); const char *ssh_gai_strerror(int); diff --git a/sshd.c b/sshd.c index 13a455d1f..04d8f9fa0 100644 --- a/sshd.c +++ b/sshd.c @@ -979,15 +979,9 @@ server_listen(void) &on, sizeof(on)) == -1) error("setsockopt SO_REUSEADDR: %s", strerror(errno)); -#ifdef IPV6_V6ONLY /* Only communicate in IPv6 over AF_INET6 sockets. */ - if (ai->ai_family == AF_INET6) { - if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, - &on, sizeof(on)) == -1) - error("setsockopt IPV6_V6ONLY: %s", - strerror(errno)); - } -#endif + if (ai->ai_family == AF_INET6) + sock_set_v6only(listen_sock); debug("Bind to port %s on %s.", strport, ntop); -- cgit v1.2.3 From 2191e04549839502631f3f97ededd301a1498cd0 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 18 Nov 2009 17:51:59 +1100 Subject: - (djm) [contrib/gnome-ssh-askpass2.c] Make askpass dialog desktop-modal. bz#1645, patch from jchadima AT redhat.com --- ChangeLog | 4 +++- contrib/gnome-ssh-askpass2.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c2e6cadc6..566167053 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,9 @@ - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only() - report and fix from jan.kratochvil AT redhat.com + bz#1648, report and fix from jan.kratochvil AT redhat.com + - (djm) [contrib/gnome-ssh-askpass2.c] Make askpass dialog desktop-modal. + bz#1645, patch from jchadima AT redhat.com 20091107 - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c index 901176dbb..9d97c30c0 100644 --- a/contrib/gnome-ssh-askpass2.c +++ b/contrib/gnome-ssh-askpass2.c @@ -120,6 +120,8 @@ passphrase_dialog(char *message) g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(ok_dialog), dialog); + gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); + /* Grab focus */ gtk_widget_show_now(dialog); if (grab_pointer) { -- cgit v1.2.3 From 409661f0d99bf9bc82543eb7bab1f502c9170281 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 20 Nov 2009 15:16:35 +1100 Subject: - (djm) [ssh-rand-helper.c] Print error and usage() when passed command- line arguments as none are supported. Exit when passed unrecognised commandline flags. bz#1568 from gson AT araneus.fi --- ChangeLog | 7 ++++++- ssh-rand-helper.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 566167053..e477a8fc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -20091107 +20091120 + - (djm) [ssh-rand-helper.c] Print error and usage() when passed command- + line arguments as none are supported. Exit when passed unrecognised + commandline flags. bz#1568 from gson AT araneus.fi + +20091118 - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only() diff --git a/ssh-rand-helper.c b/ssh-rand-helper.c index 8b1c4b4f4..0fcda7fff 100644 --- a/ssh-rand-helper.c +++ b/ssh-rand-helper.c @@ -853,11 +853,17 @@ main(int argc, char **argv) default: error("Invalid commandline option"); usage(); + exit(1); } } - log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1); + if (argc != optind) { + error("Unexpected commandline arguments."); + usage(); + exit(1); + } + #ifdef USE_SEED_FILES prng_read_seedfile(); #endif -- cgit v1.2.3 From 53e9974007661fe4026a9512ae1a7e1ea43face8 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Fri, 20 Nov 2009 19:32:15 -0800 Subject: - (tim) [opensshd.init.in] If PidFile is set in sshd_config, use it. Bug 1628. OK dtucker@ --- ChangeLog | 4 ++++ opensshd.init.in | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index e477a8fc3..41c272ec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091121 + - (tim) [opensshd.init.in] If PidFile is set in sshd_config, use it. + Bug 1628. OK dtucker@ + 20091120 - (djm) [ssh-rand-helper.c] Print error and usage() when passed command- line arguments as none are supported. Exit when passed unrecognised diff --git a/opensshd.init.in b/opensshd.init.in index c36c5c88a..d0aff7794 100755 --- a/opensshd.init.in +++ b/opensshd.init.in @@ -14,6 +14,8 @@ piddir=@piddir@ SSHD=$prefix/sbin/sshd PIDFILE=$piddir/sshd.pid +PidFile=`grep "^PidFile" ${sysconfdir}/sshd_config | tr "=" " " | awk '{print $2}'` +[ X$PidFile = X ] || PIDFILE=$PidFile SSH_KEYGEN=$prefix/bin/ssh-keygen HOST_KEY_RSA1=$sysconfdir/ssh_host_key HOST_KEY_DSA=$sysconfdir/ssh_host_dsa_key -- cgit v1.2.3 From 1533311f4ca27adf382a158e30fbb1d2c4882a62 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 7 Dec 2009 11:15:43 +1100 Subject: - (dtucker) Bug #1160: use pkg-config for opensc config if it's available. Tested by Martin Paljak. --- ChangeLog | 4 ++++ configure.ac | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 41c272ec9..1c3c93b63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091207 + - (dtucker) Bug #1160: use pkg-config for opensc config if it's available. + Tested by Martin Paljak. + 20091121 - (tim) [opensshd.init.in] If PidFile is set in sshd_config, use it. Bug 1628. OK dtucker@ diff --git a/configure.ac b/configure.ac index 0447bd62d..88a248fb5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.430 2009/10/11 10:50:20 dtucker Exp $ +# $Id: configure.ac,v 1.431 2009/12/07 00:15:43 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.430 $) +AC_REVISION($Revision: 1.431 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -3295,11 +3295,18 @@ AC_ARG_WITH(opensc, [ --with-opensc[[=PFX]] Enable smartcard support using OpenSC (optionally in PATH)], [ if test "x$withval" != "xno" ; then - if test "x$withval" != "xyes" ; then - OPENSC_CONFIG=$withval/bin/opensc-config + AC_PATH_PROG(PKGCONFIG, pkg-config, no) + AC_MSG_CHECKING(how to get opensc config) + if test "x$withval" != "xyes" -a "x$PKGCONFIG" = "xno"; then + OPENSC_CONFIG="$withval/bin/opensc-config" + elif test -f "$withval/src/libopensc/libopensc.pc"; then + OPENSC_CONFIG="$PKGCONFIG $withval/src/libopensc/libopensc.pc" + elif test "x$PKGCONFIG" != "xno"; then + OPENSC_CONFIG="$PKGCONFIG libopensc" else - AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no) + AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no) fi + AC_MSG_RESULT($OPENSC_CONFIG) if test "$OPENSC_CONFIG" != "no"; then LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags` LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs` -- cgit v1.2.3 From d35e0ef61658aa3116eebb1606fcfe6f849fdcca Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 7 Dec 2009 11:32:36 +1100 Subject: - (dtucker) Bug #1677: add conditionals around the source for ssh-askpass. --- ChangeLog | 1 + contrib/redhat/openssh.spec | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1c3c93b63..53d89c905 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 20091207 - (dtucker) Bug #1160: use pkg-config for opensc config if it's available. Tested by Martin Paljak. + - (dtucker) Bug #1677: add conditionals around the source for ssh-askpass. 20091121 - (tim) [opensshd.init.in] If PidFile is set in sshd_config, use it. diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 680906cf3..1bdaf2d93 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -74,7 +74,9 @@ Release: %{rel} %endif URL: http://www.openssh.com/portable.html Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz +%if ! %{skip_x11_askpass} Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +%endif License: BSD Group: Applications/Internet BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot -- cgit v1.2.3 From c8802aac28470714ec204d00342f6ecbca45908f Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 8 Dec 2009 13:39:48 +1100 Subject: - (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux, based on a patch from Vaclav Ovsik and Colin Watson. ok djm. --- ChangeLog | 4 +++ configure.ac | 5 ++-- openbsd-compat/port-linux.c | 63 +++++++++++++++++++++++++++++++++++++++++++-- openbsd-compat/port-linux.h | 7 ++++- platform.c | 14 +++++++++- platform.h | 3 ++- sshd.c | 1 + 7 files changed, 90 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53d89c905..7f95697f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091208 + - (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux, + based on a patch from Vaclav Ovsik and Colin Watson. ok djm. + 20091207 - (dtucker) Bug #1160: use pkg-config for opensc config if it's available. Tested by Martin Paljak. diff --git a/configure.ac b/configure.ac index 88a248fb5..94f049fc6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.431 2009/12/07 00:15:43 dtucker Exp $ +# $Id: configure.ac,v 1.432 2009/12/08 02:39:48 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.431 $) +AC_REVISION($Revision: 1.432 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -589,6 +589,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) if it doesn't return EOPNOTSUPP.]) AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts]) AC_DEFINE(USE_BTMP) + AC_DEFINE(LINUX_OOM_ADJUST, 1, [Adjust Linux out-of-memory killer]) inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 88c601e20..cda751dea 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -1,4 +1,4 @@ -/* $Id: port-linux.c,v 1.6 2009/10/24 04:04:13 dtucker Exp $ */ +/* $Id: port-linux.c,v 1.7 2009/12/08 02:39:48 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh @@ -23,15 +23,17 @@ #include "includes.h" +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) #include #include #include +#include -#ifdef WITH_SELINUX #include "log.h" #include "xmalloc.h" #include "port-linux.h" +#ifdef WITH_SELINUX #include #include #include @@ -204,3 +206,60 @@ ssh_selinux_change_context(const char *newname) xfree(newctx); } #endif /* WITH_SELINUX */ + +#ifdef LINUX_OOM_ADJUST +#define OOM_ADJ_PATH "/proc/self/oom_adj" +/* + * The magic "don't kill me", as documented in eg: + * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt + */ +#define OOM_ADJ_NOKILL -17 + +static int oom_adj_save = INT_MIN; + +/* + * Tell the kernel's out-of-memory killer to avoid sshd. + * Returns the previous oom_adj value or zero. + */ +void +oom_adjust_setup(void) +{ + FILE *fp; + + debug3("%s", __func__); + if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) { + if (fscanf(fp, "%d", &oom_adj_save) != 1) + logit("error reading %s: %s", OOM_ADJ_PATH, strerror(errno)); + else { + rewind(fp); + if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0) + logit("error writing %s: %s", + OOM_ADJ_PATH, strerror(errno)); + else + verbose("Set %s from %d to %d", + OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL); + } + fclose(fp); + } +} + +/* Restore the saved OOM adjustment */ +void +oom_adjust_restore(void) +{ + FILE *fp; + + debug3("%s", __func__); + if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL) + return; + + if (fprintf(fp, "%d\n", oom_adj_save) <= 0) + logit("error writing %s: %s", OOM_ADJ_PATH, strerror(errno)); + else + verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save); + + fclose(fp); + return; +} +#endif /* LINUX_OOM_ADJUST */ +#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 6ad4a49f6..209d9a7a2 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -1,4 +1,4 @@ -/* $Id: port-linux.h,v 1.3 2009/10/24 04:04:13 dtucker Exp $ */ +/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */ /* * Copyright (c) 2006 Damien Miller @@ -26,4 +26,9 @@ void ssh_selinux_setup_exec_context(char *); void ssh_selinux_change_context(const char *); #endif +#ifdef LINUX_OOM_ADJUST +void oom_adjust_restore(void); +void oom_adjust_setup(void); +#endif + #endif /* ! _PORT_LINUX_H */ diff --git a/platform.c b/platform.c index aee4b01e7..2dc4352f4 100644 --- a/platform.c +++ b/platform.c @@ -1,4 +1,4 @@ -/* $Id: platform.c,v 1.1 2006/08/30 17:24:41 djm Exp $ */ +/* $Id: platform.c,v 1.2 2009/12/08 02:39:48 dtucker Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -21,6 +21,15 @@ #include "openbsd-compat/openbsd-compat.h" +void +platform_pre_listen(void) +{ +#ifdef LINUX_OOM_ADJUST + /* Adjust out-of-memory killer so listening process is not killed */ + oom_adjust_setup(); +#endif +} + void platform_pre_fork(void) { @@ -43,4 +52,7 @@ platform_post_fork_child(void) #ifdef USE_SOLARIS_PROCESS_CONTRACTS solaris_contract_post_fork_child(); #endif +#ifdef LINUX_OOM_ADJUST + oom_adjust_restore(); +#endif } diff --git a/platform.h b/platform.h index cf93bc57c..8a34e364e 100644 --- a/platform.h +++ b/platform.h @@ -1,4 +1,4 @@ -/* $Id: platform.h,v 1.1 2006/08/30 17:24:41 djm Exp $ */ +/* $Id: platform.h,v 1.2 2009/12/08 02:39:48 dtucker Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -18,6 +18,7 @@ #include +void platform_pre_listen(void); void platform_pre_fork(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); diff --git a/sshd.c b/sshd.c index 04d8f9fa0..38aaa1820 100644 --- a/sshd.c +++ b/sshd.c @@ -1656,6 +1656,7 @@ main(int ac, char **av) if (inetd_flag) { server_accept_inetd(&sock_in, &sock_out); } else { + platform_pre_listen(); server_listen(); if (options.protocol & SSH_PROTO_1) -- cgit v1.2.3 From 1bf3503c9d5f0c79a108ea0060bcec3e0efe2b37 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 21 Dec 2009 10:49:21 +1100 Subject: - (dtucker) [auth-krb5.c platform.{c,h} openbsd-compat/port-aix.{c,h}] Bug #1583: Use system's kerberos principal name on AIX if it's available. Based on a patch from and tested by Miguel Sanders. --- ChangeLog | 5 +++++ auth-krb5.c | 13 ++++++++++--- openbsd-compat/port-aix.c | 25 +++++++++++++++++++++++++ openbsd-compat/port-aix.h | 6 +++++- platform.c | 12 +++++++++++- platform.h | 4 +++- 6 files changed, 59 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f95697f4..677a6af1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +20091221 + - (dtucker) [auth-krb5.c platform.{c,h} openbsd-compat/port-aix.{c,h}] + Bug #1583: Use system's kerberos principal name on AIX if it's available. + Based on a patch from and tested by Miguel Sanders + 20091208 - (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux, based on a patch from Vaclav Ovsik and Colin Watson. ok djm. diff --git a/auth-krb5.c b/auth-krb5.c index 868288126..d019fe202 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -78,6 +78,11 @@ auth_krb5_password(Authctxt *authctxt, const char *password) krb5_error_code problem; krb5_ccache ccache = NULL; int len; + char *client, *platform_client; + + /* get platform-specific kerberos client principal name (if it exists) */ + platform_client = platform_krb5_get_principal_name(authctxt->pw->pw_name); + client = platform_client ? platform_client : authctxt->pw->pw_name; temporarily_use_uid(authctxt->pw); @@ -85,7 +90,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) if (problem) goto out; - problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name, + problem = krb5_parse_name(authctxt->krb5_ctx, client, &authctxt->krb5_user); if (problem) goto out; @@ -141,8 +146,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) if (problem) goto out; - if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, - authctxt->pw->pw_name)) { + if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { problem = -1; goto out; } @@ -176,6 +180,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) out: restore_uid(); + + if (platform_client != NULL) + xfree(platform_client); if (problem) { if (ccache) diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index d9c0876f3..0bdefbf6d 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c @@ -374,6 +374,31 @@ aix_restoreauthdb(void) # endif /* WITH_AIXAUTHENTICATE */ +# ifdef USE_AIX_KRB_NAME +/* + * aix_krb5_get_principal_name: returns the user's kerberos client principal name if + * configured, otherwise NULL. Caller must free returned string. + */ +char * +aix_krb5_get_principal_name(char *pw_name) +{ + char *authname = NULL, *authdomain = NULL, *principal = NULL; + + setuserdb(S_READ); + if (getuserattr(pw_name, S_AUTHDOMAIN, &authdomain, SEC_CHAR) != 0) + debug("AIX getuserattr S_AUTHDOMAIN: %s", strerror(errno)); + if (getuserattr(pw_name, S_AUTHNAME, &authname, SEC_CHAR) != 0) + debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno)); + + if (authdomain != NULL) + xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain); + else if (authname != NULL) + principal = xstrdup(authname); + enduserdb(); + return principal; +} +# endif /* USE_AIX_KRB_NAME */ + # if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) # undef getnameinfo /* diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h index 3ac76ae15..53e4e88a0 100644 --- a/openbsd-compat/port-aix.h +++ b/openbsd-compat/port-aix.h @@ -1,4 +1,4 @@ -/* $Id: port-aix.h,v 1.31 2009/08/20 06:20:50 dtucker Exp $ */ +/* $Id: port-aix.h,v 1.32 2009/12/20 23:49:22 dtucker Exp $ */ /* * @@ -95,6 +95,10 @@ int sys_auth_record_login(const char *, const char *, const char *, Buffer *); # define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG char *sys_auth_get_lastlogin_msg(const char *, uid_t); # define CUSTOM_FAILED_LOGIN 1 +# if defined(S_AUTHDOMAIN) && defined (S_AUTHNAME) +# define USE_AIX_KRB_NAME +char *aix_krb5_get_principal_name(char *); +# endif #endif void aix_setauthdb(const char *); diff --git a/platform.c b/platform.c index 2dc4352f4..e3a428aaa 100644 --- a/platform.c +++ b/platform.c @@ -1,4 +1,4 @@ -/* $Id: platform.c,v 1.2 2009/12/08 02:39:48 dtucker Exp $ */ +/* $Id: platform.c,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -56,3 +56,13 @@ platform_post_fork_child(void) oom_adjust_restore(); #endif } + +char * +platform_krb5_get_principal_name(const char *pw_name) +{ +#ifdef USE_AIX_KRB_NAME + return aix_krb5_get_principal_name(pw_name); +#else + return NULL; +#endif +} diff --git a/platform.h b/platform.h index 8a34e364e..07ae3ad85 100644 --- a/platform.h +++ b/platform.h @@ -1,4 +1,4 @@ -/* $Id: platform.h,v 1.2 2009/12/08 02:39:48 dtucker Exp $ */ +/* $Id: platform.h,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -22,3 +22,5 @@ void platform_pre_listen(void); void platform_pre_fork(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); +char * platform_get_krb5_client(const char *); + -- cgit v1.2.3 From 880ab0d84e1c7d7957ff38d6506ff92868407a77 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sat, 26 Dec 2009 15:40:47 -0800 Subject: - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 Gzip all man pages. Patch from Corinna Vinschen. --- ChangeLog | 4 ++++ contrib/cygwin/Makefile | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 677a6af1e..dec861245 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091226 + - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 + Gzip all man pages. Patch from Corinna Vinschen. + 20091221 - (dtucker) [auth-krb5.c platform.{c,h} openbsd-compat/port-aix.{c,h}] Bug #1583: Use system's kerberos principal name on AIX if it's available. diff --git a/contrib/cygwin/Makefile b/contrib/cygwin/Makefile index 2ebd143dc..9f680c16c 100644 --- a/contrib/cygwin/Makefile +++ b/contrib/cygwin/Makefile @@ -1,8 +1,10 @@ srcdir=../.. +copyidsrcdir=.. prefix=/usr exec_prefix=$(prefix) bindir=$(prefix)/bin datadir=$(prefix)/share +mandir=$(datadir)/man docdir=$(datadir)/doc sshdocdir=$(docdir)/openssh cygdocdir=$(docdir)/Cygwin @@ -59,5 +61,16 @@ install-scripts: ssh-host-config ssh-user-config $(INSTALL) -m 755 ssh-host-config $(DESTDIR)$(bindir)/ssh-host-config $(INSTALL) -m 755 ssh-user-config $(DESTDIR)$(bindir)/ssh-user-config -cygwin-postinstall: move-config-files remove-empty-dir install-inetd-config install-doc install-scripts +install-copy-id: $(copyidsrcdir)/ssh-copy-id $(copyidsrcdir)/ssh-copy-id.1 + $(INSTALL) -m 755 $(copyidsrcdir)/ssh-copy-id $(DESTDIR)$(bindir)/ssh-copy-id + $(INSTALL) -m 644 $(copyidsrcdir)/ssh-copy-id.1 $(DESTDIR)$(mandir)/man1/ssh-copy-id.1 + +gzip-man-pages: + rm $(DESTDIR)$(mandir)/man1/slogin.1 + gzip $(DESTDIR)$(mandir)/man1/*.1 + gzip $(DESTDIR)$(mandir)/man5/*.5 + gzip $(DESTDIR)$(mandir)/man8/*.8 + cd $(DESTDIR)$(mandir)/man1 && ln -s ssh.1.gz slogin.1.gz + +cygwin-postinstall: move-config-files remove-empty-dir install-inetd-config install-doc install-scripts install-copy-id gzip-man-pages @echo "Cygwin specific configuration finished." -- cgit v1.2.3 From b7b17be4c0e235b670fb642a394abfe2e9b68cef Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 16:49:52 +1100 Subject: - andreas@cvs.openbsd.org 2009/10/24 11:11:58 [roaming.h] Declarations needed for upcoming changes. ok markus@ --- ChangeLog | 7 +++++++ roaming.h | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dec861245..5935fa6ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20091208 + - (dtucker) OpenBSD CVS Sync + - andreas@cvs.openbsd.org 2009/10/24 11:11:58 + [roaming.h] + Declarations needed for upcoming changes. + ok markus@ + 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 Gzip all man pages. Patch from Corinna Vinschen. diff --git a/roaming.h b/roaming.h index e517161f6..6bb94cc39 100644 --- a/roaming.h +++ b/roaming.h @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming.h,v 1.4 2009/06/27 09:32:43 andreas Exp $ */ +/* $OpenBSD: roaming.h,v 1.5 2009/10/24 11:11:58 andreas Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -19,12 +19,17 @@ #define ROAMING_H #define DEFAULT_ROAMBUF 65536 +#define ROAMING_REQUEST "roaming@appgate.com" +extern int roaming_enabled; extern int resume_in_progress; +void request_roaming(void); int get_snd_buf_size(void); int get_recv_buf_size(void); void add_recv_bytes(u_int64_t); +int wait_for_roaming_reconnect(void); +void roaming_reply(int, u_int32_t, void *); void set_out_buffer_size(size_t); ssize_t roaming_write(int, const void *, size_t, int *); ssize_t roaming_read(int, void *, size_t, int *); @@ -33,6 +38,7 @@ u_int64_t get_recv_bytes(void); u_int64_t get_sent_bytes(void); void roam_set_bytes(u_int64_t, u_int64_t); void resend_bytes(int, u_int64_t *); +void calculate_new_key(u_int64_t *, u_int64_t, u_int64_t); int resume_kex(void); #endif /* ROAMING */ -- cgit v1.2.3 From 36331b5d6cf8f776a27fe6fc3ed19da4f4c2ad91 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 16:50:41 +1100 Subject: - andreas@cvs.openbsd.org 2009/10/24 11:13:54 [sshconnect2.c kex.h kex.c] Let the client detect if the server supports roaming by looking for the resume@appgate.com kex algorithm. ok markus@ --- ChangeLog | 5 +++++ kex.c | 13 ++++++++++++- kex.h | 4 +++- sshconnect2.c | 7 ++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5935fa6ad..68f772b60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,11 @@ [roaming.h] Declarations needed for upcoming changes. ok markus@ + - andreas@cvs.openbsd.org 2009/10/24 11:13:54 + [sshconnect2.c kex.h kex.c] + Let the client detect if the server supports roaming by looking + for the resume@appgate.com kex algorithm. + ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/kex.c b/kex.c index f4f44f095..148cfee80 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.81 2009/05/27 06:34:36 andreas Exp $ */ +/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -48,6 +48,7 @@ #include "match.h" #include "dispatch.h" #include "monitor.h" +#include "roaming.h" #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) @@ -386,6 +387,16 @@ kex_choose_conf(Kex *kex) sprop=peer; } + /* Check whether server offers roaming */ + if (!kex->server) { + char *roaming; + roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL); + if (roaming) { + kex->roaming = 1; + xfree(roaming); + } + } + /* Algorithm Negotiation */ for (mode = 0; mode < MODE_MAX; mode++) { newkeys = xcalloc(1, sizeof(*newkeys)); diff --git a/kex.h b/kex.h index 68c80c5a9..1fa13799d 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.47 2009/05/27 06:34:36 andreas Exp $ */ +/* $OpenBSD: kex.h,v 1.48 2009/10/24 11:13:54 andreas Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -36,6 +36,7 @@ #define KEX_DH14 "diffie-hellman-group14-sha1" #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" +#define KEX_RESUME "resume@appgate.com" #define COMP_NONE 0 #define COMP_ZLIB 1 @@ -116,6 +117,7 @@ struct Kex { char *name; int hostkey_type; int kex_type; + int roaming; Buffer my; Buffer peer; sig_atomic_t done; diff --git a/sshconnect2.c b/sshconnect2.c index 1e0e9d5e1..937bb773d 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.172 2009/10/23 01:57:11 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.173 2009/10/24 11:13:54 andreas Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -152,6 +152,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) dispatch_run(DISPATCH_BLOCK, &kex->done, kex); + if (options.use_roaming && !kex->roaming) { + debug("Roaming not allowed by server"); + options.use_roaming = 0; + } + session_id2 = kex->session_id; session_id2_len = kex->session_id_len; -- cgit v1.2.3 From e32cf43106ee53e180bc855cdb60b6d414547d84 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 16:51:40 +1100 Subject: - andreas@cvs.openbsd.org 2009/10/24 11:15:29 [clientloop.c] client_loop() must detect if the session has been suspended and resumed, and take appropriate action in that case. From Martin Forssen, maf at appgate dot com ok markus@ --- ChangeLog | 6 ++++++ clientloop.c | 12 +++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 68f772b60..911f0fa0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,12 @@ Let the client detect if the server supports roaming by looking for the resume@appgate.com kex algorithm. ok markus@ + - andreas@cvs.openbsd.org 2009/10/24 11:15:29 + [clientloop.c] + client_loop() must detect if the session has been suspended and resumed, + and take appropriate action in that case. + From Martin Forssen, maf at appgate dot com + ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/clientloop.c b/clientloop.c index 9a7dc0ab0..540a6181a 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.213 2009/07/05 19:28:33 stevesk Exp $ */ +/* $OpenBSD: clientloop.c,v 1.214 2009/10/24 11:15:29 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -161,6 +161,8 @@ static int session_closed = 0; /* In SSH2: login session closed. */ static void client_init_dispatch(void); int session_ident = -1; +int session_resumed = 0; + /* Track escape per proto2 channel */ struct escape_filter_ctx { int escape_pending; @@ -1460,6 +1462,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) client_process_output(writeset); } + if (session_resumed) { + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = MAX(max_fd, connection_out); + max_fd = MAX(max_fd, connection_in); + session_resumed = 0; + } + /* * Send as much buffered packet data as possible to the * sender. -- cgit v1.2.3 From f9e6eb8f226675389c79fb9c44fcc29038ab9ff7 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 16:52:32 +1100 Subject: - andreas@cvs.openbsd.org 2009/10/24 11:19:17 [ssh2.h] Define the KEX messages used when resuming a suspended connection. ok markus@ --- ChangeLog | 3 +++ ssh2.h | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 911f0fa0f..3ee863580 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,9 @@ client_loop() must detect if the session has been suspended and resumed, and take appropriate action in that case. From Martin Forssen, maf at appgate dot com + - andreas@cvs.openbsd.org 2009/10/24 11:19:17 + [ssh2.h] + Define the KEX messages used when resuming a suspended connection. ok markus@ 20091226 diff --git a/ssh2.h b/ssh2.h index 1c33dc268..b01af7b1a 100644 --- a/ssh2.h +++ b/ssh2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh2.h,v 1.11 2008/11/04 08:22:13 djm Exp $ */ +/* $OpenBSD: ssh2.h,v 1.12 2009/10/24 11:19:17 andreas Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -166,3 +166,10 @@ #define SSH2_EXTENDED_DATA_STDERR 1 +/* kex messages for resume@appgate.com */ +#define SSH2_MSG_KEX_ROAMING_RESUME 30 +#define SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED 31 +#define SSH2_MSG_KEX_ROAMING_AUTH 32 +#define SSH2_MSG_KEX_ROAMING_AUTH_OK 33 +#define SSH2_MSG_KEX_ROAMING_AUTH_FAIL 34 + -- cgit v1.2.3 From e730118bf41c70bd519e595a7dda39df551852eb Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 16:53:31 +1100 Subject: - andreas@cvs.openbsd.org 2009/10/24 11:22:37 [roaming_common.c] Do the actual suspend/resume in the client. This won't be useful until the server side supports roaming. Most code from Martin Forssen, maf at appgate dot com. Some changes by me and markus@ ok markus@ --- ChangeLog | 7 +++++++ roaming_common.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3ee863580..d45a896bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,13 @@ [ssh2.h] Define the KEX messages used when resuming a suspended connection. ok markus@ + - andreas@cvs.openbsd.org 2009/10/24 11:22:37 + [roaming_common.c] + Do the actual suspend/resume in the client. This won't be useful until + the server side supports roaming. + Most code from Martin Forssen, maf at appgate dot com. Some changes by + me and markus@ + ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/roaming_common.c b/roaming_common.c index 73db09d79..272deade3 100644 --- a/roaming_common.c +++ b/roaming_common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_common.c,v 1.5 2009/06/27 09:32:43 andreas Exp $ */ +/* $OpenBSD: roaming_common.c,v 1.6 2009/10/24 11:22:37 andreas Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -147,6 +147,16 @@ roaming_write(int fd, const void *buf, size_t count, int *cont) } debug3("Wrote %ld bytes for a total of %llu", (long)ret, (unsigned long long)write_bytes); + if (out_buf_size > 0 && + (ret == 0 || (ret == -1 && errno == EPIPE))) { + if (wait_for_roaming_reconnect() != 0) { + ret = 0; + *cont = 1; + } else { + ret = -1; + errno = EAGAIN; + } + } return ret; } @@ -158,6 +168,15 @@ roaming_read(int fd, void *buf, size_t count, int *cont) if (!resume_in_progress) { read_bytes += ret; } + } else if (out_buf_size > 0 && + (ret == 0 || (ret == -1 && (errno == ECONNRESET + || errno == ECONNABORTED || errno == ETIMEDOUT + || errno == EHOSTUNREACH)))) { + debug("roaming_read failed for %d ret=%ld errno=%d", + fd, (long)ret, errno); + ret = 0; + if (wait_for_roaming_reconnect() == 0) + *cont = 1; } return ret; } @@ -199,3 +218,29 @@ resend_bytes(int fd, u_int64_t *offset) atomicio(vwrite, fd, out_buf + (out_last - needed), needed); } } + +/* + * Caclulate a new key after a reconnect + */ +void +calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) +{ + const EVP_MD *md = EVP_sha1(); + EVP_MD_CTX ctx; + char hash[EVP_MAX_MD_SIZE]; + Buffer b; + + buffer_init(&b); + buffer_put_int64(&b, *key); + buffer_put_int64(&b, cookie); + buffer_put_int64(&b, challenge); + + EVP_DigestInit(&ctx, md); + EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&ctx, hash, NULL); + + buffer_clear(&b); + buffer_append(&b, hash, EVP_MD_size(md)); + *key = buffer_get_int64(&b); + buffer_free(&b); +} -- cgit v1.2.3 From f1de4e5228ad86b191c3297bf6c528753587be5e Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 16:54:59 +1100 Subject: - andreas@cvs.openbsd.org 2009/10/24 11:23:42 [ssh.c] Request roaming to be enabled if UseRoaming is true and the server supports it. ok markus@ --- ChangeLog | 5 +++++ ssh.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d45a896bb..9f63b83b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,11 @@ Most code from Martin Forssen, maf at appgate dot com. Some changes by me and markus@ ok markus@ + - andreas@cvs.openbsd.org 2009/10/24 11:23:42 + [ssh.c] + Request roaming to be enabled if UseRoaming is true and the server + supports it. + ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/ssh.c b/ssh.c index adfe60e4b..5353e235c 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.326 2009/07/02 02:11:47 dtucker Exp $ */ +/* $OpenBSD: ssh.c,v 1.327 2009/10/24 11:23:42 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -100,6 +100,7 @@ #include "match.h" #include "msg.h" #include "uidswap.h" +#include "roaming.h" #include "version.h" #ifdef SMARTCARD @@ -1222,6 +1223,9 @@ ssh_session2(void) fatal("daemon() failed: %.200s", strerror(errno)); } + if (options.use_roaming) + request_roaming(); + return client_loop(tty_flag, tty_flag ? options.escape_char : SSH_ESCAPECHAR_NONE, id); } -- cgit v1.2.3 From 34e314da1b832fee576e4ebd8b177154a45fec15 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:03:46 +1100 Subject: - reyk@cvs.openbsd.org 2009/10/28 16:38:18 [ssh_config.5 sshd.c misc.h ssh-keyscan.1 readconf.h sshconnect.c channels.c channels.h servconf.h servconf.c ssh.1 ssh-keyscan.c scp.1 sftp.1 sshd_config.5 readconf.c ssh.c misc.c] Allow to set the rdomain in ssh/sftp/scp/sshd and ssh-keyscan. ok markus@ --- ChangeLog | 6 ++++++ channels.c | 26 +++++++++++++++++++------- channels.h | 3 ++- misc.c | 39 ++++++++++++++++++++++++++++++++++++++- misc.h | 4 +++- readconf.c | 22 +++++++++++++++++++--- readconf.h | 4 +++- scp.1 | 5 +++-- servconf.c | 11 +++++++++-- servconf.h | 4 +++- sftp.1 | 5 +++-- ssh-keyscan.1 | 7 +++++-- ssh-keyscan.c | 17 +++++++++++++---- ssh.1 | 5 +++-- ssh.c | 3 ++- ssh_config.5 | 7 +++++-- sshconnect.c | 5 +++-- sshd.c | 9 +++++---- sshd_config.5 | 7 +++++-- 19 files changed, 149 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f63b83b5..0a931a120 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,12 @@ Request roaming to be enabled if UseRoaming is true and the server supports it. ok markus@ + - reyk@cvs.openbsd.org 2009/10/28 16:38:18 + [ssh_config.5 sshd.c misc.h ssh-keyscan.1 readconf.h sshconnect.c + channels.c channels.h servconf.h servconf.c ssh.1 ssh-keyscan.c scp.1 + sftp.1 sshd_config.5 readconf.c ssh.c misc.c] + Allow to set the rdomain in ssh/sftp/scp/sshd and ssh-keyscan. + ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/channels.c b/channels.c index 22e7f628b..884c14c99 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.296 2009/05/25 06:48:00 andreas Exp $ */ +/* $OpenBSD: channels.c,v 1.297 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -162,6 +162,9 @@ static u_int x11_fake_data_len; /* AF_UNSPEC or AF_INET or AF_INET6 */ static int IPv4or6 = AF_UNSPEC; +/* Set the routing domain a.k.a. VRF */ +static int channel_rdomain = -1; + /* helper */ static void port_open_helper(Channel *c, char *rtype); @@ -2461,6 +2464,12 @@ channel_set_af(int af) IPv4or6 = af; } +void +channel_set_rdomain(int rdomain) +{ + channel_rdomain = rdomain; +} + static int channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, int *allocated_listen_port, @@ -2569,7 +2578,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, continue; } /* Create a port to listen for the host. */ - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + sock = socket_rdomain(ai->ai_family, ai->ai_socktype, + ai->ai_protocol, channel_rdomain); if (sock < 0) { /* this is no error since kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); @@ -2910,8 +2920,9 @@ connect_next(struct channel_connect *cctx) error("connect_next: getnameinfo failed"); continue; } - if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, - cctx->ai->ai_protocol)) == -1) { + if ((sock = socket_rdomain(cctx->ai->ai_family, + cctx->ai->ai_socktype, cctx->ai->ai_protocol, + channel_rdomain)) == -1) { if (cctx->ai->ai_next == NULL) error("socket: %.100s", strerror(errno)); else @@ -3097,8 +3108,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; - sock = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); + sock = socket_rdomain(ai->ai_family, ai->ai_socktype, + ai->ai_protocol, channel_rdomain); if (sock < 0) { if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { error("socket: %.100s", strerror(errno)); @@ -3273,7 +3284,8 @@ x11_connect_display(void) } for (ai = aitop; ai; ai = ai->ai_next) { /* Create a socket. */ - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + sock = socket_rdomain(ai->ai_family, ai->ai_socktype, + ai->ai_protocol, channel_rdomain); if (sock < 0) { debug2("socket: %.100s", strerror(errno)); continue; diff --git a/channels.h b/channels.h index 1488ed7e5..b0f5dc321 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.98 2009/02/12 03:00:56 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.99 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -231,6 +231,7 @@ int channel_find_open(void); /* tcp forwarding */ void channel_set_af(int af); +void channel_set_rdomain(int); void channel_permit_all_opens(void); void channel_add_permitted_opens(char *, int); int channel_add_adm_permitted_opens(char *, int); diff --git a/misc.c b/misc.c index 4dc152310..f0f1fd841 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.71 2009/02/21 19:32:04 tobias Exp $ */ +/* $OpenBSD: misc.c,v 1.72 2009/10/28 16:38:18 reyk Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -151,6 +151,43 @@ set_nodelay(int fd) error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); } +/* open a socket in the specified routing domain */ +int +socket_rdomain(int domain, int type, int protocol, int rdomain) +{ + int sock, ipproto = IPPROTO_IP; + + if ((sock = socket(domain, type, protocol)) == -1) + return (-1); + + if (rdomain == -1) + return (sock); + + switch (domain) { + case AF_INET6: + ipproto = IPPROTO_IPV6; + /* FALLTHROUGH */ + case AF_INET: + debug2("socket %d af %d setting rdomain %d", + sock, domain, rdomain); + if (setsockopt(sock, ipproto, SO_RDOMAIN, &rdomain, + sizeof(rdomain)) == -1) { + debug("setsockopt SO_RDOMAIN: %.100s", + strerror(errno)); + close(sock); + return (-1); + } + break; + default: + debug("socket %d af %d does not support rdomain %d", + sock, domain, rdomain); + close(sock); + return (-1); + } + + return (sock); +} + /* Characters considered whitespace in strsep calls. */ #define WHITESPACE " \t\r\n" #define QUOTE "\"" diff --git a/misc.h b/misc.h index e26b0aaff..87b7f0edf 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.38 2008/06/12 20:38:28 dtucker Exp $ */ +/* $OpenBSD: misc.h,v 1.39 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -54,6 +54,8 @@ void freeargs(arglist *); int tun_open(int, int); +int socket_rdomain(int, int, int, int); + /* Common definitions for ssh tunnel device forwarding */ #define SSH_TUNMODE_NO 0x00 #define SSH_TUNMODE_POINTOPOINT 0x01 diff --git a/readconf.c b/readconf.c index 4a16974b8..6b2e3b21d 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.178 2009/10/08 14:03:41 markus Exp $ */ +/* $OpenBSD: readconf.c,v 1.179 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -130,8 +130,8 @@ typedef enum { oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, - oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, - oDeprecated, oUnsupported + oVisualHostKey, oUseRoaming, oRDomain, + oZeroKnowledgePasswordAuthentication, oDeprecated, oUnsupported } OpCodes; /* Textual representations of the tokens. */ @@ -229,6 +229,7 @@ static struct { { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, { "useroaming", oUseRoaming }, + { "rdomain", oRDomain }, #ifdef JPAKE { "zeroknowledgepasswordauthentication", oZeroKnowledgePasswordAuthentication }, @@ -919,6 +920,19 @@ parse_int: intptr = &options->use_roaming; goto parse_flag; + case oRDomain: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + value = a2port(arg); + if (value == -1) + fatal("%.200s line %d: Bad rdomain.", + filename, linenum); + if (*activep) + options->rdomain = value; + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1069,6 +1083,7 @@ initialize_options(Options * options) options->local_command = NULL; options->permit_local_command = -1; options->use_roaming = -1; + options->rdomain = -1; options->visual_host_key = -1; options->zero_knowledge_password_authentication = -1; } @@ -1217,6 +1232,7 @@ fill_default_options(Options * options) /* options->hostname will be set in the main program if appropriate */ /* options->host_key_alias should not be set by default */ /* options->preferred_authentications will be set in ssh */ + /* options->rdomain should not be set by default */ } /* diff --git a/readconf.h b/readconf.h index 2ebfebe94..6edc2eeda 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.79 2009/06/27 09:35:06 andreas Exp $ */ +/* $OpenBSD: readconf.h,v 1.80 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -125,6 +125,8 @@ typedef struct { int use_roaming; + int rdomain; /* routing domain a.k.a. VRF */ + } Options; #define SSHCTL_MASTER_NO 0 diff --git a/scp.1 b/scp.1 index 5033d84f2..b9245ea53 100644 --- a/scp.1 +++ b/scp.1 @@ -9,9 +9,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.46 2008/07/12 05:33:41 djm Exp $ +.\" $OpenBSD: scp.1,v 1.47 2009/10/28 16:38:18 reyk Exp $ .\" -.Dd $Mdocdate: July 12 2008 $ +.Dd $Mdocdate: October 28 2009 $ .Dt SCP 1 .Os .Sh NAME @@ -158,6 +158,7 @@ For full details of the options listed below, and their possible values, see .It Protocol .It ProxyCommand .It PubkeyAuthentication +.It RDomain .It RekeyLimit .It RhostsRSAAuthentication .It RSAAuthentication diff --git a/servconf.c b/servconf.c index c2e5cc6f4..729f23bad 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.196 2009/10/08 14:03:41 markus Exp $ */ +/* $OpenBSD: servconf.c,v 1.197 2009/10/28 16:38:18 reyk Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -128,6 +128,7 @@ initialize_server_options(ServerOptions *options) options->adm_forced_command = NULL; options->chroot_directory = NULL; options->zero_knowledge_password_authentication = -1; + options->rdomain = -1; } void @@ -304,7 +305,7 @@ typedef enum { sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, + sUsePrivilegeSeparation, sAllowAgentForwarding, sRDomain, sZeroKnowledgePasswordAuthentication, sDeprecated, sUnsupported } ServerOpCodes; @@ -423,6 +424,7 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, + { "rdomain", sRDomain, SSHCFG_GLOBAL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1294,6 +1296,10 @@ process_server_config_line(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; + case sRDomain: + intptr = &options->rdomain; + goto parse_int; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1570,6 +1576,7 @@ dump_config(ServerOptions *o) dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); + dump_cfg_int(sRDomain, o->rdomain); /* formatted integer arguments */ dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); diff --git a/servconf.h b/servconf.h index b3ac7da4b..19c7ae609 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.87 2009/01/22 10:02:34 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.88 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -150,6 +150,8 @@ typedef struct { int num_permitted_opens; + int rdomain; + char *chroot_directory; } ServerOptions; diff --git a/sftp.1 b/sftp.1 index d1db0d6dd..b912d24e3 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.76 2009/08/19 04:56:03 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.77 2009/10/28 16:38:18 reyk Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 19 2009 $ +.Dd $Mdocdate: October 28 2009 $ .Dt SFTP 1 .Os .Sh NAME @@ -209,6 +209,7 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RekeyLimit .It RhostsRSAAuthentication +.It RDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index 4a5864566..c9fb597ed 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.26 2008/12/29 01:12:36 stevesk Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.27 2009/10/28 16:38:18 reyk Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd $Mdocdate: December 29 2008 $ +.Dd $Mdocdate: October 28 2009 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -20,6 +20,7 @@ .Op Fl p Ar port .Op Fl T Ar timeout .Op Fl t Ar type +.Op Fl V Ar rdomain .Op Ar host | addrlist namelist .Ar ... .Ek @@ -95,6 +96,8 @@ for protocol version 2. Multiple values may be specified by separating them with commas. The default is .Dq rsa . +.It Fl V Ar rdomain +Set the routing domain. .It Fl v Verbose mode. Causes diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 9a91be499..f30e85045 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.78 2009/01/22 10:02:34 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.79 2009/10/28 16:38:18 reyk Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -68,6 +68,9 @@ int timeout = 5; int maxfd; #define MAXCON (maxfd - 10) +/* The default routing domain */ +int scan_rdomain = -1; + extern char *__progname; fd_set *read_wait; size_t read_wait_nfdset; @@ -412,7 +415,8 @@ tcpconnect(char *host) if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); for (ai = aitop; ai; ai = ai->ai_next) { - s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + s = socket_rdomain(ai->ai_family, ai->ai_socktype, + ai->ai_protocol, scan_rdomain); if (s < 0) { error("socket: %s", strerror(errno)); continue; @@ -715,7 +719,7 @@ usage(void) { fprintf(stderr, "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n" - "\t\t [host | addrlist namelist] ...\n", + "\t\t [-V rdomain] [host | addrlist namelist] ...\n", __progname); exit(1); } @@ -741,7 +745,7 @@ main(int argc, char **argv) if (argc <= 1) usage(); - while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) { + while ((opt = getopt(argc, argv, "Hv46p:T:t:f:V:")) != -1) { switch (opt) { case 'H': hash_hosts = 1; @@ -802,6 +806,11 @@ main(int argc, char **argv) case '6': IPv4or6 = AF_INET6; break; + case 'V': + scan_rdomain = a2port(optarg); + if (scan_rdomain < 0) + scan_rdomain = -1; + break; case '?': default: usage(); diff --git a/ssh.1 b/ssh.1 index 7e7f64e46..8277d0fdf 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.286 2009/10/22 15:02:12 sobrado Exp $ -.Dd $Mdocdate: October 22 2009 $ +.\" $OpenBSD: ssh.1,v 1.287 2009/10/28 16:38:18 reyk Exp $ +.Dd $Mdocdate: October 28 2009 $ .Dt SSH 1 .Os .Sh NAME @@ -475,6 +475,7 @@ For full details of the options listed below, and their possible values, see .It Protocol .It ProxyCommand .It PubkeyAuthentication +.It RDomain .It RekeyLimit .It RemoteForward .It RhostsRSAAuthentication diff --git a/ssh.c b/ssh.c index 5353e235c..90dbc69e9 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.327 2009/10/24 11:23:42 andreas Exp $ */ +/* $OpenBSD: ssh.c,v 1.328 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -630,6 +630,7 @@ main(int ac, char **av) fill_default_options(&options); channel_set_af(options.address_family); + channel_set_rdomain(options.rdomain); /* reinit */ log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); diff --git a/ssh_config.5 b/ssh_config.5 index 89f3896e6..fde899477 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.121 2009/10/08 20:42:13 jmc Exp $ -.Dd $Mdocdate: October 8 2009 $ +.\" $OpenBSD: ssh_config.5,v 1.122 2009/10/28 16:38:18 reyk Exp $ +.Dd $Mdocdate: October 28 2009 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -782,6 +782,9 @@ or The default is .Dq yes . This option applies to protocol version 2 only. +.It Cm RDomain +Set the routing domain number. +The default routing domain is set by the system. .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated. diff --git a/sshconnect.c b/sshconnect.c index 3e57e859d..a09026e65 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.214 2009/05/28 16:50:16 andreas Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.215 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -190,7 +190,8 @@ ssh_create_socket(int privileged, struct addrinfo *ai) debug("Allocated local port %d.", p); return sock; } - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + sock = socket_rdomain(ai->ai_family, ai->ai_socktype, ai->ai_protocol, + options.rdomain); if (sock < 0) error("socket: %.100s", strerror(errno)); diff --git a/sshd.c b/sshd.c index 38aaa1820..e23d462ee 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.367 2009/05/28 16:50:16 andreas Exp $ */ +/* $OpenBSD: sshd.c,v 1.368 2009/10/28 16:38:18 reyk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -960,8 +960,8 @@ server_listen(void) continue; } /* Create socket for listening. */ - listen_sock = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); + listen_sock = socket_rdomain(ai->ai_family, ai->ai_socktype, + ai->ai_protocol, options.rdomain); if (listen_sock < 0) { /* kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); @@ -1469,8 +1469,9 @@ main(int ac, char **av) if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; - /* set default channel AF */ + /* set default channel AF and routing domain */ channel_set_af(options.address_family); + channel_set_rdomain(options.rdomain); /* Check that there are no remaining arguments. */ if (optind < ac) { diff --git a/sshd_config.5 b/sshd_config.5 index 4b3793d13..1a30f29c1 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.109 2009/10/08 20:42:13 jmc Exp $ -.Dd $Mdocdate: October 8 2009 $ +.\" $OpenBSD: sshd_config.5,v 1.110 2009/10/28 16:38:18 reyk Exp $ +.Dd $Mdocdate: October 28 2009 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -812,6 +812,9 @@ with successful RSA host authentication is allowed. The default is .Dq no . This option applies to protocol version 1 only. +.It Cm RDomain +Set the routing domain number. +The default routing domain is set by the system. .It Cm RSAAuthentication Specifies whether pure RSA authentication is allowed. The default is -- cgit v1.2.3 From cc117f0deb26a3491aa90614974517ac2f18dc45 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:05:26 +1100 Subject: - jmc@cvs.openbsd.org 2009/10/28 21:45:08 [sshd_config.5 sftp.1] tweak previous; --- ChangeLog | 3 +++ sftp.1 | 4 ++-- sshd_config.5 | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a931a120..35c116484 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,9 @@ sftp.1 sshd_config.5 readconf.c ssh.c misc.c] Allow to set the rdomain in ssh/sftp/scp/sshd and ssh-keyscan. ok markus@ + - jmc@cvs.openbsd.org 2009/10/28 21:45:08 + [sshd_config.5 sftp.1] + tweak previous; 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp.1 b/sftp.1 index b912d24e3..ab53c1690 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.77 2009/10/28 16:38:18 reyk Exp $ +.\" $OpenBSD: sftp.1,v 1.78 2009/10/28 21:45:08 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -207,9 +207,9 @@ For full details of the options listed below, and their possible values, see .It Protocol .It ProxyCommand .It PubkeyAuthentication +.It RDomain .It RekeyLimit .It RhostsRSAAuthentication -.It RDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/sshd_config.5 b/sshd_config.5 index 1a30f29c1..7e7c6f855 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.110 2009/10/28 16:38:18 reyk Exp $ +.\" $OpenBSD: sshd_config.5,v 1.111 2009/10/28 21:45:08 jmc Exp $ .Dd $Mdocdate: October 28 2009 $ .Dt SSHD_CONFIG 5 .Os @@ -806,15 +806,15 @@ Specifies whether public key authentication is allowed. The default is .Dq yes . Note that this option applies to protocol version 2 only. +.It Cm RDomain +Set the routing domain number. +The default routing domain is set by the system. .It Cm RhostsRSAAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful RSA host authentication is allowed. The default is .Dq no . This option applies to protocol version 1 only. -.It Cm RDomain -Set the routing domain number. -The default routing domain is set by the system. .It Cm RSAAuthentication Specifies whether pure RSA authentication is allowed. The default is -- cgit v1.2.3 From 78be8c54d65e151a3d8a5855ce5067c72f915799 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:05:59 +1100 Subject: - djm@cvs.openbsd.org 2009/11/10 02:56:22 [ssh_config.5] explain the constraints on LocalCommand some more so people don't try to abuse it. --- ChangeLog | 4 ++++ ssh_config.5 | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35c116484..712a9caf5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,10 @@ - jmc@cvs.openbsd.org 2009/10/28 21:45:08 [sshd_config.5 sftp.1] tweak previous; + - djm@cvs.openbsd.org 2009/11/10 02:56:22 + [ssh_config.5] + explain the constraints on LocalCommand some more so people don't + try to abuse it. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/ssh_config.5 b/ssh_config.5 index fde899477..001130936 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.122 2009/10/28 16:38:18 reyk Exp $ -.Dd $Mdocdate: October 28 2009 $ +.\" $OpenBSD: ssh_config.5,v 1.123 2009/11/10 02:56:22 djm Exp $ +.Dd $Mdocdate: November 10 2009 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -616,6 +616,13 @@ The following escape character substitutions will be performed: (remote user name) or .Ql %u (local user name). +.Pp +The command is run synchronously and does not have access to the +session of the +.Xr ssh 1 +that spawned it. +It should not be used for interactive commands. +.Pp This directive is ignored unless .Cm PermitLocalCommand has been enabled. -- cgit v1.2.3 From f788a91624601857c586a4dd97c66083946e7781 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:06:47 +1100 Subject: - djm@cvs.openbsd.org 2009/11/10 02:58:56 [sshd_config.5] clarify that StrictModes does not apply to ChrootDirectory. Permissions and ownership are always checked when chrooting. bz#1532 --- ChangeLog | 4 ++++ sshd_config.5 | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 712a9caf5..604b5d773 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,10 @@ [ssh_config.5] explain the constraints on LocalCommand some more so people don't try to abuse it. + - djm@cvs.openbsd.org 2009/11/10 02:58:56 + [sshd_config.5] + clarify that StrictModes does not apply to ChrootDirectory. Permissions + and ownership are always checked when chrooting. bz#1532 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sshd_config.5 b/sshd_config.5 index 7e7c6f855..e54e70079 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.111 2009/10/28 21:45:08 jmc Exp $ -.Dd $Mdocdate: October 28 2009 $ +.\" $OpenBSD: sshd_config.5,v 1.112 2009/11/10 02:58:56 djm Exp $ +.Dd $Mdocdate: November 10 2009 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -832,6 +832,9 @@ This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. The default is .Dq yes . +Note that this does not apply to +.Cm ChrootDirectory , +whose permissions and ownership are checked unconditionally. .It Cm Subsystem Configures an external subsystem (e.g. file transfer daemon). Arguments should be a subsystem name and a command (with optional arguments) -- cgit v1.2.3 From 6e7fe1c01b8a69099ffc42e653cc478509e84781 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:07:22 +1100 Subject: - dtucker@cvs.openbsd.org 2009/11/10 04:30:45 [sshconnect2.c channels.c sshconnect.c] Set close-on-exec on various descriptors so they don't get leaked to child processes. bz #1643, patch from jchadima at redhat, ok deraadt. --- ChangeLog | 4 ++++ channels.c | 10 ++++++++-- sshconnect.c | 8 ++++++-- sshconnect2.c | 5 ++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 604b5d773..a2cee09d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,10 @@ [sshd_config.5] clarify that StrictModes does not apply to ChrootDirectory. Permissions and ownership are always checked when chrooting. bz#1532 + - dtucker@cvs.openbsd.org 2009/11/10 04:30:45 + [sshconnect2.c channels.c sshconnect.c] + Set close-on-exec on various descriptors so they don't get leaked to + child processes. bz #1643, patch from jchadima at redhat, ok deraadt. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/channels.c b/channels.c index 884c14c99..eb0c61d8b 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.297 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: channels.c,v 1.298 2009/11/10 04:30:44 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -231,7 +232,12 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, channel_max_fd = MAX(channel_max_fd, wfd); channel_max_fd = MAX(channel_max_fd, efd); - /* XXX set close-on-exec -markus */ + if (rfd != -1) + fcntl(rfd, F_SETFD, FD_CLOEXEC); + if (wfd != -1 && wfd != rfd) + fcntl(wfd, F_SETFD, FD_CLOEXEC); + if (efd != -1 && efd != rfd && efd != wfd) + fcntl(efd, F_SETFD, FD_CLOEXEC); c->rfd = rfd; c->wfd = wfd; diff --git a/sshconnect.c b/sshconnect.c index a09026e65..3c8308ffb 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.215 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.216 2009/11/10 04:30:45 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -28,6 +28,7 @@ #include #include +#include #include #ifdef HAVE_PATHS_H #include @@ -192,8 +193,11 @@ ssh_create_socket(int privileged, struct addrinfo *ai) } sock = socket_rdomain(ai->ai_family, ai->ai_socktype, ai->ai_protocol, options.rdomain); - if (sock < 0) + if (sock < 0) { error("socket: %.100s", strerror(errno)); + return -1; + } + fcntl(sock, F_SETFD, FD_CLOEXEC); /* Bind the socket to an alternative local IP address */ if (options.bind_address == NULL) diff --git a/sshconnect2.c b/sshconnect2.c index 937bb773d..299d4f4e3 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.173 2009/10/24 11:13:54 andreas Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.174 2009/11/10 04:30:45 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -1527,6 +1528,8 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, return -1; } if (pid == 0) { + /* keep the socket on exec */ + fcntl(packet_get_connection_in(), F_SETFD, 0); permanently_drop_suid(getuid()); close(from[0]); if (dup2(from[1], STDOUT_FILENO) < 0) -- cgit v1.2.3 From 876045b0fb273ee11b02c535833b076c875253dc Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:08:00 +1100 Subject: - markus@cvs.openbsd.org 2009/11/11 21:37:03 [channels.c channels.h] fix race condition in x11/agent channel allocation: don't read after the end of the select read/write fdset and make sure a reused FD is not touched before the pre-handlers are called. with and ok djm@ --- ChangeLog | 6 ++++++ channels.c | 26 +++++++++++--------------- channels.h | 8 ++++++-- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2cee09d5..96e338c00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -51,6 +51,12 @@ [sshconnect2.c channels.c sshconnect.c] Set close-on-exec on various descriptors so they don't get leaked to child processes. bz #1643, patch from jchadima at redhat, ok deraadt. + - markus@cvs.openbsd.org 2009/11/11 21:37:03 + [channels.c channels.h] + fix race condition in x11/agent channel allocation: don't read after + the end of the select read/write fdset and make sure a reused FD + is not touched before the pre-handlers are called. + with and ok djm@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/channels.c b/channels.c index eb0c61d8b..949392390 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.298 2009/11/10 04:30:44 dtucker Exp $ */ +/* $OpenBSD: channels.c,v 1.299 2009/11/11 21:37:03 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -331,6 +331,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->output_filter = NULL; c->filter_ctx = NULL; c->filter_cleanup = NULL; + c->delayed = 1; /* prevent call to channel_post handler */ TAILQ_INIT(&c->status_confirms); debug("channel %d: new [%s]", found, remote_name); return c; @@ -1228,7 +1229,6 @@ channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) int ret; have = buffer_len(&c->input); - c->delayed = 0; debug2("channel %d: pre_dynamic: have %d", c->self, have); /* buffer_dump(&c->input); */ /* check if the fixed size part of the packet is in buffer. */ @@ -1432,16 +1432,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) if (c->path != NULL) nc->path = xstrdup(c->path); - if (nextstate == SSH_CHANNEL_DYNAMIC) { - /* - * do not call the channel_post handler until - * this flag has been reset by a pre-handler. - * otherwise the FD_ISSET calls might overflow - */ - nc->delayed = 1; - } else { + if (nextstate != SSH_CHANNEL_DYNAMIC) port_open_helper(nc, rtype); - } } } @@ -1786,8 +1778,6 @@ channel_check_window(Channel *c) static void channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) { - if (c->delayed) - return; channel_handle_rfd(c, readset, writeset); channel_handle_wfd(c, readset, writeset); if (!compat20) @@ -1919,17 +1909,23 @@ static void channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset) { static int did_init = 0; - u_int i; + u_int i, oalloc; Channel *c; if (!did_init) { channel_handler_init(); did_init = 1; } - for (i = 0; i < channels_alloc; i++) { + for (i = 0, oalloc = channels_alloc; i < oalloc; i++) { c = channels[i]; if (c == NULL) continue; + if (c->delayed) { + if (ftab == channel_pre) + c->delayed = 0; + else + continue; + } if (ftab[c->type] != NULL) (*ftab[c->type])(c, readset, writeset); channel_garbage_collect(c); diff --git a/channels.h b/channels.h index b0f5dc321..4dbeeb6e1 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.99 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: channels.h,v 1.100 2009/11/11 21:37:03 markus Exp $ */ /* * Author: Tatu Ylonen @@ -97,7 +97,11 @@ struct Channel { int wfd_isatty; /* wfd is a tty */ int client_tty; /* (client) TTY has been requested */ int force_drain; /* force close on iEOF */ - int delayed; /* fdset hack */ + int delayed; /* post-select handlers for newly created + * channels are delayed until the first call + * to a matching pre-select handler. + * this way post-select handlers are not + * accidenly called if a FD gets reused */ Buffer input; /* data read from socket, to be sent over * encrypted connection */ Buffer output; /* data received over encrypted connection for -- cgit v1.2.3 From 2944082b3f84b5260a748a529f90cd18a6187610 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:08:35 +1100 Subject: - djm@cvs.openbsd.org 2009/11/17 05:31:44 [clientloop.c] fix incorrect exit status when multiplexing and channel ID 0 is recycled bz#1570 reported by peter.oliver AT eon-is.co.uk; ok dtucker --- ChangeLog | 4 ++++ clientloop.c | 14 ++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96e338c00..72d5a21e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -57,6 +57,10 @@ the end of the select read/write fdset and make sure a reused FD is not touched before the pre-handlers are called. with and ok djm@ + - djm@cvs.openbsd.org 2009/11/17 05:31:44 + [clientloop.c] + fix incorrect exit status when multiplexing and channel ID 0 is recycled + bz#1570 reported by peter.oliver AT eon-is.co.uk; ok dtucker 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/clientloop.c b/clientloop.c index 540a6181a..eca87777f 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.214 2009/10/24 11:15:29 andreas Exp $ */ +/* $OpenBSD: clientloop.c,v 1.215 2009/11/17 05:31:44 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1856,15 +1856,17 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) chan_rcvd_eow(c); } else if (strcmp(rtype, "exit-status") == 0) { exitval = packet_get_int(); - if (id == session_ident) { + if (c->ctl_fd != -1) { + /* Dispatch to mux client */ + atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval)); + success = 1; + } else if (id == session_ident) { + /* Record exit value of local session */ success = 1; exit_status = exitval; - } else if (c->ctl_fd == -1) { + } else { error("client_input_channel_req: unexpected channel %d", session_ident); - } else { - atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval)); - success = 1; } packet_check_eom(); } -- cgit v1.2.3 From d6b06a9f39cde8708a7c6b276635cdea5dcd3820 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:09:11 +1100 Subject: - djm@cvs.openbsd.org 2009/11/19 23:39:50 [session.c] bz#1606: error when an attempt is made to connect to a server with ForceCommand=internal-sftp with a shell session (i.e. not a subsystem session). Avoids stuck client when attempting to ssh to such a service. ok dtucker@ --- ChangeLog | 6 ++++++ session.c | 29 ++++++++++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 72d5a21e1..0ece9c09d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -61,6 +61,12 @@ [clientloop.c] fix incorrect exit status when multiplexing and channel ID 0 is recycled bz#1570 reported by peter.oliver AT eon-is.co.uk; ok dtucker + - djm@cvs.openbsd.org 2009/11/19 23:39:50 + [session.c] + bz#1606: error when an attempt is made to connect to a server + with ForceCommand=internal-sftp with a shell session (i.e. not a + subsystem session). Avoids stuck client when attempting to ssh to such a + service. ok dtucker@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/session.c b/session.c index 78192314a..cc205386f 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.247 2009/10/06 04:46:40 djm Exp $ */ +/* $OpenBSD: session.c,v 1.248 2009/11/19 23:39:50 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -142,9 +142,10 @@ static int sessions_first_unused = -1; static int sessions_nalloc = 0; static Session *sessions = NULL; -#define SUBSYSTEM_NONE 0 -#define SUBSYSTEM_EXT 1 -#define SUBSYSTEM_INT_SFTP 2 +#define SUBSYSTEM_NONE 0 +#define SUBSYSTEM_EXT 1 +#define SUBSYSTEM_INT_SFTP 2 +#define SUBSYSTEM_INT_SFTP_ERROR 3 #ifdef HAVE_LOGIN_CAP login_cap_t *lc; @@ -785,17 +786,19 @@ do_exec(Session *s, const char *command) if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; - if (IS_INTERNAL_SFTP(command)) - s->is_subsystem = SUBSYSTEM_INT_SFTP; - else if (s->is_subsystem) + if (IS_INTERNAL_SFTP(command)) { + s->is_subsystem = s->is_subsystem ? + SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; + } else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (config) '%.900s'", command); } else if (forced_command) { original_command = command; command = forced_command; - if (IS_INTERNAL_SFTP(command)) - s->is_subsystem = SUBSYSTEM_INT_SFTP; - else if (s->is_subsystem) + if (IS_INTERNAL_SFTP(command)) { + s->is_subsystem = s->is_subsystem ? + SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; + } else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (key option) '%.900s'", command); } @@ -1783,7 +1786,11 @@ do_child(Session *s, const char *command) /* restore SIGPIPE for child */ signal(SIGPIPE, SIG_DFL); - if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { + if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { + printf("This service allows sftp connections only.\n"); + fflush(NULL); + exit(1); + } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { extern int optind, optreset; int i; char *p, *args; -- cgit v1.2.3 From c3dc404113c4bb3d3a86bdee47f15e5c881d12a4 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:09:50 +1100 Subject: - dtucker@cvs.openbsd.org 2009/11/20 00:15:41 [session.c] Warn but do not fail if stat()ing the subsystem binary fails. This helps with chrootdirectory+forcecommand=sftp-server and restricted shells. bz #1599, ok djm. --- ChangeLog | 5 +++++ session.c | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ece9c09d..16b9c133a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -67,6 +67,11 @@ with ForceCommand=internal-sftp with a shell session (i.e. not a subsystem session). Avoids stuck client when attempting to ssh to such a service. ok dtucker@ + - dtucker@cvs.openbsd.org 2009/11/20 00:15:41 + [session.c] + Warn but do not fail if stat()ing the subsystem binary fails. This helps + with chrootdirectory+forcecommand=sftp-server and restricted shells. + bz #1599, ok djm. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/session.c b/session.c index cc205386f..733b5a909 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.248 2009/11/19 23:39:50 djm Exp $ */ +/* $OpenBSD: session.c,v 1.249 2009/11/20 00:15:41 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -2121,16 +2121,16 @@ session_subsystem_req(Session *s) if (strcmp(subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; - if (!strcmp(INTERNAL_SFTP_NAME, prog)) { + if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) { s->is_subsystem = SUBSYSTEM_INT_SFTP; - } else if (stat(prog, &st) < 0) { - error("subsystem: cannot stat %s: %s", prog, - strerror(errno)); - break; + debug("subsystem: %s", prog); } else { + if (stat(prog, &st) < 0) + debug("subsystem: cannot stat %s: %s", + prog, strerror(errno)); s->is_subsystem = SUBSYSTEM_EXT; + debug("subsystem: exec() %s", cmd); } - debug("subsystem: exec() %s", cmd); success = do_exec(s, cmd) == 0; break; } -- cgit v1.2.3 From 210631922f86192e99aefe6cf985155d61f44965 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 17:10:36 +1100 Subject: - djm@cvs.openbsd.org 2009/11/20 00:54:01 [sftp.c] bz#1588 change "Connecting to host..." message to "Connected to host." and delay it until after the sftp protocol connection has been established. Avoids confusing sequence of messages when the underlying ssh connection experiences problems. ok dtucker@ --- ChangeLog | 6 ++++++ sftp.c | 40 +++++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16b9c133a..6494edc0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -72,6 +72,12 @@ Warn but do not fail if stat()ing the subsystem binary fails. This helps with chrootdirectory+forcecommand=sftp-server and restricted shells. bz #1599, ok djm. + - djm@cvs.openbsd.org 2009/11/20 00:54:01 + [sftp.c] + bz#1588 change "Connecting to host..." message to "Connected to host." + and delay it until after the sftp protocol connection has been established. + Avoids confusing sequence of messages when the underlying ssh connection + experiences problems. ok dtucker@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp.c b/sftp.c index 75b16b27e..85e5505b5 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.111 2009/08/18 18:36:21 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.112 2009/11/20 00:54:01 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -68,18 +68,15 @@ typedef void EditLine; #include "sftp-common.h" #include "sftp-client.h" +#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */ +#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */ + /* File to read commands from */ FILE* infile; /* Are we in batchfile mode? */ int batchmode = 0; -/* Size of buffer used when copying files */ -size_t copy_buffer_len = 32768; - -/* Number of concurrent outstanding requests */ -size_t num_requests = 64; - /* PID of ssh transport process */ static pid_t sshpid = -1; @@ -187,7 +184,7 @@ static const struct CMD cmds[] = { { NULL, -1} }; -int interactive_loop(int fd_in, int fd_out, char *file1, char *file2); +int interactive_loop(struct sftp_conn *, char *file1, char *file2); /* ARGSUSED */ static void @@ -1472,12 +1469,11 @@ prompt(EditLine *el) #endif int -interactive_loop(int fd_in, int fd_out, char *file1, char *file2) +interactive_loop(struct sftp_conn *conn, char *file1, char *file2) { char *pwd; char *dir = NULL; char cmd[2048]; - struct sftp_conn *conn; int err, interactive; EditLine *el = NULL; #ifdef USE_LIBEDIT @@ -1501,10 +1497,6 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2) } #endif /* USE_LIBEDIT */ - conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests); - if (conn == NULL) - fatal("Couldn't initialise connection to server"); - pwd = do_realpath(conn, "."); if (pwd == NULL) fatal("Need cwd"); @@ -1694,6 +1686,9 @@ main(int argc, char **argv) arglist args; extern int optind; extern char *optarg; + struct sftp_conn *conn; + size_t copy_buffer_len = DEFAULT_COPY_BUFLEN; + size_t num_requests = DEFAULT_NUM_REQUESTS; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -1837,20 +1832,27 @@ main(int argc, char **argv) addargs(&args, "%s", (sftp_server != NULL ? sftp_server : "sftp")); - if (!batchmode) - fprintf(stderr, "Connecting to %s...\n", host); connect_to_server(ssh_program, args.list, &in, &out); } else { args.list = NULL; addargs(&args, "sftp-server"); - if (!batchmode) - fprintf(stderr, "Attaching to %s...\n", sftp_direct); connect_to_server(sftp_direct, args.list, &in, &out); } freeargs(&args); - err = interactive_loop(in, out, file1, file2); + conn = do_init(in, out, copy_buffer_len, num_requests); + if (conn == NULL) + fatal("Couldn't initialise connection to server"); + + if (!batchmode) { + if (sftp_direct == NULL) + fprintf(stderr, "Connected to %s.\n", host); + else + fprintf(stderr, "Attached to %s.\n", sftp_direct); + } + + err = interactive_loop(conn, file1, file2); #if !defined(USE_PIPES) shutdown(in, SHUT_RDWR); -- cgit v1.2.3 From ab79169e2971ca4c9f98e0a98ac9f0e797b5eb18 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:48:02 +1100 Subject: - dtucker@cvs.openbsd.org 2009/11/20 00:59:36 [sshconnect2.c] Use the HostKeyAlias when prompting for passwords. bz#1039, ok djm@ --- ChangeLog | 3 +++ sshconnect2.c | 14 +++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6494edc0f..b677213f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -78,6 +78,9 @@ and delay it until after the sftp protocol connection has been established. Avoids confusing sequence of messages when the underlying ssh connection experiences problems. ok dtucker@ + - dtucker@cvs.openbsd.org 2009/11/20 00:59:36 + [sshconnect2.c] + Use the HostKeyAlias when prompting for passwords. bz#1039, ok djm@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sshconnect2.c b/sshconnect2.c index 299d4f4e3..378526bac 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.174 2009/11/10 04:30:45 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.175 2009/11/20 00:59:36 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -804,6 +804,8 @@ userauth_passwd(Authctxt *authctxt) static int attempt = 0; char prompt[150]; char *password; + const char *host = options.host_key_alias ? options.host_key_alias : + authctxt->host; if (attempt++ >= options.number_of_password_prompts) return 0; @@ -812,7 +814,7 @@ userauth_passwd(Authctxt *authctxt) error("Permission denied, please try again."); snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", - authctxt->server_user, authctxt->host); + authctxt->server_user, host); password = read_passphrase(prompt, 0); packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); @@ -841,6 +843,8 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) Authctxt *authctxt = ctxt; char *info, *lang, *password = NULL, *retype = NULL; char prompt[150]; + const char *host = options.host_key_alias ? options.host_key_alias : + authctxt->host; debug2("input_userauth_passwd_changereq"); @@ -861,7 +865,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) packet_put_char(1); /* additional info */ snprintf(prompt, sizeof(prompt), "Enter %.30s@%.128s's old password: ", - authctxt->server_user, authctxt->host); + authctxt->server_user, host); password = read_passphrase(prompt, 0); packet_put_cstring(password); memset(password, 0, strlen(password)); @@ -870,7 +874,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) while (password == NULL) { snprintf(prompt, sizeof(prompt), "Enter %.30s@%.128s's new password: ", - authctxt->server_user, authctxt->host); + authctxt->server_user, host); password = read_passphrase(prompt, RP_ALLOW_EOF); if (password == NULL) { /* bail out */ @@ -878,7 +882,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) } snprintf(prompt, sizeof(prompt), "Retype %.30s@%.128s's new password: ", - authctxt->server_user, authctxt->host); + authctxt->server_user, host); retype = read_passphrase(prompt, 0); if (strcmp(password, retype) != 0) { memset(password, 0, strlen(password)); -- cgit v1.2.3 From 70d87693f4880c7acd6f50bf2aa8697b722024e7 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:49:16 +1100 Subject: - djm@cvs.openbsd.org 2009/11/20 03:24:07 [misc.c] correct off-by-one in percent_expand(): we would fatal() when trying to expand EXPAND_MAX_KEYS, allowing only EXPAND_MAX_KEYS-1 to actually work. Note that nothing in OpenSSH actually uses close to this limit at present. bz#1607 from Jan.Pechanec AT Sun.COM --- ChangeLog | 6 ++++++ misc.c | 18 +++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index b677213f8..7a2a0e322 100644 --- a/ChangeLog +++ b/ChangeLog @@ -81,6 +81,12 @@ - dtucker@cvs.openbsd.org 2009/11/20 00:59:36 [sshconnect2.c] Use the HostKeyAlias when prompting for passwords. bz#1039, ok djm@ + - djm@cvs.openbsd.org 2009/11/20 03:24:07 + [misc.c] + correct off-by-one in percent_expand(): we would fatal() when trying + to expand EXPAND_MAX_KEYS, allowing only EXPAND_MAX_KEYS-1 to actually + work. Note that nothing in OpenSSH actually uses close to this limit at + present. bz#1607 from Jan.Pechanec AT Sun.COM 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/misc.c b/misc.c index f0f1fd841..21db00a13 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.72 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: misc.c,v 1.73 2009/11/20 03:24:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -597,11 +597,11 @@ char * percent_expand(const char *string, ...) { #define EXPAND_MAX_KEYS 16 + u_int num_keys, i, j; struct { const char *key; const char *repl; } keys[EXPAND_MAX_KEYS]; - u_int num_keys, i, j; char buf[4096]; va_list ap; @@ -613,13 +613,12 @@ percent_expand(const char *string, ...) break; keys[num_keys].repl = va_arg(ap, char *); if (keys[num_keys].repl == NULL) - fatal("percent_expand: NULL replacement"); + fatal("%s: NULL replacement", __func__); } + if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) + fatal("%s: too many keys", __func__); va_end(ap); - if (num_keys >= EXPAND_MAX_KEYS) - fatal("percent_expand: too many keys"); - /* Expand string */ *buf = '\0'; for (i = 0; *string != '\0'; string++) { @@ -627,23 +626,24 @@ percent_expand(const char *string, ...) append: buf[i++] = *string; if (i >= sizeof(buf)) - fatal("percent_expand: string too long"); + fatal("%s: string too long", __func__); buf[i] = '\0'; continue; } string++; + /* %% case */ if (*string == '%') goto append; for (j = 0; j < num_keys; j++) { if (strchr(keys[j].key, *string) != NULL) { i = strlcat(buf, keys[j].repl, sizeof(buf)); if (i >= sizeof(buf)) - fatal("percent_expand: string too long"); + fatal("%s: string too long", __func__); break; } } if (j >= num_keys) - fatal("percent_expand: unknown key %%%c", *string); + fatal("%s: unknown key %%%c", __func__, *string); } return (xstrdup(buf)); #undef EXPAND_MAX_KEYS -- cgit v1.2.3 From c4dc4f5bac9e19a99a4d391e98d012c94c647ca4 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:50:04 +1100 Subject: - halex@cvs.openbsd.org 2009/11/22 13:18:00 [sftp.c] make passing of zero-length arguments to ssh safe by passing "-" "" rather than "-" ok dtucker@, guenther@, djm@ --- ChangeLog | 5 +++++ sftp.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7a2a0e322..6d6dacd88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -87,6 +87,11 @@ to expand EXPAND_MAX_KEYS, allowing only EXPAND_MAX_KEYS-1 to actually work. Note that nothing in OpenSSH actually uses close to this limit at present. bz#1607 from Jan.Pechanec AT Sun.COM + - halex@cvs.openbsd.org 2009/11/22 13:18:00 + [sftp.c] + make passing of zero-length arguments to ssh safe by + passing "-" "" rather than "-" + ok dtucker@, guenther@, djm@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp.c b/sftp.c index 85e5505b5..2ce7cc1e1 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.112 2009/11/20 00:54:01 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.113 2009/11/22 13:18:00 halex Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1719,7 +1719,8 @@ main(int argc, char **argv) case 'c': case 'i': case 'o': - addargs(&args, "-%c%s", ch, optarg); + addargs(&args, "-%c", ch); + addargs(&args, "%s", optarg); break; case 'q': showprogress = 0; -- cgit v1.2.3 From 5246df47a4e01fb4c17c672fea31f041c88205e9 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:50:46 +1100 Subject: - dtucker@cvs.openbsd.org 2009/12/06 23:41:15 [sshconnect2.c] zap unused variable and strlen; from Steve McClellan, ok djm --- ChangeLog | 3 +++ sshconnect2.c | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d6dacd88..bf909dc3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -92,6 +92,9 @@ make passing of zero-length arguments to ssh safe by passing "-" "" rather than "-" ok dtucker@, guenther@, djm@ + - dtucker@cvs.openbsd.org 2009/12/06 23:41:15 + [sshconnect2.c] + zap unused variable and strlen; from Steve McClellan, ok djm 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sshconnect2.c b/sshconnect2.c index 378526bac..d428ac65f 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.175 2009/11/20 00:59:36 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.176 2009/12/06 23:41:15 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -1589,7 +1589,7 @@ userauth_hostbased(Authctxt *authctxt) char *chost, *pkalg, *p, myname[NI_MAXHOST]; const char *service; u_int blen, slen; - int ok, i, len, found = 0; + int ok, i, found = 0; /* check for a useful key */ for (i = 0; i < sensitive->nkeys; i++) { @@ -1626,7 +1626,6 @@ userauth_hostbased(Authctxt *authctxt) xfree(blob); return 0; } - len = strlen(p) + 2; xasprintf(&chost, "%s.", p); debug2("userauth_hostbased: chost %s", chost); xfree(p); -- cgit v1.2.3 From 75694dbe77c56c127a2d2cfd443a0d591f441a55 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:51:14 +1100 Subject: - djm@cvs.openbsd.org 2009/12/06 23:53:45 [roaming_common.c] use socklen_t for getsockopt optlen parameter; reported by Steve.McClellan AT radisys.com, ok dtucker@ --- ChangeLog | 4 ++++ roaming_common.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf909dc3d..94fb34c3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -95,6 +95,10 @@ - dtucker@cvs.openbsd.org 2009/12/06 23:41:15 [sshconnect2.c] zap unused variable and strlen; from Steve McClellan, ok djm + - djm@cvs.openbsd.org 2009/12/06 23:53:45 + [roaming_common.c] + use socklen_t for getsockopt optlen parameter; reported by + Steve.McClellan AT radisys.com, ok dtucker@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/roaming_common.c b/roaming_common.c index 272deade3..3885a0368 100644 --- a/roaming_common.c +++ b/roaming_common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_common.c,v 1.6 2009/10/24 11:22:37 andreas Exp $ */ +/* $OpenBSD: roaming_common.c,v 1.7 2009/12/06 23:53:45 djm Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -52,9 +52,9 @@ int get_snd_buf_size() { int fd = packet_get_connection_out(); - int optval, optvallen; + int optval; + socklen_t optvallen = sizeof(optval); - optvallen = sizeof(optval); if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0) optval = DEFAULT_ROAMBUF; return optval; @@ -64,9 +64,9 @@ int get_recv_buf_size() { int fd = packet_get_connection_in(); - int optval, optvallen; + int optval; + socklen_t optvallen = sizeof(optval); - optvallen = sizeof(optval); if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0) optval = DEFAULT_ROAMBUF; return optval; -- cgit v1.2.3 From b5082e90a13c9c9f96f1aed894f70f6f00737396 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:51:47 +1100 Subject: - dtucker@cvs.openbsd.org 2009/12/06 23:53:54 [sftp.c] fix potential divide-by-zero in sftp's "df" output when talking to a server that reports zero files on the filesystem (Unix filesystems always have at least the root inode). From Steve McClellan at radisys, ok djm@ --- ChangeLog | 5 +++++ sftp.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 94fb34c3b..cb64d640e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -99,6 +99,11 @@ [roaming_common.c] use socklen_t for getsockopt optlen parameter; reported by Steve.McClellan AT radisys.com, ok dtucker@ + - dtucker@cvs.openbsd.org 2009/12/06 23:53:54 + [sftp.c] + fix potential divide-by-zero in sftp's "df" output when talking to a server + that reports zero files on the filesystem (Unix filesystems always have at + least the root inode). From Steve McClellan at radisys, ok djm@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp.c b/sftp.c index 2ce7cc1e1..1aa37423c 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.113 2009/11/22 13:18:00 halex Exp $ */ +/* $OpenBSD: sftp.c,v 1.114 2009/12/06 23:53:54 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -846,19 +846,19 @@ do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) char s_avail[FMT_SCALED_STRSIZE]; char s_root[FMT_SCALED_STRSIZE]; char s_total[FMT_SCALED_STRSIZE]; + unsigned long long ffree; if (do_statvfs(conn, path, &st, 1) == -1) return -1; if (iflag) { + ffree = st.f_files ? (100 * (st.f_files - st.f_ffree) / st.f_files) : 0; printf(" Inodes Used Avail " "(root) %%Capacity\n"); printf("%11llu %11llu %11llu %11llu %3llu%%\n", (unsigned long long)st.f_files, (unsigned long long)(st.f_files - st.f_ffree), (unsigned long long)st.f_favail, - (unsigned long long)st.f_ffree, - (unsigned long long)(100 * (st.f_files - st.f_ffree) / - st.f_files)); + (unsigned long long)st.f_ffree, ffree); } else if (hflag) { strlcpy(s_used, "error", sizeof(s_used)); strlcpy(s_avail, "error", sizeof(s_avail)); -- cgit v1.2.3 From 57e0d01260d3c1c7bf9366eed58c54a96eedbc81 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:52:27 +1100 Subject: - markus@cvs.openbsd.org 2009/12/11 18:16:33 [key.c] switch from 35 to the more common value of RSA_F4 == (2**16)+1 == 65537 for the RSA public exponent; discussed with provos; ok djm@ --- ChangeLog | 4 ++++ key.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb64d640e..45f758529 100644 --- a/ChangeLog +++ b/ChangeLog @@ -104,6 +104,10 @@ fix potential divide-by-zero in sftp's "df" output when talking to a server that reports zero files on the filesystem (Unix filesystems always have at least the root inode). From Steve McClellan at radisys, ok djm@ + - markus@cvs.openbsd.org 2009/12/11 18:16:33 + [key.c] + switch from 35 to the more common value of RSA_F4 == (2**16)+1 == 65537 + for the RSA public exponent; discussed with provos; ok djm@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/key.c b/key.c index 3e17da601..f2edf6d5d 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.80 2008/10/10 05:00:12 stevesk Exp $ */ +/* $OpenBSD: key.c,v 1.81 2009/12/11 18:16:33 markus Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -685,7 +685,7 @@ rsa_generate_private_key(u_int bits) { RSA *private; - private = RSA_generate_key(bits, 35, NULL, NULL); + private = RSA_generate_key(bits, RSA_F4, NULL, NULL); if (private == NULL) fatal("rsa_generate_private_key: key generation failed."); return private; -- cgit v1.2.3 From b8c884a0ba4050e4267be786414127c0f09d5544 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:53:43 +1100 Subject: - guenther@cvs.openbsd.org 2009/12/20 07:28:36 [ssh.c sftp.c scp.c] When passing user-controlled options with arguments to other programs, pass the option and option argument as separate argv entries and not smashed into one (e.g., as -l foo and not -lfoo). Also, always pass a "--" argument to stop option parsing, so that a positional argument that starts with a '-' isn't treated as an option. This fixes some error cases as well as the handling of hostnames and filenames that start with a '-'. Based on a diff by halex@ ok halex@ djm@ deraadt@ --- ChangeLog | 11 +++++++++++ scp.c | 21 ++++++++++++++------- sftp.c | 6 ++++-- ssh.c | 4 ++-- sshd_config.5 | 10 +++++----- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45f758529..605e0dca7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -108,6 +108,17 @@ [key.c] switch from 35 to the more common value of RSA_F4 == (2**16)+1 == 65537 for the RSA public exponent; discussed with provos; ok djm@ + - guenther@cvs.openbsd.org 2009/12/20 07:28:36 + [ssh.c sftp.c scp.c] + When passing user-controlled options with arguments to other programs, + pass the option and option argument as separate argv entries and + not smashed into one (e.g., as -l foo and not -lfoo). Also, always + pass a "--" argument to stop option parsing, so that a positional + argument that starts with a '-' isn't treated as an option. This + fixes some error cases as well as the handling of hostnames and + filenames that start with a '-'. + Based on a diff by halex@ + ok halex@ djm@ deraadt@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/scp.c b/scp.c index 323747806..09efb82ac 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.164 2008/10/10 04:55:16 stevesk Exp $ */ +/* $OpenBSD: scp.c,v 1.165 2009/12/20 07:28:36 guenther Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -244,8 +244,11 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) close(pout[1]); replacearg(&args, 0, "%s", ssh_program); - if (remuser != NULL) - addargs(&args, "-l%s", remuser); + if (remuser != NULL) { + addargs(&args, "-l"); + addargs(&args, "%s", remuser); + } + addargs(&args, "--"); addargs(&args, "%s", host); addargs(&args, "%s", cmd); @@ -337,10 +340,12 @@ main(int argc, char **argv) case 'c': case 'i': case 'F': - addargs(&args, "-%c%s", ch, optarg); + addargs(&args, "-%c", ch); + addargs(&args, "%s", optarg); break; case 'P': - addargs(&args, "-p%s", optarg); + addargs(&args, "-p"); + addargs(&args, "%s", optarg); break; case 'B': addargs(&args, "-oBatchmode yes"); @@ -548,6 +553,7 @@ toremote(char *targ, int argc, char **argv) } else { host = cleanhostname(argv[i]); } + addargs(&alist, "--"); addargs(&alist, "%s", host); addargs(&alist, "%s", cmd); addargs(&alist, "%s", src); @@ -558,7 +564,7 @@ toremote(char *targ, int argc, char **argv) errs = 1; } else { /* local to remote */ if (remin == -1) { - xasprintf(&bp, "%s -t %s", cmd, targ); + xasprintf(&bp, "%s -t -- %s", cmd, targ); host = cleanhostname(thost); if (do_cmd(host, tuser, bp, &remin, &remout) < 0) @@ -591,6 +597,7 @@ tolocal(int argc, char **argv) addargs(&alist, "-r"); if (pflag) addargs(&alist, "-p"); + addargs(&alist, "--"); addargs(&alist, "%s", argv[i]); addargs(&alist, "%s", argv[argc-1]); if (do_local_cmd(&alist)) @@ -610,7 +617,7 @@ tolocal(int argc, char **argv) suser = pwd->pw_name; } host = cleanhostname(host); - xasprintf(&bp, "%s -f %s", cmd, src); + xasprintf(&bp, "%s -f -- %s", cmd, src); if (do_cmd(host, suser, bp, &remin, &remout) < 0) { (void) xfree(bp); ++errs; diff --git a/sftp.c b/sftp.c index 1aa37423c..d8728cc25 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.114 2009/12/06 23:53:54 dtucker Exp $ */ +/* $OpenBSD: sftp.c,v 1.115 2009/12/20 07:28:36 guenther Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1809,7 +1809,8 @@ main(int argc, char **argv) fprintf(stderr, "Missing username\n"); usage(); } - addargs(&args, "-l%s", userhost); + addargs(&args, "-l"); + addargs(&args, "%s", userhost); } if ((cp = colon(host)) != NULL) { @@ -1829,6 +1830,7 @@ main(int argc, char **argv) if (sftp_server == NULL || strchr(sftp_server, '/') == NULL) addargs(&args, "-s"); + addargs(&args, "--"); addargs(&args, "%s", host); addargs(&args, "%s", (sftp_server != NULL ? sftp_server : "sftp")); diff --git a/ssh.c b/ssh.c index 90dbc69e9..6abf31b52 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.328 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: ssh.c,v 1.329 2009/12/20 07:28:36 guenther Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -528,7 +528,7 @@ main(int ac, char **av) ac -= optind; av += optind; - if (ac > 0 && !host && **av != '-') { + if (ac > 0 && !host) { if (strrchr(*av, '@')) { p = xstrdup(*av); cp = strrchr(p, '@'); diff --git a/sshd_config.5 b/sshd_config.5 index e54e70079..6d2ad9df0 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.112 2009/11/10 02:58:56 djm Exp $ -.Dd $Mdocdate: November 10 2009 $ +.\" $OpenBSD: sshd_config.5,v 1.113 2009/12/19 16:53:13 stevesk Exp $ +.Dd $Mdocdate: December 19 2009 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -182,16 +182,16 @@ PAM or though authentication styles supported in The default is .Dq yes . .It Cm ChrootDirectory -Specifies a path to +Specifies the pathname of a directory to .Xr chroot 2 to after authentication. -This path, and all its components, must be root-owned directories that are +All components of the pathname must be root-owned directories that are not writable by any other user or group. After the chroot, .Xr sshd 8 changes the working directory to the user's home directory. .Pp -The path may contain the following tokens that are expanded at runtime once +The pathname may contain the following tokens that are expanded at runtime once the connecting user has been authenticated: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. -- cgit v1.2.3 From f2705c8b7d0b6a9cc33c244bdf041f2a1087e08a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:54:17 +1100 Subject: - djm@cvs.openbsd.org 2009/12/20 23:20:40 [PROTOCOL] fix an incorrect magic number and typo in PROTOCOL; bz#1688 report and fix from ueno AT unixuser.org --- ChangeLog | 4 ++++ PROTOCOL | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 605e0dca7..ce5cd8b89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -119,6 +119,10 @@ filenames that start with a '-'. Based on a diff by halex@ ok halex@ djm@ deraadt@ + - djm@cvs.openbsd.org 2009/12/20 23:20:40 + [PROTOCOL] + fix an incorrect magic number and typo in PROTOCOL; bz#1688 + report and fix from ueno AT unixuser.org 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/PROTOCOL b/PROTOCOL index 5aada630d..c4fd57062 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -121,10 +121,10 @@ layer 2 frames or layer 3 packets. It may take one of the following values: SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */ The "tunnel unit number" specifies the remote interface number, or may -be zero to allow the server to automatically chose an interface. A server -that is not willing to open a client-specified unit should refuse the -request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful open, -the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS. +be 0x7fffffff to allow the server to automatically chose an interface. A +server that is not willing to open a client-specified unit should refuse +the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful +open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS. Once established the client and server may exchange packet or frames over the tunnel channel by encapsulating them in SSH protocol strings @@ -151,7 +151,7 @@ It may be one of: The "packet data" field consists of the IPv4/IPv6 datagram itself without any link layer header. -The contents of the "data" field for layer 3 packets is: +The contents of the "data" field for layer 2 packets is: uint32 packet length byte[packet length] frame @@ -251,4 +251,4 @@ The values of the f_flag bitmask are as follows: Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are advertised in the SSH_FXP_VERSION hello with version "2". -$OpenBSD: PROTOCOL,v 1.12 2009/02/14 06:35:49 djm Exp $ +$OpenBSD: PROTOCOL,v 1.13 2009/12/20 23:20:40 djm Exp $ -- cgit v1.2.3 From 75456e8ab2df99061a6aa69bcc914d05c2f4f98c Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:55:58 +1100 Subject: - stevesk@cvs.openbsd.org 2009/12/25 19:40:21 [readconf.c servconf.c misc.h ssh-keyscan.c misc.c] validate routing domain is in range 0-RT_TABLEID_MAX. 'Looks right' deraadt@ --- ChangeLog | 4 ++++ misc.c | 14 +++++++++++++- misc.h | 3 ++- readconf.c | 4 ++-- servconf.c | 13 +++++++++++-- ssh-keyscan.c | 10 ++++++---- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce5cd8b89..feaa27aee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -123,6 +123,10 @@ [PROTOCOL] fix an incorrect magic number and typo in PROTOCOL; bz#1688 report and fix from ueno AT unixuser.org + - stevesk@cvs.openbsd.org 2009/12/25 19:40:21 + [readconf.c servconf.c misc.h ssh-keyscan.c misc.c] + validate routing domain is in range 0-RT_TABLEID_MAX. + 'Looks right' deraadt@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/misc.c b/misc.c index 21db00a13..d4bdfc0ea 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.73 2009/11/20 03:24:07 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.74 2009/12/25 19:40:21 stevesk Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -273,6 +273,18 @@ a2port(const char *s) return (int)port; } +int +a2rdomain(const char *s) +{ + long long rdomain; + const char *errstr; + + rdomain = strtonum(s, 0, RT_TABLEID_MAX, &errstr); + if (errstr != NULL) + return -1; + return (int)rdomain; +} + int a2tun(const char *s, int *remote) { diff --git a/misc.h b/misc.h index 87b7f0edf..1e859e255 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.39 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: misc.h,v 1.40 2009/12/25 19:40:21 stevesk Exp $ */ /* * Author: Tatu Ylonen @@ -23,6 +23,7 @@ int set_nonblock(int); int unset_nonblock(int); void set_nodelay(int); int a2port(const char *); +int a2rdomain(const char *); int a2tun(const char *, int *); char *put_host_port(const char *, u_short); char *hpdelim(char **); diff --git a/readconf.c b/readconf.c index 6b2e3b21d..2f1b0cd3b 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.179 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: readconf.c,v 1.180 2009/12/25 19:40:21 stevesk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -925,7 +925,7 @@ parse_int: if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - value = a2port(arg); + value = a2rdomain(arg); if (value == -1) fatal("%.200s line %d: Bad rdomain.", filename, linenum); diff --git a/servconf.c b/servconf.c index 729f23bad..8b8518aa8 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.197 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: servconf.c,v 1.198 2009/12/25 19:40:21 stevesk Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1298,7 +1298,16 @@ process_server_config_line(ServerOptions *options, char *line, case sRDomain: intptr = &options->rdomain; - goto parse_int; + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing rdomain value.", + filename, linenum); + if ((value = a2rdomain(arg)) == -1) + fatal("%s line %d: invalid rdomain value.", + filename, linenum); + if (*intptr == -1) + *intptr = value; + break; case sDeprecated: logit("%s line %d: Deprecated option %s", diff --git a/ssh-keyscan.c b/ssh-keyscan.c index f30e85045..faeb9e13e 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.79 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.80 2009/12/25 19:40:21 stevesk Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -807,9 +807,11 @@ main(int argc, char **argv) IPv4or6 = AF_INET6; break; case 'V': - scan_rdomain = a2port(optarg); - if (scan_rdomain < 0) - scan_rdomain = -1; + scan_rdomain = a2rdomain(optarg); + if (scan_rdomain == -1) { + fprintf(stderr, "Bad rdomain '%s'\n", optarg); + exit(1); + } break; case '?': default: -- cgit v1.2.3 From 535b5e172166c2515500bc20f3ea89216bd1f42b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:56:48 +1100 Subject: - stevesk@cvs.openbsd.org 2009/12/29 16:38:41 [sshd_config.5 readconf.c ssh_config.5 scp.1 servconf.c sftp.1 ssh.1] Rename RDomain config option to RoutingDomain to be more clear and consistent with other options. NOTE: if you currently use RDomain in the ssh client or server config, or ssh/sshd -o, you must update to use RoutingDomain. ok markus@ djm@ --- ChangeLog | 7 +++++++ readconf.c | 4 ++-- scp.1 | 6 +++--- servconf.c | 4 ++-- sftp.1 | 6 +++--- ssh.1 | 6 +++--- ssh_config.5 | 6 +++--- sshd_config.5 | 6 +++--- 8 files changed, 26 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index feaa27aee..9256d6488 100644 --- a/ChangeLog +++ b/ChangeLog @@ -127,6 +127,13 @@ [readconf.c servconf.c misc.h ssh-keyscan.c misc.c] validate routing domain is in range 0-RT_TABLEID_MAX. 'Looks right' deraadt@ + - stevesk@cvs.openbsd.org 2009/12/29 16:38:41 + [sshd_config.5 readconf.c ssh_config.5 scp.1 servconf.c sftp.1 ssh.1] + Rename RDomain config option to RoutingDomain to be more clear and + consistent with other options. + NOTE: if you currently use RDomain in the ssh client or server config, + or ssh/sshd -o, you must update to use RoutingDomain. + ok markus@ djm@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/readconf.c b/readconf.c index 2f1b0cd3b..40fe8f694 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.180 2009/12/25 19:40:21 stevesk Exp $ */ +/* $OpenBSD: readconf.c,v 1.181 2009/12/29 16:38:41 stevesk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -229,7 +229,7 @@ static struct { { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, { "useroaming", oUseRoaming }, - { "rdomain", oRDomain }, + { "routingdomain", oRDomain }, #ifdef JPAKE { "zeroknowledgepasswordauthentication", oZeroKnowledgePasswordAuthentication }, diff --git a/scp.1 b/scp.1 index b9245ea53..1d1cad0b0 100644 --- a/scp.1 +++ b/scp.1 @@ -9,9 +9,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.47 2009/10/28 16:38:18 reyk Exp $ +.\" $OpenBSD: scp.1,v 1.48 2009/12/29 16:38:41 stevesk Exp $ .\" -.Dd $Mdocdate: October 28 2009 $ +.Dd $Mdocdate: December 29 2009 $ .Dt SCP 1 .Os .Sh NAME @@ -158,9 +158,9 @@ For full details of the options listed below, and their possible values, see .It Protocol .It ProxyCommand .It PubkeyAuthentication -.It RDomain .It RekeyLimit .It RhostsRSAAuthentication +.It RoutingDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/servconf.c b/servconf.c index 8b8518aa8..2cdc480e6 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.198 2009/12/25 19:40:21 stevesk Exp $ */ +/* $OpenBSD: servconf.c,v 1.199 2009/12/29 16:38:41 stevesk Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -424,7 +424,7 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, - { "rdomain", sRDomain, SSHCFG_GLOBAL }, + { "routingdomain", sRDomain, SSHCFG_GLOBAL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; diff --git a/sftp.1 b/sftp.1 index ab53c1690..81d87680d 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.78 2009/10/28 21:45:08 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.79 2009/12/29 16:38:41 stevesk Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: October 28 2009 $ +.Dd $Mdocdate: December 29 2009 $ .Dt SFTP 1 .Os .Sh NAME @@ -207,9 +207,9 @@ For full details of the options listed below, and their possible values, see .It Protocol .It ProxyCommand .It PubkeyAuthentication -.It RDomain .It RekeyLimit .It RhostsRSAAuthentication +.It RoutingDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/ssh.1 b/ssh.1 index 8277d0fdf..2f6ef5fff 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.287 2009/10/28 16:38:18 reyk Exp $ -.Dd $Mdocdate: October 28 2009 $ +.\" $OpenBSD: ssh.1,v 1.288 2009/12/29 16:38:41 stevesk Exp $ +.Dd $Mdocdate: December 29 2009 $ .Dt SSH 1 .Os .Sh NAME @@ -475,10 +475,10 @@ For full details of the options listed below, and their possible values, see .It Protocol .It ProxyCommand .It PubkeyAuthentication -.It RDomain .It RekeyLimit .It RemoteForward .It RhostsRSAAuthentication +.It RoutingDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/ssh_config.5 b/ssh_config.5 index 001130936..442222cc5 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.123 2009/11/10 02:56:22 djm Exp $ -.Dd $Mdocdate: November 10 2009 $ +.\" $OpenBSD: ssh_config.5,v 1.124 2009/12/29 16:38:41 stevesk Exp $ +.Dd $Mdocdate: December 29 2009 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -789,7 +789,7 @@ or The default is .Dq yes . This option applies to protocol version 2 only. -.It Cm RDomain +.It Cm RoutingDomain Set the routing domain number. The default routing domain is set by the system. .It Cm RekeyLimit diff --git a/sshd_config.5 b/sshd_config.5 index 6d2ad9df0..ada265373 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.113 2009/12/19 16:53:13 stevesk Exp $ -.Dd $Mdocdate: December 19 2009 $ +.\" $OpenBSD: sshd_config.5,v 1.114 2009/12/29 16:38:41 stevesk Exp $ +.Dd $Mdocdate: December 29 2009 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -806,7 +806,7 @@ Specifies whether public key authentication is allowed. The default is .Dq yes . Note that this option applies to protocol version 2 only. -.It Cm RDomain +.It Cm RoutingDomain Set the routing domain number. The default routing domain is set by the system. .It Cm RhostsRSAAuthentication -- cgit v1.2.3 From 98e5d9a0d3beabc706982260fec70f823ff764b7 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:57:39 +1100 Subject: - jmc@cvs.openbsd.org 2009/12/29 18:03:32 [sshd_config.5 ssh_config.5] sort previous; --- ChangeLog | 3 +++ ssh_config.5 | 8 ++++---- sshd_config.5 | 8 ++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9256d6488..929907961 100644 --- a/ChangeLog +++ b/ChangeLog @@ -134,6 +134,9 @@ NOTE: if you currently use RDomain in the ssh client or server config, or ssh/sshd -o, you must update to use RoutingDomain. ok markus@ djm@ + - jmc@cvs.openbsd.org 2009/12/29 18:03:32 + [sshd_config.5 ssh_config.5] + sort previous; 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/ssh_config.5 b/ssh_config.5 index 442222cc5..3ffc469c2 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.124 2009/12/29 16:38:41 stevesk Exp $ +.\" $OpenBSD: ssh_config.5,v 1.125 2009/12/29 18:03:32 jmc Exp $ .Dd $Mdocdate: December 29 2009 $ .Dt SSH_CONFIG 5 .Os @@ -789,9 +789,6 @@ or The default is .Dq yes . This option applies to protocol version 2 only. -.It Cm RoutingDomain -Set the routing domain number. -The default routing domain is set by the system. .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated. @@ -860,6 +857,9 @@ The default is This option applies to protocol version 1 only and requires .Xr ssh 1 to be setuid root. +.It Cm RoutingDomain +Set the routing domain number. +The default routing domain is set by the system. .It Cm RSAAuthentication Specifies whether to try RSA authentication. The argument to this keyword must be diff --git a/sshd_config.5 b/sshd_config.5 index ada265373..a3326447f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.114 2009/12/29 16:38:41 stevesk Exp $ +.\" $OpenBSD: sshd_config.5,v 1.115 2009/12/29 18:03:32 jmc Exp $ .Dd $Mdocdate: December 29 2009 $ .Dt SSHD_CONFIG 5 .Os @@ -806,15 +806,15 @@ Specifies whether public key authentication is allowed. The default is .Dq yes . Note that this option applies to protocol version 2 only. -.It Cm RoutingDomain -Set the routing domain number. -The default routing domain is set by the system. .It Cm RhostsRSAAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful RSA host authentication is allowed. The default is .Dq no . This option applies to protocol version 1 only. +.It Cm RoutingDomain +Set the routing domain number. +The default routing domain is set by the system. .It Cm RSAAuthentication Specifies whether pure RSA authentication is allowed. The default is -- cgit v1.2.3 From 0c348f5b9eb4ac9f763cb3f55a252d86e2cfc57b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 18:58:05 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/04 01:45:30 [sshconnect2.c] Don't escape backslashes in the SSH2 banner. bz#1533, patch from Michal Gorny via Gentoo. --- ChangeLog | 4 ++++ sshconnect2.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 929907961..ac3ca7b02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -137,6 +137,10 @@ - jmc@cvs.openbsd.org 2009/12/29 18:03:32 [sshd_config.5 ssh_config.5] sort previous; + - dtucker@cvs.openbsd.org 2010/01/04 01:45:30 + [sshconnect2.c] + Don't escape backslashes in the SSH2 banner. bz#1533, patch from + Michal Gorny via Gentoo. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sshconnect2.c b/sshconnect2.c index d428ac65f..367f0fc6c 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.176 2009/12/06 23:41:15 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.177 2010/01/04 01:45:30 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -421,7 +421,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt) if (len > 65536) len = 65536; msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ - strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL); + strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); fprintf(stderr, "%s", msg); xfree(msg); } -- cgit v1.2.3 From 909d858d6b86c789003b809a636c2c228d3f30c5 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:02:40 +1100 Subject: - djm@cvs.openbsd.org 2010/01/04 02:03:57 [sftp.c] Implement tab-completion of commands, local and remote filenames for sftp. Hacked on and off for some time by myself, mouring, Carlos Silva (via 2009 Google Summer of Code) and polished to a fine sheen by myself again. It should deal more-or-less correctly with the ikky corner-cases presented by quoted filenames, but the UI could still be slightly improved. In particular, it is quite slow for remote completion on large directories. bz#200; ok markus@ --- ChangeLog | 9 ++ sftp.c | 484 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 443 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index ac3ca7b02..70e3c15e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -141,6 +141,15 @@ [sshconnect2.c] Don't escape backslashes in the SSH2 banner. bz#1533, patch from Michal Gorny via Gentoo. + - djm@cvs.openbsd.org 2010/01/04 02:03:57 + [sftp.c] + Implement tab-completion of commands, local and remote filenames for sftp. + Hacked on and off for some time by myself, mouring, Carlos Silva (via 2009 + Google Summer of Code) and polished to a fine sheen by myself again. + It should deal more-or-less correctly with the ikky corner-cases presented + by quoted filenames, but the UI could still be slightly improved. + In particular, it is quite slow for remote completion on large directories. + bz#200; ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp.c b/sftp.c index d8728cc25..6a5ccc49d 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.115 2009/12/20 07:28:36 guenther Exp $ */ +/* $OpenBSD: sftp.c,v 1.116 2010/01/04 02:03:57 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -95,6 +95,12 @@ volatile sig_atomic_t interrupted = 0; /* I wish qsort() took a separate ctx for the comparison function...*/ int sort_flag; +/* Context used for commandline completion */ +struct complete_ctx { + struct sftp_conn *conn; + char **remote_pathp; +}; + int remote_glob(struct sftp_conn *, const char *, int, int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ @@ -145,43 +151,47 @@ extern char *__progname; struct CMD { const char *c; const int n; + const int t; }; +/* Type of completion */ +#define NOARGS 0 +#define REMOTE 1 +#define LOCAL 2 + static const struct CMD cmds[] = { - { "bye", I_QUIT }, - { "cd", I_CHDIR }, - { "chdir", I_CHDIR }, - { "chgrp", I_CHGRP }, - { "chmod", I_CHMOD }, - { "chown", I_CHOWN }, - { "df", I_DF }, - { "dir", I_LS }, - { "exit", I_QUIT }, - { "get", I_GET }, - { "mget", I_GET }, - { "help", I_HELP }, - { "lcd", I_LCHDIR }, - { "lchdir", I_LCHDIR }, - { "lls", I_LLS }, - { "lmkdir", I_LMKDIR }, - { "ln", I_SYMLINK }, - { "lpwd", I_LPWD }, - { "ls", I_LS }, - { "lumask", I_LUMASK }, - { "mkdir", I_MKDIR }, - { "progress", I_PROGRESS }, - { "put", I_PUT }, - { "mput", I_PUT }, - { "pwd", I_PWD }, - { "quit", I_QUIT }, - { "rename", I_RENAME }, - { "rm", I_RM }, - { "rmdir", I_RMDIR }, - { "symlink", I_SYMLINK }, - { "version", I_VERSION }, - { "!", I_SHELL }, - { "?", I_HELP }, - { NULL, -1} + { "bye", I_QUIT, NOARGS }, + { "cd", I_CHDIR, REMOTE }, + { "chdir", I_CHDIR, REMOTE }, + { "chgrp", I_CHGRP, REMOTE }, + { "chmod", I_CHMOD, REMOTE }, + { "chown", I_CHOWN, REMOTE }, + { "df", I_DF, REMOTE }, + { "dir", I_LS, REMOTE }, + { "exit", I_QUIT, NOARGS }, + { "get", I_GET, REMOTE }, + { "help", I_HELP, NOARGS }, + { "lcd", I_LCHDIR, LOCAL }, + { "lchdir", I_LCHDIR, LOCAL }, + { "lls", I_LLS, LOCAL }, + { "lmkdir", I_LMKDIR, LOCAL }, + { "ln", I_SYMLINK, REMOTE }, + { "lpwd", I_LPWD, LOCAL }, + { "ls", I_LS, REMOTE }, + { "lumask", I_LUMASK, NOARGS }, + { "mkdir", I_MKDIR, REMOTE }, + { "progress", I_PROGRESS, NOARGS }, + { "put", I_PUT, LOCAL }, + { "pwd", I_PWD, REMOTE }, + { "quit", I_QUIT, NOARGS }, + { "rename", I_RENAME, REMOTE }, + { "rm", I_RM, REMOTE }, + { "rmdir", I_RMDIR, REMOTE }, + { "symlink", I_SYMLINK, REMOTE }, + { "version", I_VERSION, NOARGS }, + { "!", I_SHELL, NOARGS }, + { "?", I_HELP, NOARGS }, + { NULL, -1, -1 } }; int interactive_loop(struct sftp_conn *, char *file1, char *file2); @@ -932,12 +942,23 @@ undo_glob_escape(char *s) * Split a string into an argument vector using sh(1)-style quoting, * comment and escaping rules, but with some tweaks to handle glob(3) * wildcards. + * The "sloppy" flag allows for recovery from missing terminating quote, for + * use in parsing incomplete commandlines during tab autocompletion. + * * Returns NULL on error or a NULL-terminated array of arguments. + * + * If "lastquote" is not NULL, the quoting character used for the last + * argument is placed in *lastquote ("\0", "'" or "\""). + * + * If "terminated" is not NULL, *terminated will be set to 1 when the + * last argument's quote has been properly terminated or 0 otherwise. + * This parameter is only of use if "sloppy" is set. */ #define MAXARGS 128 #define MAXARGLEN 8192 static char ** -makeargv(const char *arg, int *argcp) +makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, + u_int *terminated) { int argc, quot; size_t i, j; @@ -951,6 +972,10 @@ makeargv(const char *arg, int *argcp) error("string too long"); return NULL; } + if (terminated != NULL) + *terminated = 1; + if (lastquote != NULL) + *lastquote = '\0'; state = MA_START; i = j = 0; for (;;) { @@ -967,6 +992,8 @@ makeargv(const char *arg, int *argcp) if (state == MA_START) { argv[argc] = argvs + j; state = q; + if (lastquote != NULL) + *lastquote = arg[i]; } else if (state == MA_UNQUOTED) state = q; else if (state == q) @@ -1003,6 +1030,8 @@ makeargv(const char *arg, int *argcp) if (state == MA_START) { argv[argc] = argvs + j; state = MA_UNQUOTED; + if (lastquote != NULL) + *lastquote = '\0'; } if (arg[i + 1] == '?' || arg[i + 1] == '[' || arg[i + 1] == '*' || arg[i + 1] == '\\') { @@ -1028,6 +1057,12 @@ makeargv(const char *arg, int *argcp) goto string_done; } else if (arg[i] == '\0') { if (state == MA_SQUOTE || state == MA_DQUOTE) { + if (sloppy) { + state = MA_UNQUOTED; + if (terminated != NULL) + *terminated = 0; + goto string_done; + } error("Unterminated quoted argument"); return NULL; } @@ -1041,6 +1076,8 @@ makeargv(const char *arg, int *argcp) if (state == MA_START) { argv[argc] = argvs + j; state = MA_UNQUOTED; + if (lastquote != NULL) + *lastquote = '\0'; } if ((state == MA_SQUOTE || state == MA_DQUOTE) && (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) { @@ -1063,8 +1100,8 @@ makeargv(const char *arg, int *argcp) } static int -parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, int *hflag, - unsigned long *n_arg, char **path1, char **path2) +parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, + int *hflag, unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; char *cp2, **argv; @@ -1086,7 +1123,7 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, int cp++; } - if ((argv = makeargv(cp, &argc)) == NULL) + if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL) return -1; /* Figure out which command we have */ @@ -1468,10 +1505,344 @@ prompt(EditLine *el) } #endif +/* Display entries in 'list' after skipping the first 'len' chars */ +static void +complete_display(char **list, u_int len) +{ + u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen; + struct winsize ws; + char *tmp; + + /* Count entries for sort and find longest */ + for (y = 0; list[y]; y++) + m = MAX(m, strlen(list[y])); + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) + width = ws.ws_col; + + m = m > len ? m - len : 0; + columns = width / (m + 2); + columns = MAX(columns, 1); + colspace = width / columns; + colspace = MIN(colspace, width); + + printf("\n"); + m = 1; + for (y = 0; list[y]; y++) { + llen = strlen(list[y]); + tmp = llen > len ? list[y] + len : ""; + printf("%-*s", colspace, tmp); + if (m >= columns) { + printf("\n"); + m = 1; + } else + m++; + } + printf("\n"); +} + +/* + * Given a "list" of words that begin with a common prefix of "word", + * attempt to find an autocompletion to extends "word" by the next + * characters common to all entries in "list". + */ +static char * +complete_ambiguous(const char *word, char **list, size_t count) +{ + if (word == NULL) + return NULL; + + if (count > 0) { + u_int y, matchlen = strlen(list[0]); + + /* Find length of common stem */ + for (y = 1; list[y]; y++) { + u_int x; + + for (x = 0; x < matchlen; x++) + if (list[0][x] != list[y][x]) + break; + + matchlen = x; + } + + if (matchlen > strlen(word)) { + char *tmp = xstrdup(list[0]); + + tmp[matchlen] = NULL; + return tmp; + } + } + + return xstrdup(word); +} + +/* Autocomplete a sftp command */ +static int +complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, + int terminated) +{ + u_int y, count = 0, cmdlen, tmplen; + char *tmp, **list, argterm[3]; + const LineInfo *lf; + + list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *)); + + /* No command specified: display all available commands */ + if (cmd == NULL) { + for (y = 0; cmds[y].c; y++) + list[count++] = xstrdup(cmds[y].c); + + list[count] = NULL; + complete_display(list, 0); + + for (y = 0; list[y] != NULL; y++) + xfree(list[y]); + xfree(list); + return count; + } + + /* Prepare subset of commands that start with "cmd" */ + cmdlen = strlen(cmd); + for (y = 0; cmds[y].c; y++) { + if (!strncasecmp(cmd, cmds[y].c, cmdlen)) + list[count++] = xstrdup(cmds[y].c); + } + list[count] = NULL; + + if (count == 0) + return 0; + + /* Complete ambigious command */ + tmp = complete_ambiguous(cmd, list, count); + if (count > 1) + complete_display(list, 0); + + for (y = 0; list[y]; y++) + xfree(list[y]); + xfree(list); + + if (tmp != NULL) { + tmplen = strlen(tmp); + cmdlen = strlen(cmd); + /* If cmd may be extended then do so */ + if (tmplen > cmdlen) + if (el_insertstr(el, tmp + cmdlen) == -1) + fatal("el_insertstr failed."); + lf = el_line(el); + /* Terminate argument cleanly */ + if (count == 1) { + y = 0; + if (!terminated) + argterm[y++] = quote; + if (lastarg || *(lf->cursor) != ' ') + argterm[y++] = ' '; + argterm[y] = '\0'; + if (y > 0 && el_insertstr(el, argterm) == -1) + fatal("el_insertstr failed."); + } + xfree(tmp); + } + + return count; +} + +/* + * Determine whether a particular sftp command's arguments (if any) + * represent local or remote files. + */ +static int +complete_is_remote(char *cmd) { + int i; + + if (cmd == NULL) + return -1; + + for (i = 0; cmds[i].c; i++) { + if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) + return cmds[i].t; + } + + return -1; +} + +/* Autocomplete a filename "file" */ +static int +complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, + char *file, int remote, int lastarg, char quote, int terminated) +{ + glob_t g; + char *tmp, *tmp2, ins[3]; + u_int i, hadglob, pwdlen, len, tmplen, filelen; + const LineInfo *lf; + + /* Glob from "file" location */ + if (file == NULL) + tmp = xstrdup("*"); + else + xasprintf(&tmp, "%s*", file); + + memset(&g, 0, sizeof(g)); + if (remote != LOCAL) { + tmp = make_absolute(tmp, remote_path); + remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); + } else + glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); + + /* Determine length of pwd so we can trim completion display */ + for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { + /* Terminate counting on first unescaped glob metacharacter */ + if (tmp[tmplen] == '*' || tmp[tmplen] == '?') { + if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0') + hadglob = 1; + break; + } + if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0') + tmplen++; + if (tmp[tmplen] == '/') + pwdlen = tmplen + 1; /* track last seen '/' */ + } + xfree(tmp); + + if (g.gl_matchc == 0) + goto out; + + if (g.gl_matchc > 1) + complete_display(g.gl_pathv, pwdlen); + + tmp = NULL; + /* Don't try to extend globs */ + if (file == NULL || hadglob) + goto out; + + tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc); + tmp = path_strip(tmp2, remote_path); + xfree(tmp2); + + if (tmp == NULL) + goto out; + + tmplen = strlen(tmp); + filelen = strlen(file); + + if (tmplen > filelen) { + tmp2 = tmp + filelen; + len = strlen(tmp2); + /* quote argument on way out */ + for (i = 0; i < len; i++) { + ins[0] = '\\'; + ins[1] = tmp2[i]; + ins[2] = '\0'; + switch (tmp2[i]) { + case '\'': + case '"': + case '\\': + case '\t': + case ' ': + if (quote == '\0' || tmp2[i] == quote) { + if (el_insertstr(el, ins) == -1) + fatal("el_insertstr " + "failed."); + break; + } + /* FALLTHROUGH */ + default: + if (el_insertstr(el, ins + 1) == -1) + fatal("el_insertstr failed."); + break; + } + } + } + + lf = el_line(el); + /* + * XXX should we really extend here? the user may not be done if + * the filename is a directory. + */ + if (g.gl_matchc == 1) { + i = 0; + if (!terminated) + ins[i++] = quote; + if (lastarg || *(lf->cursor) != ' ') + ins[i++] = ' '; + ins[i] = '\0'; + if (i > 0 && el_insertstr(el, ins) == -1) + fatal("el_insertstr failed."); + } + xfree(tmp); + + out: + globfree(&g); + return g.gl_matchc; +} + +/* tab-completion hook function, called via libedit */ +static unsigned char +complete(EditLine *el, int ch) +{ + char **argv, *line, quote; + u_int argc, carg, cursor, len, terminated, ret = CC_ERROR; + const LineInfo *lf; + struct complete_ctx *complete_ctx; + + lf = el_line(el); + if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0) + fatal("%s: el_get failed", __func__); + + /* Figure out which argument the cursor points to */ + cursor = lf->cursor - lf->buffer; + line = (char *)xmalloc(cursor + 1); + memcpy(line, lf->buffer, cursor); + line[cursor] = '\0'; + argv = makeargv(line, &carg, 1, "e, &terminated); + xfree(line); + + /* Get all the arguments on the line */ + len = lf->lastchar - lf->buffer; + line = (char *)xmalloc(len + 1); + memcpy(line, lf->buffer, len); + line[len] = '\0'; + argv = makeargv(line, &argc, 1, NULL, NULL); + + /* Ensure cursor is at EOL or a argument boundary */ + if (line[cursor] != ' ' && line[cursor] != '\0' && + line[cursor] != '\n') { + xfree(line); + return ret; + } + + if (carg == 0) { + /* Show all available commands */ + complete_cmd_parse(el, NULL, argc == carg, '\0', 1); + ret = CC_REDISPLAY; + } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { + /* Handle the command parsing */ + if (complete_cmd_parse(el, argv[0], argc == carg, + quote, terminated) != 0) + ret = CC_REDISPLAY; + } else if (carg >= 1) { + /* Handle file parsing */ + int remote = complete_is_remote(argv[0]); + char *filematch = NULL; + + if (carg > 1 && line[cursor-1] != ' ') + filematch = argv[carg - 1]; + + if (remote != 0 && + complete_match(el, complete_ctx->conn, + *complete_ctx->remote_pathp, filematch, + remote, carg == argc, quote, terminated) != 0) + ret = CC_REDISPLAY; + } + + xfree(line); + return ret; +} + int interactive_loop(struct sftp_conn *conn, char *file1, char *file2) { - char *pwd; + char *remote_path; char *dir = NULL; char cmd[2048]; int err, interactive; @@ -1480,6 +1851,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) History *hl = NULL; HistEvent hev; extern char *__progname; + struct complete_ctx complete_ctx; if (!batchmode && isatty(STDIN_FILENO)) { if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL) @@ -1494,23 +1866,32 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) el_set(el, EL_TERMINAL, NULL); el_set(el, EL_SIGNAL, 1); el_source(el, NULL); + + /* Tab Completion */ + el_set(el, EL_ADDFN, "ftp-complete", + "Context senstive argument completion", complete); + complete_ctx.conn = conn; + complete_ctx.remote_pathp = &remote_path; + el_set(el, EL_CLIENTDATA, (void*)&complete_ctx); + el_set(el, EL_BIND, "^I", "ftp-complete", NULL); } #endif /* USE_LIBEDIT */ - pwd = do_realpath(conn, "."); - if (pwd == NULL) + remote_path = do_realpath(conn, "."); + if (remote_path == NULL) fatal("Need cwd"); if (file1 != NULL) { dir = xstrdup(file1); - dir = make_absolute(dir, pwd); + dir = make_absolute(dir, remote_path); if (remote_is_dir(conn, dir) && file2 == NULL) { printf("Changing to: %s\n", dir); snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); - if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) { + if (parse_dispatch_command(conn, cmd, + &remote_path, 1) != 0) { xfree(dir); - xfree(pwd); + xfree(remote_path); xfree(conn); return (-1); } @@ -1521,9 +1902,10 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) snprintf(cmd, sizeof cmd, "get %s %s", dir, file2); - err = parse_dispatch_command(conn, cmd, &pwd, 1); + err = parse_dispatch_command(conn, cmd, + &remote_path, 1); xfree(dir); - xfree(pwd); + xfree(remote_path); xfree(conn); return (err); } @@ -1564,7 +1946,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) const char *line; int count = 0; - if ((line = el_gets(el, &count)) == NULL || count <= 0) { + if ((line = el_gets(el, &count)) == NULL || + count <= 0) { printf("\n"); break; } @@ -1584,11 +1967,12 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) interrupted = 0; signal(SIGINT, cmd_interrupt); - err = parse_dispatch_command(conn, cmd, &pwd, batchmode); + err = parse_dispatch_command(conn, cmd, &remote_path, + batchmode); if (err != 0) break; } - xfree(pwd); + xfree(remote_path); xfree(conn); #ifdef USE_LIBEDIT -- cgit v1.2.3 From aaf51d2d5b76c25cc549559a200a802e92b2d8aa Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:04:49 +1100 Subject: - djm@cvs.openbsd.org 2010/01/04 02:25:15 [sftp-server.c] bz#1566 don't unnecessarily dup() in and out fds for sftp-server; ok markus@ --- ChangeLog | 4 ++++ sftp-server.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70e3c15e9..05b99b160 100644 --- a/ChangeLog +++ b/ChangeLog @@ -150,6 +150,10 @@ by quoted filenames, but the UI could still be slightly improved. In particular, it is quite slow for remote completion on large directories. bz#200; ok markus@ + - djm@cvs.openbsd.org 2010/01/04 02:25:15 + [sftp-server.c] + bz#1566 don't unnecessarily dup() in and out fds for sftp-server; + ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp-server.c b/sftp-server.c index 20a601f99..cf4e273f8 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.88 2009/10/17 12:10:39 sobrado Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.89 2010/01/04 02:25:15 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1397,8 +1397,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) logit("session opened for local user %s from [%s]", pw->pw_name, client_addr); - in = dup(STDIN_FILENO); - out = dup(STDOUT_FILENO); + in = STDIN_FILENO; + out = STDOUT_FILENO; #ifdef HAVE_CYGWIN setmode(in, O_BINARY); -- cgit v1.2.3 From 8cbd403fde20dda880a7ff3262bf2c36f6582eac Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:13:25 +1100 Subject: - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new files for roaming and add to Makefile. --- ChangeLog | 2 + Makefile.in | 6 +- roaming_client.c | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ roaming_serv.c | 29 ++++++ 4 files changed, 310 insertions(+), 3 deletions(-) create mode 100644 roaming_client.c create mode 100644 roaming_serv.c diff --git a/ChangeLog b/ChangeLog index 05b99b160..dbe3c0c92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -154,6 +154,8 @@ [sftp-server.c] bz#1566 don't unnecessarily dup() in and out fds for sftp-server; ok markus@ + - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new + files for roaming and add to Makefile. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/Makefile.in b/Makefile.in index da66311d0..a16782dff 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.301 2009/10/02 01:50:55 djm Exp $ +# $Id: Makefile.in,v 1.302 2010/01/08 08:13:25 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -75,7 +75,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ - roaming_common.o + roaming_common.o roaming_client.c SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ sshpty.o sshlogin.o servconf.o serverloop.o \ @@ -88,7 +88,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \ - roaming_common.o + roaming_common.o roaming_serv.c MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 diff --git a/roaming_client.c b/roaming_client.c new file mode 100644 index 000000000..b77dbd59b --- /dev/null +++ b/roaming_client.c @@ -0,0 +1,276 @@ +/* $OpenBSD: roaming_client.c,v 1.1 2009/10/24 11:22:37 andreas Exp $ */ +/* + * Copyright (c) 2004-2009 AppGate Network Security AB + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "channels.h" +#include "cipher.h" +#include "dispatch.h" +#include "clientloop.h" +#include "log.h" +#include "match.h" +#include "misc.h" +#include "packet.h" +#include "ssh.h" +#include "key.h" +#include "kex.h" +#include "readconf.h" +#include "roaming.h" +#include "ssh2.h" +#include "sshconnect.h" + +/* import */ +extern Options options; +extern char *host; +extern struct sockaddr_storage hostaddr; +extern int session_resumed; + +static u_int32_t roaming_id; +static u_int64_t cookie; +static u_int64_t lastseenchall; +static u_int64_t key1, key2, oldkey1, oldkey2; + +void +roaming_reply(int type, u_int32_t seq, void *ctxt) +{ + if (type == SSH2_MSG_REQUEST_FAILURE) { + logit("Server denied roaming"); + return; + } + verbose("Roaming enabled"); + roaming_id = packet_get_int(); + cookie = packet_get_int64(); + key1 = oldkey1 = packet_get_int64(); + key2 = oldkey2 = packet_get_int64(); + set_out_buffer_size(packet_get_int() + get_snd_buf_size()); + roaming_enabled = 1; +} + +void +request_roaming(void) +{ + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring(ROAMING_REQUEST); + packet_put_char(1); + packet_put_int(get_recv_buf_size()); + packet_send(); + client_register_global_confirm(roaming_reply, NULL); +} + +static void +roaming_auth_required(void) +{ + u_char digest[SHA_DIGEST_LENGTH]; + EVP_MD_CTX md; + Buffer b; + const EVP_MD *evp_md = EVP_sha1(); + u_int64_t chall, oldchall; + + chall = packet_get_int64(); + oldchall = packet_get_int64(); + if (oldchall != lastseenchall) { + key1 = oldkey1; + key2 = oldkey2; + } + lastseenchall = chall; + + buffer_init(&b); + buffer_put_int64(&b, cookie); + buffer_put_int64(&b, chall); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + buffer_free(&b); + + packet_start(SSH2_MSG_KEX_ROAMING_AUTH); + packet_put_int64(key1 ^ get_recv_bytes()); + packet_put_raw(digest, sizeof(digest)); + packet_send(); + + oldkey1 = key1; + oldkey2 = key2; + calculate_new_key(&key1, cookie, chall); + calculate_new_key(&key2, cookie, chall); + + debug("Received %" PRIu64 " bytes", get_recv_bytes()); + debug("Sent roaming_auth packet"); +} + +int +resume_kex(void) +{ + /* + * This should not happen - if the client sends the kex method + * resume@appgate.com then the kex is done in roaming_resume(). + */ + return 1; +} + +static int +roaming_resume(void) +{ + u_int64_t recv_bytes; + char *str = NULL, *kexlist = NULL, *c; + int i, type; + int timeout_ms = options.connection_timeout * 1000; + u_int len; + u_int32_t rnd = 0; + + resume_in_progress = 1; + + /* Exchange banners */ + ssh_exchange_identification(timeout_ms); + packet_set_nonblocking(); + + /* Send a kexinit message with resume@appgate.com as only kex algo */ + packet_start(SSH2_MSG_KEXINIT); + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if (i % 4 == 0) + rnd = arc4random(); + packet_put_char(rnd & 0xff); + rnd >>= 8; + } + packet_put_cstring(KEX_RESUME); + for (i = 1; i < PROPOSAL_MAX; i++) { + /* kex algorithm added so start with i=1 and not 0 */ + packet_put_cstring(""); /* Not used when we resume */ + } + packet_put_char(1); /* first kex_packet follows */ + packet_put_int(0); /* reserved */ + packet_send(); + + /* Assume that resume@appgate.com will be accepted */ + packet_start(SSH2_MSG_KEX_ROAMING_RESUME); + packet_put_int(roaming_id); + packet_send(); + + /* Read the server's kexinit and check for resume@appgate.com */ + if ((type = packet_read()) != SSH2_MSG_KEXINIT) { + debug("expected kexinit on resume, got %d", type); + goto fail; + } + for (i = 0; i < KEX_COOKIE_LEN; i++) + (void)packet_get_char(); + kexlist = packet_get_string(&len); + if (!kexlist + || (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) { + debug("server doesn't allow resume"); + goto fail; + } + xfree(str); + for (i = 1; i < PROPOSAL_MAX; i++) { + /* kex algorithm taken care of so start with i=1 and not 0 */ + xfree(packet_get_string(&len)); + } + i = packet_get_char(); /* first_kex_packet_follows */ + if (i && (c = strchr(kexlist, ','))) + *c = 0; + if (i && strcmp(kexlist, KEX_RESUME)) { + debug("server's kex guess (%s) was wrong, skipping", kexlist); + (void)packet_read(); /* Wrong guess - discard packet */ + } + + /* + * Read the ROAMING_AUTH_REQUIRED challenge from the server and + * send ROAMING_AUTH + */ + if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) { + debug("expected roaming_auth_required, got %d", type); + goto fail; + } + roaming_auth_required(); + + /* Read ROAMING_AUTH_OK from the server */ + if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) { + debug("expected roaming_auth_ok, got %d", type); + goto fail; + } + recv_bytes = packet_get_int64() ^ oldkey2; + debug("Peer received %" PRIu64 " bytes", recv_bytes); + resend_bytes(packet_get_connection_out(), &recv_bytes); + + resume_in_progress = 0; + + session_resumed = 1; /* Tell clientloop */ + + return 0; + +fail: + if (kexlist) + xfree(kexlist); + if (packet_get_connection_in() == packet_get_connection_out()) + close(packet_get_connection_in()); + else { + close(packet_get_connection_in()); + close(packet_get_connection_out()); + } + return 1; +} + +int +wait_for_roaming_reconnect(void) +{ + static int reenter_guard = 0; + int timeout_ms = options.connection_timeout * 1000; + int c; + + if (reenter_guard != 0) + fatal("Server refused resume, roaming timeout may be exceeded"); + reenter_guard = 1; + + fprintf(stderr, "[connection suspended, press return to resume]"); + fflush(stderr); + packet_backup_state(); + /* TODO Perhaps we should read from tty here */ + while ((c = fgetc(stdin)) != EOF) { + if (c == 'Z' - 64) { + kill(getpid(), SIGTSTP); + continue; + } + if (c != '\n' && c != '\r') + continue; + + if (ssh_connect(host, &hostaddr, options.port, + options.address_family, 1, &timeout_ms, + options.tcp_keep_alive, options.use_privileged_port, + options.proxy_command) == 0 && roaming_resume() == 0) { + packet_restore_state(); + reenter_guard = 0; + fprintf(stderr, "[connection resumed]\n"); + fflush(stderr); + return 0; + } + + fprintf(stderr, "[reconnect failed, press return to retry]"); + fflush(stderr); + } + fprintf(stderr, "[exiting]\n"); + fflush(stderr); + exit(0); +} diff --git a/roaming_serv.c b/roaming_serv.c new file mode 100644 index 000000000..65e9fe631 --- /dev/null +++ b/roaming_serv.c @@ -0,0 +1,29 @@ +/* $OpenBSD: roaming_serv.c,v 1.1 2009/10/24 11:18:23 andreas Exp $ */ +/* + * Copyright (c) 2004-2009 AppGate Network Security AB + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "roaming.h" + +/* + * Wait for the roaming client to reconnect. Returns 0 if a connect ocurred. + */ +int +wait_for_roaming_reconnect(void) +{ + return 1; +} -- cgit v1.2.3 From dce7a92c7a1dbdfc280d6274eb5dfa5fce062acf Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:27:57 +1100 Subject: - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines. --- ChangeLog | 1 + Makefile.in | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbe3c0c92..e900cb637 100644 --- a/ChangeLog +++ b/ChangeLog @@ -156,6 +156,7 @@ ok markus@ - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new files for roaming and add to Makefile. + - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/Makefile.in b/Makefile.in index a16782dff..d7f338c0f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.302 2010/01/08 08:13:25 dtucker Exp $ +# $Id: Makefile.in,v 1.303 2010/01/08 08:27:57 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -75,7 +75,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ - roaming_common.o roaming_client.c + roaming_common.o roaming_client.o SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ sshpty.o sshlogin.o servconf.o serverloop.o \ @@ -88,7 +88,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \ - roaming_common.o roaming_serv.c + roaming_common.o roaming_serv.o MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 -- cgit v1.2.3 From e67f7db968e376c9971dd3a4d4ab3fae4a06bf78 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:50:02 +1100 Subject: - (dtucker) [sftp.c] ifdef out the sftp completion bits for platforms that don't have libedit. --- ChangeLog | 2 ++ sftp.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e900cb637..d0fde0fb3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -157,6 +157,8 @@ - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new files for roaming and add to Makefile. - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines. + - (dtucker) [sftp.c] ifdef out the sftp completion bits for platforms that + don't have libedit. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp.c b/sftp.c index 6a5ccc49d..c994887e3 100644 --- a/sftp.c +++ b/sftp.c @@ -1503,7 +1503,6 @@ prompt(EditLine *el) { return ("sftp> "); } -#endif /* Display entries in 'list' after skipping the first 'len' chars */ static void @@ -1646,6 +1645,7 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, return count; } +#endif /* * Determine whether a particular sftp command's arguments (if any) @@ -1666,6 +1666,7 @@ complete_is_remote(char *cmd) { return -1; } +#ifdef USE_LIBEDIT /* Autocomplete a filename "file" */ static int complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, @@ -1838,6 +1839,7 @@ complete(EditLine *el, int ch) xfree(line); return ret; } +#endif /* USE_LIBEDIT */ int interactive_loop(struct sftp_conn *conn, char *file1, char *file2) -- cgit v1.2.3 From 1f5e3dc274fe4616435ff451b5216b5bde217c0d Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:53:52 +1100 Subject: - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Make RoutingDomain an unsupported option on platforms that don't have it. --- ChangeLog | 2 ++ configure.ac | 9 +++++++-- misc.c | 4 ++++ readconf.c | 6 ++++++ servconf.c | 6 ++++++ ssh-keyscan.c | 6 ++++++ 6 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d0fde0fb3..440c8318e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -159,6 +159,8 @@ - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines. - (dtucker) [sftp.c] ifdef out the sftp completion bits for platforms that don't have libedit. + - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Make + RoutingDomain an unsupported option on platforms that don't have it. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/configure.ac b/configure.ac index 94f049fc6..424114015 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.432 2009/12/08 02:39:48 dtucker Exp $ +# $Id: configure.ac,v 1.433 2010/01/08 08:53:52 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.432 $) +AC_REVISION($Revision: 1.433 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1623,6 +1623,11 @@ if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "x ) fi +AC_CHECK_DECL(SO_RDOMAIN, + AC_DEFINE(USE_ROUTINGDOMAIN, 1, [Enable rdomain/VRF support]), , + [#include + #include ]) + dnl see whether mkstemp() requires XXXXXX if test "x$ac_cv_func_mkdtemp" = "xyes" ; then AC_MSG_CHECKING([for (overly) strict mkstemp]) diff --git a/misc.c b/misc.c index d4bdfc0ea..db57f92b2 100644 --- a/misc.c +++ b/misc.c @@ -155,6 +155,7 @@ set_nodelay(int fd) int socket_rdomain(int domain, int type, int protocol, int rdomain) { +#ifdef USE_ROUTINGDOMAIN int sock, ipproto = IPPROTO_IP; if ((sock = socket(domain, type, protocol)) == -1) @@ -186,6 +187,7 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) } return (sock); +#endif } /* Characters considered whitespace in strsep calls. */ @@ -273,6 +275,7 @@ a2port(const char *s) return (int)port; } +#ifdef USE_ROUTINGDOMAIN int a2rdomain(const char *s) { @@ -284,6 +287,7 @@ a2rdomain(const char *s) return -1; return (int)rdomain; } +#endif int a2tun(const char *s, int *remote) diff --git a/readconf.c b/readconf.c index 40fe8f694..47c77472a 100644 --- a/readconf.c +++ b/readconf.c @@ -229,7 +229,11 @@ static struct { { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, { "useroaming", oUseRoaming }, +#ifdef USE_ROUTINGDOMAIN { "routingdomain", oRDomain }, +#else + { "routingdomain", oUnsupported }, +#endif #ifdef JPAKE { "zeroknowledgepasswordauthentication", oZeroKnowledgePasswordAuthentication }, @@ -920,6 +924,7 @@ parse_int: intptr = &options->use_roaming; goto parse_flag; +#ifdef USE_ROUTINGDOMAIN case oRDomain: arg = strdelim(&s); if (!arg || *arg == '\0') @@ -932,6 +937,7 @@ parse_int: if (*activep) options->rdomain = value; break; +#endif case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", diff --git a/servconf.c b/servconf.c index 2cdc480e6..9ad08ce87 100644 --- a/servconf.c +++ b/servconf.c @@ -424,7 +424,11 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, +#ifdef USE_ROUTINGDOMAIN { "routingdomain", sRDomain, SSHCFG_GLOBAL }, +#else + { "routingdomain", sUnsupported, SSHCFG_GLOBAL }, +#endif { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1296,6 +1300,7 @@ process_server_config_line(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; +#ifdef USE_ROUTINGDOMAIN case sRDomain: intptr = &options->rdomain; arg = strdelim(&cp); @@ -1308,6 +1313,7 @@ process_server_config_line(ServerOptions *options, char *line, if (*intptr == -1) *intptr = value; break; +#endif case sDeprecated: logit("%s line %d: Deprecated option %s", diff --git a/ssh-keyscan.c b/ssh-keyscan.c index faeb9e13e..086c0d345 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -807,11 +807,17 @@ main(int argc, char **argv) IPv4or6 = AF_INET6; break; case 'V': +#ifdef USE_ROUTINGDOMAIN scan_rdomain = a2rdomain(optarg); if (scan_rdomain == -1) { fprintf(stderr, "Bad rdomain '%s'\n", optarg); exit(1); } +#else + fprintf(stderr, "RoutingDomain not supported on this " + "platform.\n"); + exit(1); +#endif break; case '?': default: -- cgit v1.2.3 From 843f0fa16d7e8aca36c1b14d933da2a1844d5a74 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:56:33 +1100 Subject: - (dtucker) [sftp.c] Expand ifdef for libedit to cover complete_is_remote too. --- ChangeLog | 2 ++ sftp.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 440c8318e..60162c088 100644 --- a/ChangeLog +++ b/ChangeLog @@ -161,6 +161,8 @@ don't have libedit. - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Make RoutingDomain an unsupported option on platforms that don't have it. + - (dtucker) [sftp.c] Expand ifdef for libedit to cover complete_is_remote + too. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp.c b/sftp.c index c994887e3..4b12fae4b 100644 --- a/sftp.c +++ b/sftp.c @@ -1645,7 +1645,6 @@ complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, return count; } -#endif /* * Determine whether a particular sftp command's arguments (if any) @@ -1666,7 +1665,6 @@ complete_is_remote(char *cmd) { return -1; } -#ifdef USE_LIBEDIT /* Autocomplete a filename "file" */ static int complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, -- cgit v1.2.3 From e83c3ea4b8086c04c9ba0d012808d9c65c0bbe65 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 20:03:56 +1100 Subject: - (dtucker) [misc.c] Move the routingdomain ifdef to allow the socket to be created. --- ChangeLog | 2 ++ misc.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 60162c088..8266723e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -163,6 +163,8 @@ RoutingDomain an unsupported option on platforms that don't have it. - (dtucker) [sftp.c] Expand ifdef for libedit to cover complete_is_remote too. + - (dtucker) [misc.c] Move the routingdomain ifdef to allow the socket to + be created. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/misc.c b/misc.c index db57f92b2..08a80226d 100644 --- a/misc.c +++ b/misc.c @@ -155,7 +155,6 @@ set_nodelay(int fd) int socket_rdomain(int domain, int type, int protocol, int rdomain) { -#ifdef USE_ROUTINGDOMAIN int sock, ipproto = IPPROTO_IP; if ((sock = socket(domain, type, protocol)) == -1) @@ -163,7 +162,8 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) if (rdomain == -1) return (sock); - + +#ifdef USE_ROUTINGDOMAIN switch (domain) { case AF_INET6: ipproto = IPPROTO_IPV6; @@ -187,6 +187,8 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) } return (sock); +#else + return (-1); #endif } -- cgit v1.2.3 From cb5a1b6f7028dc3e3bf9f5875aee4a071eefe359 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 20:09:01 +1100 Subject: - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more to eliminate an unused variable warning. --- ChangeLog | 2 ++ misc.c | 6 ++---- roaming_client.c | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8266723e8..adb52db3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -165,6 +165,8 @@ too. - (dtucker) [misc.c] Move the routingdomain ifdef to allow the socket to be created. + - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more + to eliminate an unused variable warning. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/misc.c b/misc.c index 08a80226d..f62f8efc6 100644 --- a/misc.c +++ b/misc.c @@ -163,12 +163,12 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) if (rdomain == -1) return (sock); -#ifdef USE_ROUTINGDOMAIN switch (domain) { case AF_INET6: ipproto = IPPROTO_IPV6; /* FALLTHROUGH */ case AF_INET: +#ifdef USE_ROUTINGDOMAIN debug2("socket %d af %d setting rdomain %d", sock, domain, rdomain); if (setsockopt(sock, ipproto, SO_RDOMAIN, &rdomain, @@ -178,6 +178,7 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) close(sock); return (-1); } +#endif break; default: debug("socket %d af %d does not support rdomain %d", @@ -187,9 +188,6 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) } return (sock); -#else - return (-1); -#endif } /* Characters considered whitespace in strsep calls. */ diff --git a/roaming_client.c b/roaming_client.c index b77dbd59b..cfa57f613 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -15,6 +15,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "includes.h" + #include #include #include -- cgit v1.2.3 From 1a8f535b970738f8de7599d5815d3be3beaa3b48 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 20:45:42 +1100 Subject: - (dtucker) [roaming_serv.c] Include includes.h for u_intXX_t types. --- ChangeLog | 1 + roaming_serv.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index adb52db3a..11093e7ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -167,6 +167,7 @@ be created. - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more to eliminate an unused variable warning. + - (dtucker) [roaming_serv.c] Include includes.h for u_intXX_t types. 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/roaming_serv.c b/roaming_serv.c index 65e9fe631..511ca8461 100644 --- a/roaming_serv.c +++ b/roaming_serv.c @@ -15,6 +15,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "includes.h" + #include #include "roaming.h" -- cgit v1.2.3 From 340d1688e658e85a3c45270bc3fca4e6d1aee9b1 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 08:54:31 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/08 21:50:49 [sftp.c] Fix two warnings: possibly used unitialized and use a nul byte instead of NULL pointer. ok djm@ --- ChangeLog | 4 ++++ sftp.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 11093e7ad..b1350dc35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -154,6 +154,10 @@ [sftp-server.c] bz#1566 don't unnecessarily dup() in and out fds for sftp-server; ok markus@ + - dtucker@cvs.openbsd.org 2010/01/08 21:50:49 + [sftp.c] + Fix two warnings: possibly used unitialized and use a nul byte instead of + NULL pointer. ok djm@ - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new files for roaming and add to Makefile. - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines. diff --git a/sftp.c b/sftp.c index 4b12fae4b..9f5fa354d 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.116 2010/01/04 02:03:57 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.117 2010/01/08 21:50:49 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1568,7 +1568,7 @@ complete_ambiguous(const char *word, char **list, size_t count) if (matchlen > strlen(word)) { char *tmp = xstrdup(list[0]); - tmp[matchlen] = NULL; + tmp[matchlen] = '\0'; return tmp; } } @@ -2062,7 +2062,7 @@ int main(int argc, char **argv) { int in, out, ch, err; - char *host, *userhost, *cp, *file2 = NULL; + char *host = NULL, *userhost, *cp, *file2 = NULL; int debug_level = 0, sshver = 2; char *file1 = NULL, *sftp_server = NULL; char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL; -- cgit v1.2.3 From 9eba40cec9de097b41f3f1c84799476f14260920 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 09:02:07 +1100 Subject: - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't have it. --- ChangeLog | 4 ++++ misc.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index b1350dc35..79491f54a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091209 + - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't + have it. + 20091208 - (dtucker) OpenBSD CVS Sync - andreas@cvs.openbsd.org 2009/10/24 11:11:58 diff --git a/misc.c b/misc.c index f62f8efc6..b260d89fe 100644 --- a/misc.c +++ b/misc.c @@ -164,9 +164,11 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) return (sock); switch (domain) { +#ifdef IPPROTO_IPV6 case AF_INET6: ipproto = IPPROTO_IPV6; /* FALLTHROUGH */ +#endif case AF_INET: #ifdef USE_ROUTINGDOMAIN debug2("socket %d af %d setting rdomain %d", -- cgit v1.2.3 From 709d0ce67201e980258c84928fda46edd1c8d38f Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 09:25:54 +1100 Subject: - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. --- ChangeLog | 1 + defines.h | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 79491f54a..65bbdd6bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 20091209 - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't have it. + - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/defines.h b/defines.h index 2ddfd96d0..053893ee4 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.156 2009/08/28 01:21:07 dtucker Exp $ */ +/* $Id: defines.h,v 1.157 2010/01/08 22:25:54 dtucker Exp $ */ /* Constants */ @@ -753,4 +753,8 @@ struct winsize { # define SSH_IOBUFSZ 8192 #endif +#ifndef PRIu64 +# define PRIu64 "llu" +#endif + #endif /* _DEFINES_H */ -- cgit v1.2.3 From 11b5c07941f206d955184ff1e4c1ff6fba37d157 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 16:40:48 +1100 Subject: - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. --- ChangeLog | 1 + roaming_client.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 65bbdd6bc..9e8b41017 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't have it. - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. + - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/roaming_client.c b/roaming_client.c index cfa57f613..c80db5826 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -21,7 +21,9 @@ #include #include +#ifdef HAVE_INTTYPES_H #include +#endif #include #include #include -- cgit v1.2.3 From 0b8a2262ac9ee2b2395cf85e3dfa065385c25b5a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 18:18:04 +1100 Subject: - (dtucker) [loginrec.c] Use the SUSv3 specified name for the user name when using utmpx. Patch from Ed Schouten. --- ChangeLog | 2 ++ loginrec.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e8b41017..31f205f6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ have it. - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. + - (dtucker) [loginrec.c] Use the SUSv3 specified name for the user name + when using utmpx. Patch from Ed Schouten. 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/loginrec.c b/loginrec.c index f4af06736..bca959707 100644 --- a/loginrec.c +++ b/loginrec.c @@ -758,8 +758,8 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) utx->ut_pid = li->pid; /* strncpy(): Don't necessarily want null termination */ - strncpy(utx->ut_name, li->username, - MIN_SIZEOF(utx->ut_name, li->username)); + strncpy(utx->ut_user, li->username, + MIN_SIZEOF(utx->ut_user, li->username)); if (li->type == LTYPE_LOGOUT) return; @@ -1316,8 +1316,8 @@ wtmpx_write_entry(struct logininfo *li) static int wtmpx_islogin(struct logininfo *li, struct utmpx *utx) { - if (strncmp(li->username, utx->ut_name, - MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { + if (strncmp(li->username, utx->ut_user, + MIN_SIZEOF(li->username, utx->ut_user)) == 0 ) { # ifdef HAVE_TYPE_IN_UTMPX if (utx->ut_type == USER_PROCESS) return (1); -- cgit v1.2.3 From db7bf82544800c21a471a89781466bbf4ac08731 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:24:33 +1100 Subject: - djm@cvs.openbsd.org 2010/01/09 00:20:26 [sftp-server.c sftp-server.8] add a 'read-only' mode to sftp-server(8) that disables open in write mode and all other fs-modifying protocol methods. bz#430 ok dtucker@ --- ChangeLog | 5 +++ sftp-server.8 | 12 +++++-- sftp-server.c | 103 +++++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31f205f6a..647d71def 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,11 @@ - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. - (dtucker) [loginrec.c] Use the SUSv3 specified name for the user name when using utmpx. Patch from Ed Schouten. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/01/09 00:20:26 + [sftp-server.c sftp-server.8] + add a 'read-only' mode to sftp-server(8) that disables open in write mode + and all other fs-modifying protocol methods. bz#430 ok dtucker@ 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-server.8 b/sftp-server.8 index ee73c345b..84036922c 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.17 2009/08/31 21:01:29 djm Exp $ +.\" $OpenBSD: sftp-server.8,v 1.18 2010/01/09 00:20:26 djm Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 31 2009 $ +.Dd $Mdocdate: January 9 2010 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -30,7 +30,7 @@ .Nd SFTP server subsystem .Sh SYNOPSIS .Nm sftp-server -.Op Fl eh +.Op Fl ehR .Op Fl f Ar log_facility .Op Fl l Ar log_level .Op Fl u Ar umask @@ -81,6 +81,12 @@ performs on behalf of the client. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. +.It Fl R +Places this instance of +.Nm +into a read-only mode. +Attempts to open files for writing, as well as other operations that change +the state of the filesystem will be denied. .It Fl u Ar umask Sets an explicit .Xr umask 2 diff --git a/sftp-server.c b/sftp-server.c index cf4e273f8..ab9391cfd 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.89 2010/01/04 02:25:15 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.90 2010/01/09 00:20:26 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -70,6 +70,9 @@ Buffer oqueue; /* Version of client */ int version; +/* Disable writes */ +int readonly; + /* portable attributes, etc. */ typedef struct Stat Stat; @@ -553,16 +556,21 @@ process_open(void) mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); - fd = open(name, flags, mode); - if (fd < 0) { - status = errno_to_portable(errno); - } else { - handle = handle_new(HANDLE_FILE, name, fd, NULL); - if (handle < 0) { - close(fd); + if (readonly && + ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) + status = SSH2_FX_PERMISSION_DENIED; + else { + fd = open(name, flags, mode); + if (fd < 0) { + status = errno_to_portable(errno); } else { - send_handle(id, handle); - status = SSH2_FX_OK; + handle = handle_new(HANDLE_FILE, name, fd, NULL); + if (handle < 0) { + close(fd); + } else { + send_handle(id, handle); + status = SSH2_FX_OK; + } } } if (status != SSH2_FX_OK) @@ -632,7 +640,7 @@ process_write(void) u_int32_t id; u_int64_t off; u_int len; - int handle, fd, ret, status = SSH2_FX_FAILURE; + int handle, fd, ret, status; char *data; id = get_int(); @@ -643,7 +651,12 @@ process_write(void) debug("request %u: write \"%s\" (handle %d) off %llu len %d", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); - if (fd >= 0) { + + if (fd < 0) + status = SSH2_FX_FAILURE; + else if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { if (lseek(fd, off, SEEK_SET) < 0) { status = errno_to_portable(errno); error("process_write: seek failed"); @@ -658,6 +671,7 @@ process_write(void) handle_update_write(handle, ret); } else { debug2("nothing at all written"); + status = SSH2_FX_FAILURE; } } } @@ -754,6 +768,10 @@ process_setstat(void) name = get_string(NULL); a = get_attrib(); debug("request %u: setstat name \"%s\"", id, name); + if (readonly) { + status = SSH2_FX_PERMISSION_DENIED; + a->flags = 0; + } if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a->size); @@ -802,9 +820,11 @@ process_fsetstat(void) a = get_attrib(); debug("request %u: fsetstat handle %d", id, handle); fd = handle_to_fd(handle); - if (fd < 0) { + if (fd < 0) status = SSH2_FX_FAILURE; - } else { + else if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { char *name = handle_to_name(handle); if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { @@ -952,8 +972,12 @@ process_remove(void) name = get_string(NULL); debug3("request %u: remove", id); logit("remove name \"%s\"", name); - ret = unlink(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = unlink(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(name); } @@ -973,8 +997,12 @@ process_mkdir(void) a->perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); - ret = mkdir(name, mode); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = mkdir(name, mode); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(name); } @@ -990,8 +1018,12 @@ process_rmdir(void) name = get_string(NULL); debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); - ret = rmdir(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = rmdir(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(name); } @@ -1036,7 +1068,9 @@ process_rename(void) debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; - if (lstat(oldpath, &sb) == -1) + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else if (lstat(oldpath, &sb) == -1) status = errno_to_portable(errno); else if (S_ISREG(sb.st_mode)) { /* Race-free rename of regular files */ @@ -1120,8 +1154,12 @@ process_symlink(void) debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ - ret = symlink(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = symlink(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(oldpath); xfree(newpath); @@ -1131,15 +1169,19 @@ static void process_extended_posix_rename(u_int32_t id) { char *oldpath, *newpath; + int ret, status; oldpath = get_string(NULL); newpath = get_string(NULL); debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); - if (rename(oldpath, newpath) == -1) - send_status(id, errno_to_portable(errno)); - else - send_status(id, SSH2_FX_OK); + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = rename(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } + send_status(id, status); xfree(oldpath); xfree(newpath); } @@ -1322,7 +1364,7 @@ sftp_server_usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-eh] [-f log_facility] [-l log_level] [-u umask]\n", + "usage: %s [-ehR] [-f log_facility] [-l log_level] [-u umask]\n", __progname); exit(1); } @@ -1344,8 +1386,11 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); - while (!skipargs && (ch = getopt(argc, argv, "f:l:u:che")) != -1) { + while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) { switch (ch) { + case 'R': + readonly = 1; + break; case 'c': /* * Ignore all arguments if we are invoked as a -- cgit v1.2.3 From a2e10485c5ef4b650536e156cc86d4bbd9bf146d Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:25:14 +1100 Subject: - djm@cvs.openbsd.org 2010/01/09 00:57:10 [PROTOCOL] tweak language --- ChangeLog | 3 +++ PROTOCOL | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 647d71def..b3260c7fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,9 @@ [sftp-server.c sftp-server.8] add a 'read-only' mode to sftp-server(8) that disables open in write mode and all other fs-modifying protocol methods. bz#430 ok dtucker@ + - djm@cvs.openbsd.org 2010/01/09 00:57:10 + [PROTOCOL] + tweak language 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/PROTOCOL b/PROTOCOL index c4fd57062..9b74b9475 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -6,8 +6,8 @@ filexfer protocol described in: http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt -Features from newer versions of the draft are not supported, unless -explicitly implemented as extensions described below. +Newer versions of the draft will not be supported, though some features +are individually implemented as extensions described below. The protocol used by OpenSSH's ssh-agent is described in the file PROTOCOL.agent @@ -251,4 +251,4 @@ The values of the f_flag bitmask are as follows: Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are advertised in the SSH_FXP_VERSION hello with version "2". -$OpenBSD: PROTOCOL,v 1.13 2009/12/20 23:20:40 djm Exp $ +$OpenBSD: PROTOCOL,v 1.14 2010/01/09 00:57:10 djm Exp $ -- cgit v1.2.3 From 838891fe85308399c4f350f8174013987b6a2f85 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:25:46 +1100 Subject: - jmc@cvs.openbsd.org 2010/01/09 03:36:00 [sftp-server.8] bad place to forget a comma... --- ChangeLog | 3 +++ sftp-server.8 | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3260c7fe..3b7fb6456 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,9 @@ - djm@cvs.openbsd.org 2010/01/09 00:57:10 [PROTOCOL] tweak language + - jmc@cvs.openbsd.org 2010/01/09 03:36:00 + [sftp-server.8] + bad place to forget a comma... 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-server.8 b/sftp-server.8 index 84036922c..bb19c15e1 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.18 2010/01/09 00:20:26 djm Exp $ +.\" $OpenBSD: sftp-server.8,v 1.19 2010/01/09 03:36:00 jmc Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -86,7 +86,7 @@ Places this instance of .Nm into a read-only mode. Attempts to open files for writing, as well as other operations that change -the state of the filesystem will be denied. +the state of the filesystem, will be denied. .It Fl u Ar umask Sets an explicit .Xr umask 2 -- cgit v1.2.3 From 37c1b3d6fc9043123f33e64051ea56656a5e7ef4 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:26:23 +1100 Subject: - djm@cvs.openbsd.org 2010/01/09 05:04:24 [mux.c sshpty.h clientloop.c sshtty.c] quell tc[gs]etattr warnings when forcing a tty (ssh -tt), since we usually don't actually have a tty to read/set; bz#1686 ok dtucker@ --- ChangeLog | 4 ++++ clientloop.c | 23 +++++++++++++---------- mux.c | 7 ++++--- sshpty.h | 6 +++--- sshtty.c | 23 +++++++++++++---------- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b7fb6456..b3ae6bdb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,10 @@ - jmc@cvs.openbsd.org 2010/01/09 03:36:00 [sftp-server.8] bad place to forget a comma... + - djm@cvs.openbsd.org 2010/01/09 05:04:24 + [mux.c sshpty.h clientloop.c sshtty.c] + quell tc[gs]etattr warnings when forcing a tty (ssh -tt), since we + usually don't actually have a tty to read/set; bz#1686 ok dtucker@ 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/clientloop.c b/clientloop.c index eca87777f..5793a6e91 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.215 2009/11/17 05:31:44 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.216 2010/01/09 05:04:24 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -130,6 +130,9 @@ extern int muxserver_sock; */ extern char *host; +/* Force TTY allocation */ +extern int force_tty_flag; + /* * Flag to indicate that we have received a window change signal which has * not yet been processed. This will cause a message indicating the new @@ -610,7 +613,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); - leave_raw_mode(); + leave_raw_mode(force_tty_flag); /* * Free (and clear) the buffer to reduce the amount of data that gets @@ -631,7 +634,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) buffer_init(bout); buffer_init(berr); - enter_raw_mode(); + enter_raw_mode(force_tty_flag); } static void @@ -774,7 +777,7 @@ process_cmdline(void) bzero(&fwd, sizeof(fwd)); fwd.listen_host = fwd.connect_host = NULL; - leave_raw_mode(); + leave_raw_mode(force_tty_flag); handler = signal(SIGINT, SIG_IGN); cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); if (s == NULL) @@ -877,7 +880,7 @@ process_cmdline(void) out: signal(SIGINT, handler); - enter_raw_mode(); + enter_raw_mode(force_tty_flag); if (cmd) xfree(cmd); if (fwd.listen_host != NULL) @@ -996,7 +999,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, * more new connections). */ /* Restore tty modes. */ - leave_raw_mode(); + leave_raw_mode(force_tty_flag); /* Stop listening for new connections. */ channel_stop_listening(); @@ -1291,7 +1294,7 @@ client_channel_closed(int id, void *arg) { channel_cancel_cleanup(id); session_closed = 1; - leave_raw_mode(); + leave_raw_mode(force_tty_flag); } /* @@ -1364,7 +1367,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) signal(SIGWINCH, window_change_handler); if (have_pty) - enter_raw_mode(); + enter_raw_mode(force_tty_flag); if (compat20) { session_ident = ssh2_chan_id; @@ -1498,7 +1501,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) channel_free_all(); if (have_pty) - leave_raw_mode(); + leave_raw_mode(force_tty_flag); /* restore blocking io */ if (!isatty(fileno(stdin))) @@ -2062,7 +2065,7 @@ client_init_dispatch(void) void cleanup_exit(int i) { - leave_raw_mode(); + leave_raw_mode(force_tty_flag); leave_non_blocking(); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); diff --git a/mux.c b/mux.c index fac43a71f..239edd5f5 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.8 2009/08/20 23:54:28 dtucker Exp $ */ +/* $OpenBSD: mux.c,v 1.9 2010/01/09 05:04:24 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -82,6 +82,7 @@ /* from ssh.c */ extern int tty_flag; +extern int force_tty_flag; extern Options options; extern int stdin_null_flag; extern char *host; @@ -683,7 +684,7 @@ muxclient(const char *path) signal(SIGWINCH, control_client_sigrelay); if (tty_flag) - enter_raw_mode(); + enter_raw_mode(force_tty_flag); /* * Stick around until the controlee closes the client_fd. @@ -708,7 +709,7 @@ muxclient(const char *path) } close(sock); - leave_raw_mode(); + leave_raw_mode(force_tty_flag); if (i > (int)sizeof(int)) fatal("%s: master returned too much data (%d > %lu)", __func__, i, (u_long)sizeof(int)); diff --git a/sshpty.h b/sshpty.h index ac9003584..cfa322480 100644 --- a/sshpty.h +++ b/sshpty.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshpty.h,v 1.11 2008/05/19 15:45:07 djm Exp $ */ +/* $OpenBSD: sshpty.h,v 1.12 2010/01/09 05:04:24 djm Exp $ */ /* * Author: Tatu Ylonen @@ -17,8 +17,8 @@ #include struct termios *get_saved_tio(void); -void leave_raw_mode(void); -void enter_raw_mode(void); +void leave_raw_mode(int); +void enter_raw_mode(int); int pty_allocate(int *, int *, char *, size_t); void pty_release(const char *); diff --git a/sshtty.c b/sshtty.c index 21ade4e51..d214ce3bb 100644 --- a/sshtty.c +++ b/sshtty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshtty.c,v 1.13 2008/05/19 15:45:07 djm Exp $ */ +/* $OpenBSD: sshtty.c,v 1.14 2010/01/09 05:04:24 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -54,23 +54,25 @@ get_saved_tio(void) } void -leave_raw_mode(void) +leave_raw_mode(int quiet) { if (!_in_raw_mode) return; - if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) - perror("tcsetattr"); - else + if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) { + if (!quiet) + perror("tcsetattr"); + } else _in_raw_mode = 0; } void -enter_raw_mode(void) +enter_raw_mode(int quiet) { struct termios tio; if (tcgetattr(fileno(stdin), &tio) == -1) { - perror("tcgetattr"); + if (!quiet) + perror("tcgetattr"); return; } _saved_tio = tio; @@ -86,8 +88,9 @@ enter_raw_mode(void) tio.c_oflag &= ~OPOST; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; - if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) - perror("tcsetattr"); - else + if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) { + if (!quiet) + perror("tcsetattr"); + } else _in_raw_mode = 1; } -- cgit v1.2.3 From 4b28251df4f1b653e7b3e015138c3da53a05bd58 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:27:06 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/09 05:17:00 [roaming_client.c] Remove a PRIu64 format string that snuck in with roaming. ok djm@ --- ChangeLog | 3 +++ roaming_client.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3ae6bdb4..9eda2f396 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,9 @@ [mux.c sshpty.h clientloop.c sshtty.c] quell tc[gs]etattr warnings when forcing a tty (ssh -tt), since we usually don't actually have a tty to read/set; bz#1686 ok dtucker@ + - dtucker@cvs.openbsd.org 2010/01/09 05:17:00 + [roaming_client.c] + Remove a PRIu64 format string that snuck in with roaming. ok djm@ 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/roaming_client.c b/roaming_client.c index c80db5826..cc387a544 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_client.c,v 1.1 2009/10/24 11:22:37 andreas Exp $ */ +/* $OpenBSD: roaming_client.c,v 1.2 2010/01/09 05:17:00 dtucker Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -122,7 +122,7 @@ roaming_auth_required(void) calculate_new_key(&key1, cookie, chall); calculate_new_key(&key2, cookie, chall); - debug("Received %" PRIu64 " bytes", get_recv_bytes()); + debug("Received %llu bytes", (long long unsigned)get_recv_bytes()); debug("Sent roaming_auth packet"); } @@ -216,7 +216,7 @@ roaming_resume(void) goto fail; } recv_bytes = packet_get_int64() ^ oldkey2; - debug("Peer received %" PRIu64 " bytes", recv_bytes); + debug("Peer received %llu bytes", (long long unsigned)recv_bytes); resend_bytes(packet_get_connection_out(), &recv_bytes); resume_in_progress = 0; -- cgit v1.2.3 From 70cc092817a61af78c751b8f7a8ac5dcabfeae00 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:28:03 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/09 11:13:02 [sftp.c] Prevent sftp from derefing a null pointer when given a "-" without a command. Also, allow whitespace to follow a "-". bz#1691, path from Colin Watson via Debian. ok djm@ deraadt@ --- ChangeLog | 5 +++++ sftp.c | 11 ++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9eda2f396..094d1bec3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,11 @@ - dtucker@cvs.openbsd.org 2010/01/09 05:17:00 [roaming_client.c] Remove a PRIu64 format string that snuck in with roaming. ok djm@ + - dtucker@cvs.openbsd.org 2010/01/09 11:13:02 + [sftp.c] + Prevent sftp from derefing a null pointer when given a "-" without a + command. Also, allow whitespace to follow a "-". bz#1691, path from + Colin Watson via Debian. ok djm@ deraadt@ 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/sftp.c b/sftp.c index 9f5fa354d..78f8ca178 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.117 2010/01/08 21:50:49 dtucker Exp $ */ +/* $OpenBSD: sftp.c,v 1.118 2010/01/09 11:13:02 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1112,17 +1112,18 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, /* Skip leading whitespace */ cp = cp + strspn(cp, WHITESPACE); - /* Ignore blank lines and lines which begin with comment '#' char */ - if (*cp == '\0' || *cp == '#') - return (0); - /* Check for leading '-' (disable error processing) */ *iflag = 0; if (*cp == '-') { *iflag = 1; cp++; + cp = cp + strspn(cp, WHITESPACE); } + /* Ignore blank lines and lines which begin with comment '#' char */ + if (*cp == '\0' || *cp == '#') + return (0); + if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL) return -1; -- cgit v1.2.3 From 2c671bf6a8b93489624fafa79a40cb69d7a53ba3 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:28:43 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/09 11:17:56 [sshd.c] Afer sshd receives a SIGHUP, ignore subsequent HUPs while sshd re-execs itself. Prevents two HUPs in quick succession from resulting in sshd dying. bz#1692, patch from Colin Watson via Ubuntu. --- ChangeLog | 5 +++++ sshd.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 094d1bec3..47cb97afe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,11 @@ Prevent sftp from derefing a null pointer when given a "-" without a command. Also, allow whitespace to follow a "-". bz#1691, path from Colin Watson via Debian. ok djm@ deraadt@ + - dtucker@cvs.openbsd.org 2010/01/09 11:17:56 + [sshd.c] + Afer sshd receives a SIGHUP, ignore subsequent HUPs while sshd re-execs + itself. Prevents two HUPs in quick succession from resulting in sshd + dying. bz#1692, patch from Colin Watson via Ubuntu. 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/sshd.c b/sshd.c index e23d462ee..bdaf1574a 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.368 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: sshd.c,v 1.369 2010/01/09 11:17:56 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -309,6 +309,7 @@ sighup_restart(void) close_listen_socks(); close_startup_pipes(); alarm(0); /* alarm timer persists across exec */ + signal(SIGHUP, SIG_IGN); /* will be restored after exec */ execv(saved_argv[0], saved_argv); logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno)); -- cgit v1.2.3 From 269275c90cd2ffda85f32114bfaeff978298e346 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:33:37 +1100 Subject: - (dtucker) [defines.h] Remove now-undeeded PRIu64 define. --- ChangeLog | 1 + defines.h | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47cb97afe..6700f308e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -33,6 +33,7 @@ Afer sshd receives a SIGHUP, ignore subsequent HUPs while sshd re-execs itself. Prevents two HUPs in quick succession from resulting in sshd dying. bz#1692, patch from Colin Watson via Ubuntu. + - (dtucker) [defines.h] Remove now-undeeded PRIu64 define. 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/defines.h b/defines.h index 053893ee4..3211cc916 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.157 2010/01/08 22:25:54 dtucker Exp $ */ +/* $Id: defines.h,v 1.158 2010/01/09 11:33:37 dtucker Exp $ */ /* Constants */ @@ -753,8 +753,4 @@ struct winsize { # define SSH_IOBUFSZ 8192 #endif -#ifndef PRIu64 -# define PRIu64 "llu" -#endif - #endif /* _DEFINES_H */ -- cgit v1.2.3 From 8c65f646a93ed2f61da65ba0ecf65a99bd585b79 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 10 Jan 2010 10:26:57 +1100 Subject: - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Remove hacks add for RoutingDomain in preparation for its removal. --- ChangeLog | 4 ++++ configure.ac | 9 ++------- misc.c | 6 ------ readconf.c | 6 ------ servconf.c | 6 ------ ssh-keyscan.c | 6 ------ 6 files changed, 6 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6700f308e..e38cd5108 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20091210 + - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] + Remove hacks add for RoutingDomain in preparation for its removal. + 20091209 - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't have it. diff --git a/configure.ac b/configure.ac index 424114015..e6e6259bd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.433 2010/01/08 08:53:52 dtucker Exp $ +# $Id: configure.ac,v 1.434 2010/01/09 23:26:58 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.433 $) +AC_REVISION($Revision: 1.434 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1623,11 +1623,6 @@ if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "x ) fi -AC_CHECK_DECL(SO_RDOMAIN, - AC_DEFINE(USE_ROUTINGDOMAIN, 1, [Enable rdomain/VRF support]), , - [#include - #include ]) - dnl see whether mkstemp() requires XXXXXX if test "x$ac_cv_func_mkdtemp" = "xyes" ; then AC_MSG_CHECKING([for (overly) strict mkstemp]) diff --git a/misc.c b/misc.c index b260d89fe..550b03cad 100644 --- a/misc.c +++ b/misc.c @@ -164,13 +164,10 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) return (sock); switch (domain) { -#ifdef IPPROTO_IPV6 case AF_INET6: ipproto = IPPROTO_IPV6; /* FALLTHROUGH */ -#endif case AF_INET: -#ifdef USE_ROUTINGDOMAIN debug2("socket %d af %d setting rdomain %d", sock, domain, rdomain); if (setsockopt(sock, ipproto, SO_RDOMAIN, &rdomain, @@ -180,7 +177,6 @@ socket_rdomain(int domain, int type, int protocol, int rdomain) close(sock); return (-1); } -#endif break; default: debug("socket %d af %d does not support rdomain %d", @@ -277,7 +273,6 @@ a2port(const char *s) return (int)port; } -#ifdef USE_ROUTINGDOMAIN int a2rdomain(const char *s) { @@ -289,7 +284,6 @@ a2rdomain(const char *s) return -1; return (int)rdomain; } -#endif int a2tun(const char *s, int *remote) diff --git a/readconf.c b/readconf.c index 47c77472a..40fe8f694 100644 --- a/readconf.c +++ b/readconf.c @@ -229,11 +229,7 @@ static struct { { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, { "useroaming", oUseRoaming }, -#ifdef USE_ROUTINGDOMAIN { "routingdomain", oRDomain }, -#else - { "routingdomain", oUnsupported }, -#endif #ifdef JPAKE { "zeroknowledgepasswordauthentication", oZeroKnowledgePasswordAuthentication }, @@ -924,7 +920,6 @@ parse_int: intptr = &options->use_roaming; goto parse_flag; -#ifdef USE_ROUTINGDOMAIN case oRDomain: arg = strdelim(&s); if (!arg || *arg == '\0') @@ -937,7 +932,6 @@ parse_int: if (*activep) options->rdomain = value; break; -#endif case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", diff --git a/servconf.c b/servconf.c index 9ad08ce87..2cdc480e6 100644 --- a/servconf.c +++ b/servconf.c @@ -424,11 +424,7 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, -#ifdef USE_ROUTINGDOMAIN { "routingdomain", sRDomain, SSHCFG_GLOBAL }, -#else - { "routingdomain", sUnsupported, SSHCFG_GLOBAL }, -#endif { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1300,7 +1296,6 @@ process_server_config_line(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; -#ifdef USE_ROUTINGDOMAIN case sRDomain: intptr = &options->rdomain; arg = strdelim(&cp); @@ -1313,7 +1308,6 @@ process_server_config_line(ServerOptions *options, char *line, if (*intptr == -1) *intptr = value; break; -#endif case sDeprecated: logit("%s line %d: Deprecated option %s", diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 086c0d345..faeb9e13e 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -807,17 +807,11 @@ main(int argc, char **argv) IPv4or6 = AF_INET6; break; case 'V': -#ifdef USE_ROUTINGDOMAIN scan_rdomain = a2rdomain(optarg); if (scan_rdomain == -1) { fprintf(stderr, "Bad rdomain '%s'\n", optarg); exit(1); } -#else - fprintf(stderr, "RoutingDomain not supported on this " - "platform.\n"); - exit(1); -#endif break; case '?': default: -- cgit v1.2.3 From 7bd98e7f74ebd8bd32157b607acedcb68201b7de Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 10 Jan 2010 10:31:12 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/09 23:04:13 [channels.c ssh.1 servconf.c sshd_config.5 sshd.c channels.h servconf.h ssh-keyscan.1 ssh-keyscan.c readconf.c sshconnect.c misc.c ssh.c readconf.h scp.1 sftp.1 ssh_config.5 misc.h] Remove RoutingDomain from ssh since it's now not needed. It can be replaced with "route exec" or "nc -V" as a proxycommand. "route exec" also ensures that trafic such as DNS lookups stays withing the specified routingdomain. For example (from reyk): # route -T 2 exec /usr/sbin/sshd or inherited from the parent process $ route -T 2 exec sh $ ssh 10.1.2.3 ok deraadt@ markus@ stevesk@ reyk@ --- ChangeLog | 13 +++++++++++++ channels.c | 26 +++++++------------------- channels.h | 3 +-- misc.c | 51 +-------------------------------------------------- misc.h | 5 +---- readconf.c | 22 +++------------------- readconf.h | 4 +--- scp.1 | 5 ++--- servconf.c | 20 ++------------------ servconf.h | 4 +--- sftp.1 | 5 ++--- ssh-keyscan.1 | 7 ++----- ssh-keyscan.c | 19 ++++--------------- ssh.1 | 5 ++--- ssh.c | 3 +-- ssh_config.5 | 7 ++----- sshconnect.c | 5 ++--- sshd.c | 9 ++++----- sshd_config.5 | 7 ++----- 19 files changed, 53 insertions(+), 167 deletions(-) diff --git a/ChangeLog b/ChangeLog index e38cd5108..ca189f943 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,19 @@ 20091210 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Remove hacks add for RoutingDomain in preparation for its removal. + - dtucker@cvs.openbsd.org 2010/01/09 23:04:13 + [channels.c ssh.1 servconf.c sshd_config.5 sshd.c channels.h servconf.h + ssh-keyscan.1 ssh-keyscan.c readconf.c sshconnect.c misc.c ssh.c + readconf.h scp.1 sftp.1 ssh_config.5 misc.h] + Remove RoutingDomain from ssh since it's now not needed. It can be + replaced with "route exec" or "nc -V" as a proxycommand. "route exec" + also ensures that trafic such as DNS lookups stays withing the specified + routingdomain. For example (from reyk): + # route -T 2 exec /usr/sbin/sshd + or inherited from the parent process + $ route -T 2 exec sh + $ ssh 10.1.2.3 + ok deraadt@ markus@ stevesk@ reyk@ 20091209 - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't diff --git a/channels.c b/channels.c index 949392390..87dbe96d3 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.299 2009/11/11 21:37:03 markus Exp $ */ +/* $OpenBSD: channels.c,v 1.300 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -163,9 +163,6 @@ static u_int x11_fake_data_len; /* AF_UNSPEC or AF_INET or AF_INET6 */ static int IPv4or6 = AF_UNSPEC; -/* Set the routing domain a.k.a. VRF */ -static int channel_rdomain = -1; - /* helper */ static void port_open_helper(Channel *c, char *rtype); @@ -2466,12 +2463,6 @@ channel_set_af(int af) IPv4or6 = af; } -void -channel_set_rdomain(int rdomain) -{ - channel_rdomain = rdomain; -} - static int channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, int *allocated_listen_port, @@ -2580,8 +2571,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, continue; } /* Create a port to listen for the host. */ - sock = socket_rdomain(ai->ai_family, ai->ai_socktype, - ai->ai_protocol, channel_rdomain); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { /* this is no error since kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); @@ -2922,9 +2912,8 @@ connect_next(struct channel_connect *cctx) error("connect_next: getnameinfo failed"); continue; } - if ((sock = socket_rdomain(cctx->ai->ai_family, - cctx->ai->ai_socktype, cctx->ai->ai_protocol, - channel_rdomain)) == -1) { + if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, + cctx->ai->ai_protocol)) == -1) { if (cctx->ai->ai_next == NULL) error("socket: %.100s", strerror(errno)); else @@ -3110,8 +3099,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; - sock = socket_rdomain(ai->ai_family, ai->ai_socktype, - ai->ai_protocol, channel_rdomain); + sock = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); if (sock < 0) { if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { error("socket: %.100s", strerror(errno)); @@ -3286,8 +3275,7 @@ x11_connect_display(void) } for (ai = aitop; ai; ai = ai->ai_next) { /* Create a socket. */ - sock = socket_rdomain(ai->ai_family, ai->ai_socktype, - ai->ai_protocol, channel_rdomain); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { debug2("socket: %.100s", strerror(errno)); continue; diff --git a/channels.h b/channels.h index 4dbeeb6e1..f65a311dc 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.100 2009/11/11 21:37:03 markus Exp $ */ +/* $OpenBSD: channels.h,v 1.101 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -235,7 +235,6 @@ int channel_find_open(void); /* tcp forwarding */ void channel_set_af(int af); -void channel_set_rdomain(int); void channel_permit_all_opens(void); void channel_add_permitted_opens(char *, int); int channel_add_adm_permitted_opens(char *, int); diff --git a/misc.c b/misc.c index 550b03cad..e1f723123 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.74 2009/12/25 19:40:21 stevesk Exp $ */ +/* $OpenBSD: misc.c,v 1.75 2010/01/09 23:04:13 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -151,43 +151,6 @@ set_nodelay(int fd) error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); } -/* open a socket in the specified routing domain */ -int -socket_rdomain(int domain, int type, int protocol, int rdomain) -{ - int sock, ipproto = IPPROTO_IP; - - if ((sock = socket(domain, type, protocol)) == -1) - return (-1); - - if (rdomain == -1) - return (sock); - - switch (domain) { - case AF_INET6: - ipproto = IPPROTO_IPV6; - /* FALLTHROUGH */ - case AF_INET: - debug2("socket %d af %d setting rdomain %d", - sock, domain, rdomain); - if (setsockopt(sock, ipproto, SO_RDOMAIN, &rdomain, - sizeof(rdomain)) == -1) { - debug("setsockopt SO_RDOMAIN: %.100s", - strerror(errno)); - close(sock); - return (-1); - } - break; - default: - debug("socket %d af %d does not support rdomain %d", - sock, domain, rdomain); - close(sock); - return (-1); - } - - return (sock); -} - /* Characters considered whitespace in strsep calls. */ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -273,18 +236,6 @@ a2port(const char *s) return (int)port; } -int -a2rdomain(const char *s) -{ - long long rdomain; - const char *errstr; - - rdomain = strtonum(s, 0, RT_TABLEID_MAX, &errstr); - if (errstr != NULL) - return -1; - return (int)rdomain; -} - int a2tun(const char *s, int *remote) { diff --git a/misc.h b/misc.h index 1e859e255..32073acd4 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.40 2009/12/25 19:40:21 stevesk Exp $ */ +/* $OpenBSD: misc.h,v 1.41 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -23,7 +23,6 @@ int set_nonblock(int); int unset_nonblock(int); void set_nodelay(int); int a2port(const char *); -int a2rdomain(const char *); int a2tun(const char *, int *); char *put_host_port(const char *, u_short); char *hpdelim(char **); @@ -55,8 +54,6 @@ void freeargs(arglist *); int tun_open(int, int); -int socket_rdomain(int, int, int, int); - /* Common definitions for ssh tunnel device forwarding */ #define SSH_TUNMODE_NO 0x00 #define SSH_TUNMODE_POINTOPOINT 0x01 diff --git a/readconf.c b/readconf.c index 40fe8f694..d424c1697 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.181 2009/12/29 16:38:41 stevesk Exp $ */ +/* $OpenBSD: readconf.c,v 1.182 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -130,8 +130,8 @@ typedef enum { oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, - oVisualHostKey, oUseRoaming, oRDomain, - oZeroKnowledgePasswordAuthentication, oDeprecated, oUnsupported + oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, + oDeprecated, oUnsupported } OpCodes; /* Textual representations of the tokens. */ @@ -229,7 +229,6 @@ static struct { { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, { "useroaming", oUseRoaming }, - { "routingdomain", oRDomain }, #ifdef JPAKE { "zeroknowledgepasswordauthentication", oZeroKnowledgePasswordAuthentication }, @@ -920,19 +919,6 @@ parse_int: intptr = &options->use_roaming; goto parse_flag; - case oRDomain: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", - filename, linenum); - value = a2rdomain(arg); - if (value == -1) - fatal("%.200s line %d: Bad rdomain.", - filename, linenum); - if (*activep) - options->rdomain = value; - break; - case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1083,7 +1069,6 @@ initialize_options(Options * options) options->local_command = NULL; options->permit_local_command = -1; options->use_roaming = -1; - options->rdomain = -1; options->visual_host_key = -1; options->zero_knowledge_password_authentication = -1; } @@ -1232,7 +1217,6 @@ fill_default_options(Options * options) /* options->hostname will be set in the main program if appropriate */ /* options->host_key_alias should not be set by default */ /* options->preferred_authentications will be set in ssh */ - /* options->rdomain should not be set by default */ } /* diff --git a/readconf.h b/readconf.h index 6edc2eeda..f7c0b9c6d 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.80 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: readconf.h,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -125,8 +125,6 @@ typedef struct { int use_roaming; - int rdomain; /* routing domain a.k.a. VRF */ - } Options; #define SSHCTL_MASTER_NO 0 diff --git a/scp.1 b/scp.1 index 1d1cad0b0..74ee5db13 100644 --- a/scp.1 +++ b/scp.1 @@ -9,9 +9,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.48 2009/12/29 16:38:41 stevesk Exp $ +.\" $OpenBSD: scp.1,v 1.49 2010/01/09 23:04:13 dtucker Exp $ .\" -.Dd $Mdocdate: December 29 2009 $ +.Dd $Mdocdate: January 9 2010 $ .Dt SCP 1 .Os .Sh NAME @@ -160,7 +160,6 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RekeyLimit .It RhostsRSAAuthentication -.It RoutingDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/servconf.c b/servconf.c index 2cdc480e6..fc3e479bd 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.199 2009/12/29 16:38:41 stevesk Exp $ */ +/* $OpenBSD: servconf.c,v 1.200 2010/01/09 23:04:13 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -128,7 +128,6 @@ initialize_server_options(ServerOptions *options) options->adm_forced_command = NULL; options->chroot_directory = NULL; options->zero_knowledge_password_authentication = -1; - options->rdomain = -1; } void @@ -305,7 +304,7 @@ typedef enum { sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, sRDomain, + sUsePrivilegeSeparation, sAllowAgentForwarding, sZeroKnowledgePasswordAuthentication, sDeprecated, sUnsupported } ServerOpCodes; @@ -424,7 +423,6 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, - { "routingdomain", sRDomain, SSHCFG_GLOBAL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1296,19 +1294,6 @@ process_server_config_line(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; - case sRDomain: - intptr = &options->rdomain; - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing rdomain value.", - filename, linenum); - if ((value = a2rdomain(arg)) == -1) - fatal("%s line %d: invalid rdomain value.", - filename, linenum); - if (*intptr == -1) - *intptr = value; - break; - case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1585,7 +1570,6 @@ dump_config(ServerOptions *o) dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); - dump_cfg_int(sRDomain, o->rdomain); /* formatted integer arguments */ dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); diff --git a/servconf.h b/servconf.h index 19c7ae609..25a3f1b21 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.88 2009/10/28 16:38:18 reyk Exp $ */ +/* $OpenBSD: servconf.h,v 1.89 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -150,8 +150,6 @@ typedef struct { int num_permitted_opens; - int rdomain; - char *chroot_directory; } ServerOptions; diff --git a/sftp.1 b/sftp.1 index 81d87680d..3ec7a0234 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.79 2009/12/29 16:38:41 stevesk Exp $ +.\" $OpenBSD: sftp.1,v 1.80 2010/01/09 23:04:13 dtucker Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: December 29 2009 $ +.Dd $Mdocdate: January 9 2010 $ .Dt SFTP 1 .Os .Sh NAME @@ -209,7 +209,6 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RekeyLimit .It RhostsRSAAuthentication -.It RoutingDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index c9fb597ed..78255ff79 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.27 2009/10/28 16:38:18 reyk Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.28 2010/01/09 23:04:13 dtucker Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd $Mdocdate: October 28 2009 $ +.Dd $Mdocdate: January 9 2010 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -20,7 +20,6 @@ .Op Fl p Ar port .Op Fl T Ar timeout .Op Fl t Ar type -.Op Fl V Ar rdomain .Op Ar host | addrlist namelist .Ar ... .Ek @@ -96,8 +95,6 @@ for protocol version 2. Multiple values may be specified by separating them with commas. The default is .Dq rsa . -.It Fl V Ar rdomain -Set the routing domain. .It Fl v Verbose mode. Causes diff --git a/ssh-keyscan.c b/ssh-keyscan.c index faeb9e13e..7afe446ae 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.80 2009/12/25 19:40:21 stevesk Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -68,9 +68,6 @@ int timeout = 5; int maxfd; #define MAXCON (maxfd - 10) -/* The default routing domain */ -int scan_rdomain = -1; - extern char *__progname; fd_set *read_wait; size_t read_wait_nfdset; @@ -415,8 +412,7 @@ tcpconnect(char *host) if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); for (ai = aitop; ai; ai = ai->ai_next) { - s = socket_rdomain(ai->ai_family, ai->ai_socktype, - ai->ai_protocol, scan_rdomain); + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { error("socket: %s", strerror(errno)); continue; @@ -719,7 +715,7 @@ usage(void) { fprintf(stderr, "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n" - "\t\t [-V rdomain] [host | addrlist namelist] ...\n", + "\t\t [host | addrlist namelist] ...\n", __progname); exit(1); } @@ -745,7 +741,7 @@ main(int argc, char **argv) if (argc <= 1) usage(); - while ((opt = getopt(argc, argv, "Hv46p:T:t:f:V:")) != -1) { + while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) { switch (opt) { case 'H': hash_hosts = 1; @@ -806,13 +802,6 @@ main(int argc, char **argv) case '6': IPv4or6 = AF_INET6; break; - case 'V': - scan_rdomain = a2rdomain(optarg); - if (scan_rdomain == -1) { - fprintf(stderr, "Bad rdomain '%s'\n", optarg); - exit(1); - } - break; case '?': default: usage(); diff --git a/ssh.1 b/ssh.1 index 2f6ef5fff..8b228fcdf 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.288 2009/12/29 16:38:41 stevesk Exp $ -.Dd $Mdocdate: December 29 2009 $ +.\" $OpenBSD: ssh.1,v 1.289 2010/01/09 23:04:13 dtucker Exp $ +.Dd $Mdocdate: January 9 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -478,7 +478,6 @@ For full details of the options listed below, and their possible values, see .It RekeyLimit .It RemoteForward .It RhostsRSAAuthentication -.It RoutingDomain .It RSAAuthentication .It SendEnv .It ServerAliveInterval diff --git a/ssh.c b/ssh.c index 6abf31b52..ee30e2b27 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.329 2009/12/20 07:28:36 guenther Exp $ */ +/* $OpenBSD: ssh.c,v 1.330 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -630,7 +630,6 @@ main(int ac, char **av) fill_default_options(&options); channel_set_af(options.address_family); - channel_set_rdomain(options.rdomain); /* reinit */ log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); diff --git a/ssh_config.5 b/ssh_config.5 index 3ffc469c2..01f5f4304 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.125 2009/12/29 18:03:32 jmc Exp $ -.Dd $Mdocdate: December 29 2009 $ +.\" $OpenBSD: ssh_config.5,v 1.126 2010/01/09 23:04:13 dtucker Exp $ +.Dd $Mdocdate: January 9 2010 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -857,9 +857,6 @@ The default is This option applies to protocol version 1 only and requires .Xr ssh 1 to be setuid root. -.It Cm RoutingDomain -Set the routing domain number. -The default routing domain is set by the system. .It Cm RSAAuthentication Specifies whether to try RSA authentication. The argument to this keyword must be diff --git a/sshconnect.c b/sshconnect.c index 3c8308ffb..5cfc3c16a 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.216 2009/11/10 04:30:45 dtucker Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.217 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -191,8 +191,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai) debug("Allocated local port %d.", p); return sock; } - sock = socket_rdomain(ai->ai_family, ai->ai_socktype, ai->ai_protocol, - options.rdomain); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { error("socket: %.100s", strerror(errno)); return -1; diff --git a/sshd.c b/sshd.c index bdaf1574a..4e34f2439 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.369 2010/01/09 11:17:56 dtucker Exp $ */ +/* $OpenBSD: sshd.c,v 1.370 2010/01/09 23:04:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -961,8 +961,8 @@ server_listen(void) continue; } /* Create socket for listening. */ - listen_sock = socket_rdomain(ai->ai_family, ai->ai_socktype, - ai->ai_protocol, options.rdomain); + listen_sock = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); if (listen_sock < 0) { /* kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); @@ -1470,9 +1470,8 @@ main(int ac, char **av) if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; - /* set default channel AF and routing domain */ + /* set default channel AF */ channel_set_af(options.address_family); - channel_set_rdomain(options.rdomain); /* Check that there are no remaining arguments. */ if (optind < ac) { diff --git a/sshd_config.5 b/sshd_config.5 index a3326447f..bf3319c4d 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.115 2009/12/29 18:03:32 jmc Exp $ -.Dd $Mdocdate: December 29 2009 $ +.\" $OpenBSD: sshd_config.5,v 1.116 2010/01/09 23:04:13 dtucker Exp $ +.Dd $Mdocdate: January 9 2010 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -812,9 +812,6 @@ with successful RSA host authentication is allowed. The default is .Dq no . This option applies to protocol version 1 only. -.It Cm RoutingDomain -Set the routing domain number. -The default routing domain is set by the system. .It Cm RSAAuthentication Specifies whether pure RSA authentication is allowed. The default is -- cgit v1.2.3 From d3300454d84715a921978163895e961d24b6deaa Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 10 Jan 2010 19:26:43 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/10 03:51:17 [servconf.c] Add ChrootDirectory to sshd.c test-mode output --- ChangeLog | 4 ++++ servconf.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca189f943..8b419858d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 20091210 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Remove hacks add for RoutingDomain in preparation for its removal. + - (dtucker) OpenBSD CVS Sync - dtucker@cvs.openbsd.org 2010/01/09 23:04:13 [channels.c ssh.1 servconf.c sshd_config.5 sshd.c channels.h servconf.h ssh-keyscan.1 ssh-keyscan.c readconf.c sshconnect.c misc.c ssh.c @@ -14,6 +15,9 @@ $ route -T 2 exec sh $ ssh 10.1.2.3 ok deraadt@ markus@ stevesk@ reyk@ + - dtucker@cvs.openbsd.org 2010/01/10 03:51:17 + [servconf.c] + Add ChrootDirectory to sshd.c test-mode output 20091209 - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't diff --git a/servconf.c b/servconf.c index fc3e479bd..b1964e865 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.200 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: servconf.c,v 1.201 2010/01/10 03:51:17 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1626,6 +1626,7 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file); dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2); dump_cfg_string(sForceCommand, o->adm_forced_command); + dump_cfg_string(sChrootDirectory, o->chroot_directory); /* string arguments requiring a lookup */ dump_cfg_string(sLogLevel, log_level_name(o->log_level)); -- cgit v1.2.3 From 43551527dc1cc9f18561c4816960440de2ce289b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 10 Jan 2010 19:27:17 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/10 07:15:56 [auth.c] Output a debug if we can't open an existing keyfile. bz#1694, ok djm@ --- ChangeLog | 3 +++ auth.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b419858d..40c9647cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,9 @@ - dtucker@cvs.openbsd.org 2010/01/10 03:51:17 [servconf.c] Add ChrootDirectory to sshd.c test-mode output + - dtucker@cvs.openbsd.org 2010/01/10 07:15:56 + [auth.c] + Output a debug if we can't open an existing keyfile. bz#1694, ok djm@ 20091209 - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't diff --git a/auth.c b/auth.c index 3585daadc..a4c31f580 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.81 2010/01/10 07:15:56 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -483,8 +483,12 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) * Open the file containing the authorized keys * Fail quietly if file does not exist */ - if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) + if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { + if (errno != ENOENT) + debug("Could not open keyfile '%s': %s", file, + strerror(errno)); return NULL; + } if (fstat(fd, &st) < 0) { close(fd); -- cgit v1.2.3 From 7ad8dd21da5e2a2687fdff14142b70f1587f96ce Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:40:27 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/11 01:39:46 [ssh_config channels.c ssh.1 channels.h ssh.c] Add a 'netcat mode' (ssh -W). This connects stdio on the client to a single port forward on the server. This allows, for example, using ssh as a ProxyCommand to route connections via intermediate servers. bz #1618, man page help from jmc@, ok markus@ --- ChangeLog | 15 ++++++++++++--- channels.c | 31 ++++++++++++++++++++++++++++++- channels.h | 3 ++- ssh.1 | 20 ++++++++++++++++---- ssh.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- ssh_config | 3 ++- 6 files changed, 116 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40c9647cb..72a68a613 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ -20091210 +20100111 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2010/01/11 01:39:46 + [ssh_config channels.c ssh.1 channels.h ssh.c] + Add a 'netcat mode' (ssh -W). This connects stdio on the client to a + single port forward on the server. This allows, for example, using ssh as + a ProxyCommand to route connections via intermediate servers. + bz #1618, man page help from jmc@, ok markus@ + +20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Remove hacks add for RoutingDomain in preparation for its removal. - (dtucker) OpenBSD CVS Sync @@ -22,7 +31,7 @@ [auth.c] Output a debug if we can't open an existing keyfile. bz#1694, ok djm@ -20091209 +20100109 - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't have it. - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. @@ -59,7 +68,7 @@ dying. bz#1692, patch from Colin Watson via Ubuntu. - (dtucker) [defines.h] Remove now-undeeded PRIu64 define. -20091208 +20100108 - (dtucker) OpenBSD CVS Sync - andreas@cvs.openbsd.org 2009/10/24 11:11:58 [roaming.h] diff --git a/channels.c b/channels.c index 87dbe96d3..e8589d8c4 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.300 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: channels.c,v 1.301 2010/01/11 01:39:46 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1217,6 +1217,35 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) return 1; } +Channel * +channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect) +{ + Channel *c; + int in, out; + + debug("channel_connect_stdio_fwd %s:%d", host_to_connect, + port_to_connect); + + in = dup(STDIN_FILENO); + out = dup(STDOUT_FILENO); + if (in < 0 || out < 0) + fatal("channel_connect_stdio_fwd: dup() in/out failed"); + + c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out, + -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, "stdio-forward", /*nonblock*/0); + + c->path = xstrdup(host_to_connect); + c->host_port = port_to_connect; + c->listening_port = 0; + c->force_drain = 1; + + channel_register_fds(c, in, out, -1, 0, 1, 0); + port_open_helper(c, "direct-tcpip"); + + return c; +} + /* dynamic port forwarding */ static void channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) diff --git a/channels.h b/channels.h index f65a311dc..79ebe047a 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.101 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: channels.h,v 1.102 2010/01/11 01:39:46 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -243,6 +243,7 @@ void channel_clear_adm_permitted_opens(void); void channel_print_adm_permitted_opens(void); int channel_input_port_forward_request(int, int); Channel *channel_connect_to(const char *, u_short, char *, char *); +Channel *channel_connect_stdio_fwd(const char*, u_short); Channel *channel_connect_by_listen_address(u_short, char *, char *); int channel_request_remote_forwarding(const char *, u_short, const char *, u_short); diff --git a/ssh.1 b/ssh.1 index 8b228fcdf..1ff2cce4d 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.289 2010/01/09 23:04:13 dtucker Exp $ -.Dd $Mdocdate: January 9 2010 $ +.\" $OpenBSD: ssh.1,v 1.290 2010/01/11 01:39:46 dtucker Exp $ +.Dd $Mdocdate: January 11 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -77,12 +77,11 @@ .Sm on .Oc .Op Fl S Ar ctl_path -.Bk -words +.Op Fl W Ar host : Ns Ar port .Oo Fl w Ar local_tun Ns .Op : Ns Ar remote_tun Oc .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command -.Ek .Sh DESCRIPTION .Nm (SSH client) is a program for logging into a remote machine and for @@ -594,6 +593,19 @@ Multiple .Fl v options increase the verbosity. The maximum is 3. +.It Fl W Ar host : Ns Ar port +Requests that standard input and output on the client be forwarded to +.Ar host +on +.Ar port +over the secure channel. +Implies +.Fl N , +.Fl T , +.Cm ExitOnForwardFailure +and +.Cm ClearAllForwardings +and works with Protocol version 2 only. .It Fl w Xo .Ar local_tun Ns Op : Ns Ar remote_tun .Xc diff --git a/ssh.c b/ssh.c index ee30e2b27..b86a764f6 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.330 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: ssh.c,v 1.331 2010/01/11 01:39:46 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -133,6 +133,10 @@ int stdin_null_flag = 0; */ int fork_after_authentication_flag = 0; +/* forward stdio to remote host and port */ +char *stdio_forward_host = NULL; +int stdio_forward_port = 0; + /* * General data structure for command line options and options configurable * in configuration files. See readconf.h. @@ -186,7 +190,8 @@ usage(void) " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" -" [-w local_tun[:remote_tun]] [user@]hostname [command]\n" +" [-W host:port] [-w local_tun[:remote_tun]]\n" +" [user@]hostname [command]\n" ); exit(255); } @@ -276,7 +281,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" - "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) { + "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -389,6 +394,22 @@ main(int ac, char **av) exit(255); } break; + case 'W': + if (parse_forward(&fwd, optarg, 1, 0)) { + stdio_forward_host = fwd.listen_host; + stdio_forward_port = fwd.listen_port; + xfree(fwd.connect_host); + } else { + fprintf(stderr, + "Bad stdio forwarding specification '%s'\n", + optarg); + exit(255); + } + no_tty_flag = 1; + no_shell_flag = 1; + options.clear_forwardings = 1; + options.exit_on_forward_failure = 1; + break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; @@ -870,12 +891,42 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) } } +static void +client_cleanup_stdio_fwd(int id, void *arg) +{ + debug("stdio forwarding: done"); + cleanup_exit(0); +} + +static int +client_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect) +{ + Channel *c; + + debug3("client_setup_stdio_fwd %s:%d", host_to_connect, + port_to_connect); + if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect)) + == NULL) + return 0; + channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); + return 1; +} + static void ssh_init_forwarding(void) { int success = 0; int i; + if (stdio_forward_host != NULL) { + if (!compat20) { + fatal("stdio forwarding require Protocol 2"); + } + if (!client_setup_stdio_fwd(stdio_forward_host, + stdio_forward_port)) + fatal("Failed to connect in stdio forward mode."); + } + /* Initiate local TCP/IP port forwardings. */ for (i = 0; i < options.num_local_forwards; i++) { debug("Local connections to %.200s:%d forwarded to remote " diff --git a/ssh_config b/ssh_config index f28d59583..18936740f 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $ +# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -44,3 +44,4 @@ # TunnelDevice any:any # PermitLocalCommand no # VisualHostKey no +# ProxyCommand ssh -q -W %h:%p gateway.example.com -- cgit v1.2.3 From d4c86b13254d7c84b27b7cb8d32dcc7036ca3788 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:41:22 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/11 04:46:45 [authfile.c sshconnect2.c] Do not prompt for a passphrase if we fail to open a keyfile, and log the reason the open failed to debug. bz #1693, found by tj AT castaglia org, ok djm@ --- ChangeLog | 5 +++++ authfile.c | 14 +++++++++++--- sshconnect2.c | 4 ++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 72a68a613..74936fa8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,11 @@ single port forward on the server. This allows, for example, using ssh as a ProxyCommand to route connections via intermediate servers. bz #1618, man page help from jmc@, ok markus@ + - dtucker@cvs.openbsd.org 2010/01/11 04:46:45 + [authfile.c sshconnect2.c] + Do not prompt for a passphrase if we fail to open a keyfile, and log the + reason the open failed to debug. + bz #1693, found by tj AT castaglia org, ok djm@ 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/authfile.c b/authfile.c index 3fbe11b0e..23535fa07 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.77 2009/10/22 22:26:13 djm Exp $ */ +/* $OpenBSD: authfile.c,v 1.78 2010/01/11 04:46:45 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -559,7 +559,12 @@ key_load_private_type(int type, const char *filename, const char *passphrase, int fd; fd = open(filename, O_RDONLY); - if (fd < 0) + if (fd < 0) { + debug("could not open key file '%s': %s", filename, + strerror(errno)); + if (perm_ok != NULL) + *perm_ok = 0; + } return NULL; if (!key_perm_ok(fd, filename)) { if (perm_ok != NULL) @@ -595,8 +600,11 @@ key_load_private(const char *filename, const char *passphrase, int fd; fd = open(filename, O_RDONLY); - if (fd < 0) + if (fd < 0) { + debug("could not open key file '%s': %s", filename, + strerror(errno)); return NULL; + } if (!key_perm_ok(fd, filename)) { error("bad permissions: ignore key: %s", filename); close(fd); diff --git a/sshconnect2.c b/sshconnect2.c index 367f0fc6c..ed40a9d70 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.177 2010/01/04 01:45:30 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.178 2010/01/11 04:46:45 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -1250,7 +1250,7 @@ load_identity_file(char *filename) { Key *private; char prompt[300], *passphrase; - int perm_ok, quit, i; + int perm_ok = 0, quit, i; struct stat st; if (stat(filename, &st) < 0) { -- cgit v1.2.3 From d04758dc4c001104933ce3e2088ac46d461ec1f1 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:41:57 +1100 Subject: - djm@cvs.openbsd.org 2010/01/11 10:51:07 [ssh-keygen.c] when converting keys, truncate key comments at 72 chars as per RFC4716; bz#1630 reported by tj AT castaglia.org; ok markus@ --- ChangeLog | 4 ++++ ssh-keygen.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74936fa8b..a9ae9ea3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,10 @@ Do not prompt for a passphrase if we fail to open a keyfile, and log the reason the open failed to debug. bz #1693, found by tj AT castaglia org, ok djm@ + - djm@cvs.openbsd.org 2010/01/11 10:51:07 + [ssh-keygen.c] + when converting keys, truncate key comments at 72 chars as per RFC4716; + bz#1630 reported by tj AT castaglia.org; ok markus@ 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/ssh-keygen.c b/ssh-keygen.c index 4f90ac5c1..7f5185f8e 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.175 2009/08/27 17:33:49 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.176 2010/01/11 10:51:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -181,6 +181,7 @@ do_convert_to_ssh2(struct passwd *pw) Key *k; u_int len; u_char *blob; + char comment[61]; struct stat st; if (!have_identity) @@ -203,11 +204,14 @@ do_convert_to_ssh2(struct passwd *pw) fprintf(stderr, "key_to_blob failed\n"); exit(1); } - fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); - fprintf(stdout, - "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n", + /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ + snprintf(comment, sizeof(comment), + "%u-bit %s, converted by %s@%s from OpenSSH", key_size(k), key_type(k), pw->pw_name, hostname); + + fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); + fprintf(stdout, "Comment: \"%s\"\n", comment); dump_base64(stdout, blob, len); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); key_free(k); -- cgit v1.2.3 From 69c01b1c4a9068478174b9cc39eb9957e78416a6 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:42:29 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/12 00:16:47 [authfile.c] Fix bug introduced in r1.78 (incorrect brace location) that broke key auth. Patch from joachim joachimschipper nl. --- ChangeLog | 4 ++++ authfile.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9ae9ea3e..688e8c109 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,10 @@ [ssh-keygen.c] when converting keys, truncate key comments at 72 chars as per RFC4716; bz#1630 reported by tj AT castaglia.org; ok markus@ + - dtucker@cvs.openbsd.org 2010/01/12 00:16:47 + [authfile.c] + Fix bug introduced in r1.78 (incorrect brace location) that broke key auth. + Patch from joachim joachimschipper nl. 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/authfile.c b/authfile.c index 23535fa07..2c615709d 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.78 2010/01/11 04:46:45 dtucker Exp $ */ +/* $OpenBSD: authfile.c,v 1.79 2010/01/12 00:16:47 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -564,8 +564,8 @@ key_load_private_type(int type, const char *filename, const char *passphrase, strerror(errno)); if (perm_ok != NULL) *perm_ok = 0; - } return NULL; + } if (!key_perm_ok(fd, filename)) { if (perm_ok != NULL) *perm_ok = 0; -- cgit v1.2.3 From e371a13238c6e5ebc0949a987830d21162f4bbac Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:43:12 +1100 Subject: - djm@cvs.openbsd.org 2010/01/12 00:58:25 [monitor_fdpass.c] avoid spinning when fd passing on nonblocking sockets by calling poll() in the EINTR/EAGAIN path, much like we do in atomicio; ok dtucker@ --- ChangeLog | 4 ++++ monitor_fdpass.c | 21 ++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 688e8c109..a6b547198 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,10 @@ [authfile.c] Fix bug introduced in r1.78 (incorrect brace location) that broke key auth. Patch from joachim joachimschipper nl. + - djm@cvs.openbsd.org 2010/01/12 00:58:25 + [monitor_fdpass.c] + avoid spinning when fd passing on nonblocking sockets by calling poll() + in the EINTR/EAGAIN path, much like we do in atomicio; ok dtucker@ 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/monitor_fdpass.c b/monitor_fdpass.c index 4b9a066bc..56d3afdf3 100644 --- a/monitor_fdpass.c +++ b/monitor_fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.c,v 1.18 2008/11/30 11:59:26 dtucker Exp $ */ +/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */ /* * Copyright 2001 Niels Provos * All rights reserved. @@ -34,6 +34,7 @@ #endif #include +#include #include #include @@ -55,6 +56,7 @@ mm_send_fd(int sock, int fd) struct iovec vec; char ch = '\0'; ssize_t n; + struct pollfd pfd; memset(&msg, 0, sizeof(msg)); #ifdef HAVE_ACCRIGHTS_IN_MSGHDR @@ -75,9 +77,13 @@ mm_send_fd(int sock, int fd) msg.msg_iov = &vec; msg.msg_iovlen = 1; - while ((n = sendmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN || - errno == EINTR)) + pfd.fd = sock; + pfd.events = POLLOUT; + while ((n = sendmsg(sock, &msg, 0)) == -1 && + (errno == EAGAIN || errno == EINTR)) { debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); + (void)poll(&pfd, 1, -1); + } if (n == -1) { error("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); @@ -112,6 +118,7 @@ mm_receive_fd(int sock) ssize_t n; char ch; int fd; + struct pollfd pfd; memset(&msg, 0, sizeof(msg)); vec.iov_base = &ch; @@ -126,9 +133,13 @@ mm_receive_fd(int sock) msg.msg_controllen = sizeof(cmsgbuf.buf); #endif - while ((n = recvmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN || - errno == EINTR)) + pfd.fd = sock; + pfd.events = POLLIN; + while ((n = recvmsg(sock, &msg, 0)) == -1 && + (errno == EAGAIN || errno == EINTR)) { debug3("%s: recvmsg: %s", __func__, strerror(errno)); + (void)poll(&pfd, 1, -1); + } if (n == -1) { error("%s: recvmsg: %s", __func__, strerror(errno)); return -1; -- cgit v1.2.3 From c6cc90b4653ad605072f11986cdbfc8a9d968185 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:43:46 +1100 Subject: - djm@cvs.openbsd.org 2010/01/12 00:59:29 [roaming_common.c] delete with extreme prejudice a debug() that fired with every keypress; ok dtucker deraadt --- ChangeLog | 4 ++++ roaming_common.c | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6b547198..0317221ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,10 @@ [monitor_fdpass.c] avoid spinning when fd passing on nonblocking sockets by calling poll() in the EINTR/EAGAIN path, much like we do in atomicio; ok dtucker@ + - djm@cvs.openbsd.org 2010/01/12 00:59:29 + [roaming_common.c] + delete with extreme prejudice a debug() that fired with every keypress; + ok dtucker deraadt 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/roaming_common.c b/roaming_common.c index 3885a0368..9adbe56fc 100644 --- a/roaming_common.c +++ b/roaming_common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_common.c,v 1.7 2009/12/06 23:53:45 djm Exp $ */ +/* $OpenBSD: roaming_common.c,v 1.8 2010/01/12 00:59:29 djm Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -145,8 +145,6 @@ roaming_write(int fd, const void *buf, size_t count, int *cont) if (out_buf_size > 0) buf_append(buf, ret); } - debug3("Wrote %ld bytes for a total of %llu", (long)ret, - (unsigned long long)write_bytes); if (out_buf_size > 0 && (ret == 0 || (ret == -1 && errno == EPIPE))) { if (wait_for_roaming_reconnect() != 0) { -- cgit v1.2.3 From 1b0c2455daf26b9eca30210f7628b7e4667501ad Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:45:26 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/12 01:31:05 [session.c] Do not allow logins if /etc/nologin exists but is not readable by the user logging in. Noted by Jan.Pechanec at Sun, ok djm@ deraadt@ --- ChangeLog | 4 ++++ session.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0317221ee..ddfa8af44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,10 @@ [roaming_common.c] delete with extreme prejudice a debug() that fired with every keypress; ok dtucker deraadt + - dtucker@cvs.openbsd.org 2010/01/12 01:31:05 + [session.c] + Do not allow logins if /etc/nologin exists but is not readable by the user + logging in. Noted by Jan.Pechanec at Sun, ok djm@ deraadt@ 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/session.c b/session.c index 733b5a909..6cd07d4fe 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.249 2009/11/20 00:15:41 dtucker Exp $ */ +/* $OpenBSD: session.c,v 1.250 2010/01/12 01:31:05 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1387,10 +1387,12 @@ do_nologin(struct passwd *pw) if (pw->pw_uid) f = fopen(_PATH_NOLOGIN, "r"); #endif - if (f) { + if (f != NULL || errno == EPERM) { /* /etc/nologin exists. Print its contents and exit. */ logit("User %.100s not allowed because %s exists", pw->pw_name, _PATH_NOLOGIN); + if (f == NULL) + exit(254); while (fgets(buf, sizeof(buf), f)) fputs(buf, stderr); fclose(f); -- cgit v1.2.3 From ebc71d908cc10cafea05e1aaaa7886d3f8b0bf80 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:45:59 +1100 Subject: - djm@cvs.openbsd.org 2010/01/12 01:36:08 [buffer.h bufaux.c] add a buffer_get_string_ptr_ret() that does the same as buffer_get_string_ptr() but does not fatal() on error; ok dtucker@ --- ChangeLog | 4 ++++ bufaux.c | 23 ++++++++++++++++++----- buffer.h | 3 ++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index ddfa8af44..6992a01b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,10 @@ [session.c] Do not allow logins if /etc/nologin exists but is not readable by the user logging in. Noted by Jan.Pechanec at Sun, ok djm@ deraadt@ + - djm@cvs.openbsd.org 2010/01/12 01:36:08 + [buffer.h bufaux.c] + add a buffer_get_string_ptr_ret() that does the same as + buffer_get_string_ptr() but does not fatal() on error; ok dtucker@ 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/bufaux.c b/bufaux.c index cd9a35ded..e17f001e1 100644 --- a/bufaux.c +++ b/bufaux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufaux.c,v 1.46 2008/06/10 23:21:34 dtucker Exp $ */ +/* $OpenBSD: bufaux.c,v 1.47 2010/01/12 01:36:08 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -198,14 +198,17 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr) } void * -buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) +buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr) { void *ptr; u_int len; - len = buffer_get_int(buffer); - if (len > 256 * 1024) - fatal("buffer_get_string_ptr: bad string length %u", len); + if (buffer_get_int_ret(&len, buffer) != 0) + return NULL; + if (len > 256 * 1024) { + error("buffer_get_string_ptr: bad string length %u", len); + return NULL; + } ptr = buffer_ptr(buffer); buffer_consume(buffer, len); if (length_ptr) @@ -213,6 +216,16 @@ buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) return (ptr); } +void * +buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) +{ + void *ret; + + if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL) + fatal("buffer_get_string_ptr: buffer error"); + return (ret); +} + /* * Stores and arbitrary binary string in the buffer. */ diff --git a/buffer.h b/buffer.h index d0f354ee7..ecad28973 100644 --- a/buffer.h +++ b/buffer.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.h,v 1.17 2008/05/08 06:59:01 markus Exp $ */ +/* $OpenBSD: buffer.h,v 1.18 2010/01/12 01:36:08 djm Exp $ */ /* * Author: Tatu Ylonen @@ -81,6 +81,7 @@ int buffer_get_short_ret(u_short *, Buffer *); int buffer_get_int_ret(u_int *, Buffer *); int buffer_get_int64_ret(u_int64_t *, Buffer *); void *buffer_get_string_ret(Buffer *, u_int *); +void *buffer_get_string_ptr_ret(Buffer *, u_int *); int buffer_get_char_ret(char *, Buffer *); #endif /* BUFFER_H */ -- cgit v1.2.3 From 09aa4c000e16cdb23628d563920f48294997945e Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jan 2010 19:51:48 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/12 08:33:17 [session.c] Add explicit stat so we reliably detect nologin with bad perms. ok djm markus --- ChangeLog | 6 +++++- session.c | 40 ++++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6992a01b8..174b60a06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -20100111 +20100112 - (dtucker) OpenBSD CVS Sync - dtucker@cvs.openbsd.org 2010/01/11 01:39:46 [ssh_config channels.c ssh.1 channels.h ssh.c] @@ -35,6 +35,10 @@ [buffer.h bufaux.c] add a buffer_get_string_ptr_ret() that does the same as buffer_get_string_ptr() but does not fatal() on error; ok dtucker@ + - dtucker@cvs.openbsd.org 2010/01/12 08:33:17 + [session.c] + Add explicit stat so we reliably detect nologin with bad perms. + ok djm markus 20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] diff --git a/session.c b/session.c index 6cd07d4fe..fd7acbe03 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.250 2010/01/12 01:31:05 dtucker Exp $ */ +/* $OpenBSD: session.c,v 1.251 2010/01/12 08:33:17 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1377,28 +1377,32 @@ static void do_nologin(struct passwd *pw) { FILE *f = NULL; - char buf[1024]; + char buf[1024], *nl, *def_nl = _PATH_NOLOGIN; + struct stat sb; #ifdef HAVE_LOGIN_CAP - if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) - f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, - _PATH_NOLOGIN), "r"); + if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) + return; + nl = login_getcapstr(lc, "nologin", def_nl, def_nl); #else - if (pw->pw_uid) - f = fopen(_PATH_NOLOGIN, "r"); + if (pw->pw_uid == 0) + return; + nl = def_nl; #endif - if (f != NULL || errno == EPERM) { - /* /etc/nologin exists. Print its contents and exit. */ - logit("User %.100s not allowed because %s exists", - pw->pw_name, _PATH_NOLOGIN); - if (f == NULL) - exit(254); - while (fgets(buf, sizeof(buf), f)) - fputs(buf, stderr); - fclose(f); - fflush(NULL); - exit(254); + if (stat(nl, &sb) == -1) { + if (nl != def_nl) + xfree(nl); + return; } + + /* /etc/nologin exists. Print its contents if we can and exit. */ + logit("User %.100s not allowed because %s exists", pw->pw_name, nl); + if ((f = fopen(nl, "r")) != NULL) { + while (fgets(buf, sizeof(buf), f)) + fputs(buf, stderr); + fclose(f); + } + exit(254); } /* -- cgit v1.2.3 From a8f20cff82ec514df8aa60bc5248dcad6f90066c Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 10:54:46 +1100 Subject: - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs. --- ChangeLog | 3 +++ monitor_fdpass.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 174b60a06..9bd45a121 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +20100113 + - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs. + 20100112 - (dtucker) OpenBSD CVS Sync - dtucker@cvs.openbsd.org 2010/01/11 01:39:46 diff --git a/monitor_fdpass.c b/monitor_fdpass.c index 56d3afdf3..7eb6f5c6e 100644 --- a/monitor_fdpass.c +++ b/monitor_fdpass.c @@ -34,7 +34,9 @@ #endif #include +#ifdef HAVE_POLL_H #include +#endif #include #include -- cgit v1.2.3 From ab3c2cab18a6c5ae9dd93cacb1a179e48d245228 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 18:27:32 +1100 Subject: - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18: missing restore of SIGTTOU and some whitespace. --- ChangeLog | 2 ++ openbsd-compat/readpassphrase.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9bd45a121..87c236e66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 20100113 - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs. + - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18: + missing restore of SIGTTOU and some whitespace. 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/openbsd-compat/readpassphrase.c b/openbsd-compat/readpassphrase.c index 11bd8f646..16e07e816 100644 --- a/openbsd-compat/readpassphrase.c +++ b/openbsd-compat/readpassphrase.c @@ -152,6 +152,7 @@ restart: (void)sigaction(SIGTERM, &saveterm, NULL); (void)sigaction(SIGTSTP, &savetstp, NULL); (void)sigaction(SIGTTIN, &savettin, NULL); + (void)sigaction(SIGTTOU, &savettou, NULL); if (input != STDIN_FILENO) (void)close(input); @@ -172,7 +173,7 @@ restart: errno = save_errno; return(nr == -1 ? NULL : buf); } - + #if 0 char * getpass(const char *prompt) -- cgit v1.2.3 From 1035cb4729857ec00d1a976476b840bfe0351312 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 18:32:59 +1100 Subject: - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.21. --- ChangeLog | 1 + openbsd-compat/readpassphrase.c | 47 +++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87c236e66..7c4fad33d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs. - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18: missing restore of SIGTTOU and some whitespace. + - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.21. 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/openbsd-compat/readpassphrase.c b/openbsd-compat/readpassphrase.c index 16e07e816..8b9486357 100644 --- a/openbsd-compat/readpassphrase.c +++ b/openbsd-compat/readpassphrase.c @@ -1,7 +1,7 @@ -/* $OpenBSD: readpassphrase.c,v 1.18 2005/08/08 08:05:34 espie Exp $ */ +/* $OpenBSD: readpassphrase.c,v 1.21 2008/01/17 16:27:07 millert Exp $ */ /* - * Copyright (c) 2000-2002 Todd C. Miller + * Copyright (c) 2000-2002, 2007 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -68,6 +68,8 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) restart: signo = 0; + nr = -1; + save_errno = 0; /* * Read and write to /dev/tty if available. If not, read from * stdin and write to stderr unless a tty is required. @@ -117,26 +119,30 @@ restart: oterm.c_lflag |= ECHO; } - if (!(flags & RPP_STDIN)) - (void)write(output, prompt, strlen(prompt)); - end = buf + bufsiz - 1; - for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { - if (p < end) { - if ((flags & RPP_SEVENBIT)) - ch &= 0x7f; - if (isalpha(ch)) { - if ((flags & RPP_FORCELOWER)) - ch = tolower(ch); - if ((flags & RPP_FORCEUPPER)) - ch = toupper(ch); + /* No I/O if we are already backgrounded. */ + if (signo != SIGTTOU && signo != SIGTTIN) { + if (!(flags & RPP_STDIN)) + (void)write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + p = buf; + while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { + if (p < end) { + if ((flags & RPP_SEVENBIT)) + ch &= 0x7f; + if (isalpha(ch)) { + if ((flags & RPP_FORCELOWER)) + ch = (char)tolower(ch); + if ((flags & RPP_FORCEUPPER)) + ch = (char)toupper(ch); + } + *p++ = ch; } - *p++ = ch; } + *p = '\0'; + save_errno = errno; + if (!(term.c_lflag & ECHO)) + (void)write(output, "\n", 1); } - *p = '\0'; - save_errno = errno; - if (!(term.c_lflag & ECHO)) - (void)write(output, "\n", 1); /* Restore old terminal settings and signals. */ if (memcmp(&term, &oterm, sizeof(term)) != 0) { @@ -170,7 +176,8 @@ restart: } } - errno = save_errno; + if (save_errno) + errno = save_errno; return(nr == -1 ? NULL : buf); } -- cgit v1.2.3 From d59487a33bfaadc3ced41a1c604ec603d716df42 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 21:32:44 +1100 Subject: - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.22. Fixes bz #1590, where sometimes you could not interrupt a connection while ssh was prompting for a passphrase or password. --- ChangeLog | 3 +++ openbsd-compat/readpassphrase.c | 32 +++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c4fad33d..652d8d19b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18: missing restore of SIGTTOU and some whitespace. - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.21. + - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.22. + Fixes bz #1590, where sometimes you could not interrupt a connection while + ssh was prompting for a passphrase or password. 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/openbsd-compat/readpassphrase.c b/openbsd-compat/readpassphrase.c index 8b9486357..62b6d0d84 100644 --- a/openbsd-compat/readpassphrase.c +++ b/openbsd-compat/readpassphrase.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readpassphrase.c,v 1.21 2008/01/17 16:27:07 millert Exp $ */ +/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */ /* * Copyright (c) 2000-2002, 2007 Todd C. Miller @@ -46,7 +46,7 @@ # define _POSIX_VDISABLE VDISABLE #endif -static volatile sig_atomic_t signo; +static volatile sig_atomic_t signo[_NSIG]; static void handler(int); @@ -54,7 +54,7 @@ char * readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { ssize_t nr; - int input, output, save_errno; + int input, output, save_errno, i, need_restart; char ch, *p, *end; struct termios term, oterm; struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; @@ -67,9 +67,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) } restart: - signo = 0; + for (i = 0; i < _NSIG; i++) + signo[i] = 0; nr = -1; save_errno = 0; + need_restart = 0; /* * Read and write to /dev/tty if available. If not, read from * stdin and write to stderr unless a tty is required. @@ -120,7 +122,7 @@ restart: } /* No I/O if we are already backgrounded. */ - if (signo != SIGTTOU && signo != SIGTTIN) { + if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) { if (!(flags & RPP_STDIN)) (void)write(output, prompt, strlen(prompt)); end = buf + bufsiz - 1; @@ -166,15 +168,19 @@ restart: * If we were interrupted by a signal, resend it to ourselves * now that we have restored the signal handlers. */ - if (signo) { - kill(getpid(), signo); - switch (signo) { - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - goto restart; + for (i = 0; i < _NSIG; i++) { + if (signo[i]) { + kill(getpid(), i); + switch (i) { + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + need_restart = 1; + } } } + if (need_restart) + goto restart; if (save_errno) errno = save_errno; @@ -194,6 +200,6 @@ getpass(const char *prompt) static void handler(int s) { - signo = s; + signo[s] = 1; } #endif /* HAVE_READPASSPHRASE */ -- cgit v1.2.3 From e2b36741725c2214f72a3ef07bc0788191ac7ea9 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 22:42:34 +1100 Subject: - (dtucker) OpenBSD CVS Sync - dtucker@cvs.openbsd.org 2010/01/13 00:19:04 [sshconnect.c auth.c] Fix a couple of typos/mispellings in comments --- ChangeLog | 4 ++++ auth.c | 4 ++-- sshconnect.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 652d8d19b..8ee8e2768 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,10 @@ - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.22. Fixes bz #1590, where sometimes you could not interrupt a connection while ssh was prompting for a passphrase or password. + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2010/01/13 00:19:04 + [sshconnect.c auth.c] + Fix a couple of typos/mispellings in comments 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/auth.c b/auth.c index a4c31f580..3dc116907 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.81 2010/01/10 07:15:56 dtucker Exp $ */ +/* $OpenBSD: auth.c,v 1.82 2010/01/13 00:19:04 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -455,7 +455,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw, return -1; } - /* If are passed the homedir then we can stop */ + /* If are past the homedir then we can stop */ if (comparehome && strcmp(homedir, buf) == 0) { debug3("secure_filename: terminating check at '%s'", buf); diff --git a/sshconnect.c b/sshconnect.c index 5cfc3c16a..63c4650f7 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.217 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.218 2010/01/13 00:19:04 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -929,7 +929,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, * XXX Should permit the user to change to use the new id. * This could be done by converting the host key to an * identifying sentence, tell that the host identifies itself - * by that sentence, and ask the user if he/she whishes to + * by that sentence, and ask the user if he/she wishes to * accept the authentication. */ break; -- cgit v1.2.3 From 561724f38dd8b4e56ec918a70f9314f41c34b46a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 22:43:05 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/13 01:10:56 [key.c] Ignore and log any Protocol 1 keys where the claimed size is not equal to the actual size. Noted by Derek Martin, ok djm@ --- ChangeLog | 4 ++++ key.c | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8ee8e2768..866e4aa46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,10 @@ - dtucker@cvs.openbsd.org 2010/01/13 00:19:04 [sshconnect.c auth.c] Fix a couple of typos/mispellings in comments + - dtucker@cvs.openbsd.org 2010/01/13 01:10:56 + [key.c] + Ignore and log any Protocol 1 keys where the claimed size is not equal to + the actual size. Noted by Derek Martin, ok djm@ 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/key.c b/key.c index f2edf6d5d..5aea416b3 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.81 2009/12/11 18:16:33 markus Exp $ */ +/* $OpenBSD: key.c,v 1.82 2010/01/13 01:10:56 dtucker Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -522,6 +522,12 @@ key_read(Key *ret, char **cpp) return -1; if (!read_bignum(cpp, ret->rsa->n)) return -1; + /* validate the claimed number of bits */ + if ((u_int)BN_num_bits(ret->rsa->n) != bits) { + verbose("key_read: claimed key size %d does not match " + "actual %d", bits, BN_num_bits(ret->rsa->n)); + return -1; + } success = 1; break; case KEY_UNSPEC: -- cgit v1.2.3 From daaa4500519627abee7c6d1969bc33df6572c1e8 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 22:43:33 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/13 01:20:20 [canohost.c ssh-keysign.c sshconnect2.c] Make HostBased authentication work with a ProxyCommand. bz #1569, patch from imorgan at nas nasa gov, ok djm@ --- ChangeLog | 4 ++++ canohost.c | 20 +++++++++++++++++--- ssh-keysign.c | 4 ++-- sshconnect2.c | 17 ++++------------- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 866e4aa46..7624812b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,10 @@ [key.c] Ignore and log any Protocol 1 keys where the claimed size is not equal to the actual size. Noted by Derek Martin, ok djm@ + - dtucker@cvs.openbsd.org 2010/01/13 01:20:20 + [canohost.c ssh-keysign.c sshconnect2.c] + Make HostBased authentication work with a ProxyCommand. bz #1569, patch + from imorgan at nas nasa gov, ok djm@ 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/canohost.c b/canohost.c index 22b19bb9f..ef94d9155 100644 --- a/canohost.c +++ b/canohost.c @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.c,v 1.65 2009/05/27 06:31:25 andreas Exp $ */ +/* $OpenBSD: canohost.c,v 1.66 2010/01/13 01:20:20 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -27,6 +27,7 @@ #include #include #include +#include #include "xmalloc.h" #include "packet.h" @@ -301,9 +302,22 @@ get_local_ipaddr(int sock) } char * -get_local_name(int sock) +get_local_name(int fd) { - return get_socket_address(sock, 0, NI_NAMEREQD); + char *host, myname[NI_MAXHOST]; + + /* Assume we were passed a socket */ + if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL) + return host; + + /* Handle the case where we were passed a pipe */ + if (gethostname(myname, sizeof(myname)) == -1) { + verbose("get_local_name: gethostname: %s", strerror(errno)); + } else { + host = xstrdup(myname); + } + + return host; } void diff --git a/ssh-keysign.c b/ssh-keysign.c index c4bc7e56e..0fdcebbd2 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.30 2010/01/13 01:20:20 dtucker Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -222,7 +222,7 @@ main(int argc, char **argv) if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO)) fatal("bad fd"); if ((host = get_local_name(fd)) == NULL) - fatal("cannot get sockname for fd"); + fatal("cannot get local name for fd"); data = buffer_get_string(&b, &dlen); if (valid_request(pw, host, &key, data, dlen) < 0) diff --git a/sshconnect2.c b/sshconnect2.c index ed40a9d70..e81064dae 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.178 2010/01/11 04:46:45 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.179 2010/01/13 01:20:20 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -1514,7 +1514,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, debug2("ssh_keysign called"); if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { - error("ssh_keysign: no installed: %s", strerror(errno)); + error("ssh_keysign: not installed: %s", strerror(errno)); return -1; } if (fflush(stdout) != 0) @@ -1586,7 +1586,7 @@ userauth_hostbased(Authctxt *authctxt) Sensitive *sensitive = authctxt->sensitive; Buffer b; u_char *signature, *blob; - char *chost, *pkalg, *p, myname[NI_MAXHOST]; + char *chost, *pkalg, *p; const char *service; u_int blen, slen; int ok, i, found = 0; @@ -1610,16 +1610,7 @@ userauth_hostbased(Authctxt *authctxt) return 0; } /* figure out a name for the client host */ - p = NULL; - if (packet_connection_is_on_socket()) - p = get_local_name(packet_get_connection_in()); - if (p == NULL) { - if (gethostname(myname, sizeof(myname)) == -1) { - verbose("userauth_hostbased: gethostname: %s", - strerror(errno)); - } else - p = xstrdup(myname); - } + p = get_local_name(packet_get_connection_in()); if (p == NULL) { error("userauth_hostbased: cannot get local ipaddr/name"); key_free(private); -- cgit v1.2.3 From 2901e2daebe3a0890209f31d05d5bb9338cbed5b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 22:44:06 +1100 Subject: - djm@cvs.openbsd.org 2010/01/13 01:40:16 [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h] support '-h' (human-readable units) for sftp's ls command, just like ls(1); ok dtucker@ --- ChangeLog | 4 ++++ sftp-common.c | 19 ++++++++++++++----- sftp-common.h | 4 ++-- sftp-server.c | 4 ++-- sftp.1 | 11 ++++++++--- sftp.c | 39 ++++++++++++++++++++++----------------- 6 files changed, 52 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7624812b1..d4210354e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,10 @@ [canohost.c ssh-keysign.c sshconnect2.c] Make HostBased authentication work with a ProxyCommand. bz #1569, patch from imorgan at nas nasa gov, ok djm@ + - djm@cvs.openbsd.org 2010/01/13 01:40:16 + [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h] + support '-h' (human-readable units) for sftp's ls command, just like + ls(1); ok dtucker@ 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-common.c b/sftp-common.c index 7ebadcc53..7393fc6a9 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sftp-common.c,v 1.21 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -36,6 +36,7 @@ #include #include #include +#include #include "xmalloc.h" #include "buffer.h" @@ -184,7 +185,7 @@ fx2txt(int status) * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh */ char * -ls_file(const char *name, const struct stat *st, int remote) +ls_file(const char *name, const struct stat *st, int remote, int si_units) { int ulen, glen, sz = 0; struct passwd *pw; @@ -192,6 +193,7 @@ ls_file(const char *name, const struct stat *st, int remote) struct tm *ltime = localtime(&st->st_mtime); char *user, *group; char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; + char sbuf[FMT_SCALED_STRSIZE]; strmode(st->st_mode, mode); if (!remote && (pw = getpwuid(st->st_uid)) != NULL) { @@ -216,8 +218,15 @@ ls_file(const char *name, const struct stat *st, int remote) tbuf[0] = '\0'; ulen = MAX(strlen(user), 8); glen = MAX(strlen(group), 8); - snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, - (u_int)st->st_nlink, ulen, user, glen, group, - (unsigned long long)st->st_size, tbuf, name); + if (si_units) { + fmt_scaled((long long)st->st_size, sbuf); + snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode, + (u_int)st->st_nlink, ulen, user, glen, group, + sbuf, tbuf, name); + } else { + snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, + (u_int)st->st_nlink, ulen, user, glen, group, + (unsigned long long)st->st_size, tbuf, name); + } return xstrdup(buf); } diff --git a/sftp-common.h b/sftp-common.h index 9b5848462..9ed86c070 100644 --- a/sftp-common.h +++ b/sftp-common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sftp-common.h,v 1.11 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -46,6 +46,6 @@ void stat_to_attrib(const struct stat *, Attrib *); void attrib_to_stat(const Attrib *, struct stat *); Attrib *decode_attrib(Buffer *); void encode_attrib(Buffer *, const Attrib *); -char *ls_file(const char *, const struct stat *, int); +char *ls_file(const char *, const struct stat *, int, int); const char *fx2txt(int); diff --git a/sftp-server.c b/sftp-server.c index ab9391cfd..a98ac2b6d 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.90 2010/01/09 00:20:26 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.91 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -940,7 +940,7 @@ process_readdir(void) continue; stat_to_attrib(&st, &(stats[count].attrib)); stats[count].name = xstrdup(dp->d_name); - stats[count].long_name = ls_file(dp->d_name, &st, 0); + stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); count++; /* send up to 100 entries in one message */ /* XXX check packet size instead */ diff --git a/sftp.1 b/sftp.1 index 3ec7a0234..f6371cf54 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.80 2010/01/09 23:04:13 dtucker Exp $ +.\" $OpenBSD: sftp.1,v 1.81 2010/01/13 01:40:16 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: January 9 2010 $ +.Dd $Mdocdate: January 13 2010 $ .Dt SFTP 1 .Os .Sh NAME @@ -393,7 +393,7 @@ to .It Ic lpwd Print local working directory. .It Xo Ic ls -.Op Fl 1aflnrSt +.Op Fl 1aflhnrSt .Op Ar path .Xc Display a remote directory listing of either @@ -421,6 +421,11 @@ The default sort order is lexicographical. .It Fl l Display additional details including permissions and ownership information. +.It Fl h +When used with a long format option, use unit suffixes: Byte, Kilobyte, +Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce +the number of digits to four or fewer using powers of 2 for sizes (K=1024, +M=1048576, etc.). .It Fl n Produce a long listing with user and group information presented numerically. diff --git a/sftp.c b/sftp.c index 78f8ca178..16f84987c 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.118 2010/01/09 11:13:02 dtucker Exp $ */ +/* $OpenBSD: sftp.c,v 1.119 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -110,16 +110,17 @@ extern char *__progname; #define WHITESPACE " \t\r\n" /* ls flags */ -#define LS_LONG_VIEW 0x01 /* Full view ala ls -l */ -#define LS_SHORT_VIEW 0x02 /* Single row view ala ls -1 */ -#define LS_NUMERIC_VIEW 0x04 /* Long view with numeric uid/gid */ -#define LS_NAME_SORT 0x08 /* Sort by name (default) */ -#define LS_TIME_SORT 0x10 /* Sort by mtime */ -#define LS_SIZE_SORT 0x20 /* Sort by file size */ -#define LS_REVERSE_SORT 0x40 /* Reverse sort order */ -#define LS_SHOW_ALL 0x80 /* Don't skip filenames starting with '.' */ - -#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW) +#define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */ +#define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */ +#define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */ +#define LS_NAME_SORT 0x0008 /* Sort by name (default) */ +#define LS_TIME_SORT 0x0010 /* Sort by mtime */ +#define LS_SIZE_SORT 0x0020 /* Sort by file size */ +#define LS_REVERSE_SORT 0x0040 /* Reverse sort order */ +#define LS_SHOW_ALL 0x0080 /* Don't skip filenames starting with '.' */ +#define LS_SI_UNITS 0x0100 /* Display sizes as K, M, G, etc. */ + +#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS) #define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) /* Commands for interactive mode */ @@ -383,7 +384,7 @@ parse_ls_flags(char **argv, int argc, int *lflag) opterr = 0; *lflag = LS_NAME_SORT; - while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) { + while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) { switch (ch) { case '1': *lflag &= ~VIEW_FLAGS; @@ -399,12 +400,15 @@ parse_ls_flags(char **argv, int argc, int *lflag) case 'f': *lflag &= ~SORT_FLAGS; break; + case 'h': + *lflag |= LS_SI_UNITS; + break; case 'l': - *lflag &= ~VIEW_FLAGS; + *lflag &= ~LS_SHORT_VIEW; *lflag |= LS_LONG_VIEW; break; case 'n': - *lflag &= ~VIEW_FLAGS; + *lflag &= ~LS_SHORT_VIEW; *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; break; case 'r': @@ -716,13 +720,14 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) xfree(tmp); if (lflag & LS_LONG_VIEW) { - if (lflag & LS_NUMERIC_VIEW) { + if (lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) { char *lname; struct stat sb; memset(&sb, 0, sizeof(sb)); attrib_to_stat(&d[n]->a, &sb); - lname = ls_file(fname, &sb, 1); + lname = ls_file(fname, &sb, 1, + (lflag & LS_SI_UNITS)); printf("%s\n", lname); xfree(lname); } else @@ -824,7 +829,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, a = do_lstat(conn, g.gl_pathv[i], 1); if (a != NULL) attrib_to_stat(a, &sb); - lname = ls_file(fname, &sb, 1); + lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS)); printf("%s\n", lname); xfree(lname); } else { -- cgit v1.2.3 From 88b6fb2b55a5c8bb9aeadec185991c5bfae780c0 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 22:44:29 +1100 Subject: - djm@cvs.openbsd.org 2010/01/13 03:48:13 [servconf.c servconf.h sshd.c] avoid run-time failures when specifying hostkeys via a relative path by prepending the cwd in these cases; bz#1290; ok dtucker@ --- ChangeLog | 4 ++++ servconf.c | 20 ++++++++++++++++++-- servconf.h | 3 ++- sshd.c | 5 +++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index d4210354e..1b86fe47e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,10 @@ [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h] support '-h' (human-readable units) for sftp's ls command, just like ls(1); ok dtucker@ + - djm@cvs.openbsd.org 2010/01/13 03:48:13 + [servconf.c servconf.h sshd.c] + avoid run-time failures when specifying hostkeys via a relative + path by prepending the cwd in these cases; bz#1290; ok dtucker@ 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/servconf.c b/servconf.c index b1964e865..09296c9cf 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.201 2010/01/10 03:51:17 dtucker Exp $ */ +/* $OpenBSD: servconf.c,v 1.202 2010/01/13 03:48:12 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -459,6 +459,22 @@ parse_token(const char *cp, const char *filename, return sBadOption; } +char * +derelativise_path(const char *path) +{ + char *expanded, *ret, *cwd; + + expanded = tilde_expand_filename(path, getuid()); + if (*expanded == '/') + return expanded; + if ((cwd = getcwd(NULL, 0)) == NULL) + fatal("%s: getcwd: %s", __func__, strerror(errno)); + xasprintf(&ret, "%s/%s", cwd, expanded); + xfree(cwd); + xfree(expanded); + return ret; +} + static void add_listen_addr(ServerOptions *options, char *addr, int port) { @@ -793,7 +809,7 @@ process_server_config_line(ServerOptions *options, char *line, fatal("%s line %d: missing file name.", filename, linenum); if (*activep && *charptr == NULL) { - *charptr = tilde_expand_filename(arg, getuid()); + *charptr = derelativise_path(arg); /* increase optional counter */ if (intptr != NULL) *intptr = *intptr + 1; diff --git a/servconf.h b/servconf.h index 25a3f1b21..c9b8619cd 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.89 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: servconf.h,v 1.90 2010/01/13 03:48:13 djm Exp $ */ /* * Author: Tatu Ylonen @@ -164,5 +164,6 @@ void parse_server_match_config(ServerOptions *, const char *, const char *, const char *); void copy_set_server_options(ServerOptions *, ServerOptions *, int); void dump_config(ServerOptions *); +char *derelativise_path(const char *); #endif /* SERVCONF_H */ diff --git a/sshd.c b/sshd.c index 4e34f2439..d84db897c 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.370 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: sshd.c,v 1.371 2010/01/13 03:48:13 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1351,7 +1351,8 @@ main(int ac, char **av) fprintf(stderr, "too many host keys.\n"); exit(1); } - options.host_key_files[options.num_host_key_files++] = optarg; + options.host_key_files[options.num_host_key_files++] = + derelativise_path(optarg); break; case 't': test_flag = 1; -- cgit v1.2.3 From 9c3ba07f60434e68657630fec0d7ab0dd7f984a3 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 22:45:03 +1100 Subject: - djm@cvs.openbsd.org 2010/01/13 04:10:50 [sftp.c] don't append a space after inserting a completion of a directory (i.e. a path ending in '/') for a slightly better user experience; ok dtucker@ --- ChangeLog | 4 ++++ sftp.c | 9 +++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b86fe47e..00cb316b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,10 @@ [servconf.c servconf.h sshd.c] avoid run-time failures when specifying hostkeys via a relative path by prepending the cwd in these cases; bz#1290; ok dtucker@ + - djm@cvs.openbsd.org 2010/01/13 04:10:50 + [sftp.c] + don't append a space after inserting a completion of a directory (i.e. + a path ending in '/') for a slightly better user experience; ok dtucker@ 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/sftp.c b/sftp.c index 16f84987c..3bacb7d51 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.119 2010/01/13 01:40:16 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.120 2010/01/13 04:10:50 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1760,15 +1760,12 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, } lf = el_line(el); - /* - * XXX should we really extend here? the user may not be done if - * the filename is a directory. - */ if (g.gl_matchc == 1) { i = 0; if (!terminated) ins[i++] = quote; - if (lastarg || *(lf->cursor) != ' ') + if (*(lf->cursor - 1) != '/' && + (lastarg || *(lf->cursor) != ' ')) ins[i++] = ' '; ins[i] = '\0'; if (i > 0 && el_insertstr(el, ins) == -1) -- cgit v1.2.3 From 096630d06c75f762efeb778f8b43def6f85976c0 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 23:00:38 +1100 Subject: - (dtucker) [sftp-common.c] Wrap include of util.h in an ifdef. --- ChangeLog | 1 + sftp-common.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 00cb316b2..18ce0aa38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,7 @@ [sftp.c] don't append a space after inserting a completion of a directory (i.e. a path ending in '/') for a slightly better user experience; ok dtucker@ + - (dtucker) [sftp-common.c] Wrap include of util.h in an ifdef. 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-common.c b/sftp-common.c index 7393fc6a9..96eb4f79a 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -36,7 +36,9 @@ #include #include #include +#ifdef HAVE_UTIL_H #include +#endif #include "xmalloc.h" #include "buffer.h" -- cgit v1.2.3 From d4a7fcbc462b2af134f6e59a6068fbe5b35fba80 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Wed, 13 Jan 2010 15:44:34 -0800 Subject: - (tim) [defines.h] openbsd-compat/readpassphrase.c now needs _NSIG. feedback and ok dtucker@ --- ChangeLog | 2 ++ defines.h | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 18ce0aa38..1efed808c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,8 @@ don't append a space after inserting a completion of a directory (i.e. a path ending in '/') for a slightly better user experience; ok dtucker@ - (dtucker) [sftp-common.c] Wrap include of util.h in an ifdef. + - (tim) [defines.h] openbsd-compat/readpassphrase.c now needs _NSIG. + feedback and ok dtucker@ 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/defines.h b/defines.h index 3211cc916..c9b93bf71 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.158 2010/01/09 11:33:37 dtucker Exp $ */ +/* $Id: defines.h,v 1.159 2010/01/13 23:44:34 tim Exp $ */ /* Constants */ @@ -753,4 +753,12 @@ struct winsize { # define SSH_IOBUFSZ 8192 #endif +#ifndef _NSIG +# ifdef NSIG +# define _NSIG NSIG +# else +# define _NSIG 128 +# endif +#endif + #endif /* _DEFINES_H */ -- cgit v1.2.3 From 6abc9f68aa19288a4673f5e3030706e31d606407 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 14 Jan 2010 12:44:16 +1100 Subject: - (djm) [platform.h] Add missing prototype for platform_krb5_get_principal_name --- ChangeLog | 4 ++++ platform.h | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1efed808c..d10a96f55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20100114 + - (djm) [platform.h] Add missing prototype for + platform_krb5_get_principal_name + 20100113 - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs. - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18: diff --git a/platform.h b/platform.h index 07ae3ad85..30a1d2259 100644 --- a/platform.h +++ b/platform.h @@ -1,4 +1,4 @@ -/* $Id: platform.h,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */ +/* $Id: platform.h,v 1.4 2010/01/14 01:44:16 djm Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -22,5 +22,7 @@ void platform_pre_listen(void); void platform_pre_fork(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); -char * platform_get_krb5_client(const char *); +char *platform_get_krb5_client(const char *); +char *platform_krb5_get_principal_name(const char *); + -- cgit v1.2.3 From 75fe626489bbafd966332db1b4801fee0c179ffd Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jan 2010 11:42:51 +1100 Subject: - jmc@cvs.openbsd.org 2010/01/13 12:48:34 [sftp.1 sftp.c] sftp.1: put ls -h in the right place sftp.c: as above, plus add -p to get/put, and shorten their arg names to keep the help usage nicely aligned ok djm --- ChangeLog | 9 +++++++++ sftp.1 | 10 +++++----- sftp.c | 8 ++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index d10a96f55..088af5f26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +20100115 + - (dtucker) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2010/01/13 12:48:34 + [sftp.1 sftp.c] + sftp.1: put ls -h in the right place + sftp.c: as above, plus add -p to get/put, and shorten their arg names + to keep the help usage nicely aligned + ok djm + 20100114 - (djm) [platform.h] Add missing prototype for platform_krb5_get_principal_name diff --git a/sftp.1 b/sftp.1 index f6371cf54..175dc6520 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.81 2010/01/13 01:40:16 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.82 2010/01/13 12:48:34 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -393,7 +393,7 @@ to .It Ic lpwd Print local working directory. .It Xo Ic ls -.Op Fl 1aflhnrSt +.Op Fl 1afhlnrSt .Op Ar path .Xc Display a remote directory listing of either @@ -418,14 +418,14 @@ List files beginning with a dot .It Fl f Do not sort the listing. The default sort order is lexicographical. -.It Fl l -Display additional details including permissions -and ownership information. .It Fl h When used with a long format option, use unit suffixes: Byte, Kilobyte, Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce the number of digits to four or fewer using powers of 2 for sizes (K=1024, M=1048576, etc.). +.It Fl l +Display additional details including permissions +and ownership information. .It Fl n Produce a long listing with user and group information presented numerically. diff --git a/sftp.c b/sftp.c index 3bacb7d51..ac6ac9fed 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.120 2010/01/13 04:10:50 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.121 2010/01/13 12:48:34 jmc Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -233,18 +233,18 @@ help(void) "df [-hi] [path] Display statistics for current directory or\n" " filesystem containing 'path'\n" "exit Quit sftp\n" - "get [-Pr] remote-path [local-path] Download file\n" + "get [-Ppr] remote [local] Download file\n" "help Display this help text\n" "lcd path Change local directory to 'path'\n" "lls [ls-options [path]] Display local directory listing\n" "lmkdir path Create local directory\n" "ln oldpath newpath Symlink remote file\n" "lpwd Print local working directory\n" - "ls [-1aflnrSt] [path] Display remote directory listing\n" + "ls [-1afhlnrSt] [path] Display remote directory listing\n" "lumask umask Set local umask to 'umask'\n" "mkdir path Create remote directory\n" "progress Toggle display of progress meter\n" - "put [-Pr] local-path [remote-path] Upload file\n" + "put [-Ppr] local [remote] Upload file\n" "pwd Display remote working directory\n" "quit Quit sftp\n" "rename oldpath newpath Rename remote file\n" -- cgit v1.2.3 From 94881d8dbb228e170d476d35fb523425c0c4c001 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jan 2010 11:44:46 +1100 Subject: - djm@cvs.openbsd.org 2010/01/13 23:47:26 [auth.c] when using ChrootDirectory, make sure we test for the existence of the user's shell inside the chroot; bz #1679, patch from alex AT rtfs.hu; ok dtucker --- ChangeLog | 5 +++++ auth.c | 26 +++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 088af5f26..8a324f350 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,11 @@ sftp.c: as above, plus add -p to get/put, and shorten their arg names to keep the help usage nicely aligned ok djm + - djm@cvs.openbsd.org 2010/01/13 23:47:26 + [auth.c] + when using ChrootDirectory, make sure we test for the existence of the + user's shell inside the chroot; bz #1679, patch from alex AT rtfs.hu; + ok dtucker 20100114 - (djm) [platform.h] Add missing prototype for diff --git a/auth.c b/auth.c index 3dc116907..da87807a8 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.82 2010/01/13 00:19:04 dtucker Exp $ */ +/* $OpenBSD: auth.c,v 1.83 2010/01/13 23:47:26 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -95,7 +95,7 @@ allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; - char *shell; + char *shell, *tmp, *chroot_path; u_int i; #ifdef USE_SHADOW struct spwd *spw = NULL; @@ -156,20 +156,40 @@ allowed_user(struct passwd * pw) * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ - shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; + shell = xstrdup((pw->pw_shell[0] == '\0') ? + _PATH_BSHELL : pw->pw_shell); + + /* + * Amend shell if chroot is requested. + */ + if (options.chroot_directory != NULL && + strcasecmp(options.chroot_directory, "none") != 0) { + tmp = tilde_expand_filename(options.chroot_directory, + pw->pw_uid); + chroot_path = percent_expand(tmp, "h", pw->pw_dir, + "u", pw->pw_name, (char *)NULL); + xfree(tmp); + xasprintf(&tmp, "%s/%s", chroot_path, shell); + xfree(shell); + shell = tmp; + free(chroot_path); + } /* deny if shell does not exists or is not executable */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s does not exist", pw->pw_name, shell); + xfree(shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s is not executable", pw->pw_name, shell); + xfree(shell); return 0; } + xfree(shell); if (options.num_deny_users > 0 || options.num_allow_users > 0 || options.num_deny_groups > 0 || options.num_allow_groups > 0) { -- cgit v1.2.3 From a788de206647e1ffa51b0a95bac1951a02880f76 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jan 2010 11:45:33 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/14 23:41:49 [sftp-common.c] use user_from{uid,gid} to lookup up ids since it keeps a small cache. ok djm --- ChangeLog | 4 ++++ sftp-common.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8a324f350..257204240 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,10 @@ when using ChrootDirectory, make sure we test for the existence of the user's shell inside the chroot; bz #1679, patch from alex AT rtfs.hu; ok dtucker + - dtucker@cvs.openbsd.org 2010/01/14 23:41:49 + [sftp-common.c] + use user_from{uid,gid} to lookup up ids since it keeps a small cache. + ok djm 20100114 - (djm) [platform.h] Add missing prototype for diff --git a/sftp-common.c b/sftp-common.c index 96eb4f79a..d015d7549 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.c,v 1.21 2010/01/13 01:40:16 djm Exp $ */ +/* $OpenBSD: sftp-common.c,v 1.22 2010/01/14 23:41:49 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -198,14 +198,14 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units) char sbuf[FMT_SCALED_STRSIZE]; strmode(st->st_mode, mode); - if (!remote && (pw = getpwuid(st->st_uid)) != NULL) { - user = pw->pw_name; + if (!remote) { + user = user_from_uid(st->st_uid, 0); } else { snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid); user = ubuf; } - if (!remote && (gr = getgrgid(st->st_gid)) != NULL) { - group = gr->gr_name; + if (!remote) { + group = group_from_gid(st->st_gid, 0); } else { snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid); group = gbuf; -- cgit v1.2.3 From b8b17e984acab330b13c66460e6570e72c55ded9 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jan 2010 11:46:03 +1100 Subject: - guenther@cvs.openbsd.org 2010/01/15 00:05:22 [sftp.c] Reset SIGTERM to SIG_DFL before executing ssh, so that even if sftp inherited SIGTERM as ignored it will still be able to kill the ssh it starts. ok dtucker@ --- ChangeLog | 6 ++++++ sftp.c | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 257204240..0d35871eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,12 @@ [sftp-common.c] use user_from{uid,gid} to lookup up ids since it keeps a small cache. ok djm + - guenther@cvs.openbsd.org 2010/01/15 00:05:22 + [sftp.c] + Reset SIGTERM to SIG_DFL before executing ssh, so that even if sftp + inherited SIGTERM as ignored it will still be able to kill the ssh it + starts. + ok dtucker@ 20100114 - (djm) [platform.h] Add missing prototype for diff --git a/sftp.c b/sftp.c index ac6ac9fed..e01703ba9 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.121 2010/01/13 12:48:34 jmc Exp $ */ +/* $OpenBSD: sftp.c,v 1.122 2010/01/15 00:05:22 guenther Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -2027,9 +2027,11 @@ connect_to_server(char *path, char **args, int *in, int *out) * The underlying ssh is in the same process group, so we must * ignore SIGINT if we want to gracefully abort commands, * otherwise the signal will make it to the ssh process and - * kill it too + * kill it too. Contrawise, since sftp sends SIGTERMs to the + * underlying ssh, it must *not* ignore that signal. */ signal(SIGINT, SIG_IGN); + signal(SIGTERM, SIG_DFL); execvp(path, args); fprintf(stderr, "exec: %s: %s\n", path, strerror(errno)); _exit(1); -- cgit v1.2.3 From 9d1fd5bc1017c09bc9ff8b28511b0851fd3472a4 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jan 2010 12:14:45 +1100 Subject: - (dtucker) [openbsd-compat.c/pwcache.c] Pull in pwcache.c from OpenBSD (no changes yet but there will be some to come). --- ChangeLog | 2 + openbsd-compat/pwcache.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 openbsd-compat/pwcache.c diff --git a/ChangeLog b/ChangeLog index 0d35871eb..5e2caf338 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,8 @@ inherited SIGTERM as ignored it will still be able to kill the ssh it starts. ok dtucker@ + - (dtucker) [openbsd-compat.c/pwcache.c] Pull in pwcache.c from OpenBSD (no + changes yet but there will be some to come). 20100114 - (djm) [platform.h] Add missing prototype for diff --git a/openbsd-compat/pwcache.c b/openbsd-compat/pwcache.c new file mode 100644 index 000000000..6f8e6447e --- /dev/null +++ b/openbsd-compat/pwcache.c @@ -0,0 +1,99 @@ +/* $OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include +#include +#include + +#define NCACHE 64 /* power of 2 */ +#define MASK (NCACHE - 1) /* bits to store with */ + +char * +user_from_uid(uid_t uid, int nouser) +{ + static struct ncache { + uid_t uid; + char name[_PW_NAME_LEN + 1]; + } c_uid[NCACHE]; + static int pwopen; + static char nbuf[15]; /* 32 bits == 10 digits */ + struct passwd *pw; + struct ncache *cp; + + cp = c_uid + (uid & MASK); + if (cp->uid != uid || !*cp->name) { + if (pwopen == 0) { + setpassent(1); + pwopen = 1; + } + if ((pw = getpwuid(uid)) == NULL) { + if (nouser) + return (NULL); + (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); + return (nbuf); + } + cp->uid = uid; + strlcpy(cp->name, pw->pw_name, sizeof(cp->name)); + } + return (cp->name); +} + +char * +group_from_gid(gid_t gid, int nogroup) +{ + static struct ncache { + gid_t gid; + char name[_PW_NAME_LEN + 1]; + } c_gid[NCACHE]; + static int gropen; + static char nbuf[15]; /* 32 bits == 10 digits */ + struct group *gr; + struct ncache *cp; + + cp = c_gid + (gid & MASK); + if (cp->gid != gid || !*cp->name) { + if (gropen == 0) { + setgroupent(1); + gropen = 1; + } + if ((gr = getgrgid(gid)) == NULL) { + if (nogroup) + return (NULL); + (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); + return (nbuf); + } + cp->gid = gid; + strlcpy(cp->name, gr->gr_name, sizeof(cp->name)); + } + return (cp->name); +} -- cgit v1.2.3 From 909a390bb812b49f283a4b02e0cc8d582f020fb2 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jan 2010 12:38:30 +1100 Subject: - (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability for pwcache. Also, added caching of negative hits. --- ChangeLog | 2 ++ configure.ac | 8 ++++++-- openbsd-compat/Makefile.in | 4 ++-- openbsd-compat/pwcache.c | 29 +++++++++++++++++++++-------- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e2caf338..d7b082248 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,8 @@ ok dtucker@ - (dtucker) [openbsd-compat.c/pwcache.c] Pull in pwcache.c from OpenBSD (no changes yet but there will be some to come). + - (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability + for pwcache. Also, added caching of negative hits. 20100114 - (djm) [platform.h] Add missing prototype for diff --git a/configure.ac b/configure.ac index e6e6259bd..3293e61c6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.434 2010/01/09 23:26:58 dtucker Exp $ +# $Id: configure.ac,v 1.435 2010/01/15 01:38:30 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.434 $) +AC_REVISION($Revision: 1.435 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1351,6 +1351,7 @@ AC_CHECK_FUNCS( \ getrlimit \ getttyent \ glob \ + group_from_gid \ inet_aton \ inet_ntoa \ inet_ntop \ @@ -1377,8 +1378,10 @@ AC_CHECK_FUNCS( \ setegid \ setenv \ seteuid \ + setgroupent \ setgroups \ setlogin \ + setpassent\ setpcred \ setproctitle \ setregid \ @@ -1407,6 +1410,7 @@ AC_CHECK_FUNCS( \ truncate \ unsetenv \ updwtmpx \ + user_from_uid \ vasprintf \ vhangup \ vsnprintf \ diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index a60e5a68d..d65b77b5b 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.43 2008/06/08 17:32:29 dtucker Exp $ +# $Id: Makefile.in,v 1.44 2010/01/15 01:38:30 dtucker Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ @@ -16,7 +16,7 @@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ -OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o +OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o diff --git a/openbsd-compat/pwcache.c b/openbsd-compat/pwcache.c index 6f8e6447e..472505d02 100644 --- a/openbsd-compat/pwcache.c +++ b/openbsd-compat/pwcache.c @@ -28,22 +28,26 @@ * SUCH DAMAGE. */ +/* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */ + #include #include #include #include +#include #include #define NCACHE 64 /* power of 2 */ #define MASK (NCACHE - 1) /* bits to store with */ +#ifndef HAVE_USER_FROM_UID char * user_from_uid(uid_t uid, int nouser) { static struct ncache { uid_t uid; - char name[_PW_NAME_LEN + 1]; + char *name; } c_uid[NCACHE]; static int pwopen; static char nbuf[15]; /* 32 bits == 10 digits */ @@ -51,29 +55,34 @@ user_from_uid(uid_t uid, int nouser) struct ncache *cp; cp = c_uid + (uid & MASK); - if (cp->uid != uid || !*cp->name) { + if (cp->uid != uid || cp->name == NULL) { +#ifdef HAVE_SETPASSENT if (pwopen == 0) { setpassent(1); pwopen = 1; } +#endif if ((pw = getpwuid(uid)) == NULL) { if (nouser) return (NULL); (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); - return (nbuf); } cp->uid = uid; - strlcpy(cp->name, pw->pw_name, sizeof(cp->name)); + if (cp->name != NULL) + free(cp->name); + cp->name = strdup(pw ? pw->pw_name : nbuf); } return (cp->name); } +#endif +#ifndef HAVE_GROUP_FROM_GID char * group_from_gid(gid_t gid, int nogroup) { static struct ncache { gid_t gid; - char name[_PW_NAME_LEN + 1]; + char *name; } c_gid[NCACHE]; static int gropen; static char nbuf[15]; /* 32 bits == 10 digits */ @@ -81,19 +90,23 @@ group_from_gid(gid_t gid, int nogroup) struct ncache *cp; cp = c_gid + (gid & MASK); - if (cp->gid != gid || !*cp->name) { + if (cp->gid != gid || cp->name == NULL) { +#ifdef HAVE_SETGROUPENT if (gropen == 0) { setgroupent(1); gropen = 1; } +#endif if ((gr = getgrgid(gid)) == NULL) { if (nogroup) return (NULL); (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); - return (nbuf); } cp->gid = gid; - strlcpy(cp->name, gr->gr_name, sizeof(cp->name)); + if (cp->name != NULL) + free(cp->name); + cp->name = strdup(gr ? gr->gr_name : nbuf); } return (cp->name); } +#endif -- cgit v1.2.3 From 7fa3a856ea36d63d7e42243c4428013677255b93 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 15 Jan 2010 13:12:10 +1100 Subject: typo --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d7b082248..23e98fffa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,7 +21,7 @@ inherited SIGTERM as ignored it will still be able to kill the ssh it starts. ok dtucker@ - - (dtucker) [openbsd-compat.c/pwcache.c] Pull in pwcache.c from OpenBSD (no + - (dtucker) [openbsd-compat/pwcache.c] Pull in pwcache.c from OpenBSD (no changes yet but there will be some to come). - (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability for pwcache. Also, added caching of negative hits. -- cgit v1.2.3 From ca94485a484a2f33a50bc293a5bf6e8c26b6d2b5 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 16 Jan 2010 11:48:27 +1100 Subject: - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h so we correctly detect whether or not we have a native user_from_uid. --- ChangeLog | 4 ++++ openbsd-compat/pwcache.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 23e98fffa..e4d6b8c44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20100116 + - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h + so we correctly detect whether or not we have a native user_from_uid. + 20100115 - (dtucker) OpenBSD CVS Sync - jmc@cvs.openbsd.org 2010/01/13 12:48:34 diff --git a/openbsd-compat/pwcache.c b/openbsd-compat/pwcache.c index 472505d02..fa60935d0 100644 --- a/openbsd-compat/pwcache.c +++ b/openbsd-compat/pwcache.c @@ -30,6 +30,8 @@ /* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */ +#include "includes.h" + #include #include -- cgit v1.2.3 From 2563e3f2729b90b62cc0a53137a516d2f009dc53 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 16 Jan 2010 11:53:07 +1100 Subject: - (dtucker) [openbsd-compat/openbsd-compat.h] Prototypes for user_from_uid and group_from_gid. --- ChangeLog | 2 ++ openbsd-compat/openbsd-compat.h | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e4d6b8c44..ebe777032 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ 20100116 - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h so we correctly detect whether or not we have a native user_from_uid. + - (dtucker) [openbsd-compat/openbsd-compat.h] Prototypes for user_from_uid + and group_from_gid. 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 50c6d990b..a38068d71 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.46 2008/06/08 17:32:29 dtucker Exp $ */ +/* $Id: openbsd-compat.h,v 1.47 2010/01/16 00:53:07 dtucker Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -200,6 +200,14 @@ int vasprintf(char **, const char *, va_list); int vsnprintf(char *, size_t, const char *, va_list); #endif +#ifndef HAVE_USER_FROM_UID +char *user_from_uid(uid_t); +#endif + +#ifndef HAVE_GROUP_FROM_GUID +char *group_from_gid(gid_t); +#endif + void *xmmap(size_t size); char *xcrypt(const char *password, const char *salt); char *shadow_pw(struct passwd *pw); -- cgit v1.2.3 From 69371b511b998f2637fdf4bf708e15462162bc0d Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 16 Jan 2010 13:30:30 +1100 Subject: - (dtucker) [openbsd-compat/openbsd-compat.h] Fix prototypes, spotted by Tim. --- ChangeLog | 2 ++ openbsd-compat/openbsd-compat.h | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ebe777032..55e8bb1d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ so we correctly detect whether or not we have a native user_from_uid. - (dtucker) [openbsd-compat/openbsd-compat.h] Prototypes for user_from_uid and group_from_gid. + - (dtucker) [openbsd-compat/openbsd-compat.h] Fix prototypes, spotted by + Tim. 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index a38068d71..020032bc4 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.47 2010/01/16 00:53:07 dtucker Exp $ */ +/* $Id: openbsd-compat.h,v 1.48 2010/01/16 02:30:30 dtucker Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -201,11 +201,11 @@ int vsnprintf(char *, size_t, const char *, va_list); #endif #ifndef HAVE_USER_FROM_UID -char *user_from_uid(uid_t); +char *user_from_uid(uid_t, int); #endif #ifndef HAVE_GROUP_FROM_GUID -char *group_from_gid(gid_t); +char *group_from_gid(gid_t, int); #endif void *xmmap(size_t size); -- cgit v1.2.3 From dab129bef57139232133a870430a9284858909bf Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 16 Jan 2010 13:43:50 +1100 Subject: - markus@cvs.openbsd.org 2010/01/15 09:24:23 [sftp-common.c] unused --- ChangeLog | 4 ++++ sftp-common.c | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 55e8bb1d7..0b533798d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ and group_from_gid. - (dtucker) [openbsd-compat/openbsd-compat.h] Fix prototypes, spotted by Tim. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2010/01/15 09:24:23 + [sftp-common.c] + unused 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-common.c b/sftp-common.c index d015d7549..a042875c6 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.c,v 1.22 2010/01/14 23:41:49 dtucker Exp $ */ +/* $OpenBSD: sftp-common.c,v 1.23 2010/01/15 09:24:23 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -190,8 +190,6 @@ char * ls_file(const char *name, const struct stat *st, int remote, int si_units) { int ulen, glen, sz = 0; - struct passwd *pw; - struct group *gr; struct tm *ltime = localtime(&st->st_mtime); char *user, *group; char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; -- cgit v1.2.3 From 612e400c68e644054e476082cb757b0a157a564b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 16 Jan 2010 13:53:52 +1100 Subject: - (dtucker) [openbsd-compat/pwcache.c] Shrink ifdef area to prevent unused variable warnings. --- ChangeLog | 2 ++ openbsd-compat/pwcache.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b533798d..29e555ab1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,8 @@ - markus@cvs.openbsd.org 2010/01/15 09:24:23 [sftp-common.c] unused + - (dtucker) [openbsd-compat/pwcache.c] Shrink ifdef area to prevent unused + variable warnings. 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/openbsd-compat/pwcache.c b/openbsd-compat/pwcache.c index fa60935d0..5a8b78801 100644 --- a/openbsd-compat/pwcache.c +++ b/openbsd-compat/pwcache.c @@ -58,12 +58,12 @@ user_from_uid(uid_t uid, int nouser) cp = c_uid + (uid & MASK); if (cp->uid != uid || cp->name == NULL) { -#ifdef HAVE_SETPASSENT if (pwopen == 0) { +#ifdef HAVE_SETPASSENT setpassent(1); +#endif pwopen = 1; } -#endif if ((pw = getpwuid(uid)) == NULL) { if (nouser) return (NULL); @@ -93,12 +93,12 @@ group_from_gid(gid_t gid, int nogroup) cp = c_gid + (gid & MASK); if (cp->gid != gid || cp->name == NULL) { -#ifdef HAVE_SETGROUPENT if (gropen == 0) { +#ifdef HAVE_SETGROUPENT setgroupent(1); +#endif gropen = 1; } -#endif if ((gr = getgrgid(gid)) == NULL) { if (nogroup) return (NULL); -- cgit v1.2.3 From 4e218554222592a99991fe6320eae6277f3109a6 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 16 Jan 2010 23:58:37 +1100 Subject: - (dtucker) [openbsd-compat/openbsd-compat.h] Typo. --- ChangeLog | 1 + openbsd-compat/openbsd-compat.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29e555ab1..e41bf6a97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ unused - (dtucker) [openbsd-compat/pwcache.c] Shrink ifdef area to prevent unused variable warnings. + - (dtucker) [openbsd-compat/openbsd-compat.h] Typo. 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 020032bc4..cad2408d6 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.48 2010/01/16 02:30:30 dtucker Exp $ */ +/* $Id: openbsd-compat.h,v 1.49 2010/01/16 12:58:37 dtucker Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -204,7 +204,7 @@ int vsnprintf(char *, size_t, const char *, va_list); char *user_from_uid(uid_t, int); #endif -#ifndef HAVE_GROUP_FROM_GUID +#ifndef HAVE_GROUP_FROM_GID char *group_from_gid(gid_t, int); #endif -- cgit v1.2.3 From 999aaf4182fe7f0b21600299826139520b1b8212 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sat, 16 Jan 2010 11:37:53 -0800 Subject: - (tim) [regress/portnum.sh] Shell portability fix. --- ChangeLog | 1 + regress/portnum.sh | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e41bf6a97..dfae0d687 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ - (dtucker) [openbsd-compat/pwcache.c] Shrink ifdef area to prevent unused variable warnings. - (dtucker) [openbsd-compat/openbsd-compat.h] Typo. + - (tim) [regress/portnum.sh] Shell portability fix. 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/regress/portnum.sh b/regress/portnum.sh index 82abbc9f0..1de0680fe 100644 --- a/regress/portnum.sh +++ b/regress/portnum.sh @@ -13,7 +13,9 @@ badport() { goodport() { port=$1 verbose "$tid: valid port $port" - if ! ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then + if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then + : + else fail "$tid rejected valid port $port" fi } -- cgit v1.2.3 From 4a7db1ca2fbd794ffa41bad2bb8e0aec0f1595f0 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sat, 16 Jan 2010 12:23:25 -0800 Subject: - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native getaddrinfo() is too old and limited for addr_pton() in addrmatch.c. --- ChangeLog | 2 ++ configure.ac | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index dfae0d687..00d78c698 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,8 @@ variable warnings. - (dtucker) [openbsd-compat/openbsd-compat.h] Typo. - (tim) [regress/portnum.sh] Shell portability fix. + - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native + getaddrinfo() is too old and limited for addr_pton() in addrmatch.c. 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/configure.ac b/configure.ac index 3293e61c6..a105de71d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.435 2010/01/15 01:38:30 dtucker Exp $ +# $Id: configure.ac,v 1.436 2010/01/16 20:23:25 tim Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.435 $) +AC_REVISION($Revision: 1.436 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -747,6 +747,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(UNIXWARE_LONG_PASSWORDS, 1, [Support passwords > 8 chars]) AC_DEFINE(USE_PIPES) AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_GETADDRINFO) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) AC_DEFINE(PASSWD_NEEDS_USERNAME) -- cgit v1.2.3 From f37756759fef9ad9a65080424f50cbcfdbc6e512 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sat, 16 Jan 2010 16:48:39 -0800 Subject: - (tim) [roaming_client.c] Use of is not really portable so we use "openbsd-compat/sys-queue.h" --- ChangeLog | 2 ++ roaming_client.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00d78c698..145955680 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,8 @@ - (tim) [regress/portnum.sh] Shell portability fix. - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native getaddrinfo() is too old and limited for addr_pton() in addrmatch.c. + - (tim) [roaming_client.c] Use of is not really portable so + we use "openbsd-compat/sys-queue.h" 20100115 - (dtucker) OpenBSD CVS Sync diff --git a/roaming_client.c b/roaming_client.c index cc387a544..c0dd9ea9c 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -17,7 +17,7 @@ #include "includes.h" -#include +#include "openbsd-compat/sys-queue.h" #include #include @@ -122,7 +122,7 @@ roaming_auth_required(void) calculate_new_key(&key1, cookie, chall); calculate_new_key(&key2, cookie, chall); - debug("Received %llu bytes", (long long unsigned)get_recv_bytes()); + debug("Received %llu bytes", (unsigned long long)get_recv_bytes()); debug("Sent roaming_auth packet"); } @@ -216,7 +216,7 @@ roaming_resume(void) goto fail; } recv_bytes = packet_get_int64() ^ oldkey2; - debug("Peer received %llu bytes", (long long unsigned)recv_bytes); + debug("Peer received %llu bytes", (unsigned long long)recv_bytes); resend_bytes(packet_get_connection_out(), &recv_bytes); resume_in_progress = 0; -- cgit v1.2.3 From 33e48ac7b234bd52426184a945e5d1a2c99d99ba Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sun, 17 Jan 2010 07:12:40 -0800 Subject: Oops, forgot to document second change to roaming_client.c s/long long unsigned/unsigned long long/ to keep USL compilers happy. --- ChangeLog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 145955680..4c170522b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,8 +15,9 @@ - (tim) [regress/portnum.sh] Shell portability fix. - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native getaddrinfo() is too old and limited for addr_pton() in addrmatch.c. - - (tim) [roaming_client.c] Use of is not really portable so - we use "openbsd-compat/sys-queue.h" + - (tim) [roaming_client.c] Use of is not really portable so we + use "openbsd-compat/sys-queue.h". s/long long unsigned/unsigned long long/ + to keep USL compilers happy. 20100115 - (dtucker) OpenBSD CVS Sync -- cgit v1.2.3 From 7ab7b9346d658f86cbd08bd0e7f5f41dbf6ee880 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sun, 17 Jan 2010 12:48:22 -0800 Subject: - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too. --- ChangeLog | 3 +++ configure.ac | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c170522b..9759182dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +20100117 + - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too. + 20100116 - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h so we correctly detect whether or not we have a native user_from_uid. diff --git a/configure.ac b/configure.ac index a105de71d..2ea3ed706 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.436 2010/01/16 20:23:25 tim Exp $ +# $Id: configure.ac,v 1.437 2010/01/17 20:48:22 tim Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.436 $) +AC_REVISION($Revision: 1.437 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -786,6 +786,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_FD_PASSING) AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_GETADDRINFO) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) AC_DEFINE(WITH_ABBREV_NO_TTY) -- cgit v1.2.3 From 641ebf1f86b4f254cab71f9496e8915940248004 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sun, 17 Jan 2010 17:05:39 -0800 Subject: - (tim) [configure.ac] Use the C99-conforming functions snprintf() and vsnprintf() named _xsnprintf() and _xvsnprintf() on SVR5 systems. --- ChangeLog | 2 ++ configure.ac | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9759182dc..aed4bba47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 20100117 - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too. + - (tim) [configure.ac] Use the C99-conforming functions snprintf() and + vsnprintf() named _xsnprintf() and _xvsnprintf() on SVR5 systems. 20100116 - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h diff --git a/configure.ac b/configure.ac index 2ea3ed706..aa74fc30f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.437 2010/01/17 20:48:22 tim Exp $ +# $Id: configure.ac,v 1.438 2010/01/18 01:05:39 tim Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.437 $) +AC_REVISION($Revision: 1.438 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -744,6 +744,7 @@ mips-sony-bsd|mips-sony-newsos4) ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) + CPPFLAGS="$CPPFLAGS -Dvsnprintf=_xvsnprintf -Dsnprintf=_xsnprintf" AC_DEFINE(UNIXWARE_LONG_PASSWORDS, 1, [Support passwords > 8 chars]) AC_DEFINE(USE_PIPES) AC_DEFINE(SETEUID_BREAKS_SETUID) -- cgit v1.2.3 From 7bb7471b80af905452cd7e3a5b3ad1c5cbed9595 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sun, 17 Jan 2010 22:49:57 -0800 Subject: Reword comment in last commit for additional clearity. --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index aed4bba47..6913bf580 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ 20100117 - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too. - - (tim) [configure.ac] Use the C99-conforming functions snprintf() and - vsnprintf() named _xsnprintf() and _xvsnprintf() on SVR5 systems. + - (tim) [configure.ac] On SVR5 systems, use the C99-conforming functions + snprintf() and vsnprintf() named _xsnprintf() and _xvsnprintf(). 20100116 - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h -- cgit v1.2.3 From 6761c7417d362fb8c0d71ddc60c3914f97e88c28 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Fri, 22 Jan 2010 10:25:15 -0800 Subject: - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of socket inheritance, reduce the default SO_RCVBUF/SO_SNDBUF buffer size in Cygwin to 65535. Patch from Corinna Vinschen. --- ChangeLog | 5 +++++ configure.ac | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6913bf580..e43b42e26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +20100122 + - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of + socket inheritance, reduce the default SO_RCVBUF/SO_SNDBUF buffer size + in Cygwin to 65535. Patch from Corinna Vinschen. + 20100117 - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too. - (tim) [configure.ac] On SVR5 systems, use the C99-conforming functions diff --git a/configure.ac b/configure.ac index aa74fc30f..e5de6f58b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.438 2010/01/18 01:05:39 tim Exp $ +# $Id: configure.ac,v 1.439 2010/01/22 18:25:15 tim Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.438 $) +AC_REVISION($Revision: 1.439 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -446,7 +446,7 @@ int main(void) { exit(0); } AC_DEFINE(DISABLE_FD_PASSING, 1, [Define if your platform needs to skip post auth file descriptor passing]) - AC_DEFINE(SSH_IOBUFSZ, 65536, [Windows is sensitive to read buffer size]) + AC_DEFINE(SSH_IOBUFSZ, 65535, [Windows is sensitive to read buffer size]) ;; *-*-dgux*) AC_DEFINE(IP_TOS_IS_BROKEN, 1, -- cgit v1.2.3 From 2e68d793d6967e01faa9ead98b0e527bd19a8d16 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 26 Jan 2010 12:51:13 +1100 Subject: - tedu@cvs.openbsd.org 2010/01/17 21:49:09 [ssh-agent.1] Correct and clarify ssh-add's password asking behavior. Improved text dtucker and ok jmc --- ChangeLog | 7 +++++++ ssh-agent.1 | 9 +++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e43b42e26..569a2d0a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20100126 + - (djm) OpenBSD CVS Sync + - tedu@cvs.openbsd.org 2010/01/17 21:49:09 + [ssh-agent.1] + Correct and clarify ssh-add's password asking behavior. + Improved text dtucker and ok jmc + 20100122 - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of socket inheritance, reduce the default SO_RCVBUF/SO_SNDBUF buffer size diff --git a/ssh-agent.1 b/ssh-agent.1 index acc115bd4..f65e8e625 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.49 2009/10/22 15:02:12 sobrado Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.50 2010/01/17 21:49:09 tedu Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: October 22 2009 $ +.Dd $Mdocdate: January 17 2010 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -119,8 +119,9 @@ and .Pa ~/.ssh/identity . If the identity has a passphrase, .Xr ssh-add 1 -asks for the passphrase (using a small X11 application if running -under X11, or from the terminal if running without X). +asks for the passphrase on the terminal if it has one or from a small X11 +program if running under X11. +If neither of these is the case then the authentication will fail. It then sends the identity to the agent. Several identities can be stored in the agent; the agent can automatically use any of these identities. -- cgit v1.2.3 From f589fd1ea8c352e6bf819733ecd505119a694c51 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 26 Jan 2010 12:53:06 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/18 01:50:27 [roaming_client.c] s/long long unsigned/unsigned long long/, from tim via portable (Id sync only, change already in portable) --- ChangeLog | 4 ++++ roaming_client.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 569a2d0a4..4334f6768 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,10 @@ [ssh-agent.1] Correct and clarify ssh-add's password asking behavior. Improved text dtucker and ok jmc + - dtucker@cvs.openbsd.org 2010/01/18 01:50:27 + [roaming_client.c] + s/long long unsigned/unsigned long long/, from tim via portable + (Id sync only, change already in portable) 20100122 - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of diff --git a/roaming_client.c b/roaming_client.c index c0dd9ea9c..cea8e7360 100644 --- a/roaming_client.c +++ b/roaming_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_client.c,v 1.2 2010/01/09 05:17:00 dtucker Exp $ */ +/* $OpenBSD: roaming_client.c,v 1.3 2010/01/18 01:50:27 dtucker Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * -- cgit v1.2.3 From e1537f951fa87e4d070adda82b474b25cf4902ec Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 26 Jan 2010 13:26:22 +1100 Subject: - djm@cvs.openbsd.org 2010/01/26 01:28:35 [channels.c channels.h clientloop.c clientloop.h mux.c nchan.c ssh.c] rewrite ssh(1) multiplexing code to a more sensible protocol. The new multiplexing code uses channels for the listener and accepted control sockets to make the mux master non-blocking, so no stalls when processing messages from a slave. avoid use of fatal() in mux master protocol parsing so an errant slave process cannot take down a running master. implement requesting of port-forwards over multiplexed sessions. Any port forwards requested by the slave are added to those the master has established. add support for stdio forwarding ("ssh -W host:port ...") in mux slaves. document master/slave mux protocol so that other tools can use it to control a running ssh(1). Note: there are no guarantees that this protocol won't be incompatibly changed (though it is versioned). feedback Salvador Fandino, dtucker@ channel changes ok markus@ --- ChangeLog | 23 + channels.c | 214 +++++-- channels.h | 18 +- clientloop.c | 35 +- clientloop.h | 12 +- mux.c | 1938 ++++++++++++++++++++++++++++++++++++++++++++-------------- nchan.c | 21 +- ssh.c | 22 +- 8 files changed, 1725 insertions(+), 558 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4334f6768..b85350453 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,29 @@ [roaming_client.c] s/long long unsigned/unsigned long long/, from tim via portable (Id sync only, change already in portable) + - djm@cvs.openbsd.org 2010/01/26 01:28:35 + [channels.c channels.h clientloop.c clientloop.h mux.c nchan.c ssh.c] + rewrite ssh(1) multiplexing code to a more sensible protocol. + + The new multiplexing code uses channels for the listener and + accepted control sockets to make the mux master non-blocking, so + no stalls when processing messages from a slave. + + avoid use of fatal() in mux master protocol parsing so an errant slave + process cannot take down a running master. + + implement requesting of port-forwards over multiplexed sessions. Any + port forwards requested by the slave are added to those the master has + established. + + add support for stdio forwarding ("ssh -W host:port ...") in mux slaves. + + document master/slave mux protocol so that other tools can use it to + control a running ssh(1). Note: there are no guarantees that this + protocol won't be incompatibly changed (though it is versioned). + + feedback Salvador Fandino, dtucker@ + channel changes ok markus@ 20100122 - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of diff --git a/channels.c b/channels.c index e8589d8c4..81261679a 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.301 2010/01/11 01:39:46 dtucker Exp $ */ +/* $OpenBSD: channels.c,v 1.302 2010/01/26 01:28:35 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -239,7 +239,6 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, c->rfd = rfd; c->wfd = wfd; c->sock = (rfd == wfd) ? rfd : -1; - c->ctl_fd = -1; /* XXX: set elsewhere */ c->efd = efd; c->extended_usage = extusage; @@ -328,6 +327,9 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->output_filter = NULL; c->filter_ctx = NULL; c->filter_cleanup = NULL; + c->ctl_chan = -1; + c->mux_rcb = NULL; + c->mux_ctx = NULL; c->delayed = 1; /* prevent call to channel_post handler */ TAILQ_INIT(&c->status_confirms); debug("channel %d: new [%s]", found, remote_name); @@ -370,11 +372,10 @@ channel_close_fd(int *fdp) static void channel_close_fds(Channel *c) { - debug3("channel %d: close_fds r %d w %d e %d c %d", - c->self, c->rfd, c->wfd, c->efd, c->ctl_fd); + debug3("channel %d: close_fds r %d w %d e %d", + c->self, c->rfd, c->wfd, c->efd); channel_close_fd(&c->sock); - channel_close_fd(&c->ctl_fd); channel_close_fd(&c->rfd); channel_close_fd(&c->wfd); channel_close_fd(&c->efd); @@ -400,8 +401,6 @@ channel_free(Channel *c) if (c->sock != -1) shutdown(c->sock, SHUT_RDWR); - if (c->ctl_fd != -1) - shutdown(c->ctl_fd, SHUT_RDWR); channel_close_fds(c); buffer_free(&c->input); buffer_free(&c->output); @@ -523,6 +522,7 @@ channel_still_open(void) case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_MUX_LISTENER: case SSH_CHANNEL_CLOSED: case SSH_CHANNEL_AUTH_SOCKET: case SSH_CHANNEL_DYNAMIC: @@ -536,6 +536,7 @@ channel_still_open(void) case SSH_CHANNEL_OPENING: case SSH_CHANNEL_OPEN: case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_MUX_CLIENT: return 1; case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: @@ -567,6 +568,8 @@ channel_find_open(void) case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_MUX_LISTENER: + case SSH_CHANNEL_MUX_CLIENT: case SSH_CHANNEL_OPENING: case SSH_CHANNEL_CONNECTING: case SSH_CHANNEL_ZOMBIE: @@ -617,6 +620,8 @@ channel_open_message(void) case SSH_CHANNEL_CLOSED: case SSH_CHANNEL_AUTH_SOCKET: case SSH_CHANNEL_ZOMBIE: + case SSH_CHANNEL_MUX_CLIENT: + case SSH_CHANNEL_MUX_LISTENER: continue; case SSH_CHANNEL_LARVAL: case SSH_CHANNEL_OPENING: @@ -627,12 +632,12 @@ channel_open_message(void) case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: snprintf(buf, sizeof buf, - " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cfd %d)\r\n", + " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cc %d)\r\n", c->self, c->remote_name, c->type, c->remote_id, c->istate, buffer_len(&c->input), c->ostate, buffer_len(&c->output), - c->rfd, c->wfd, c->ctl_fd); + c->rfd, c->wfd, c->ctl_chan); buffer_append(&buffer, buf, strlen(buf)); continue; default: @@ -839,9 +844,6 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) FD_SET(c->efd, readset); } /* XXX: What about efd? races? */ - if (compat20 && c->ctl_fd != -1 && - c->istate == CHAN_INPUT_OPEN && c->ostate == CHAN_OUTPUT_OPEN) - FD_SET(c->ctl_fd, readset); } /* ARGSUSED */ @@ -986,6 +988,28 @@ channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset) } } +static void +channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset) +{ + if (c->istate == CHAN_INPUT_OPEN && + buffer_check_alloc(&c->input, CHAN_RBUF)) + FD_SET(c->rfd, readset); + if (c->istate == CHAN_INPUT_WAIT_DRAIN) { + /* clear buffer immediately (discard any partial packet) */ + buffer_clear(&c->input); + chan_ibuf_empty(c); + /* Start output drain. XXX just kill chan? */ + chan_rcvd_oclose(c); + } + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + if (buffer_len(&c->output) > 0) + FD_SET(c->wfd, writeset); + else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) + chan_obuf_empty(c); + } +} + /* try to decode a socks4 header */ /* ARGSUSED */ static int @@ -1218,19 +1242,14 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) } Channel * -channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect) +channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect, + int in, int out) { Channel *c; - int in, out; debug("channel_connect_stdio_fwd %s:%d", host_to_connect, port_to_connect); - in = dup(STDIN_FILENO); - out = dup(STDOUT_FILENO); - if (in < 0 || out < 0) - fatal("channel_connect_stdio_fwd: dup() in/out failed"); - c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "stdio-forward", /*nonblock*/0); @@ -1749,36 +1768,6 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset) return 1; } -/* ARGSUSED */ -static int -channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset) -{ - char buf[16]; - int len; - - /* Monitor control fd to detect if the slave client exits */ - if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) { - len = read(c->ctl_fd, buf, sizeof(buf)); - if (len < 0 && - (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) - return 1; - if (len <= 0) { - debug2("channel %d: ctl read<=0", c->self); - if (c->type != SSH_CHANNEL_OPEN) { - debug2("channel %d: not open", c->self); - chan_mark_dead(c); - return -1; - } else { - chan_read_failed(c); - chan_write_failed(c); - } - return -1; - } else - fatal("%s: unexpected data on ctl fd", __func__); - } - return 1; -} - static int channel_check_window(Channel *c) { @@ -1809,10 +1798,131 @@ channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) if (!compat20) return; channel_handle_efd(c, readset, writeset); - channel_handle_ctl(c, readset, writeset); channel_check_window(c); } +static u_int +read_mux(Channel *c, u_int need) +{ + char buf[CHAN_RBUF]; + int len; + u_int rlen; + + if (buffer_len(&c->input) < need) { + rlen = need - buffer_len(&c->input); + len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF)); + if (len <= 0) { + if (errno != EINTR && errno != EAGAIN) { + debug2("channel %d: ctl read<=0 rfd %d len %d", + c->self, c->rfd, len); + chan_read_failed(c); + return 0; + } + } else + buffer_append(&c->input, buf, len); + } + return buffer_len(&c->input); +} + +static void +channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset) +{ + u_int need; + ssize_t len; + + if (!compat20) + fatal("%s: entered with !compat20", __func__); + + if (c->rfd != -1 && FD_ISSET(c->rfd, readset) && + (c->istate == CHAN_INPUT_OPEN || + c->istate == CHAN_INPUT_WAIT_DRAIN)) { + /* + * Don't not read past the precise end of packets to + * avoid disrupting fd passing. + */ + if (read_mux(c, 4) < 4) /* read header */ + return; + need = get_u32(buffer_ptr(&c->input)); +#define CHANNEL_MUX_MAX_PACKET (256 * 1024) + if (need > CHANNEL_MUX_MAX_PACKET) { + debug2("channel %d: packet too big %u > %u", + c->self, CHANNEL_MUX_MAX_PACKET, need); + chan_rcvd_oclose(c); + return; + } + if (read_mux(c, need + 4) < need + 4) /* read body */ + return; + if (c->mux_rcb(c) != 0) { + debug("channel %d: mux_rcb failed", c->self); + chan_mark_dead(c); + return; + } + } + + if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) && + buffer_len(&c->output) > 0) { + len = write(c->wfd, buffer_ptr(&c->output), + buffer_len(&c->output)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return; + if (len <= 0) { + chan_mark_dead(c); + return; + } + buffer_consume(&c->output, len); + } +} + +static void +channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset) +{ + Channel *nc; + struct sockaddr_storage addr; + socklen_t addrlen; + int newsock; + uid_t euid; + gid_t egid; + + if (!FD_ISSET(c->sock, readset)) + return; + + debug("multiplexing control connection"); + + /* + * Accept connection on control socket + */ + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + if ((newsock = accept(c->sock, (struct sockaddr*)&addr, + &addrlen)) == -1) { + error("%s accept: %s", __func__, strerror(errno)); + return; + } + + if (getpeereid(newsock, &euid, &egid) < 0) { + error("%s getpeereid failed: %s", __func__, + strerror(errno)); + close(newsock); + return; + } + if ((euid != 0) && (getuid() != euid)) { + error("multiplex uid mismatch: peer euid %u != uid %u", + (u_int)euid, (u_int)getuid()); + close(newsock); + return; + } + nc = channel_new("multiplex client", SSH_CHANNEL_MUX_CLIENT, + newsock, newsock, -1, c->local_window_max, + c->local_maxpacket, 0, "mux-control", 1); + nc->mux_rcb = c->mux_rcb; + debug3("%s: new mux channel %d fd %d", __func__, + nc->self, nc->sock); + /* establish state */ + nc->mux_rcb(nc); + /* mux state transitions must not elicit protocol messages */ + nc->flags |= CHAN_LOCAL; +} + /* ARGSUSED */ static void channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset) @@ -1841,6 +1951,8 @@ channel_handler_init_20(void) channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; + channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client; channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; @@ -1849,6 +1961,8 @@ channel_handler_init_20(void) channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; + channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener; + channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client; } static void diff --git a/channels.h b/channels.h index 79ebe047a..cc71885f4 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.102 2010/01/11 01:39:46 dtucker Exp $ */ +/* $OpenBSD: channels.h,v 1.103 2010/01/26 01:28:35 djm Exp $ */ /* * Author: Tatu Ylonen @@ -53,7 +53,9 @@ #define SSH_CHANNEL_CONNECTING 12 #define SSH_CHANNEL_DYNAMIC 13 #define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */ -#define SSH_CHANNEL_MAX_TYPE 15 +#define SSH_CHANNEL_MUX_LISTENER 15 /* Listener for mux conn. */ +#define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux slave */ +#define SSH_CHANNEL_MAX_TYPE 17 struct Channel; typedef struct Channel Channel; @@ -81,6 +83,9 @@ struct channel_connect { struct addrinfo *ai, *aitop; }; +/* Callbacks for mux channels back into client-specific code */ +typedef int mux_callback_fn(struct Channel *); + struct Channel { int type; /* channel type/state */ int self; /* my own channel identifier */ @@ -92,7 +97,7 @@ struct Channel { int wfd; /* write fd */ int efd; /* extended fd */ int sock; /* sock fd */ - int ctl_fd; /* control fd (client sharing) */ + int ctl_chan; /* control channel (multiplexed connections) */ int isatty; /* rfd is a tty */ int wfd_isatty; /* wfd is a tty */ int client_tty; /* (client) TTY has been requested */ @@ -142,6 +147,10 @@ struct Channel { /* non-blocking connect */ struct channel_connect connect_ctx; + + /* multiplexing protocol hook, called for each packet received */ + mux_callback_fn *mux_rcb; + void *mux_ctx; }; #define CHAN_EXTENDED_IGNORE 0 @@ -172,6 +181,7 @@ struct Channel { #define CHAN_CLOSE_RCVD 0x02 #define CHAN_EOF_SENT 0x04 #define CHAN_EOF_RCVD 0x08 +#define CHAN_LOCAL 0x10 #define CHAN_RBUF 16*1024 @@ -243,7 +253,7 @@ void channel_clear_adm_permitted_opens(void); void channel_print_adm_permitted_opens(void); int channel_input_port_forward_request(int, int); Channel *channel_connect_to(const char *, u_short, char *, char *); -Channel *channel_connect_stdio_fwd(const char*, u_short); +Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); Channel *channel_connect_by_listen_address(u_short, char *, char *); int channel_request_remote_forwarding(const char *, u_short, const char *, u_short); diff --git a/clientloop.c b/clientloop.c index 5793a6e91..05f4720a1 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.216 2010/01/09 05:04:24 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.217 2010/01/26 01:28:35 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -121,7 +121,7 @@ extern int stdin_null_flag; extern int no_shell_flag; /* Control socket */ -extern int muxserver_sock; +extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */ /* * Name of the host we are connecting to. This is the name given on the @@ -146,7 +146,7 @@ static volatile sig_atomic_t received_signal = 0; static int in_non_blocking_mode = 0; /* Common data for the client loop code. */ -static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ +volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ static int escape_char1; /* Escape character. (proto1 only) */ static int escape_pending1; /* Last character was an escape (proto1 only) */ static int last_was_cr; /* Last character was a newline. */ @@ -564,9 +564,6 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, if (packet_have_data_to_write()) FD_SET(connection_out, *writesetp); - if (muxserver_sock != -1) - FD_SET(muxserver_sock, *readsetp); - /* * Wait for something to happen. This will suspend the process until * some selected descriptor can be read, written, or has some other @@ -695,7 +692,7 @@ client_status_confirm(int type, Channel *c, void *ctx) /* XXX supress on mux _client_ quietmode */ tochan = options.log_level >= SYSLOG_LEVEL_ERROR && - c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; + c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; if (type == SSH2_MSG_CHANNEL_SUCCESS) { debug2("%s request accepted on channel %d", @@ -839,6 +836,7 @@ process_cmdline(void) while (isspace(*++s)) ; + /* XXX update list of forwards in options */ if (delete) { cancel_port = 0; cancel_host = hpdelim(&s); /* may be NULL */ @@ -936,7 +934,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, escape_char); buffer_append(berr, string, strlen(string)); - if (c && c->ctl_fd != -1) { + if (c && c->ctl_chan != -1) { chan_read_failed(c); chan_write_failed(c); return 0; @@ -946,7 +944,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, case 'Z' - 64: /* XXX support this for mux clients */ - if (c && c->ctl_fd != -1) { + if (c && c->ctl_chan != -1) { noescape: snprintf(string, sizeof string, "%c%c escape not available to " @@ -991,7 +989,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, continue; case '&': - if (c && c->ctl_fd != -1) + if (c && c->ctl_chan != -1) goto noescape; /* * Detach the program (continue to serve @@ -1042,7 +1040,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, continue; case '?': - if (c && c->ctl_fd != -1) { + if (c && c->ctl_chan != -1) { snprintf(string, sizeof string, "%c?\r\n\ Supported escape sequences:\r\n\ @@ -1091,7 +1089,7 @@ Supported escape sequences:\r\n\ continue; case 'C': - if (c && c->ctl_fd != -1) + if (c && c->ctl_chan != -1) goto noescape; process_cmdline(); continue; @@ -1327,8 +1325,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); max_fd = MAX(connection_in, connection_out); - if (muxserver_sock != -1) - max_fd = MAX(max_fd, muxserver_sock); if (!compat20) { /* enable nonblocking unless tty */ @@ -1446,12 +1442,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Buffer input from the connection. */ client_process_net_input(readset); - /* Accept control connections. */ - if (muxserver_sock != -1 &&FD_ISSET(muxserver_sock, readset)) { - if (muxserver_accept_control()) - quit_pending = 1; - } - if (quit_pending) break; @@ -1859,9 +1849,8 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) chan_rcvd_eow(c); } else if (strcmp(rtype, "exit-status") == 0) { exitval = packet_get_int(); - if (c->ctl_fd != -1) { - /* Dispatch to mux client */ - atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval)); + if (c->ctl_chan != -1) { + mux_exit_message(c, exitval); success = 1; } else if (id == session_ident) { /* Record exit value of local session */ diff --git a/clientloop.h b/clientloop.h index 8bb874b38..0b8257b99 100644 --- a/clientloop.h +++ b/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.22 2008/06/12 15:19:17 djm Exp $ */ +/* $OpenBSD: clientloop.h,v 1.23 2010/01/26 01:28:35 djm Exp $ */ /* * Author: Tatu Ylonen @@ -56,18 +56,14 @@ typedef void global_confirm_cb(int, u_int32_t seq, void *); void client_register_global_confirm(global_confirm_cb *, void *); /* Multiplexing protocol version */ -#define SSHMUX_VER 2 +#define SSHMUX_VER 4 /* Multiplexing control protocol flags */ #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ #define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ #define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ - -#define SSHMUX_FLAG_TTY (1) /* Request tty on open */ -#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ -#define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */ -#define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */ +#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */ void muxserver_listen(void); -int muxserver_accept_control(void); void muxclient(const char *); +void mux_exit_message(Channel *, int); diff --git a/mux.c b/mux.c index 239edd5f5..dcd6dc028 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.9 2010/01/09 05:04:24 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.10 2010/01/26 01:28:35 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -17,25 +17,21 @@ /* ssh session multiplexing support */ -#include "includes.h" - /* * TODO: - * 1. partial reads in muxserver_accept_control (maybe make channels - * from accepted connections) - * 2. Better signalling from master to slave, especially passing of + * - Better signalling from master to slave, especially passing of * error messages - * 3. Better fall-back from mux slave error to new connection. - * 3. Add/delete forwardings via slave - * 4. ExitOnForwardingFailure (after #3 obviously) - * 5. Maybe extension mechanisms for multi-X11/multi-agent forwarding - * 6. Document the mux mini-protocol somewhere. - * 7. Support ~^Z in mux slaves. - * 8. Inspect or control sessions in master. - * 9. If we ever support the "signal" channel request, send signals on - * sessions in master. + * - Better fall-back from mux slave error to new connection. + * - ExitOnForwardingFailure + * - Maybe extension mechanisms for multi-X11/multi-agent forwarding + * - Support ~^Z in mux slaves. + * - Inspect or control sessions in master. + * - If we ever support the "signal" channel request, send signals on + * sessions in master. */ +#include "includes.h" + #include #include #include @@ -55,6 +51,14 @@ #include #endif +#ifdef HAVE_POLL_H +#include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif + #ifdef HAVE_UTIL_H # include #endif @@ -88,13 +92,16 @@ extern int stdin_null_flag; extern char *host; extern int subsystem_flag; extern Buffer command; +extern volatile sig_atomic_t quit_pending; +extern char *stdio_forward_host; +extern int stdio_forward_port; /* Context for session open confirmation callback */ struct mux_session_confirm_ctx { - int want_tty; - int want_subsys; - int want_x_fwd; - int want_agent_fwd; + u_int want_tty; + u_int want_subsys; + u_int want_x_fwd; + u_int want_agent_fwd; Buffer cmd; char *term; struct termios tio; @@ -104,6 +111,9 @@ struct mux_session_confirm_ctx { /* fd to control socket */ int muxserver_sock = -1; +/* client request id */ +u_int muxclient_request_id = 0; + /* Multiplexing control command */ u_int muxclient_command = 0; @@ -113,269 +123,234 @@ static volatile sig_atomic_t muxclient_terminate = 0; /* PID of multiplex server */ static u_int muxserver_pid = 0; +static Channel *mux_listener_channel = NULL; -/* ** Multiplexing master support */ - -/* Prepare a mux master to listen on a Unix domain socket. */ -void -muxserver_listen(void) -{ - struct sockaddr_un addr; - mode_t old_umask; - int addr_len; - - if (options.control_path == NULL || - options.control_master == SSHCTL_MASTER_NO) - return; - - debug("setting up multiplex master socket"); - - memset(&addr, '\0', sizeof(addr)); - addr.sun_family = AF_UNIX; - addr_len = offsetof(struct sockaddr_un, sun_path) + - strlen(options.control_path) + 1; - - if (strlcpy(addr.sun_path, options.control_path, - sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) - fatal("ControlPath too long"); +struct mux_master_state { + int hello_rcvd; +}; - if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - fatal("%s socket(): %s", __func__, strerror(errno)); +/* mux protocol messages */ +#define MUX_MSG_HELLO 0x00000001 +#define MUX_C_NEW_SESSION 0x10000002 +#define MUX_C_ALIVE_CHECK 0x10000004 +#define MUX_C_TERMINATE 0x10000005 +#define MUX_C_OPEN_FWD 0x10000006 +#define MUX_C_CLOSE_FWD 0x10000007 +#define MUX_C_NEW_STDIO_FWD 0x10000008 +#define MUX_S_OK 0x80000001 +#define MUX_S_PERMISSION_DENIED 0x80000002 +#define MUX_S_FAILURE 0x80000003 +#define MUX_S_EXIT_MESSAGE 0x80000004 +#define MUX_S_ALIVE 0x80000005 +#define MUX_S_SESSION_OPENED 0x80000006 + +/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ +#define MUX_FWD_LOCAL 1 +#define MUX_FWD_REMOTE 2 +#define MUX_FWD_DYNAMIC 3 + +static void mux_session_confirm(int, void *); + +static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); +static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); +static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *); +static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *); +static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); +static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); +static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); + +static const struct { + u_int type; + int (*handler)(u_int, Channel *, Buffer *, Buffer *); +} mux_master_handlers[] = { + { MUX_MSG_HELLO, process_mux_master_hello }, + { MUX_C_NEW_SESSION, process_mux_new_session }, + { MUX_C_ALIVE_CHECK, process_mux_alive_check }, + { MUX_C_TERMINATE, process_mux_terminate }, + { MUX_C_OPEN_FWD, process_mux_open_fwd }, + { MUX_C_CLOSE_FWD, process_mux_close_fwd }, + { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd }, + { 0, NULL } +}; - old_umask = umask(0177); - if (bind(muxserver_sock, (struct sockaddr *)&addr, addr_len) == -1) { - muxserver_sock = -1; - if (errno == EINVAL || errno == EADDRINUSE) { - error("ControlSocket %s already exists, " - "disabling multiplexing", options.control_path); - close(muxserver_sock); - muxserver_sock = -1; - xfree(options.control_path); - options.control_path = NULL; - options.control_master = SSHCTL_MASTER_NO; - return; - } else - fatal("%s bind(): %s", __func__, strerror(errno)); +/* Cleanup callback fired on closure of mux slave _session_ channel */ +/* ARGSUSED */ +static void +mux_master_session_cleanup_cb(int cid, void *unused) +{ + Channel *cc, *c = channel_by_id(cid); + + debug3("%s: entering for channel %d", __func__, cid); + if (c == NULL) + fatal("%s: channel_by_id(%i) == NULL", __func__, cid); + if (c->ctl_chan != -1) { + if ((cc = channel_by_id(c->ctl_chan)) == NULL) + fatal("%s: channel %d missing control channel %d", + __func__, c->self, c->ctl_chan); + c->ctl_chan = -1; + cc->remote_id = -1; + chan_rcvd_oclose(cc); } - umask(old_umask); - - if (listen(muxserver_sock, 64) == -1) - fatal("%s listen(): %s", __func__, strerror(errno)); - - set_nonblock(muxserver_sock); + channel_cancel_cleanup(c->self); } -/* Callback on open confirmation in mux master for a mux client session. */ +/* Cleanup callback fired on closure of mux slave _control_ channel */ +/* ARGSUSED */ static void -mux_session_confirm(int id, void *arg) +mux_master_control_cleanup_cb(int cid, void *unused) { - struct mux_session_confirm_ctx *cctx = arg; - const char *display; - Channel *c; - int i; - - if (cctx == NULL) - fatal("%s: cctx == NULL", __func__); - if ((c = channel_lookup(id)) == NULL) - fatal("%s: no channel for id %d", __func__, id); - - display = getenv("DISPLAY"); - if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { - char *proto, *data; - /* Get reasonable local authentication information. */ - client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, &proto, &data); - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(id, display, proto, data); - /* XXX wait for reply */ - } - - if (cctx->want_agent_fwd && options.forward_agent) { - debug("Requesting authentication agent forwarding."); - channel_request_start(id, "auth-agent-req@openssh.com", 0); - packet_send(); + Channel *sc, *c = channel_by_id(cid); + + debug3("%s: entering for channel %d", __func__, cid); + if (c == NULL) + fatal("%s: channel_by_id(%i) == NULL", __func__, cid); + if (c->remote_id != -1) { + if ((sc = channel_by_id(c->remote_id)) == NULL) + debug2("%s: channel %d n session channel %d", + __func__, c->self, c->remote_id); + c->remote_id = -1; + sc->ctl_chan = -1; + chan_mark_dead(sc); } - - client_session2_setup(id, cctx->want_tty, cctx->want_subsys, - cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); - - c->open_confirm_ctx = NULL; - buffer_free(&cctx->cmd); - xfree(cctx->term); - if (cctx->env != NULL) { - for (i = 0; cctx->env[i] != NULL; i++) - xfree(cctx->env[i]); - xfree(cctx->env); - } - xfree(cctx); + channel_cancel_cleanup(c->self); } -/* - * Accept a connection on the mux master socket and process the - * client's request. Returns flag indicating whether mux master should - * begin graceful close. - */ -int -muxserver_accept_control(void) +/* Check mux client environment variables before passing them to mux master. */ +static int +env_permitted(char *env) { - Buffer m; - Channel *c; - int client_fd, new_fd[3], ver, allowed, window, packetmax; - socklen_t addrlen; - struct sockaddr_storage addr; - struct mux_session_confirm_ctx *cctx; - char *cmd; - u_int i, j, len, env_len, mux_command, flags, escape_char; - uid_t euid; - gid_t egid; - int start_close = 0; - - /* - * Accept connection on control socket - */ - memset(&addr, 0, sizeof(addr)); - addrlen = sizeof(addr); - if ((client_fd = accept(muxserver_sock, - (struct sockaddr*)&addr, &addrlen)) == -1) { - error("%s accept: %s", __func__, strerror(errno)); - return 0; - } + int i, ret; + char name[1024], *cp; - if (getpeereid(client_fd, &euid, &egid) < 0) { - error("%s getpeereid failed: %s", __func__, strerror(errno)); - close(client_fd); + if ((cp = strchr(env, '=')) == NULL || cp == env) return 0; - } - if ((euid != 0) && (getuid() != euid)) { - error("control mode uid mismatch: peer euid %u != uid %u", - (u_int) euid, (u_int) getuid()); - close(client_fd); + ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env); + if (ret <= 0 || (size_t)ret >= sizeof(name)) { + error("env_permitted: name '%.100s...' too long", env); return 0; } - /* XXX handle asynchronously */ - unset_nonblock(client_fd); + for (i = 0; i < options.num_send_env; i++) + if (match_pattern(name, options.send_env[i])) + return 1; + + return 0; +} + +/* Mux master protocol message handlers */ - /* Read command */ - buffer_init(&m); - if (ssh_msg_recv(client_fd, &m) == -1) { - error("%s: client msg_recv failed", __func__); - close(client_fd); - buffer_free(&m); - return 0; +static int +process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) +{ + u_int ver; + struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; + + if (state == NULL) + fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self); + if (state->hello_rcvd) { + error("%s: HELLO received twice", __func__); + return -1; } - if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { - error("%s: wrong client version %d", __func__, ver); - buffer_free(&m); - close(client_fd); - return 0; + if (buffer_get_int_ret(&ver, m) != 0) { + malf: + error("%s: malformed message", __func__); + return -1; } + if (ver != SSHMUX_VER) { + error("Unsupported multiplexing protocol version %d " + "(expected %d)", ver, SSHMUX_VER); + return -1; + } + debug2("%s: channel %d slave version %u", __func__, c->self, ver); - allowed = 1; - mux_command = buffer_get_int(&m); - flags = buffer_get_int(&m); - - buffer_clear(&m); + /* No extensions are presently defined */ + while (buffer_len(m) > 0) { + char *name = buffer_get_string_ret(m, NULL); + char *value = buffer_get_string_ret(m, NULL); - switch (mux_command) { - case SSHMUX_COMMAND_OPEN: - if (options.control_master == SSHCTL_MASTER_ASK || - options.control_master == SSHCTL_MASTER_AUTO_ASK) - allowed = ask_permission("Allow shared connection " - "to %s? ", host); - /* continue below */ - break; - case SSHMUX_COMMAND_TERMINATE: - if (options.control_master == SSHCTL_MASTER_ASK || - options.control_master == SSHCTL_MASTER_AUTO_ASK) - allowed = ask_permission("Terminate shared connection " - "to %s? ", host); - if (allowed) - start_close = 1; - /* FALLTHROUGH */ - case SSHMUX_COMMAND_ALIVE_CHECK: - /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ - buffer_clear(&m); - buffer_put_int(&m, allowed); - buffer_put_int(&m, getpid()); - if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { - error("%s: client msg_send failed", __func__); - close(client_fd); - buffer_free(&m); - return start_close; + if (name == NULL || value == NULL) { + if (name != NULL) + xfree(name); + goto malf; } - buffer_free(&m); - close(client_fd); - return start_close; - default: - error("Unsupported command %d", mux_command); - buffer_free(&m); - close(client_fd); - return 0; + debug2("Unrecognised slave extension \"%s\"", name); + xfree(name); + xfree(value); } + state->hello_rcvd = 1; + return 0; +} + +static int +process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) +{ + Channel *nc; + struct mux_session_confirm_ctx *cctx; + char *reserved, *cmd, *cp; + u_int i, j, len, env_len, escape_char, window, packetmax; + int new_fd[3]; /* Reply for SSHMUX_COMMAND_OPEN */ - buffer_clear(&m); - buffer_put_int(&m, allowed); - buffer_put_int(&m, getpid()); - if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { - error("%s: client msg_send failed", __func__); - close(client_fd); - buffer_free(&m); - return 0; + cctx = xcalloc(1, sizeof(*cctx)); + cctx->term = NULL; + cmd = reserved = NULL; + if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || + buffer_get_int_ret(&cctx->want_tty, m) != 0 || + buffer_get_int_ret(&cctx->want_x_fwd, m) != 0 || + buffer_get_int_ret(&cctx->want_agent_fwd, m) != 0 || + buffer_get_int_ret(&cctx->want_subsys, m) != 0 || + buffer_get_int_ret(&escape_char, m) != 0 || + (cctx->term = buffer_get_string_ret(m, &len)) == NULL || + (cmd = buffer_get_string_ret(m, &len)) == NULL) { + malf: + if (cmd != NULL) + xfree(cmd); + if (reserved != NULL) + xfree(reserved); + if (cctx->term != NULL) + xfree(cctx->term); + error("%s: malformed message", __func__); + return -1; } - - if (!allowed) { - error("Refused control connection"); - close(client_fd); - buffer_free(&m); - return 0; + xfree(reserved); + reserved = NULL; + + cctx->env = NULL; + env_len = 0; + while (buffer_len(m) > 0) { +#define MUX_MAX_ENV_VARS 4096 + if ((cp = buffer_get_string_ret(m, &len)) == NULL) { + xfree(cmd); + goto malf; + } + if (!env_permitted(cp)) { + xfree(cp); + continue; + } + cctx->env = xrealloc(cctx->env, env_len + 2, + sizeof(*cctx->env)); + cctx->env[env_len++] = cp; + cctx->env[env_len] = NULL; + if (env_len > MUX_MAX_ENV_VARS) { + error(">%d environment variables received, ignoring " + "additional", MUX_MAX_ENV_VARS); + break; + } } - buffer_clear(&m); - if (ssh_msg_recv(client_fd, &m) == -1) { - error("%s: client msg_recv failed", __func__); - close(client_fd); - buffer_free(&m); - return 0; - } - if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { - error("%s: wrong client version %d", __func__, ver); - buffer_free(&m); - close(client_fd); - return 0; - } + debug2("%s: channel %d: request tty %d, X %d, agent %d, subsys %d, " + "term \"%s\", cmd \"%s\", env %u", __func__, c->self, + cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd, + cctx->want_subsys, cctx->term, cmd, env_len); - cctx = xcalloc(1, sizeof(*cctx)); - cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; - cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; - cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; - cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; - cctx->term = buffer_get_string(&m, &len); - escape_char = buffer_get_int(&m); - - cmd = buffer_get_string(&m, &len); buffer_init(&cctx->cmd); buffer_append(&cctx->cmd, cmd, strlen(cmd)); - - env_len = buffer_get_int(&m); - env_len = MIN(env_len, 4096); - debug3("%s: receiving %d env vars", __func__, env_len); - if (env_len != 0) { - cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env)); - for (i = 0; i < env_len; i++) - cctx->env[i] = buffer_get_string(&m, &len); - cctx->env[i] = NULL; - } - - debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, - cctx->want_tty, cctx->want_subsys, cmd); xfree(cmd); + cmd = NULL; /* Gather fds from client */ for(i = 0; i < 3; i++) { - if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) { + if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) { error("%s: failed to receive fd %d from slave", __func__, i); for (j = 0; j < i; j++) @@ -386,37 +361,56 @@ muxserver_accept_control(void) xfree(cctx->env); xfree(cctx->term); buffer_free(&cctx->cmd); - close(client_fd); xfree(cctx); - return 0; + + /* prepare reply */ + buffer_put_int(r, MUX_S_FAILURE); + buffer_put_int(r, rid); + buffer_put_cstring(r, + "did not receive file descriptors"); + return -1; } } - debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, + debug3("%s: got fds stdin %d, stdout %d, stderr %d", __func__, new_fd[0], new_fd[1], new_fd[2]); - /* Try to pick up ttymodes from client before it goes raw */ - if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) - error("%s: tcgetattr: %s", __func__, strerror(errno)); - - /* This roundtrip is just for synchronisation of ttymodes */ - buffer_clear(&m); - if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { - error("%s: client msg_send failed", __func__); - close(client_fd); + /* XXX support multiple child sessions in future */ + if (c->remote_id != -1) { + debug2("%s: session already open", __func__); + /* prepare reply */ + buffer_put_int(r, MUX_S_FAILURE); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Multiple sessions not supported"); + cleanup: close(new_fd[0]); close(new_fd[1]); close(new_fd[2]); - buffer_free(&m); xfree(cctx->term); if (env_len != 0) { for (i = 0; i < env_len; i++) xfree(cctx->env[i]); xfree(cctx->env); } + buffer_free(&cctx->cmd); return 0; } - buffer_free(&m); + + if (options.control_master == SSHCTL_MASTER_ASK || + options.control_master == SSHCTL_MASTER_AUTO_ASK) { + if (!ask_permission("Allow shared connection to %s? ", host)) { + debug2("%s: session refused by user", __func__); + /* prepare reply */ + buffer_put_int(r, MUX_S_PERMISSION_DENIED); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Permission denied"); + goto cleanup; + } + } + + /* Try to pick up ttymodes from client before it goes raw */ + if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) + error("%s: tcgetattr: %s", __func__, strerror(errno)); /* enable nonblocking unless tty */ if (!isatty(new_fd[0])) @@ -426,257 +420,1084 @@ muxserver_accept_control(void) if (!isatty(new_fd[2])) set_nonblock(new_fd[2]); - set_nonblock(client_fd); - window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (cctx->want_tty) { window >>= 1; packetmax >>= 1; } - - c = channel_new("session", SSH_CHANNEL_OPENING, + + nc = channel_new("session", SSH_CHANNEL_OPENING, new_fd[0], new_fd[1], new_fd[2], window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); - c->ctl_fd = client_fd; + nc->ctl_chan = c->self; /* link session -> control channel */ + c->remote_id = nc->self; /* link control -> session channel */ + if (cctx->want_tty && escape_char != 0xffffffff) { - channel_register_filter(c->self, + channel_register_filter(nc->self, client_simple_escape_filter, NULL, client_filter_cleanup, client_new_escape_filter_ctx((int)escape_char)); } - debug3("%s: channel_new: %d", __func__, c->self); + debug2("%s: channel_new: %d linked to control channel %d", + __func__, nc->self, nc->ctl_chan); - channel_send_open(c->self); - channel_register_open_confirm(c->self, mux_session_confirm, cctx); - return 0; -} + channel_send_open(nc->self); + channel_register_open_confirm(nc->self, mux_session_confirm, cctx); + channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0); -/* ** Multiplexing client support */ + /* prepare reply */ + /* XXX defer until mux_session_confirm() fires */ + buffer_put_int(r, MUX_S_SESSION_OPENED); + buffer_put_int(r, rid); + buffer_put_int(r, nc->self); -/* Exit signal handler */ -static void -control_client_sighandler(int signo) -{ - muxclient_terminate = signo; + return 0; } -/* - * Relay signal handler - used to pass some signals from mux client to - * mux master. - */ -static void -control_client_sigrelay(int signo) +static int +process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) { - int save_errno = errno; + debug2("%s: channel %d: alive check", __func__, c->self); - if (muxserver_pid > 1) - kill(muxserver_pid, signo); + /* prepare reply */ + buffer_put_int(r, MUX_S_ALIVE); + buffer_put_int(r, rid); + buffer_put_int(r, (u_int)getpid()); - errno = save_errno; + return 0; } -/* Check mux client environment variables before passing them to mux master. */ static int -env_permitted(char *env) +process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) { - int i, ret; - char name[1024], *cp; - - if ((cp = strchr(env, '=')) == NULL || cp == env) - return (0); - ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env); - if (ret <= 0 || (size_t)ret >= sizeof(name)) - fatal("env_permitted: name '%.100s...' too long", env); - - for (i = 0; i < options.num_send_env; i++) - if (match_pattern(name, options.send_env[i])) - return (1); + debug2("%s: channel %d: terminate request", __func__, c->self); + + if (options.control_master == SSHCTL_MASTER_ASK || + options.control_master == SSHCTL_MASTER_AUTO_ASK) { + if (!ask_permission("Terminate shared connection to %s? ", + host)) { + debug2("%s: termination refused by user", __func__); + buffer_put_int(r, MUX_S_PERMISSION_DENIED); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Permission denied"); + return 0; + } + } - return (0); + quit_pending = 1; + buffer_put_int(r, MUX_S_OK); + buffer_put_int(r, rid); + /* XXX exit happens too soon - message never makes it to client */ + return 0; } -/* Multiplex client main loop. */ -void -muxclient(const char *path) +static char * +format_forward(u_int ftype, Forward *fwd) { - struct sockaddr_un addr; - int i, r, fd, sock, exitval[2], num_env, addr_len; - Buffer m; - char *term; - extern char **environ; - u_int allowed, flags; - - if (muxclient_command == 0) - muxclient_command = SSHMUX_COMMAND_OPEN; - - switch (options.control_master) { - case SSHCTL_MASTER_AUTO: - case SSHCTL_MASTER_AUTO_ASK: - debug("auto-mux: Trying existing master"); - /* FALLTHROUGH */ - case SSHCTL_MASTER_NO: + char *ret; + + switch (ftype) { + case MUX_FWD_LOCAL: + xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d", + (fwd->listen_host == NULL) ? + (options.gateway_ports ? "*" : "LOCALHOST") : + fwd->listen_host, fwd->listen_port, + fwd->connect_host, fwd->connect_port); + break; + case MUX_FWD_DYNAMIC: + xasprintf(&ret, "dynamic forward %.200s:%d -> *", + (fwd->listen_host == NULL) ? + (options.gateway_ports ? "*" : "LOCALHOST") : + fwd->listen_host, fwd->listen_port); + break; + case MUX_FWD_REMOTE: + xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d", + (fwd->listen_host == NULL) ? + "LOCALHOST" : fwd->listen_host, + fwd->listen_port, + fwd->connect_host, fwd->connect_port); break; default: - return; + fatal("%s: unknown forward type %u", __func__, ftype); } + return ret; +} - memset(&addr, '\0', sizeof(addr)); - addr.sun_family = AF_UNIX; - addr_len = offsetof(struct sockaddr_un, sun_path) + - strlen(path) + 1; +static int +compare_host(const char *a, const char *b) +{ + if (a == NULL && b == NULL) + return 1; + if (a == NULL || b == NULL) + return 0; + return strcmp(a, b) == 0; +} - if (strlcpy(addr.sun_path, path, - sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) - fatal("ControlPath too long"); +static int +compare_forward(Forward *a, Forward *b) +{ + if (!compare_host(a->listen_host, b->listen_host)) + return 0; + if (a->listen_port != b->listen_port) + return 0; + if (!compare_host(a->connect_host, b->connect_host)) + return 0; + if (a->connect_port != b->connect_port) + return 0; - if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - fatal("%s socket(): %s", __func__, strerror(errno)); + return 1; +} - if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) { - if (muxclient_command != SSHMUX_COMMAND_OPEN) { - fatal("Control socket connect(%.100s): %s", path, - strerror(errno)); +static int +process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) +{ + Forward fwd; + char *fwd_desc = NULL; + u_int ftype; + int i, ret = 0, freefwd = 1; + + fwd.listen_host = fwd.connect_host = NULL; + if (buffer_get_int_ret(&ftype, m) != 0 || + (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || + buffer_get_int_ret(&fwd.listen_port, m) != 0 || + (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || + buffer_get_int_ret(&fwd.connect_port, m) != 0) { + error("%s: malformed message", __func__); + ret = -1; + goto out; + } + + if (*fwd.listen_host == '\0') { + xfree(fwd.listen_host); + fwd.listen_host = NULL; + } + if (*fwd.connect_host == '\0') { + xfree(fwd.connect_host); + fwd.connect_host = NULL; + } + + debug2("%s: channel %d: request %s", __func__, c->self, + (fwd_desc = format_forward(ftype, &fwd))); + + if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE && + ftype != MUX_FWD_DYNAMIC) { + logit("%s: invalid forwarding type %u", __func__, ftype); + invalid: + xfree(fwd.listen_host); + xfree(fwd.connect_host); + buffer_put_int(r, MUX_S_FAILURE); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Invalid forwarding request"); + return 0; + } + /* XXX support rport0 forwarding with reply of port assigned */ + if (fwd.listen_port == 0 || fwd.listen_port >= 65536) { + logit("%s: invalid listen port %u", __func__, + fwd.listen_port); + goto invalid; + } + if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC && + ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { + logit("%s: invalid connect port %u", __func__, + fwd.connect_port); + goto invalid; + } + if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) { + logit("%s: missing connect host", __func__); + goto invalid; + } + + /* Skip forwards that have already been requested */ + switch (ftype) { + case MUX_FWD_LOCAL: + case MUX_FWD_DYNAMIC: + for (i = 0; i < options.num_local_forwards; i++) { + if (compare_forward(&fwd, + options.local_forwards + i)) { + exists: + debug2("%s: found existing forwarding", + __func__); + buffer_put_int(r, MUX_S_OK); + buffer_put_int(r, rid); + goto out; + } } - if (errno == ENOENT) - debug("Control socket \"%.100s\" does not exist", path); - else { - error("Control socket connect(%.100s): %s", path, - strerror(errno)); + break; + case MUX_FWD_REMOTE: + for (i = 0; i < options.num_remote_forwards; i++) { + if (compare_forward(&fwd, + options.remote_forwards + i)) + goto exists; } - close(sock); - return; + break; } - if (stdin_null_flag) { - if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) - fatal("open(/dev/null): %s", strerror(errno)); - if (dup2(fd, STDIN_FILENO) == -1) - fatal("dup2: %s", strerror(errno)); - if (fd > STDERR_FILENO) - close(fd); + if (options.control_master == SSHCTL_MASTER_ASK || + options.control_master == SSHCTL_MASTER_AUTO_ASK) { + if (!ask_permission("Open %s on %s?", fwd_desc, host)) { + debug2("%s: forwarding refused by user", __func__); + buffer_put_int(r, MUX_S_PERMISSION_DENIED); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Permission denied"); + goto out; + } } - term = getenv("TERM"); + if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { + if (options.num_local_forwards + 1 >= + SSH_MAX_FORWARDS_PER_DIRECTION || + channel_setup_local_fwd_listener(fwd.listen_host, + fwd.listen_port, fwd.connect_host, fwd.connect_port, + options.gateway_ports) < 0) { + fail: + logit("slave-requested %s failed", fwd_desc); + buffer_put_int(r, MUX_S_FAILURE); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Port forwarding failed"); + goto out; + } + add_local_forward(&options, &fwd); + freefwd = 0; + } else { + /* XXX wait for remote to confirm */ + if (options.num_remote_forwards + 1 >= + SSH_MAX_FORWARDS_PER_DIRECTION || + channel_request_remote_forwarding(fwd.listen_host, + fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0) + goto fail; + add_remote_forward(&options, &fwd); + freefwd = 0; + } + buffer_put_int(r, MUX_S_OK); + buffer_put_int(r, rid); + out: + if (fwd_desc != NULL) + xfree(fwd_desc); + if (freefwd) { + if (fwd.listen_host != NULL) + xfree(fwd.listen_host); + if (fwd.connect_host != NULL) + xfree(fwd.connect_host); + } + return ret; +} - flags = 0; - if (tty_flag) - flags |= SSHMUX_FLAG_TTY; - if (subsystem_flag) - flags |= SSHMUX_FLAG_SUBSYS; - if (options.forward_x11) - flags |= SSHMUX_FLAG_X11_FWD; - if (options.forward_agent) - flags |= SSHMUX_FLAG_AGENT_FWD; +static int +process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) +{ + Forward fwd; + char *fwd_desc = NULL; + u_int ftype; + int ret = 0; + + fwd.listen_host = fwd.connect_host = NULL; + if (buffer_get_int_ret(&ftype, m) != 0 || + (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || + buffer_get_int_ret(&fwd.listen_port, m) != 0 || + (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || + buffer_get_int_ret(&fwd.connect_port, m) != 0) { + error("%s: malformed message", __func__); + ret = -1; + goto out; + } - signal(SIGPIPE, SIG_IGN); + if (*fwd.listen_host == '\0') { + xfree(fwd.listen_host); + fwd.listen_host = NULL; + } + if (*fwd.connect_host == '\0') { + xfree(fwd.connect_host); + fwd.connect_host = NULL; + } + + debug2("%s: channel %d: request %s", __func__, c->self, + (fwd_desc = format_forward(ftype, &fwd))); + + /* XXX implement this */ + buffer_put_int(r, MUX_S_FAILURE); + buffer_put_int(r, rid); + buffer_put_cstring(r, "unimplemented"); + + out: + if (fwd_desc != NULL) + xfree(fwd_desc); + if (fwd.listen_host != NULL) + xfree(fwd.listen_host); + if (fwd.connect_host != NULL) + xfree(fwd.connect_host); + + return ret; +} + +static int +process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) +{ + Channel *nc; + char *reserved, *chost; + u_int cport, i, j; + int new_fd[2]; + + chost = reserved = NULL; + if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || + (chost = buffer_get_string_ret(m, NULL)) == NULL || + buffer_get_int_ret(&cport, m) != 0) { + if (reserved != NULL) + xfree(reserved); + if (chost != NULL) + xfree(chost); + error("%s: malformed message", __func__); + return -1; + } + xfree(reserved); + + debug2("%s: channel %d: request stdio fwd to %s:%u", + __func__, c->self, chost, cport); + + /* Gather fds from client */ + for(i = 0; i < 2; i++) { + if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) { + error("%s: failed to receive fd %d from slave", + __func__, i); + for (j = 0; j < i; j++) + close(new_fd[j]); + xfree(chost); + + /* prepare reply */ + buffer_put_int(r, MUX_S_FAILURE); + buffer_put_int(r, rid); + buffer_put_cstring(r, + "did not receive file descriptors"); + return -1; + } + } + debug3("%s: got fds stdin %d, stdout %d", __func__, + new_fd[0], new_fd[1]); + + /* XXX support multiple child sessions in future */ + if (c->remote_id != -1) { + debug2("%s: session already open", __func__); + /* prepare reply */ + buffer_put_int(r, MUX_S_FAILURE); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Multiple sessions not supported"); + cleanup: + close(new_fd[0]); + close(new_fd[1]); + xfree(chost); + return 0; + } + + if (options.control_master == SSHCTL_MASTER_ASK || + options.control_master == SSHCTL_MASTER_AUTO_ASK) { + if (!ask_permission("Allow forward to to %s:%u? ", + chost, cport)) { + debug2("%s: stdio fwd refused by user", __func__); + /* prepare reply */ + buffer_put_int(r, MUX_S_PERMISSION_DENIED); + buffer_put_int(r, rid); + buffer_put_cstring(r, "Permission denied"); + goto cleanup; + } + } + + /* enable nonblocking unless tty */ + if (!isatty(new_fd[0])) + set_nonblock(new_fd[0]); + if (!isatty(new_fd[1])) + set_nonblock(new_fd[1]); + + nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]); + + nc->ctl_chan = c->self; /* link session -> control channel */ + c->remote_id = nc->self; /* link control -> session channel */ + + debug2("%s: channel_new: %d linked to control channel %d", + __func__, nc->self, nc->ctl_chan); + + channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0); + + /* prepare reply */ + /* XXX defer until channel confirmed */ + buffer_put_int(r, MUX_S_SESSION_OPENED); + buffer_put_int(r, rid); + buffer_put_int(r, nc->self); + + return 0; +} + +/* Channel callbacks fired on read/write from mux slave fd */ +static int +mux_master_read_cb(Channel *c) +{ + struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; + Buffer in, out; + void *ptr; + u_int type, rid, have, i; + int ret = -1; + + /* Setup ctx and */ + if (c->mux_ctx == NULL) { + state = xcalloc(1, sizeof(state)); + c->mux_ctx = state; + channel_register_cleanup(c->self, + mux_master_control_cleanup_cb, 0); + + /* Send hello */ + buffer_init(&out); + buffer_put_int(&out, MUX_MSG_HELLO); + buffer_put_int(&out, SSHMUX_VER); + /* no extensions */ + buffer_put_string(&c->output, buffer_ptr(&out), + buffer_len(&out)); + buffer_free(&out); + debug3("%s: channel %d: hello sent", __func__, c->self); + return 0; + } + + buffer_init(&in); + buffer_init(&out); + + /* Channel code ensures that we receive whole packets */ + if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) { + malf: + error("%s: malformed message", __func__); + goto out; + } + buffer_append(&in, ptr, have); + + if (buffer_get_int_ret(&type, &in) != 0) + goto malf; + debug3("%s: channel %d packet type 0x%08x len %u", + __func__, c->self, type, buffer_len(&in)); + + if (type == MUX_MSG_HELLO) + rid = 0; + else { + if (!state->hello_rcvd) { + error("%s: expected MUX_MSG_HELLO(0x%08x), " + "received 0x%08x", __func__, MUX_MSG_HELLO, type); + goto out; + } + if (buffer_get_int_ret(&rid, &in) != 0) + goto malf; + } + + for (i = 0; mux_master_handlers[i].handler != NULL; i++) { + if (type == mux_master_handlers[i].type) { + ret = mux_master_handlers[i].handler(rid, c, &in, &out); + break; + } + } + if (mux_master_handlers[i].handler == NULL) { + error("%s: unsupported mux message 0x%08x", __func__, type); + buffer_put_int(&out, MUX_S_FAILURE); + buffer_put_int(&out, rid); + buffer_put_cstring(&out, "unsupported request"); + ret = 0; + } + /* Enqueue reply packet */ + if (buffer_len(&out) != 0) { + buffer_put_string(&c->output, buffer_ptr(&out), + buffer_len(&out)); + } + out: + buffer_free(&in); + buffer_free(&out); + return ret; +} + +void +mux_exit_message(Channel *c, int exitval) +{ + Buffer m; + Channel *mux_chan; + + debug3("%s: channel %d: exit message, evitval %d", __func__, c->self, + exitval); + + if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) + fatal("%s: channel %d missing mux channel %d", + __func__, c->self, c->ctl_chan); + + /* Append exit message packet to control socket output queue */ buffer_init(&m); + buffer_put_int(&m, MUX_S_EXIT_MESSAGE); + buffer_put_int(&m, c->self); + buffer_put_int(&m, exitval); - /* Send our command to server */ - buffer_put_int(&m, muxclient_command); - buffer_put_int(&m, flags); - if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { - error("%s: msg_send", __func__); - muxerr: - close(sock); - buffer_free(&m); - if (muxclient_command != SSHMUX_COMMAND_OPEN) - cleanup_exit(255); - logit("Falling back to non-multiplexed connection"); - xfree(options.control_path); - options.control_path = NULL; - options.control_master = SSHCTL_MASTER_NO; + buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); + buffer_free(&m); +} + +/* Prepare a mux master to listen on a Unix domain socket. */ +void +muxserver_listen(void) +{ + struct sockaddr_un addr; + socklen_t sun_len; + mode_t old_umask; + + if (options.control_path == NULL || + options.control_master == SSHCTL_MASTER_NO) return; + + debug("setting up multiplex master socket"); + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + sun_len = offsetof(struct sockaddr_un, sun_path) + + strlen(options.control_path) + 1; + + if (strlcpy(addr.sun_path, options.control_path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); + + if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s", __func__, strerror(errno)); + + old_umask = umask(0177); + if (bind(muxserver_sock, (struct sockaddr *)&addr, sun_len) == -1) { + muxserver_sock = -1; + if (errno == EINVAL || errno == EADDRINUSE) { + error("ControlSocket %s already exists, " + "disabling multiplexing", options.control_path); + close(muxserver_sock); + muxserver_sock = -1; + xfree(options.control_path); + options.control_path = NULL; + options.control_master = SSHCTL_MASTER_NO; + return; + } else + fatal("%s bind(): %s", __func__, strerror(errno)); + } + umask(old_umask); + + if (listen(muxserver_sock, 64) == -1) + fatal("%s listen(): %s", __func__, strerror(errno)); + + set_nonblock(muxserver_sock); + + mux_listener_channel = channel_new("mux listener", + SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, addr.sun_path, 1); + mux_listener_channel->mux_rcb = mux_master_read_cb; + debug3("%s: mux listener channel %d fd %d", __func__, + mux_listener_channel->self, mux_listener_channel->sock); +} + +/* Callback on open confirmation in mux master for a mux client session. */ +static void +mux_session_confirm(int id, void *arg) +{ + struct mux_session_confirm_ctx *cctx = arg; + const char *display; + Channel *c; + int i; + + if (cctx == NULL) + fatal("%s: cctx == NULL", __func__); + if ((c = channel_by_id(id)) == NULL) + fatal("%s: no channel for id %d", __func__, id); + + display = getenv("DISPLAY"); + if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { + char *proto, *data; + /* Get reasonable local authentication information. */ + client_x11_get_proto(display, options.xauth_location, + options.forward_x11_trusted, &proto, &data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(id, display, proto, data); + /* XXX wait for reply */ + } + + if (cctx->want_agent_fwd && options.forward_agent) { + debug("Requesting authentication agent forwarding."); + channel_request_start(id, "auth-agent-req@openssh.com", 0); + packet_send(); + } + + client_session2_setup(id, cctx->want_tty, cctx->want_subsys, + cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); + + c->open_confirm_ctx = NULL; + buffer_free(&cctx->cmd); + xfree(cctx->term); + if (cctx->env != NULL) { + for (i = 0; cctx->env[i] != NULL; i++) + xfree(cctx->env[i]); + xfree(cctx->env); + } + xfree(cctx); +} + +/* ** Multiplexing client support */ + +/* Exit signal handler */ +static void +control_client_sighandler(int signo) +{ + muxclient_terminate = signo; +} + +/* + * Relay signal handler - used to pass some signals from mux client to + * mux master. + */ +static void +control_client_sigrelay(int signo) +{ + int save_errno = errno; + + if (muxserver_pid > 1) + kill(muxserver_pid, signo); + + errno = save_errno; +} + +static int +mux_client_read(int fd, Buffer *b, u_int need) +{ + u_int have; + ssize_t len; + u_char *p; + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = POLLIN; + p = buffer_append_space(b, need); + for (have = 0; have < need; ) { + if (muxclient_terminate) { + errno = EINTR; + return -1; + } + len = read(fd, p + have, need - have); + if (len < 0) { + switch (errno) { +#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) + case EWOULDBLOCK: +#endif + case EAGAIN: + (void)poll(&pfd, 1, -1); + /* FALLTHROUGH */ + case EINTR: + continue; + default: + return -1; + } + } + if (len == 0) { + errno = EPIPE; + return -1; + } + have += (u_int)len; + } + return 0; +} + +static int +mux_client_write_packet(int fd, Buffer *m) +{ + Buffer queue; + u_int have, need; + int oerrno, len; + u_char *ptr; + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = POLLOUT; + buffer_init(&queue); + buffer_put_string(&queue, buffer_ptr(m), buffer_len(m)); + + need = buffer_len(&queue); + ptr = buffer_ptr(&queue); + + for (have = 0; have < need; ) { + if (muxclient_terminate) { + buffer_free(&queue); + errno = EINTR; + return -1; + } + len = write(fd, ptr + have, need - have); + if (len < 0) { + switch (errno) { +#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) + case EWOULDBLOCK: +#endif + case EAGAIN: + (void)poll(&pfd, 1, -1); + /* FALLTHROUGH */ + case EINTR: + continue; + default: + oerrno = errno; + buffer_free(&queue); + errno = oerrno; + return -1; + } + } + if (len == 0) { + buffer_free(&queue); + errno = EPIPE; + return -1; + } + have += (u_int)len; + } + buffer_free(&queue); + return 0; +} + +static int +mux_client_read_packet(int fd, Buffer *m) +{ + Buffer queue; + u_int need, have; + void *ptr; + int oerrno; + + buffer_init(&queue); + if (mux_client_read(fd, &queue, 4) != 0) { + if ((oerrno = errno) == EPIPE) + debug3("%s: read header failed: %s", __func__, strerror(errno)); + errno = oerrno; + return -1; } + need = get_u32(buffer_ptr(&queue)); + if (mux_client_read(fd, &queue, need) != 0) { + oerrno = errno; + debug3("%s: read body failed: %s", __func__, strerror(errno)); + errno = oerrno; + return -1; + } + ptr = buffer_get_string_ptr(&queue, &have); + buffer_append(m, ptr, have); + buffer_free(&queue); + return 0; +} + +static int +mux_client_hello_exchange(int fd) +{ + Buffer m; + u_int type, ver; + + buffer_init(&m); + buffer_put_int(&m, MUX_MSG_HELLO); + buffer_put_int(&m, SSHMUX_VER); + /* no extensions */ + + if (mux_client_write_packet(fd, &m) != 0) + fatal("%s: write packet: %s", __func__, strerror(errno)); + buffer_clear(&m); - /* Get authorisation status and PID of controlee */ - if (ssh_msg_recv(sock, &m) == -1) { - error("%s: Did not receive reply from master", __func__); - goto muxerr; + /* Read their HELLO */ + if (mux_client_read_packet(fd, &m) != 0) { + buffer_free(&m); + return -1; } - if (buffer_get_char(&m) != SSHMUX_VER) { - error("%s: Master replied with wrong version", __func__); - goto muxerr; + + type = buffer_get_int(&m); + if (type != MUX_MSG_HELLO) + fatal("%s: expected HELLO (%u) received %u", + __func__, MUX_MSG_HELLO, type); + ver = buffer_get_int(&m); + if (ver != SSHMUX_VER) + fatal("Unsupported multiplexing protocol version %d " + "(expected %d)", ver, SSHMUX_VER); + debug2("%s: master version %u", __func__, ver); + /* No extensions are presently defined */ + while (buffer_len(&m) > 0) { + char *name = buffer_get_string(&m, NULL); + char *value = buffer_get_string(&m, NULL); + + debug2("Unrecognised master extension \"%s\"", name); + xfree(name); + xfree(value); } - if (buffer_get_int_ret(&allowed, &m) != 0) { - error("%s: bad server reply", __func__); - goto muxerr; + buffer_free(&m); + return 0; +} + +static u_int +mux_client_request_alive(int fd) +{ + Buffer m; + char *e; + u_int pid, type, rid; + + debug3("%s: entering", __func__); + + buffer_init(&m); + buffer_put_int(&m, MUX_C_ALIVE_CHECK); + buffer_put_int(&m, muxclient_request_id); + + if (mux_client_write_packet(fd, &m) != 0) + fatal("%s: write packet: %s", __func__, strerror(errno)); + + buffer_clear(&m); + + /* Read their reply */ + if (mux_client_read_packet(fd, &m) != 0) { + buffer_free(&m); + return 0; } - if (allowed != 1) { - error("Connection to master denied"); - goto muxerr; + + type = buffer_get_int(&m); + if (type != MUX_S_ALIVE) { + e = buffer_get_string(&m, NULL); + fatal("%s: master returned error: %s", __func__, e); } - muxserver_pid = buffer_get_int(&m); + + if ((rid = buffer_get_int(&m)) != muxclient_request_id) + fatal("%s: out of sequence reply: my id %u theirs %u", + __func__, muxclient_request_id, rid); + pid = buffer_get_int(&m); + buffer_free(&m); + + debug3("%s: done pid = %u", __func__, pid); + + muxclient_request_id++; + + return pid; +} + +static void +mux_client_request_terminate(int fd) +{ + Buffer m; + char *e; + u_int type, rid; + + debug3("%s: entering", __func__); + + buffer_init(&m); + buffer_put_int(&m, MUX_C_TERMINATE); + buffer_put_int(&m, muxclient_request_id); + + if (mux_client_write_packet(fd, &m) != 0) + fatal("%s: write packet: %s", __func__, strerror(errno)); buffer_clear(&m); - switch (muxclient_command) { - case SSHMUX_COMMAND_ALIVE_CHECK: - fprintf(stderr, "Master running (pid=%d)\r\n", - muxserver_pid); - exit(0); - case SSHMUX_COMMAND_TERMINATE: - fprintf(stderr, "Exit request sent.\r\n"); - exit(0); - case SSHMUX_COMMAND_OPEN: - buffer_put_cstring(&m, term ? term : ""); - if (options.escape_char == SSH_ESCAPECHAR_NONE) - buffer_put_int(&m, 0xffffffff); - else - buffer_put_int(&m, options.escape_char); - buffer_append(&command, "\0", 1); - buffer_put_cstring(&m, buffer_ptr(&command)); - - if (options.num_send_env == 0 || environ == NULL) { - buffer_put_int(&m, 0); - } else { - /* Pass environment */ - num_env = 0; - for (i = 0; environ[i] != NULL; i++) { - if (env_permitted(environ[i])) - num_env++; /* Count */ - } - buffer_put_int(&m, num_env); - for (i = 0; environ[i] != NULL && num_env >= 0; i++) { - if (env_permitted(environ[i])) { - num_env--; - buffer_put_cstring(&m, environ[i]); - } - } + /* Read their reply */ + if (mux_client_read_packet(fd, &m) != 0) { + /* Remote end exited already */ + if (errno == EPIPE) { + buffer_free(&m); + return; } + fatal("%s: read from master failed: %s", + __func__, strerror(errno)); + } + + type = buffer_get_int(&m); + if ((rid = buffer_get_int(&m)) != muxclient_request_id) + fatal("%s: out of sequence reply: my id %u theirs %u", + __func__, muxclient_request_id, rid); + switch (type) { + case MUX_S_OK: break; + case MUX_S_PERMISSION_DENIED: + e = buffer_get_string(&m, NULL); + fatal("Master refused termination request: %s", e); + case MUX_S_FAILURE: + e = buffer_get_string(&m, NULL); + fatal("%s: termination request failed: %s", __func__, e); default: - fatal("unrecognised muxclient_command %d", muxclient_command); + fatal("%s: unexpected response from master 0x%08x", + __func__, type); } + buffer_free(&m); + muxclient_request_id++; +} + +static int +mux_client_request_forward(int fd, u_int ftype, Forward *fwd) +{ + Buffer m; + char *e, *fwd_desc; + u_int type, rid; + + fwd_desc = format_forward(ftype, fwd); + debug("Requesting %s", fwd_desc); + xfree(fwd_desc); + + buffer_init(&m); + buffer_put_int(&m, MUX_C_OPEN_FWD); + buffer_put_int(&m, muxclient_request_id); + buffer_put_int(&m, ftype); + buffer_put_cstring(&m, + fwd->listen_host == NULL ? "" : fwd->listen_host); + buffer_put_int(&m, fwd->listen_port); + buffer_put_cstring(&m, + fwd->connect_host == NULL ? "" : fwd->connect_host); + buffer_put_int(&m, fwd->connect_port); + + if (mux_client_write_packet(fd, &m) != 0) + fatal("%s: write packet: %s", __func__, strerror(errno)); + + buffer_clear(&m); - if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { - error("%s: msg_send", __func__); - goto muxerr; + /* Read their reply */ + if (mux_client_read_packet(fd, &m) != 0) { + buffer_free(&m); + return -1; } - if (mm_send_fd(sock, STDIN_FILENO) == -1 || - mm_send_fd(sock, STDOUT_FILENO) == -1 || - mm_send_fd(sock, STDERR_FILENO) == -1) { - error("%s: send fds failed", __func__); - goto muxerr; + type = buffer_get_int(&m); + if ((rid = buffer_get_int(&m)) != muxclient_request_id) + fatal("%s: out of sequence reply: my id %u theirs %u", + __func__, muxclient_request_id, rid); + switch (type) { + case MUX_S_OK: + break; + case MUX_S_PERMISSION_DENIED: + e = buffer_get_string(&m, NULL); + buffer_free(&m); + error("Master refused forwarding request: %s", e); + return -1; + case MUX_S_FAILURE: + e = buffer_get_string(&m, NULL); + buffer_free(&m); + error("%s: session request failed: %s", __func__, e); + return -1; + default: + fatal("%s: unexpected response from master 0x%08x", + __func__, type); } + buffer_free(&m); - /* - * Mux errors are non-recoverable from this point as the master - * has ownership of the session now. - */ + muxclient_request_id++; + return 0; +} - /* Wait for reply, so master has a chance to gather ttymodes */ +static int +mux_client_request_forwards(int fd) +{ + int i; + + debug3("%s: requesting forwardings: %d local, %d remote", __func__, + options.num_local_forwards, options.num_remote_forwards); + + /* XXX ExitOnForwardingFailure */ + for (i = 0; i < options.num_local_forwards; i++) { + if (mux_client_request_forward(fd, + options.local_forwards[i].connect_port == 0 ? + MUX_FWD_DYNAMIC : MUX_FWD_LOCAL, + options.local_forwards + i) != 0) + return -1; + } + for (i = 0; i < options.num_remote_forwards; i++) { + if (mux_client_request_forward(fd, MUX_FWD_REMOTE, + options.remote_forwards + i) != 0) + return -1; + } + return 0; +} + +static int +mux_client_request_session(int fd) +{ + Buffer m; + char *e, *term; + u_int i, rid, sid, esid, exitval, type, exitval_seen; + extern char **environ; + int devnull; + + debug3("%s: entering", __func__); + + if ((muxserver_pid = mux_client_request_alive(fd)) == 0) { + error("%s: master alive request failed", __func__); + return -1; + } + + signal(SIGPIPE, SIG_IGN); + + if (stdin_null_flag) { + if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1) + fatal("open(/dev/null): %s", strerror(errno)); + if (dup2(devnull, STDIN_FILENO) == -1) + fatal("dup2: %s", strerror(errno)); + if (devnull > STDERR_FILENO) + close(devnull); + } + + term = getenv("TERM"); + + buffer_init(&m); + buffer_put_int(&m, MUX_C_NEW_SESSION); + buffer_put_int(&m, muxclient_request_id); + buffer_put_cstring(&m, ""); /* reserved */ + buffer_put_int(&m, tty_flag); + buffer_put_int(&m, options.forward_x11); + buffer_put_int(&m, options.forward_agent); + buffer_put_int(&m, subsystem_flag); + buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ? + 0xffffffff : (u_int)options.escape_char); + buffer_put_cstring(&m, term == NULL ? "" : term); + buffer_put_string(&m, buffer_ptr(&command), buffer_len(&command)); + + if (options.num_send_env > 0 && environ != NULL) { + /* Pass environment */ + for (i = 0; environ[i] != NULL; i++) { + if (env_permitted(environ[i])) { + buffer_put_cstring(&m, environ[i]); + } + } + } + + if (mux_client_write_packet(fd, &m) != 0) + fatal("%s: write packet: %s", __func__, strerror(errno)); + + /* Send the stdio file descriptors */ + if (mm_send_fd(fd, STDIN_FILENO) == -1 || + mm_send_fd(fd, STDOUT_FILENO) == -1 || + mm_send_fd(fd, STDERR_FILENO) == -1) + fatal("%s: send fds failed", __func__); + + debug3("%s: session request sent", __func__); + + /* Read their reply */ buffer_clear(&m); - if (ssh_msg_recv(sock, &m) == -1) - fatal("%s: msg_recv", __func__); - if (buffer_get_char(&m) != SSHMUX_VER) - fatal("%s: wrong version", __func__); - buffer_free(&m); + if (mux_client_read_packet(fd, &m) != 0) { + error("%s: read from master failed: %s", + __func__, strerror(errno)); + buffer_free(&m); + return -1; + } + + type = buffer_get_int(&m); + if ((rid = buffer_get_int(&m)) != muxclient_request_id) + fatal("%s: out of sequence reply: my id %u theirs %u", + __func__, muxclient_request_id, rid); + switch (type) { + case MUX_S_SESSION_OPENED: + sid = buffer_get_int(&m); + debug("%s: master session id: %u", __func__, sid); + break; + case MUX_S_PERMISSION_DENIED: + e = buffer_get_string(&m, NULL); + buffer_free(&m); + error("Master refused forwarding request: %s", e); + return -1; + case MUX_S_FAILURE: + e = buffer_get_string(&m, NULL); + buffer_free(&m); + error("%s: forwarding request failed: %s", __func__, e); + return -1; + default: + buffer_free(&m); + error("%s: unexpected response from master 0x%08x", + __func__, type); + return -1; + } + muxclient_request_id++; signal(SIGHUP, control_client_sighandler); signal(SIGINT, control_client_sighandler); @@ -688,42 +1509,231 @@ muxclient(const char *path) /* * Stick around until the controlee closes the client_fd. - * Before it does, it is expected to write this process' exit - * value (one int). This process must read the value and wait for - * the closure of the client_fd; if this one closes early, the - * multiplex master will terminate early too (possibly losing data). + * Before it does, it is expected to write an exit message. + * This process must read the value and wait for the closure of + * the client_fd; if this one closes early, the multiplex master will + * terminate early too (possibly losing data). */ - exitval[0] = 0; - for (i = 0; !muxclient_terminate && i < (int)sizeof(exitval);) { - r = read(sock, (char *)exitval + i, sizeof(exitval) - i); - if (r == 0) { - debug2("Received EOF from master"); + for (exitval = 255, exitval_seen = 0;;) { + buffer_clear(&m); + if (mux_client_read_packet(fd, &m) != 0) break; + type = buffer_get_int(&m); + if (type != MUX_S_EXIT_MESSAGE) { + e = buffer_get_string(&m, NULL); + fatal("%s: master returned error: %s", __func__, e); } - if (r == -1) { - if (errno == EINTR) - continue; - fatal("%s: read %s", __func__, strerror(errno)); - } - i += r; + if ((esid = buffer_get_int(&m)) != sid) + fatal("%s: exit on unknown session: my id %u theirs %u", + __func__, sid, esid); + debug("%s: master session id: %u", __func__, sid); + if (exitval_seen) + fatal("%s: exitval sent twice", __func__); + exitval = buffer_get_int(&m); + exitval_seen = 1; } - close(sock); + close(fd); leave_raw_mode(force_tty_flag); - if (i > (int)sizeof(int)) - fatal("%s: master returned too much data (%d > %lu)", - __func__, i, (u_long)sizeof(int)); + if (muxclient_terminate) { debug2("Exiting on signal %d", muxclient_terminate); - exitval[0] = 255; - } else if (i < (int)sizeof(int)) { + exitval = 255; + } else if (!exitval_seen) { debug2("Control master terminated unexpectedly"); - exitval[0] = 255; + exitval = 255; } else - debug2("Received exit status from master %d", exitval[0]); + debug2("Received exit status from master %d", exitval); if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) fprintf(stderr, "Shared connection to %s closed.\r\n", host); - exit(exitval[0]); + exit(exitval); +} + +static int +mux_client_request_stdio_fwd(int fd) +{ + Buffer m; + char *e; + u_int type, rid, sid; + int devnull; + + debug3("%s: entering", __func__); + + if ((muxserver_pid = mux_client_request_alive(fd)) == 0) { + error("%s: master alive request failed", __func__); + return -1; + } + + signal(SIGPIPE, SIG_IGN); + + if (stdin_null_flag) { + if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1) + fatal("open(/dev/null): %s", strerror(errno)); + if (dup2(devnull, STDIN_FILENO) == -1) + fatal("dup2: %s", strerror(errno)); + if (devnull > STDERR_FILENO) + close(devnull); + } + + buffer_init(&m); + buffer_put_int(&m, MUX_C_NEW_STDIO_FWD); + buffer_put_int(&m, muxclient_request_id); + buffer_put_cstring(&m, ""); /* reserved */ + buffer_put_cstring(&m, stdio_forward_host); + buffer_put_int(&m, stdio_forward_port); + + if (mux_client_write_packet(fd, &m) != 0) + fatal("%s: write packet: %s", __func__, strerror(errno)); + + /* Send the stdio file descriptors */ + if (mm_send_fd(fd, STDIN_FILENO) == -1 || + mm_send_fd(fd, STDOUT_FILENO) == -1) + fatal("%s: send fds failed", __func__); + + debug3("%s: stdio forward request sent", __func__); + + /* Read their reply */ + buffer_clear(&m); + + if (mux_client_read_packet(fd, &m) != 0) { + error("%s: read from master failed: %s", + __func__, strerror(errno)); + buffer_free(&m); + return -1; + } + + type = buffer_get_int(&m); + if ((rid = buffer_get_int(&m)) != muxclient_request_id) + fatal("%s: out of sequence reply: my id %u theirs %u", + __func__, muxclient_request_id, rid); + switch (type) { + case MUX_S_SESSION_OPENED: + sid = buffer_get_int(&m); + debug("%s: master session id: %u", __func__, sid); + break; + case MUX_S_PERMISSION_DENIED: + e = buffer_get_string(&m, NULL); + buffer_free(&m); + fatal("Master refused forwarding request: %s", e); + case MUX_S_FAILURE: + e = buffer_get_string(&m, NULL); + buffer_free(&m); + fatal("%s: stdio forwarding request failed: %s", __func__, e); + default: + buffer_free(&m); + error("%s: unexpected response from master 0x%08x", + __func__, type); + return -1; + } + muxclient_request_id++; + + signal(SIGHUP, control_client_sighandler); + signal(SIGINT, control_client_sighandler); + signal(SIGTERM, control_client_sighandler); + signal(SIGWINCH, control_client_sigrelay); + + /* + * Stick around until the controlee closes the client_fd. + */ + buffer_clear(&m); + if (mux_client_read_packet(fd, &m) != 0) { + if (errno == EPIPE || + (errno == EINTR && muxclient_terminate != 0)) + return 0; + fatal("%s: mux_client_read_packet: %s", + __func__, strerror(errno)); + } + fatal("%s: master returned unexpected message %u", __func__, type); +} + +/* Multiplex client main loop. */ +void +muxclient(const char *path) +{ + struct sockaddr_un addr; + socklen_t sun_len; + int sock; + u_int pid; + + if (muxclient_command == 0) { + if (stdio_forward_host != NULL) + muxclient_command = SSHMUX_COMMAND_STDIO_FWD; + else + muxclient_command = SSHMUX_COMMAND_OPEN; + } + + switch (options.control_master) { + case SSHCTL_MASTER_AUTO: + case SSHCTL_MASTER_AUTO_ASK: + debug("auto-mux: Trying existing master"); + /* FALLTHROUGH */ + case SSHCTL_MASTER_NO: + break; + default: + return; + } + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + sun_len = offsetof(struct sockaddr_un, sun_path) + + strlen(path) + 1; + + if (strlcpy(addr.sun_path, path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s", __func__, strerror(errno)); + + if (connect(sock, (struct sockaddr *)&addr, sun_len) == -1) { + switch (muxclient_command) { + case SSHMUX_COMMAND_OPEN: + case SSHMUX_COMMAND_STDIO_FWD: + break; + default: + fatal("Control socket connect(%.100s): %s", path, + strerror(errno)); + } + if (errno == ENOENT) + debug("Control socket \"%.100s\" does not exist", path); + else { + error("Control socket connect(%.100s): %s", path, + strerror(errno)); + } + close(sock); + return; + } + set_nonblock(sock); + + if (mux_client_hello_exchange(sock) != 0) { + error("%s: master hello exchange failed", __func__); + close(sock); + return; + } + + switch (muxclient_command) { + case SSHMUX_COMMAND_ALIVE_CHECK: + if ((pid = mux_client_request_alive(sock)) == 0) + fatal("%s: master alive check failed", __func__); + fprintf(stderr, "Master running (pid=%d)\r\n", pid); + exit(0); + case SSHMUX_COMMAND_TERMINATE: + mux_client_request_terminate(sock); + fprintf(stderr, "Exit request sent.\r\n"); + exit(0); + case SSHMUX_COMMAND_OPEN: + if (mux_client_request_forwards(sock) != 0) { + error("%s: master forward request failed", __func__); + return; + } + mux_client_request_session(sock); + return; + case SSHMUX_COMMAND_STDIO_FWD: + mux_client_request_stdio_fwd(sock); + exit(0); + default: + fatal("unrecognised muxclient_command %d", muxclient_command); + } } diff --git a/nchan.c b/nchan.c index 160445e5a..20f6a2f49 100644 --- a/nchan.c +++ b/nchan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nchan.c,v 1.62 2008/11/07 18:50:18 stevesk Exp $ */ +/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -161,7 +161,7 @@ chan_ibuf_empty(Channel *c) switch (c->istate) { case CHAN_INPUT_WAIT_DRAIN: if (compat20) { - if (!(c->flags & CHAN_CLOSE_SENT)) + if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) chan_send_eof2(c); chan_set_istate(c, CHAN_INPUT_CLOSED); } else { @@ -278,9 +278,12 @@ static void chan_rcvd_close2(Channel *c) { debug2("channel %d: rcvd close", c->self); - if (c->flags & CHAN_CLOSE_RCVD) - error("channel %d: protocol error: close rcvd twice", c->self); - c->flags |= CHAN_CLOSE_RCVD; + if (!(c->flags & CHAN_LOCAL)) { + if (c->flags & CHAN_CLOSE_RCVD) + error("channel %d: protocol error: close rcvd twice", + c->self); + c->flags |= CHAN_CLOSE_RCVD; + } if (c->type == SSH_CHANNEL_LARVAL) { /* tear down larval channels immediately */ chan_set_ostate(c, CHAN_OUTPUT_CLOSED); @@ -302,11 +305,13 @@ chan_rcvd_close2(Channel *c) chan_set_istate(c, CHAN_INPUT_CLOSED); break; case CHAN_INPUT_WAIT_DRAIN: - chan_send_eof2(c); + if (!(c->flags & CHAN_LOCAL)) + chan_send_eof2(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; } } + void chan_rcvd_eow(Channel *c) { @@ -454,6 +459,10 @@ chan_is_dead(Channel *c, int do_send) c->self, c->efd, buffer_len(&c->extended)); return 0; } + if (c->flags & CHAN_LOCAL) { + debug2("channel %d: is dead (local)", c->self); + return 1; + } if (!(c->flags & CHAN_CLOSE_SENT)) { if (do_send) { chan_send_close2(c); diff --git a/ssh.c b/ssh.c index b86a764f6..97afdcfee 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.331 2010/01/11 01:39:46 dtucker Exp $ */ +/* $OpenBSD: ssh.c,v 1.332 2010/01/26 01:28:35 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -319,6 +319,11 @@ main(int ac, char **av) options.gateway_ports = 1; break; case 'O': + if (stdio_forward_host != NULL) + fatal("Cannot specify multiplexing " + "command with -W"); + else if (muxclient_command != 0) + fatal("Multiplexing command already specified"); if (strcmp(optarg, "check") == 0) muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; else if (strcmp(optarg, "exit") == 0) @@ -395,6 +400,10 @@ main(int ac, char **av) } break; case 'W': + if (stdio_forward_host != NULL) + fatal("stdio forward already specified"); + if (muxclient_command != 0) + fatal("Cannot specify stdio forward with -O"); if (parse_forward(&fwd, optarg, 1, 0)) { stdio_forward_host = fwd.listen_host; stdio_forward_port = fwd.listen_port; @@ -902,11 +911,18 @@ static int client_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect) { Channel *c; + int in, out; debug3("client_setup_stdio_fwd %s:%d", host_to_connect, port_to_connect); - if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect)) - == NULL) + + in = dup(STDIN_FILENO); + out = dup(STDOUT_FILENO); + if (in < 0 || out < 0) + fatal("channel_connect_stdio_fwd: dup() in/out failed"); + + if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect, + in, out)) == NULL) return 0; channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); return 1; -- cgit v1.2.3 From 45a81a0e18fe988f20794622390146c7e3975d6f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 28 Jan 2010 06:26:20 +1100 Subject: - djm@cvs.openbsd.org 2010/01/26 02:15:20 [mux.c] -Wuninitialized and remove a // comment; from portable (Id sync only) --- ChangeLog | 7 +++++++ mux.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b85350453..aac1b7193 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20100128 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/01/26 02:15:20 + [mux.c] + -Wuninitialized and remove a // comment; from portable + (Id sync only) + 20100126 - (djm) OpenBSD CVS Sync - tedu@cvs.openbsd.org 2010/01/17 21:49:09 diff --git a/mux.c b/mux.c index dcd6dc028..ef99b5737 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.10 2010/01/26 01:28:35 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.11 2010/01/26 02:15:20 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * -- cgit v1.2.3 From a21cdfac2fd89360b5c60152bda60b4150ad35fc Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 28 Jan 2010 06:26:59 +1100 Subject: - djm@cvs.openbsd.org 2010/01/27 13:26:17 [mux.c] fix bug introduced in mux rewrite: In a mux master, when a socket to a mux slave closes before its server session (as may occur when the slave has been signalled), gracefully close the server session rather than deleting its channel immediately. A server may have more messages on that channel to send (e.g. an exit message) that will fatal() the client if they are sent to a channel that has been prematurely deleted. spotted by imorgan AT nas.nasa.gov --- ChangeLog | 12 ++++++++++++ mux.c | 10 ++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index aac1b7193..05cbba64a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,18 @@ [mux.c] -Wuninitialized and remove a // comment; from portable (Id sync only) + - djm@cvs.openbsd.org 2010/01/27 13:26:17 + [mux.c] + fix bug introduced in mux rewrite: + + In a mux master, when a socket to a mux slave closes before its server + session (as may occur when the slave has been signalled), gracefully + close the server session rather than deleting its channel immediately. + A server may have more messages on that channel to send (e.g. an exit + message) that will fatal() the client if they are sent to a channel that + has been prematurely deleted. + + spotted by imorgan AT nas.nasa.gov 20100126 - (djm) OpenBSD CVS Sync diff --git a/mux.c b/mux.c index ef99b5737..64781d44c 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.11 2010/01/26 02:15:20 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.12 2010/01/27 13:26:17 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -210,7 +210,13 @@ mux_master_control_cleanup_cb(int cid, void *unused) __func__, c->self, c->remote_id); c->remote_id = -1; sc->ctl_chan = -1; - chan_mark_dead(sc); + if (sc->type != SSH_CHANNEL_OPEN) { + debug2("%s: channel %d: not open", __func__, sc->self); + chan_mark_dead(c); + } else { + chan_read_failed(sc); + chan_write_failed(sc); + } } channel_cancel_cleanup(c->self); } -- cgit v1.2.3 From a1162985a51321158a625a214424a7ec51030a7d Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 28 Jan 2010 06:27:54 +1100 Subject: - djm@cvs.openbsd.org 2010/01/27 19:21:39 [sftp.c] add missing "p" flag to getopt optstring; bz#1704 from imorgan AT nas.nasa.gov --- ChangeLog | 4 ++++ sftp.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05cbba64a..5cd1d8f63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,10 @@ has been prematurely deleted. spotted by imorgan AT nas.nasa.gov + - djm@cvs.openbsd.org 2010/01/27 19:21:39 + [sftp.c] + add missing "p" flag to getopt optstring; + bz#1704 from imorgan AT nas.nasa.gov 20100126 - (djm) OpenBSD CVS Sync diff --git a/sftp.c b/sftp.c index e01703ba9..d65d4ec62 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.122 2010/01/15 00:05:22 guenther Exp $ */ +/* $OpenBSD: sftp.c,v 1.123 2010/01/27 19:21:39 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -2095,7 +2095,7 @@ main(int argc, char **argv) infile = stdin; while ((ch = getopt(argc, argv, - "1246hqrvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) { + "1246hpqrvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { /* Passed through to ssh(1) */ case '4': -- cgit v1.2.3 From 19d32cb9348baec8e86bb4b19de513ff8d7fa3ce Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 29 Jan 2010 10:54:11 +1100 Subject: - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config() after registering the hardware engines, which causes the openssl.cnf file to be processed. See OpenSSL's man page for OPENSSL_config(3) for details. Patch from Solomon Peachy, ok djm@. --- ChangeLog | 6 ++++++ openbsd-compat/openssl-compat.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5cd1d8f63..8e427cc41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20100129 + - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config() + after registering the hardware engines, which causes the openssl.cnf file to + be processed. See OpenSSL's man page for OPENSSL_config(3) for details. + Patch from Solomon Peachy, ok djm@. + 20100128 - (djm) OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/01/26 02:15:20 diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index dd326c00f..420496caa 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.c,v 1.8 2009/03/07 11:22:35 dtucker Exp $ */ +/* $Id: openssl-compat.c,v 1.9 2010/01/28 23:54:11 dtucker Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -67,5 +67,6 @@ ssh_SSLeay_add_all_algorithms(void) /* Enable use of crypto hardware */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); + OPENSSL_config(NULL); } #endif -- cgit v1.2.3 From 36f57ebf3b5ecf697c5ae868dbc0992792890e06 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 30 Jan 2010 17:28:34 +1100 Subject: - djm@cvs.openbsd.org 2010/01/28 00:21:18 [clientloop.c] downgrade an error() to a debug() - this particular case can be hit in normal operation for certain sequences of mux slave vs session closure and is harmless --- ChangeLog | 8 ++++++++ clientloop.c | 7 ++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e427cc41..f9a84fddf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +20100130 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/01/28 00:21:18 + [clientloop.c] + downgrade an error() to a debug() - this particular case can be hit in + normal operation for certain sequences of mux slave vs session closure + and is harmless + 20100129 - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config() after registering the hardware engines, which causes the openssl.cnf file to diff --git a/clientloop.c b/clientloop.c index 05f4720a1..6ffef95a2 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.217 2010/01/26 01:28:35 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.218 2010/01/28 00:21:18 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1857,8 +1857,9 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) success = 1; exit_status = exitval; } else { - error("client_input_channel_req: unexpected channel %d", - session_ident); + /* Probably for a mux channel that has already closed */ + debug("%s: no sink for exit-status on channel %d", + __func__, id); } packet_check_eom(); } -- cgit v1.2.3 From 133d9d313e1058ed5d028abb450de253c00a4c5d Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 30 Jan 2010 17:30:04 +1100 Subject: - djm@cvs.openbsd.org 2010/01/29 00:20:41 [sshd.c] set FD_CLOEXEC on sock_in/sock_out; bz#1706 from jchadima AT redhat.com ok dtucker@ --- ChangeLog | 4 ++++ mux.c | 4 ++-- sshd.c | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9a84fddf..67cf0fc1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ downgrade an error() to a debug() - this particular case can be hit in normal operation for certain sequences of mux slave vs session closure and is harmless + - djm@cvs.openbsd.org 2010/01/29 00:20:41 + [sshd.c] + set FD_CLOEXEC on sock_in/sock_out; bz#1706 from jchadima AT redhat.com + ok dtucker@ 20100129 - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config() diff --git a/mux.c b/mux.c index 64781d44c..0e07883e4 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.12 2010/01/27 13:26:17 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.13 2010/01/29 20:16:17 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -212,7 +212,7 @@ mux_master_control_cleanup_cb(int cid, void *unused) sc->ctl_chan = -1; if (sc->type != SSH_CHANNEL_OPEN) { debug2("%s: channel %d: not open", __func__, sc->self); - chan_mark_dead(c); + chan_mark_dead(sc); } else { chan_read_failed(sc); chan_write_failed(sc); diff --git a/sshd.c b/sshd.c index d84db897c..bf2e76cc8 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.371 2010/01/13 03:48:13 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.372 2010/01/29 00:20:41 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1748,6 +1748,10 @@ main(int ac, char **av) sock_in, sock_out, newsock, startup_pipe, config_s[0]); } + /* Executed child processes don't need these. */ + fcntl(sock_out, F_SETFD, FD_CLOEXEC); + fcntl(sock_in, F_SETFD, FD_CLOEXEC); + /* * Disable the key regeneration alarm. We will not regenerate the * key since we are no longer in a position to give it to anyone. We -- cgit v1.2.3 From 0dac03febdb52ccf0dfe19dcb1d7e895264b218a Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 30 Jan 2010 17:36:33 +1100 Subject: - djm@cvs.openbsd.org 2010/01/29 20:16:17 [mux.c] kill correct channel (was killing already-dead mux channel, not its session channel) --- ChangeLog | 4 ++++ mux.c | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67cf0fc1d..37c5fa4e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,10 @@ [sshd.c] set FD_CLOEXEC on sock_in/sock_out; bz#1706 from jchadima AT redhat.com ok dtucker@ + - djm@cvs.openbsd.org 2010/01/29 20:16:17 + [mux.c] + kill correct channel (was killing already-dead mux channel, not + its session channel) 20100129 - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config() diff --git a/mux.c b/mux.c index 0e07883e4..825fb7a9a 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.13 2010/01/29 20:16:17 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.14 2010/01/30 02:54:53 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -214,8 +214,10 @@ mux_master_control_cleanup_cb(int cid, void *unused) debug2("%s: channel %d: not open", __func__, sc->self); chan_mark_dead(sc); } else { - chan_read_failed(sc); - chan_write_failed(sc); + if (sc->istate == CHAN_INPUT_OPEN) + chan_read_failed(sc); + if (sc->ostate == CHAN_OUTPUT_OPEN) + chan_write_failed(sc); } } channel_cancel_cleanup(c->self); -- cgit v1.2.3 From c3ca35f42421d6cdc66411f29c0220068475efa7 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 30 Jan 2010 17:42:01 +1100 Subject: - djm@cvs.openbsd.org 2010/01/30 02:54:53 [mux.c] don't mark channel as read failed if it is already closing; suppresses harmless error messages when connecting to SSH.COM Tectia server report by imorgan AT nas.nasa.gov --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 37c5fa4e5..56cc86ae7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,11 @@ [mux.c] kill correct channel (was killing already-dead mux channel, not its session channel) + - djm@cvs.openbsd.org 2010/01/30 02:54:53 + [mux.c] + don't mark channel as read failed if it is already closing; suppresses + harmless error messages when connecting to SSH.COM Tectia server + report by imorgan AT nas.nasa.gov 20100129 - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config() -- cgit v1.2.3 From 74d9825c0fb714398667200c6ca5ef8d2431ed8b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 2 Feb 2010 17:01:46 +1100 Subject: - djm@cvs.openbsd.org 2010/01/30 21:08:33 [sshd.8] debug output goes to stderr, not "the system log"; ok markus dtucker --- ChangeLog | 6 ++++++ sshd.8 | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56cc86ae7..703ed6dd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20100202 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/01/30 21:08:33 + [sshd.8] + debug output goes to stderr, not "the system log"; ok markus dtucker + 20100130 - (djm) OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/01/28 00:21:18 diff --git a/sshd.8 b/sshd.8 index 7878d9f06..76b7e2987 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.249 2009/10/08 20:42:13 jmc Exp $ -.Dd $Mdocdate: October 8 2009 $ +.\" $OpenBSD: sshd.8,v 1.250 2010/01/30 21:08:33 djm Exp $ +.Dd $Mdocdate: January 30 2010 $ .Dt SSHD 8 .Os .Sh NAME @@ -127,8 +127,8 @@ This allows easy monitoring of .Nm sshd . .It Fl d Debug mode. -The server sends verbose debug output to the system -log, and does not put itself in the background. +The server sends verbose debug output to standard error, +and does not put itself in the background. The server also will not fork and will only process one connection. This option is only intended for debugging for the server. Multiple -- cgit v1.2.3 From d636943d088349d13eae228871132849b8d5174c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 2 Feb 2010 17:02:07 +1100 Subject: - djm@cvs.openbsd.org 2010/01/30 21:12:08 [channels.c] fake local addr:port when stdio fowarding as some servers (Tectia at least) validate that they are well-formed; reported by imorgan AT nas.nasa.gov ok dtucker --- ChangeLog | 6 ++++++ channels.c | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 703ed6dd1..83af29679 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,12 @@ - djm@cvs.openbsd.org 2010/01/30 21:08:33 [sshd.8] debug output goes to stderr, not "the system log"; ok markus dtucker + - djm@cvs.openbsd.org 2010/01/30 21:12:08 + [channels.c] + fake local addr:port when stdio fowarding as some servers (Tectia at + least) validate that they are well-formed; + reported by imorgan AT nas.nasa.gov + ok dtucker 20100130 - (djm) OpenBSD CVS Sync diff --git a/channels.c b/channels.c index 81261679a..d8c53a4a8 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.302 2010/01/26 01:28:35 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.303 2010/01/30 21:12:08 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1376,6 +1376,13 @@ port_open_helper(Channel *c, char *rtype) char *remote_ipaddr = get_peer_ipaddr(c->sock); int remote_port = get_peer_port(c->sock); + if (remote_port == -1) { + /* Fake addr/port to appease peers that validate it (Tectia) */ + xfree(remote_ipaddr); + remote_ipaddr = xstrdup("127.0.0.1"); + remote_port = 65535; + } + direct = (strcmp(rtype, "direct-tcpip") == 0); snprintf(buf, sizeof buf, -- cgit v1.2.3 From b401f922b20347b60ef55ae032611d09734016c8 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 10 Feb 2010 10:17:49 +1100 Subject: This should have gone in with the multiplexing merge, but I dropped it at the time. --- PROTOCOL.mux | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 PROTOCOL.mux diff --git a/PROTOCOL.mux b/PROTOCOL.mux new file mode 100644 index 000000000..d22f7379c --- /dev/null +++ b/PROTOCOL.mux @@ -0,0 +1,196 @@ +This document describes the multiplexing protocol used by ssh(1)'s +ControlMaster connection-sharing. + +Most messages from the client to the server contain a "request id" field. +This field is returned in replies as "client request id" to facilitate +matching of responses to requests. + +1. Connection setup + +When a multiplexing connection is made to a ssh(1) operating as a +ControlMaster from a ssh(1) in multiplex slave mode, the first +action of each is to exchange hello messages: + + uint32 MUX_MSG_HELLO + uint32 protocol version + string extension name [optional] + string extension value [optional] + ... + +The current version of the mux protocol is 4. A slave should refuse +to connect to a master that speaks an unsupported protocol version. +Following the version identifier are zero or more extensions +represented as a name/value pair. No extensions are currently +defined. + +2. Opening sessions + +To open a new multiplexed session, a client may send the following +request: + + uint32 MUX_C_MSG_NEW_SESSION + uint32 request id + string reserved + bool want tty flag + bool want X11 forwarding flag + bool want agent flag + bool subsystem flag + uint32 escape char + string terminal type + string command + string environment string 0 [optional] + ... + +To disable the use of an escape character, "escape char" may be set +to 0xffffffff. "terminal type" is generally set to the value of +$TERM. zero or more environment strings may follow the command. + +The client then sends its standard input, output and error file +descriptors (in that order) using Unix domain socket control messages. + +The contents of "reserved" are currently ignored. + +If successful, the server will reply with MUX_S_SESSION_OPENED + + uint32 MUX_S_SESSION_OPENED + uint32 client request id + uint32 session id + +Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or +MUX_S_FAILURE. + +Once the server has received the fds, it will respond with MUX_S_OK +indicating that the session is up. The client now waits for the +session to end. When it does, the server will send an exit status +message: + + uint32 MUX_S_EXIT_MESSAGE + uint32 session id + uint32 exit value + +The client should exit with this value to mimic the behaviour of a +non-multiplexed ssh(1) connection. Two additional cases that the +client must cope with are it receiving a signal itself and the +server disconnecting without sending an exit message. + +3. Health checks + +The client may request a health check/PID report from a server: + + uint32 MUX_C_ALIVE_CHECK + uint32 request id + +The server replies with: + + uint32 MUX_S_ALIVE + uint32 client request id + uint32 server pid + +4. Remotely terminating a master + +A client may request that a master terminate immediately: + + uint32 MUX_C_TERMINATE + uint32 request id + +The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED. + +5. Requesting establishment of port forwards + +A client may request the master to establish a port forward: + + uint32 MUX_C_OPEN_FORWARD + uint32 request id + uint32 forwarding type + string listen host + string listen port + string connect host + string connect port + +forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. + +A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a +MUX_S_FAILURE. + +5. Requesting closure of port forwards + +A client may request the master to establish a port forward: + + uint32 MUX_C_OPEN_FORWARD + uint32 request id + uint32 forwarding type + string listen host + string listen port + string connect host + string connect port + +forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. + +A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a +MUX_S_FAILURE. + +6. Requesting stdio forwarding + +A client may request the master to establish a stdio forwarding: + + uint32 MUX_C_NEW_STDIO_FWD + uint32 request id + string reserved + string connect host + string connect port + +The client then sends its standard input and output file descriptors +(in that order) using Unix domain socket control messages. + +The contents of "reserved" are currently ignored. + +A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED +or a MUX_S_FAILURE. + +7. Status messages + +The MUX_S_OK message is empty: + + uint32 MUX_S_OK + uint32 client request id + +The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason: + + uint32 MUX_S_PERMISSION_DENIED + uint32 client request id + string reason + + uint32 MUX_S_FAILURE + uint32 client request id + string reason + +7. Protocol numbers + +#define MUX_MSG_HELLO 0x00000001 +#define MUX_C_NEW_SESSION 0x10000002 +#define MUX_C_ALIVE_CHECK 0x10000004 +#define MUX_C_TERMINATE 0x10000005 +#define MUX_C_OPEN_FORWARD 0x10000006 +#define MUX_C_CLOSE_FORWARD 0x10000007 +#define MUX_S_OK 0x80000001 +#define MUX_S_PERMISSION_DENIED 0x80000002 +#define MUX_S_FAILURE 0x80000003 +#define MUX_S_EXIT_MESSAGE 0x80000004 +#define MUX_S_ALIVE 0x80000005 +#define MUX_S_SESSION_OPENED 0x80000006 + +#define MUX_FWD_LOCAL 1 +#define MUX_FWD_REMOTE 2 +#define MUX_FWD_DYNAMIC 3 + +XXX TODO +XXX extended status (e.g. report open channels / forwards) +XXX graceful close (delete listening socket, but keep existing sessions active) +XXX lock (maybe) +XXX watch in/out traffic (pre/post crypto) +XXX inject packet (what about replies) +XXX server->client error/warning notifications +XXX port0 rfwd (need custom response message) +XXX send signals via mux + +$OpenBSD: PROTOCOL.mux,v 1.1 2010/01/26 01:28:35 djm Exp $ -- cgit v1.2.3 From 1d2bfc41180087391303145f1bec9f4f4f7cd8fb Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 10 Feb 2010 10:19:29 +1100 Subject: - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for getseuserbyname; patch from calebcase AT gmail.com via cjwatson AT debian.org --- ChangeLog | 5 +++++ configure.ac | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83af29679..2c71e6c89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +20100210 + - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for + getseuserbyname; patch from calebcase AT gmail.com via + cjwatson AT debian.org + 20100202 - (djm) OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/01/30 21:08:33 diff --git a/configure.ac b/configure.ac index e5de6f58b..5fc1d4a46 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.439 2010/01/22 18:25:15 tim Exp $ +# $Id: configure.ac,v 1.440 2010/02/09 23:19:29 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.439 $) +AC_REVISION($Revision: 1.440 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -3413,9 +3413,12 @@ AC_ARG_WITH(selinux, AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.]) SELINUX_MSG="yes" AC_CHECK_HEADER([selinux/selinux.h], , - AC_MSG_ERROR(SELinux support requires selinux.h header)) - AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ], - AC_MSG_ERROR(SELinux support requires libselinux library)) + AC_MSG_ERROR(SELinux support requires selinux.h header)) + AC_CHECK_LIB(selinux, setexeccon, + [ LIBSELINUX="-lselinux" + LIBS="$LIBS -lselinux" + ], + AC_MSG_ERROR(SELinux support requires libselinux library)) SSHDLIBS="$SSHDLIBS $LIBSELINUX" AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level) LIBS="$save_LIBS" -- cgit v1.2.3 From 17751bcab25681d341442fdc2386a30a6bea345e Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 07:35:08 +1100 Subject: - djm@cvs.openbsd.org 2010/02/02 22:49:34 [bufaux.c] make buffer_get_string_ret() really non-fatal in all cases (it was using buffer_get_int(), which could fatal() on buffer empty); ok markus dtucker --- ChangeLog | 8 ++++++++ bufaux.c | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2c71e6c89..2c815a3ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +20100212 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/02/02 22:49:34 + [bufaux.c] + make buffer_get_string_ret() really non-fatal in all cases (it was + using buffer_get_int(), which could fatal() on buffer empty); + ok markus dtucker + 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for getseuserbyname; patch from calebcase AT gmail.com via diff --git a/bufaux.c b/bufaux.c index e17f001e1..4ef19c454 100644 --- a/bufaux.c +++ b/bufaux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufaux.c,v 1.47 2010/01/12 01:36:08 djm Exp $ */ +/* $OpenBSD: bufaux.c,v 1.48 2010/02/02 22:49:34 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -166,7 +166,10 @@ buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) u_int len; /* Get the length. */ - len = buffer_get_int(buffer); + if (buffer_get_int_ret(&len, buffer) != 0) { + error("buffer_get_string_ret: cannot extract length"); + return (NULL); + } if (len > 256 * 1024) { error("buffer_get_string_ret: bad string length %u", len); return (NULL); -- cgit v1.2.3 From 7ea845e48df6d34a333ebbe79380cba0938d02a5 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:21:02 +1100 Subject: - markus@cvs.openbsd.org 2010/02/08 10:50:20 [pathnames.h readconf.c readconf.h scp.1 sftp.1 ssh-add.1 ssh-add.c] [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config.5] replace our obsolete smartcard code with PKCS#11. ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf ssh(1) and ssh-keygen(1) use dlopen(3) directly to talk to a PKCS#11 provider (shared library) while ssh-agent(1) delegates PKCS#11 to a forked a ssh-pkcs11-helper process. PKCS#11 is currently a compile time option. feedback and ok djm@; inspired by patches from Alon Bar-Lev ` --- ChangeLog | 10 + Makefile.in | 20 +- configure.ac | 8 +- pathnames.h | 7 +- readconf.c | 16 +- readconf.h | 4 +- scp.1 | 6 +- sftp.1 | 6 +- ssh-add.1 | 16 +- ssh-add.c | 20 +- ssh-agent.c | 101 +++++----- ssh-keygen.1 | 14 +- ssh-keygen.c | 84 +++----- ssh-pkcs11-client.c | 229 ++++++++++++++++++++++ ssh-pkcs11-helper.c | 349 +++++++++++++++++++++++++++++++++ ssh-pkcs11.c | 544 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ssh-pkcs11.h | 19 ++ ssh.1 | 14 +- ssh.c | 29 +-- ssh_config.5 | 18 +- 20 files changed, 1326 insertions(+), 188 deletions(-) create mode 100644 ssh-pkcs11-client.c create mode 100644 ssh-pkcs11-helper.c create mode 100644 ssh-pkcs11.c create mode 100644 ssh-pkcs11.h diff --git a/ChangeLog b/ChangeLog index 2c815a3ab..776116171 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,16 @@ make buffer_get_string_ret() really non-fatal in all cases (it was using buffer_get_int(), which could fatal() on buffer empty); ok markus dtucker + - markus@cvs.openbsd.org 2010/02/08 10:50:20 + [pathnames.h readconf.c readconf.h scp.1 sftp.1 ssh-add.1 ssh-add.c] + [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config.5] + replace our obsolete smartcard code with PKCS#11. + ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf + ssh(1) and ssh-keygen(1) use dlopen(3) directly to talk to a PKCS#11 + provider (shared library) while ssh-agent(1) delegates PKCS#11 to + a forked a ssh-pkcs11-helper process. + PKCS#11 is currently a compile time option. + feedback and ok djm@; inspired by patches from Alon Bar-Lev 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/Makefile.in b/Makefile.in index d7f338c0f..0c45bfca6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.303 2010/01/08 08:27:57 dtucker Exp $ +# $Id: Makefile.in,v 1.304 2010/02/11 22:21:02 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -25,6 +25,7 @@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign +SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper RAND_HELPER=$(libexecdir)/ssh-rand-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -35,6 +36,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \ -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ + -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ -DSSH_RAND_HELPER=\"$(RAND_HELPER)\" @@ -60,7 +62,7 @@ EXEEXT=@EXEEXT@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@ -TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \ @@ -71,7 +73,8 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ - entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o + entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o \ + ssh-pkcs11.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ @@ -147,8 +150,8 @@ scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o - $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o + $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -156,6 +159,9 @@ ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o + $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -265,6 +271,7 @@ install-files: scard-install $(INSTALL) -m 0755 $(STRIP_OPT) ssh-rand-helper $(DESTDIR)$(libexecdir)/ssh-rand-helper ; \ fi $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign $(DESTDIR)$(SSH_KEYSIGN) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper $(DESTDIR)$(SSH_PKCS11_HELPER) $(INSTALL) -m 0755 $(STRIP_OPT) sftp $(DESTDIR)$(bindir)/sftp $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server $(DESTDIR)$(SFTP_SERVER) $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 @@ -368,6 +375,7 @@ uninstall: -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT) -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) -rm -f $(DESTDIR)$(RAND_HELPER)$(EXEEXT) -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 @@ -393,6 +401,7 @@ tests interop-tests: $(TARGETS) TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \ TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \ TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \ + TEST_SSH_SSHPKCS11HELPER="$${BUILDDIR}/ssh-pkcs11-helper"; \ TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \ TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \ TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \ @@ -413,6 +422,7 @@ tests interop-tests: $(TARGETS) TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \ TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \ TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \ + TEST_SSH_SSHPKCS11HELPER="$${TEST_SSH_SSHPKCS11HELPER}" \ TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \ TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \ TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \ diff --git a/configure.ac b/configure.ac index 5fc1d4a46..717d315fd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.440 2010/02/09 23:19:29 djm Exp $ +# $Id: configure.ac,v 1.441 2010/02/11 22:21:02 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.440 $) +AC_REVISION($Revision: 1.441 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -4197,6 +4197,10 @@ else AC_SUBST(TEST_SSH_IPV6, yes) fi +if test "x$enable_pkcs11" != "xno" ; then + AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support]) +fi + AC_EXEEXT AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ openbsd-compat/Makefile openbsd-compat/regress/Makefile \ diff --git a/pathnames.h b/pathnames.h index 80c5d9cbb..32b9e065b 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.17 2008/12/29 02:23:26 stevesk Exp $ */ +/* $OpenBSD: pathnames.h,v 1.18 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen @@ -125,6 +125,11 @@ #define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" #endif +/* Location of ssh-keysign for hostbased authentication */ +#ifndef _PATH_SSH_PKCS11_HELPER +#define _PATH_SSH_PKCS11_HELPER "/usr/libexec/ssh-pkcs11-helper" +#endif + /* xauth for X11 forwarding */ #ifndef _PATH_XAUTH #define _PATH_XAUTH "/usr/X11R6/bin/xauth" diff --git a/readconf.c b/readconf.c index d424c1697..8bdc8caf1 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.182 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -123,7 +123,7 @@ typedef enum { oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, - oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, + oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -205,10 +205,12 @@ static struct { { "preferredauthentications", oPreferredAuthentications }, { "hostkeyalgorithms", oHostKeyAlgorithms }, { "bindaddress", oBindAddress }, -#ifdef SMARTCARD - { "smartcarddevice", oSmartcardDevice }, +#ifdef ENABLE_PKCS11 + { "smartcarddevice", oPKCS11Provider }, + { "pkcs11provider", oPKCS11Provider }, #else { "smartcarddevice", oUnsupported }, + { "pkcs11provider", oUnsupported }, #endif { "clearallforwardings", oClearAllForwardings }, { "enablesshkeysign", oEnableSSHKeysign }, @@ -609,8 +611,8 @@ parse_string: charptr = &options->bind_address; goto parse_string; - case oSmartcardDevice: - charptr = &options->smartcard_device; + case oPKCS11Provider: + charptr = &options->pkcs11_provider; goto parse_string; case oProxyCommand: @@ -1051,7 +1053,7 @@ initialize_options(Options * options) options->log_level = SYSLOG_LEVEL_NOT_SET; options->preferred_authentications = NULL; options->bind_address = NULL; - options->smartcard_device = NULL; + options->pkcs11_provider = NULL; options->enable_ssh_keysign = - 1; options->no_host_authentication_for_localhost = - 1; options->identities_only = - 1; diff --git a/readconf.h b/readconf.h index f7c0b9c6d..4264751c5 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: readconf.h,v 1.82 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen @@ -84,7 +84,7 @@ typedef struct { char *user_hostfile2; char *preferred_authentications; char *bind_address; /* local socket address for connection to sshd */ - char *smartcard_device; /* Smartcard reader device */ + char *pkcs11_provider; /* PKCS#11 provider */ int verify_host_key_dns; /* Verify host key using DNS */ int num_identity_files; /* Number of files for RSA/DSA identities. */ diff --git a/scp.1 b/scp.1 index 74ee5db13..bc5e259f5 100644 --- a/scp.1 +++ b/scp.1 @@ -9,9 +9,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.49 2010/01/09 23:04:13 dtucker Exp $ +.\" $OpenBSD: scp.1,v 1.50 2010/02/08 10:50:20 markus Exp $ .\" -.Dd $Mdocdate: January 9 2010 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SCP 1 .Os .Sh NAME @@ -153,6 +153,7 @@ For full details of the options listed below, and their possible values, see .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication +.It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol @@ -164,7 +165,6 @@ For full details of the options listed below, and their possible values, see .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax -.It SmartcardDevice .It StrictHostKeyChecking .It TCPKeepAlive .It UsePrivilegedPort diff --git a/sftp.1 b/sftp.1 index 175dc6520..777b02a58 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.82 2010/01/13 12:48:34 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.83 2010/02/08 10:50:20 markus Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: January 13 2010 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SFTP 1 .Os .Sh NAME @@ -202,6 +202,7 @@ For full details of the options listed below, and their possible values, see .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication +.It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol @@ -213,7 +214,6 @@ For full details of the options listed below, and their possible values, see .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax -.It SmartcardDevice .It StrictHostKeyChecking .It TCPKeepAlive .It UsePrivilegedPort diff --git a/ssh-add.1 b/ssh-add.1 index ee9a00ff0..a5dc3311a 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.48 2009/10/22 15:02:12 sobrado Exp $ +.\" $OpenBSD: ssh-add.1,v 1.49 2010/02/08 10:50:20 markus Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: October 22 2009 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -101,17 +101,17 @@ If no public key is found at a given path, will append .Pa .pub and retry. -.It Fl e Ar reader -Remove key in smartcard -.Ar reader . +.It Fl e Ar pkcs11 +Remove key provided by +.Ar pkcs11 . .It Fl L Lists public key parameters of all identities currently represented by the agent. .It Fl l Lists fingerprints of all identities currently represented by the agent. -.It Fl s Ar reader -Add key in smartcard -.Ar reader . +.It Fl s Ar pkcs11 +Add key provider by +.Ar pkcs11 . .It Fl t Ar life Set a maximum lifetime when adding identities to an agent. The lifetime may be specified in seconds or in a time format diff --git a/ssh-add.c b/ssh-add.c index 084478d78..90e5be20b 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.91 2009/08/27 17:44:52 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.92 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -211,7 +211,7 @@ update_card(AuthenticationConnection *ac, int add, const char *id) char *pin; int ret = -1; - pin = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN); + pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN); if (pin == NULL) return -1; @@ -317,10 +317,8 @@ usage(void) fprintf(stderr, " -X Unlock agent.\n"); fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n"); fprintf(stderr, " -c Require confirmation to sign using identities\n"); -#ifdef SMARTCARD - fprintf(stderr, " -s reader Add key in smartcard reader.\n"); - fprintf(stderr, " -e reader Remove key in smartcard reader.\n"); -#endif + fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); + fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); } int @@ -329,7 +327,7 @@ main(int argc, char **argv) extern char *optarg; extern int optind; AuthenticationConnection *ac = NULL; - char *sc_reader_id = NULL; + char *pkcs11provider = NULL; int i, ch, deleting = 0, ret = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ @@ -371,11 +369,11 @@ main(int argc, char **argv) ret = 1; goto done; case 's': - sc_reader_id = optarg; + pkcs11provider = optarg; break; case 'e': deleting = 1; - sc_reader_id = optarg; + pkcs11provider = optarg; break; case 't': if ((lifetime = convtime(optarg)) == -1) { @@ -392,8 +390,8 @@ main(int argc, char **argv) } argc -= optind; argv += optind; - if (sc_reader_id != NULL) { - if (update_card(ac, !deleting, sc_reader_id) == -1) + if (pkcs11provider != NULL) { + if (update_card(ac, !deleting, pkcs11provider) == -1) ret = 1; goto done; } diff --git a/ssh-agent.c b/ssh-agent.c index df3a87d9a..f745c2513 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.162 2009/09/01 14:43:17 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.163 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -76,8 +76,8 @@ #include "log.h" #include "misc.h" -#ifdef SMARTCARD -#include "scard.h" +#ifdef ENABLE_PKCS11 +#include "ssh-pkcs11.h" #endif #if defined(HAVE_SYS_PRCTL_H) @@ -105,6 +105,7 @@ typedef struct identity { TAILQ_ENTRY(identity) next; Key *key; char *comment; + char *provider; u_int death; u_int confirm; } Identity; @@ -171,6 +172,7 @@ static void free_identity(Identity *id) { key_free(id->key); + xfree(id->provider); xfree(id->comment); xfree(id); } @@ -549,7 +551,7 @@ process_add_identity(SocketEntry *e, int version) if (lifetime && !death) death = time(NULL) + lifetime; if ((id = lookup_identity(k, version)) == NULL) { - id = xmalloc(sizeof(Identity)); + id = xcalloc(1, sizeof(Identity)); id->key = k; TAILQ_INSERT_TAIL(&tab->idlist, id, next); /* Increment the number of identities. */ @@ -609,17 +611,17 @@ no_identities(SocketEntry *e, u_int type) buffer_free(&msg); } -#ifdef SMARTCARD +#ifdef ENABLE_PKCS11 static void process_add_smartcard_key(SocketEntry *e) { - char *sc_reader_id = NULL, *pin; - int i, type, version, success = 0, death = 0, confirm = 0; - Key **keys, *k; + char *provider = NULL, *pin; + int i, type, version, count = 0, success = 0, death = 0, confirm = 0; + Key **keys = NULL, *k; Identity *id; Idtab *tab; - sc_reader_id = buffer_get_string(&e->request, NULL); + provider = buffer_get_string(&e->request, NULL); pin = buffer_get_string(&e->request, NULL); while (buffer_len(&e->request)) { @@ -633,30 +635,22 @@ process_add_smartcard_key(SocketEntry *e) default: error("process_add_smartcard_key: " "Unknown constraint type %d", type); - xfree(sc_reader_id); - xfree(pin); goto send; } } if (lifetime && !death) death = time(NULL) + lifetime; - keys = sc_get_keys(sc_reader_id, pin); - xfree(sc_reader_id); - xfree(pin); - - if (keys == NULL || keys[0] == NULL) { - error("sc_get_keys failed"); - goto send; - } - for (i = 0; keys[i] != NULL; i++) { + count = pkcs11_add_provider(provider, pin, &keys); + for (i = 0; i < count; i++) { k = keys[i]; version = k->type == KEY_RSA1 ? 1 : 2; tab = idtab_lookup(version); if (lookup_identity(k, version) == NULL) { - id = xmalloc(sizeof(Identity)); + id = xcalloc(1, sizeof(Identity)); id->key = k; - id->comment = sc_get_key_label(k); + id->provider = xstrdup(provider); + id->comment = xstrdup(provider); /* XXX */ id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); @@ -667,8 +661,13 @@ process_add_smartcard_key(SocketEntry *e) } keys[i] = NULL; } - xfree(keys); send: + if (pin) + xfree(pin); + if (provider) + xfree(provider); + if (keys) + xfree(keys); buffer_put_int(&e->output, 1); buffer_put_char(&e->output, success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); @@ -677,42 +676,37 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { - char *sc_reader_id = NULL, *pin; - int i, version, success = 0; - Key **keys, *k = NULL; - Identity *id; + char *provider = NULL, *pin = NULL; + int version, success = 0; + Identity *id, *nxt; Idtab *tab; - sc_reader_id = buffer_get_string(&e->request, NULL); + provider = buffer_get_string(&e->request, NULL); pin = buffer_get_string(&e->request, NULL); - keys = sc_get_keys(sc_reader_id, pin); - xfree(sc_reader_id); xfree(pin); - if (keys == NULL || keys[0] == NULL) { - error("sc_get_keys failed"); - goto send; - } - for (i = 0; keys[i] != NULL; i++) { - k = keys[i]; - version = k->type == KEY_RSA1 ? 1 : 2; - if ((id = lookup_identity(k, version)) != NULL) { - tab = idtab_lookup(version); - TAILQ_REMOVE(&tab->idlist, id, next); - tab->nentries--; - free_identity(id); - success = 1; + for (version = 1; version < 3; version++) { + tab = idtab_lookup(version); + for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { + nxt = TAILQ_NEXT(id, next); + if (!strcmp(provider, id->provider)) { + TAILQ_REMOVE(&tab->idlist, id, next); + free_identity(id); + tab->nentries--; + } } - key_free(k); - keys[i] = NULL; } - xfree(keys); -send: + if (pkcs11_del_provider(provider) == 0) + success = 1; + else + error("process_remove_smartcard_key:" + " pkcs11_del_provider failed"); + xfree(provider); buffer_put_int(&e->output, 1); buffer_put_char(&e->output, success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } -#endif /* SMARTCARD */ +#endif /* ENABLE_PKCS11 */ /* dispatch incoming messages */ @@ -797,7 +791,7 @@ process_message(SocketEntry *e) case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: process_remove_all_identities(e, 2); break; -#ifdef SMARTCARD +#ifdef ENABLE_PKCS11 case SSH_AGENTC_ADD_SMARTCARD_KEY: case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: process_add_smartcard_key(e); @@ -805,7 +799,7 @@ process_message(SocketEntry *e) case SSH_AGENTC_REMOVE_SMARTCARD_KEY: process_remove_smartcard_key(e); break; -#endif /* SMARTCARD */ +#endif /* ENABLE_PKCS11 */ default: /* Unknown message. Respond with failure. */ error("Unknown message %d", type); @@ -1009,6 +1003,9 @@ static void cleanup_handler(int sig) { cleanup_socket(); +#ifdef ENABLE_PKCS11 + pkcs11_terminate(); +#endif _exit(2); } @@ -1255,6 +1252,10 @@ main(int ac, char **av) #endif skip: + +#ifdef ENABLE_PKCS11 + pkcs11_init(0); +#endif new_socket(AUTH_SOCKET, sock); if (ac > 0) parent_alive_interval = 10; diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 9e59c16f7..7dc76976a 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.80 2009/10/24 00:48:34 dtucker Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.81 2010/02/08 10:50:20 markus Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: October 24 2009 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -201,9 +201,10 @@ Requests changing the comment in the private and public key files. This operation is only supported for RSA1 keys. The program will prompt for the file containing the private keys, for the passphrase if the key has one, and for the new comment. -.It Fl D Ar reader -Download the RSA public key stored in the smartcard in -.Ar reader . +.It Fl D Ar pkcs11 +Download the RSA public keys stored in the +.Ar pkcs11 +provider. .It Fl e This option will read a private or public OpenSSH key file and print the key in @@ -313,9 +314,6 @@ for protocol version 1 and or .Dq dsa for protocol version 2. -.It Fl U Ar reader -Upload an existing RSA private key into the smartcard in -.Ar reader . .It Fl v Verbose mode. Causes diff --git a/ssh-keygen.c b/ssh-keygen.c index 7f5185f8e..005f9c7ab 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.176 2010/01/11 10:51:07 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.177 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -49,8 +49,8 @@ #include "hostfile.h" #include "dns.h" -#ifdef SMARTCARD -#include "scard.h" +#ifdef ENABLE_PKCS11 +#include "ssh-pkcs11.h" #endif /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ @@ -459,51 +459,29 @@ do_print_public(struct passwd *pw) exit(0); } -#ifdef SMARTCARD static void -do_upload(struct passwd *pw, const char *sc_reader_id) -{ - Key *prv = NULL; - struct stat st; - int ret; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - prv = load_identity(identity_file); - if (prv == NULL) { - error("load failed"); - exit(1); - } - ret = sc_put_key(prv, sc_reader_id); - key_free(prv); - if (ret < 0) - exit(1); - logit("loading key done"); - exit(0); -} - -static void -do_download(struct passwd *pw, const char *sc_reader_id) +do_download(struct passwd *pw, const char *pkcs11provider) { +#ifdef ENABLE_PKCS11 Key **keys = NULL; - int i; + int i, nkeys; - keys = sc_get_keys(sc_reader_id, NULL); - if (keys == NULL) - fatal("cannot read public key from smartcard"); - for (i = 0; keys[i]; i++) { + pkcs11_init(0); + nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); + if (nkeys <= 0) + fatal("cannot read public key from pkcs11"); + for (i = 0; i < nkeys; i++) { key_write(keys[i], stdout); key_free(keys[i]); fprintf(stdout, "\n"); } xfree(keys); + pkcs11_terminate(); exit(0); +#else + fatal("no pkcs11 support"); +#endif /* ENABLE_PKCS11 */ } -#endif /* SMARTCARD */ static void do_fingerprint(struct passwd *pw) @@ -1044,9 +1022,9 @@ usage(void) fprintf(stderr, " -b bits Number of bits in the key to create.\n"); fprintf(stderr, " -C comment Provide new comment.\n"); fprintf(stderr, " -c Change comment in private and public key files.\n"); -#ifdef SMARTCARD - fprintf(stderr, " -D reader Download public key from smartcard.\n"); -#endif /* SMARTCARD */ +#ifdef ENABLE_PKCS11 + fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n"); +#endif fprintf(stderr, " -e Convert OpenSSH to RFC 4716 key file.\n"); fprintf(stderr, " -F hostname Find hostname in known hosts file.\n"); fprintf(stderr, " -f filename Filename of the key file.\n"); @@ -1065,9 +1043,6 @@ usage(void) fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n"); fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n"); fprintf(stderr, " -t type Specify type of key to create.\n"); -#ifdef SMARTCARD - fprintf(stderr, " -U reader Upload private key to smartcard.\n"); -#endif /* SMARTCARD */ fprintf(stderr, " -v Verbose.\n"); fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); fprintf(stderr, " -y Read private key file and print public key.\n"); @@ -1082,12 +1057,12 @@ int main(int argc, char **argv) { char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; - char out_file[MAXPATHLEN], *reader_id = NULL; + char out_file[MAXPATHLEN], *pkcs11provider = NULL; char *rr_hostname = NULL; Key *private, *public; struct passwd *pw; struct stat st; - int opt, type, fd, download = 0; + int opt, type, fd; u_int32_t memory = 0, generator_wanted = 0, trials = 100; int do_gen_candidates = 0, do_screen_candidates = 0; BIGNUM *start = NULL; @@ -1120,7 +1095,7 @@ main(int argc, char **argv) } while ((opt = getopt(argc, argv, - "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) { + "degiqpclBHvxXyF:b:f:t:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) { switch (opt) { case 'b': bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr); @@ -1192,10 +1167,7 @@ main(int argc, char **argv) key_type_name = optarg; break; case 'D': - download = 1; - /*FALLTHROUGH*/ - case 'U': - reader_id = optarg; + pkcs11provider = optarg; break; case 'v': if (log_level == SYSLOG_LEVEL_INFO) @@ -1303,16 +1275,8 @@ main(int argc, char **argv) exit(0); } } - if (reader_id != NULL) { -#ifdef SMARTCARD - if (download) - do_download(pw, reader_id); - else - do_upload(pw, reader_id); -#else /* SMARTCARD */ - fatal("no support for smartcards."); -#endif /* SMARTCARD */ - } + if (pkcs11provider != NULL) + do_download(pw, pkcs11provider); if (do_gen_candidates) { FILE *out = fopen(out_file, "w"); diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c new file mode 100644 index 000000000..6ffdd9364 --- /dev/null +++ b/ssh-pkcs11-client.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2010 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "pathnames.h" +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" +#include "key.h" +#include "authfd.h" +#include "atomicio.h" +#include "ssh-pkcs11.h" + +/* borrows code from sftp-server and ssh-agent */ + +int fd = -1; +pid_t pid = -1; + +static void +send_msg(Buffer *m) +{ + u_char buf[4]; + int mlen = buffer_len(m); + + put_u32(buf, mlen); + if (atomicio(vwrite, fd, buf, 4) != 4 || + atomicio(vwrite, fd, buffer_ptr(m), + buffer_len(m)) != buffer_len(m)) + error("write to helper failed"); + buffer_consume(m, mlen); +} + +static int +recv_msg(Buffer *m) +{ + u_int l, len; + u_char buf[1024]; + + if ((len = atomicio(read, fd, buf, 4)) != 4) { + error("read from helper failed: %u", len); + return (0); /* XXX */ + } + len = get_u32(buf); + if (len > 256 * 1024) + fatal("response too long: %u", len); + /* read len bytes into m */ + buffer_clear(m); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + if (atomicio(read, fd, buf, l) != l) { + error("response from helper failed."); + return (0); /* XXX */ + } + buffer_append(m, buf, l); + len -= l; + } + return (buffer_get_char(m)); +} + +int +pkcs11_init(int interactive) +{ + return (0); +} + +void +pkcs11_terminate(void) +{ + close(fd); +} + +static int +pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + int padding) +{ + Key key; + u_char *blob, *signature = NULL; + u_int blen, slen = 0; + int ret = -1; + Buffer msg; + + if (padding != RSA_PKCS1_PADDING) + return (-1); + key.type = KEY_RSA; + key.rsa = rsa; + if (key_to_blob(&key, &blob, &blen) == 0) + return -1; + buffer_init(&msg); + buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); + buffer_put_string(&msg, blob, blen); + buffer_put_string(&msg, from, flen); + buffer_put_int(&msg, 0); + xfree(blob); + send_msg(&msg); + + if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) { + signature = buffer_get_string(&msg, &slen); + if (slen <= (u_int)RSA_size(rsa)) { + memcpy(to, signature, slen); + ret = slen; + } + xfree(signature); + } + return (ret); +} + +/* redirect the private key encrypt operation to the ssh-pkcs11-helper */ +static int +wrap_key(RSA *rsa) +{ + static RSA_METHOD helper_rsa; + + memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa)); + helper_rsa.name = "ssh-pkcs11-helper"; + helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt; + RSA_set_method(rsa, &helper_rsa); + return (0); +} + +static int +pkcs11_start_helper(void) +{ + int pair[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { + error("socketpair: %s", strerror(errno)); + return (-1); + } + if ((pid = fork()) == -1) { + error("fork: %s", strerror(errno)); + return (-1); + } else if (pid == 0) { + if ((dup2(pair[1], STDIN_FILENO) == -1) || + (dup2(pair[1], STDOUT_FILENO) == -1)) { + fprintf(stderr, "dup2: %s\n", strerror(errno)); + _exit(1); + } + close(pair[0]); + close(pair[1]); + execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER, + (char *) 0); + fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER, + strerror(errno)); + _exit(1); + } + close(pair[1]); + fd = pair[0]; + return (0); +} + +int +pkcs11_add_provider(char *name, char *pin, Key ***keysp) +{ + Key *k; + int i, nkeys; + u_char *blob; + u_int blen; + Buffer msg; + + if (fd < 0 && pkcs11_start_helper() < 0) + return (-1); + + buffer_init(&msg); + buffer_put_char(&msg, SSH_AGENTC_ADD_SMARTCARD_KEY); + buffer_put_cstring(&msg, name); + buffer_put_cstring(&msg, pin); + send_msg(&msg); + buffer_clear(&msg); + + if (recv_msg(&msg) == SSH2_AGENT_IDENTITIES_ANSWER) { + nkeys = buffer_get_int(&msg); + *keysp = xcalloc(nkeys, sizeof(Key *)); + for (i = 0; i < nkeys; i++) { + blob = buffer_get_string(&msg, &blen); + xfree(buffer_get_string(&msg, NULL)); + k = key_from_blob(blob, blen); + wrap_key(k->rsa); + (*keysp)[i] = k; + xfree(blob); + } + } else { + nkeys = -1; + } + buffer_free(&msg); + return (nkeys); +} + +int +pkcs11_del_provider(char *name) +{ + int ret = -1; + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY); + buffer_put_cstring(&msg, name); + buffer_put_cstring(&msg, ""); + send_msg(&msg); + buffer_clear(&msg); + + if (recv_msg(&msg) == SSH_AGENT_SUCCESS) + ret = 0; + buffer_free(&msg); + return (ret); +} diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c new file mode 100644 index 000000000..f9962709b --- /dev/null +++ b/ssh-pkcs11-helper.c @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2010 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" +#include "key.h" +#include "authfd.h" +#include "ssh-pkcs11.h" + +/* borrows code from sftp-server and ssh-agent */ + +struct pkcs11_keyinfo { + Key *key; + char *providername; + TAILQ_ENTRY(pkcs11_keyinfo) next; +}; + +TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist; + +#define MAX_MSG_LENGTH 10240 /*XXX*/ + +/* helper */ +#define get_int() buffer_get_int(&iqueue); +#define get_string(lenp) buffer_get_string(&iqueue, lenp); + +/* input and output queue */ +Buffer iqueue; +Buffer oqueue; + +static void +add_key(Key *k, char *name) +{ + struct pkcs11_keyinfo *ki; + + ki = xcalloc(1, sizeof(*ki)); + ki->providername = xstrdup(name); + ki->key = k; + TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next); +} + +static void +del_keys_by_name(char *name) +{ + struct pkcs11_keyinfo *ki, *nxt; + + for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) { + nxt = TAILQ_NEXT(ki, next); + if (!strcmp(ki->providername, name)) { + TAILQ_REMOVE(&pkcs11_keylist, ki, next); + xfree(ki->providername); + key_free(ki->key); + free(ki); + } + } +} + +/* lookup matching 'private' key */ +static Key * +lookup_key(Key *k) +{ + struct pkcs11_keyinfo *ki; + + TAILQ_FOREACH(ki, &pkcs11_keylist, next) { + debug("check %p %s", ki, ki->providername); + if (key_equal(k, ki->key)) + return (ki->key); + } + return (NULL); +} + +static void +send_msg(Buffer *m) +{ + int mlen = buffer_len(m); + + buffer_put_int(&oqueue, mlen); + buffer_append(&oqueue, buffer_ptr(m), mlen); + buffer_consume(m, mlen); +} + +static void +process_add(void) +{ + char *name, *pin; + Key **keys; + int i, nkeys; + u_char *blob; + u_int blen; + Buffer msg; + + buffer_init(&msg); + name = get_string(NULL); + pin = get_string(NULL); + if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) { + buffer_put_char(&msg, SSH2_AGENT_IDENTITIES_ANSWER); + buffer_put_int(&msg, nkeys); + for (i = 0; i < nkeys; i++) { + key_to_blob(keys[i], &blob, &blen); + buffer_put_string(&msg, blob, blen); + buffer_put_cstring(&msg, name); + xfree(blob); + add_key(keys[i], name); + } + xfree(keys); + } else { + buffer_put_char(&msg, SSH_AGENT_FAILURE); + } + xfree(pin); + xfree(name); + send_msg(&msg); + buffer_free(&msg); +} + +static void +process_del(void) +{ + char *name, *pin; + Buffer msg; + + buffer_init(&msg); + name = get_string(NULL); + pin = get_string(NULL); + del_keys_by_name(name); + if (pkcs11_del_provider(name) == 0) + buffer_put_char(&msg, SSH_AGENT_SUCCESS); + else + buffer_put_char(&msg, SSH_AGENT_FAILURE); + xfree(pin); + xfree(name); + send_msg(&msg); + buffer_free(&msg); +} + +static void +process_sign(void) +{ + u_char *blob, *data, *signature = NULL; + u_int blen, dlen, slen = 0; + int ok = -1, flags, ret; + Key *key, *found; + Buffer msg; + + blob = get_string(&blen); + data = get_string(&dlen); + flags = get_int(); /* XXX ignore */ + + if ((key = key_from_blob(blob, blen)) != NULL) { + if ((found = lookup_key(key)) != NULL) { + slen = RSA_size(key->rsa); + signature = xmalloc(slen); + if ((ret = RSA_private_encrypt(dlen, data, signature, + found->rsa, RSA_PKCS1_PADDING)) != -1) { + slen = ret; + ok = 0; + } + } + key_free(key); + } + buffer_init(&msg); + if (ok == 0) { + buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); + buffer_put_string(&msg, signature, slen); + } else { + buffer_put_char(&msg, SSH_AGENT_FAILURE); + } + xfree(data); + xfree(blob); + if (signature != NULL) + xfree(signature); + send_msg(&msg); + buffer_free(&msg); +} + +static void +process(void) +{ + u_int msg_len; + u_int buf_len; + u_int consumed; + u_int type; + u_char *cp; + + buf_len = buffer_len(&iqueue); + if (buf_len < 5) + return; /* Incomplete message. */ + cp = buffer_ptr(&iqueue); + msg_len = get_u32(cp); + if (msg_len > MAX_MSG_LENGTH) { + error("bad message len %d", msg_len); + cleanup_exit(11); + } + if (buf_len < msg_len + 4) + return; + buffer_consume(&iqueue, 4); + buf_len -= 4; + type = buffer_get_char(&iqueue); + switch (type) { + case SSH_AGENTC_ADD_SMARTCARD_KEY: + debug("process_add"); + process_add(); + break; + case SSH_AGENTC_REMOVE_SMARTCARD_KEY: + debug("process_del"); + process_del(); + break; + case SSH2_AGENTC_SIGN_REQUEST: + debug("process_sign"); + process_sign(); + break; + default: + error("Unknown message %d", type); + break; + } + /* discard the remaining bytes from the current packet */ + if (buf_len < buffer_len(&iqueue)) { + error("iqueue grew unexpectedly"); + cleanup_exit(255); + } + consumed = buf_len - buffer_len(&iqueue); + if (msg_len < consumed) { + error("msg_len %d < consumed %d", msg_len, consumed); + cleanup_exit(255); + } + if (msg_len > consumed) + buffer_consume(&iqueue, msg_len - consumed); +} + +void +cleanup_exit(int i) +{ + /* XXX */ + _exit(i); +} + +int +main(int argc, char **argv) +{ + fd_set *rset, *wset; + int in, out, max, log_stderr = 0; + ssize_t len, olen, set_size; + SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; + LogLevel log_level = SYSLOG_LEVEL_ERROR; + char buf[4*4096]; + + TAILQ_INIT(&pkcs11_keylist); + pkcs11_init(0); + + extern char *optarg; + extern char *__progname; + + log_init(__progname, log_level, log_facility, log_stderr); + + in = STDIN_FILENO; + out = STDOUT_FILENO; + + max = 0; + if (in > max) + max = in; + if (out > max) + max = out; + + buffer_init(&iqueue); + buffer_init(&oqueue); + + set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); + rset = (fd_set *)xmalloc(set_size); + wset = (fd_set *)xmalloc(set_size); + + for (;;) { + memset(rset, 0, set_size); + memset(wset, 0, set_size); + + /* + * Ensure that we can read a full buffer and handle + * the worst-case length packet it can generate, + * otherwise apply backpressure by stopping reads. + */ + if (buffer_check_alloc(&iqueue, sizeof(buf)) && + buffer_check_alloc(&oqueue, MAX_MSG_LENGTH)) + FD_SET(in, rset); + + olen = buffer_len(&oqueue); + if (olen > 0) + FD_SET(out, wset); + + if (select(max+1, rset, wset, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + error("select: %s", strerror(errno)); + cleanup_exit(2); + } + + /* copy stdin to iqueue */ + if (FD_ISSET(in, rset)) { + len = read(in, buf, sizeof buf); + if (len == 0) { + debug("read eof"); + cleanup_exit(0); + } else if (len < 0) { + error("read: %s", strerror(errno)); + cleanup_exit(1); + } else { + buffer_append(&iqueue, buf, len); + } + } + /* send oqueue to stdout */ + if (FD_ISSET(out, wset)) { + len = write(out, buffer_ptr(&oqueue), olen); + if (len < 0) { + error("write: %s", strerror(errno)); + cleanup_exit(1); + } else { + buffer_consume(&oqueue, len); + } + } + + /* + * Process requests from client if we can fit the results + * into the output buffer, otherwise stop processing input + * and let the output queue drain. + */ + if (buffer_check_alloc(&oqueue, MAX_MSG_LENGTH)) + process(); + } +} diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c new file mode 100644 index 000000000..f82454329 --- /dev/null +++ b/ssh-pkcs11.c @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2010 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include + +#define CRYPTOKI_COMPAT +#include "pkcs11.h" + +#include "log.h" +#include "misc.h" +#include "key.h" +#include "ssh-pkcs11.h" +#include "xmalloc.h" + +struct pkcs11_slotinfo { + CK_TOKEN_INFO token; + CK_SESSION_HANDLE session; + int logged_in; +}; + +struct pkcs11_provider { + char *name; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; + CK_ULONG nslots; + CK_SLOT_ID *slotlist; + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; + TAILQ_ENTRY(pkcs11_provider) next; +}; + +TAILQ_HEAD(, pkcs11_provider) pkcs11_providers; + +struct pkcs11_key { + struct pkcs11_provider *provider; + CK_ULONG slotidx; + int (*orig_finish)(RSA *rsa); + RSA_METHOD rsa_method; + char *keyid; + int keyid_len; +}; + +int pkcs11_interactive = 0; + +int +pkcs11_init(int interactive) +{ + pkcs11_interactive = interactive; + TAILQ_INIT(&pkcs11_providers); + return (0); +} + +/* + * finalize a provider shared libarary, it's no longer usable. + * however, there might still be keys referencing this provider, + * so the actuall freeing of memory is handled by pkcs11_provider_unref(). + * this is called when a provider gets unregistered. + */ +static void +pkcs11_provider_finalize(struct pkcs11_provider *p) +{ + CK_RV rv; + CK_ULONG i; + + debug("pkcs11_provider_finalize: %p refcount %d valid %d", + p, p->refcount, p->valid); + if (!p->valid) + return; + for (i = 0; i < p->nslots; i++) { + if (p->slotinfo[i].session && + (rv = p->function_list->C_CloseSession( + p->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } + if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); + p->valid = 0; + p->function_list = NULL; + dlclose(p->handle); +} + +/* + * remove a reference to the provider. + * called when a key gets destroyed or when the provider is unregistered. + */ +static void +pkcs11_provider_unref(struct pkcs11_provider *p) +{ + debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); + if (--p->refcount <= 0) { + if (p->valid) + error("pkcs11_provider_unref: %p still valid", p); + xfree(p->slotlist); + xfree(p->slotinfo); + xfree(p); + } +} + +/* unregister all providers, keys might still point to the providers */ +void +pkcs11_terminate(void) +{ + struct pkcs11_provider *p; + + while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); + } +} + +/* lookup provider by name */ +static struct pkcs11_provider * +pkcs11_provider_lookup(char *provider_id) +{ + struct pkcs11_provider *p; + + TAILQ_FOREACH(p, &pkcs11_providers, next) { + debug("check %p %s", p, p->name); + if (!strcmp(provider_id, p->name)) + return (p); + } + return (NULL); +} + +/* unregister provider by name */ +int +pkcs11_del_provider(char *provider_id) +{ + struct pkcs11_provider *p; + + if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); + return (0); + } + return (-1); +} + +/* openssl callback for freeing an RSA key */ +static int +pkcs11_rsa_finish(RSA *rsa) +{ + struct pkcs11_key *k11; + int rv = -1; + + if ((k11 = RSA_get_app_data(rsa)) != NULL) { + if (k11->orig_finish) + rv = k11->orig_finish(rsa); + if (k11->provider) + pkcs11_provider_unref(k11->provider); + if (k11->keyid) + xfree(k11->keyid); + xfree(k11); + } + return (rv); +} + +/* openssl callback doing the actual signing operation */ +static int +pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + int padding) +{ + struct pkcs11_key *k11; + struct pkcs11_slotinfo *si; + CK_FUNCTION_LIST *f; + CK_OBJECT_HANDLE obj; + CK_ULONG tlen = 0, nfound = 0; + CK_RV rv; + CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; + CK_BBOOL true = CK_TRUE; + CK_MECHANISM mech = { + CKM_RSA_PKCS, NULL_PTR, 0 + }; + CK_ATTRIBUTE key_filter[] = { + {CKA_CLASS, &private_key_class, sizeof(private_key_class) }, + {CKA_ID, NULL, 0}, + {CKA_SIGN, &true, sizeof(true) } + }; + char *pin, prompt[1024]; + int rval = -1; + + if ((k11 = RSA_get_app_data(rsa)) == NULL) { + error("RSA_get_app_data failed for rsa %p", rsa); + return (-1); + } + if (!k11->provider || !k11->provider->valid) { + error("no pkcs11 (valid) provider for rsa %p", rsa); + return (-1); + } + f = k11->provider->function_list; + si = &k11->provider->slotinfo[k11->slotidx]; + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (!pkcs11_interactive) { + error("need pin"); + return (-1); + } + snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", + si->token.label); + pin = read_passphrase(prompt, RP_ALLOW_EOF); + if (pin == NULL) + return (-1); /* bail out */ + if ((rv = f->C_Login(si->session, CKU_USER, pin, strlen(pin))) + != CKR_OK) { + xfree(pin); + error("C_Login failed: %lu", rv); + return (-1); + } + xfree(pin); + si->logged_in = 1; + } + key_filter[1].pValue = k11->keyid; + key_filter[1].ulValueLen = k11->keyid_len; + if ((rv = f->C_FindObjectsInit(si->session, key_filter, 3)) != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + return (-1); + } + if ((rv = f->C_FindObjects(si->session, &obj, 1, &nfound)) != CKR_OK || + nfound != 1) { + error("C_FindObjects failed (%lu nfound): %lu", nfound, rv); + } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { + error("C_SignInit failed: %lu", rv); + } else { + /* XXX handle CKR_BUFFER_TOO_SMALL */ + tlen = RSA_size(rsa); + rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen); + if (rv == CKR_OK) + rval = tlen; + else + error("C_Sign failed: %lu", rv); + } + if ((rv = f->C_FindObjectsFinal(si->session)) != CKR_OK) + error("C_FindObjectsFinal failed: %lu", rv); + return (rval); +} + +static int +pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa, + int padding) +{ + return (-1); +} + +/* redirect private key operations for rsa key to pkcs11 token */ +static int +pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + CK_ATTRIBUTE *keyid_attrib, RSA *rsa) +{ + struct pkcs11_key *k11; + const RSA_METHOD *def = RSA_get_default_method(); + + k11 = xcalloc(1, sizeof(*k11)); + k11->provider = provider; + provider->refcount++; /* provider referenced by RSA key */ + k11->slotidx = slotidx; + /* identify key object on smartcard */ + k11->keyid_len = keyid_attrib->ulValueLen; + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + k11->orig_finish = def->finish; + memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); + k11->rsa_method.name = "pkcs11"; + k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; + k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; + k11->rsa_method.finish = pkcs11_rsa_finish; + RSA_set_method(rsa, &k11->rsa_method); + RSA_set_app_data(rsa, k11); + return (0); +} + +/* remove trailing spaces */ +static void +rmspace(char *buf, size_t len) +{ + size_t i; + + if (!len) + return; + for (i = len - 1; i > 0; i--) + if (i == len - 1 || buf[i] == ' ') + buf[i] = '\0'; + else + break; +} + +/* + * open a pkcs11 session and login if required. + * if pin == NULL we delay login until key use + */ +static int +pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) +{ + CK_RV rv; + CK_FUNCTION_LIST *f; + CK_SESSION_HANDLE session; + int login_required; + + f = p->function_list; + login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; + if (pin && login_required && !strlen(pin)) { + error("pin required"); + return (-1); + } + if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) + != CKR_OK) { + error("C_OpenSession failed: %lu", rv); + return (-1); + } + if (login_required && pin) { + if ((rv = f->C_Login(session, CKU_USER, pin, strlen(pin))) + != CKR_OK) { + error("C_Login failed: %lu", rv); + if ((rv = f->C_CloseSession(session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + return (-1); + } + p->slotinfo[slotidx].logged_in = 1; + } + p->slotinfo[slotidx].session = session; + return (0); +} + +/* + * lookup public keys for token in slot identified by slotidx, + * add 'wrapped' public keys to the 'keysp' array and increment nkeys. + * keysp points to an (possibly empty) array with *nkeys keys. + */ +static int +pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp, + int *nkeys) +{ + Key *key; + RSA *rsa; + int i; + CK_RV rv; + CK_OBJECT_HANDLE obj; + CK_ULONG nfound; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f; + CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; + CK_ATTRIBUTE pubkey_filter[] = { + { CKA_CLASS, &pubkey_class, sizeof(pubkey_class) } + }; + CK_ATTRIBUTE attribs[] = { + { CKA_ID, NULL, 0 }, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 } + }; + + f = p->function_list; + session = p->slotinfo[slotidx].session; + /* setup a filter the looks for public keys */ + if ((rv = f->C_FindObjectsInit(session, pubkey_filter, 1)) != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + return (-1); + } + while (1) { + /* XXX 3 attributes in attribs[] */ + for (i = 0; i < 3; i++) { + attribs[i].pValue = NULL; + attribs[i].ulValueLen = 0; + } + if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK + || nfound == 0) + break; + /* found a key, so figure out size of the attributes */ + if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) + != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + continue; + } + /* allocate buffers for attributes, XXX check ulValueLen? */ + for (i = 0; i < 3; i++) + attribs[i].pValue = xmalloc(attribs[i].ulValueLen); + /* retrieve ID, modulus and public exponent of RSA key */ + if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) + != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + } else if ((rsa = RSA_new()) == NULL) { + error("RSA_new failed"); + } else { + rsa->n = BN_bin2bn(attribs[1].pValue, + attribs[1].ulValueLen, NULL); + rsa->e = BN_bin2bn(attribs[2].pValue, + attribs[2].ulValueLen, NULL); + if (rsa->n && rsa->e && + pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { + key = key_new(KEY_UNSPEC); + key->rsa = rsa; + key->type = KEY_RSA; + key->flags |= KEY_FLAG_EXT; + /* expand key array and add key */ + *keysp = xrealloc(*keysp, *nkeys + 1, + sizeof(Key *)); + (*keysp)[*nkeys] = key; + *nkeys = *nkeys + 1; + debug("have %d keys", *nkeys); + } else { + RSA_free(rsa); + } + } + for (i = 0; i < 3; i++) + xfree(attribs[i].pValue); + } + if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) + error("C_FindObjectsFinal failed: %lu", rv); + return (0); +} + +/* register a new provider, fails if provider already exists */ +int +pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp) +{ + int nkeys, need_finalize = 0; + struct pkcs11_provider *p = NULL; + void *handle = NULL; + CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); + CK_RV rv; + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; + + *keyp = NULL; + if (pkcs11_provider_lookup(provider_id) != NULL) { + error("provider already registered: %s", provider_id); + goto fail; + } + /* open shared pkcs11-libarary */ + if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { + error("dlopen %s failed: %s", provider_id, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { + error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + goto fail; + } + p = xcalloc(1, sizeof(*p)); + p->name = xstrdup(provider_id); + p->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList failed: %lu", rv); + goto fail; + } + p->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize failed: %lu", rv); + goto fail; + } + need_finalize = 1; + if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { + error("C_GetInfo failed: %lu", rv); + goto fail; + } + rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); + rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); + debug("manufacturerID <%s> cryptokiVersion %d.%d" + " libraryDescription <%s> libraryVersion %d.%d", + p->info.manufacturerID, + p->info.cryptokiVersion.major, + p->info.cryptokiVersion.minor, + p->info.libraryDescription, + p->info.libraryVersion.major, + p->info.libraryVersion.minor); + if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } + if (p->nslots == 0) { + error("no slots"); + goto fail; + } + p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); + if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) + != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } + p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); + p->valid = 1; + nkeys = 0; + for (i = 0; i < p->nslots; i++) { + token = &p->slotinfo[i].token; + if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo failed: %lu", rv); + continue; + } + rmspace(token->label, sizeof(token->label)); + rmspace(token->manufacturerID, sizeof(token->manufacturerID)); + rmspace(token->model, sizeof(token->model)); + rmspace(token->serialNumber, sizeof(token->serialNumber)); + debug("label <%s> manufacturerID <%s> model <%s> serial <%s>" + " flags 0x%lx", + token->label, token->manufacturerID, token->model, + token->serialNumber, token->flags); + /* open session, login with pin and retrieve public keys */ + if (pkcs11_open_session(p, i, pin) == 0) + pkcs11_fetch_keys(p, i, keyp, &nkeys); + } + if (nkeys > 0) { + TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); + p->refcount++; /* add to provider list */ + return (nkeys); + } + error("no keys"); + /* don't add the provider, since it does not have any keys */ +fail: + if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); + if (p) { + if (p->slotlist) + xfree(p->slotlist); + if (p->slotinfo) + xfree(p->slotinfo); + xfree(p); + } + if (handle) + dlclose(handle); + return (-1); +} diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h new file mode 100644 index 000000000..fae41a7b5 --- /dev/null +++ b/ssh-pkcs11.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +int pkcs11_init(int); +void pkcs11_terminate(void); +int pkcs11_add_provider(char *, char *, Key ***); +int pkcs11_del_provider(char *); diff --git a/ssh.1 b/ssh.1 index 1ff2cce4d..97a2455ab 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.290 2010/01/11 01:39:46 dtucker Exp $ -.Dd $Mdocdate: January 11 2010 $ +.\" $OpenBSD: ssh.1,v 1.291 2010/02/08 10:50:20 markus Exp $ +.Dd $Mdocdate: February 8 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -284,12 +284,12 @@ will wait for all remote port forwards to be successfully established before placing itself in the background. .It Fl g Allows remote hosts to connect to local forwarded ports. -.It Fl I Ar smartcard_device -Specify the device +.It Fl I Ar pkcs11 +Specify the PKCS#11 shared libarary .Nm -should use to communicate with a smartcard used for storing the user's +should use to communicate with a PKCS#11 token used for storing the user's private RSA key. -This option is only available if support for smartcard devices +This option is only available if support for PKCS#11 is compiled in (default is no support). .It Fl i Ar identity_file Selects a file from which the identity (private key) for @@ -469,6 +469,7 @@ For full details of the options listed below, and their possible values, see .It NumberOfPasswordPrompts .It PasswordAuthentication .It PermitLocalCommand +.It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol @@ -481,7 +482,6 @@ For full details of the options listed below, and their possible values, see .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax -.It SmartcardDevice .It StrictHostKeyChecking .It TCPKeepAlive .It Tunnel diff --git a/ssh.c b/ssh.c index 97afdcfee..63523b42a 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.332 2010/01/26 01:28:35 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.333 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -103,8 +103,8 @@ #include "roaming.h" #include "version.h" -#ifdef SMARTCARD -#include "scard.h" +#ifdef ENABLE_PKCS11 +#include "ssh-pkcs11.h" #endif extern char *__progname; @@ -362,10 +362,10 @@ main(int ac, char **av) xstrdup(optarg); break; case 'I': -#ifdef SMARTCARD - options.smartcard_device = xstrdup(optarg); +#ifdef ENABLE_PKCS11 + options.pkcs11_provider = xstrdup(optarg); #else - fprintf(stderr, "no support for smartcards.\n"); + fprintf(stderr, "no support for PKCS#11.\n"); #endif break; case 't': @@ -1305,14 +1305,17 @@ load_public_identity_files(void) int i = 0; Key *public; struct passwd *pw; -#ifdef SMARTCARD +#ifdef ENABLE_PKCS11 Key **keys; + int nkeys; - if (options.smartcard_device != NULL && + if (options.pkcs11_provider != NULL && options.num_identity_files < SSH_MAX_IDENTITY_FILES && - (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) { + (pkcs11_init(!options.batch_mode) == 0) && + (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, + &keys)) > 0) { int count = 0; - for (i = 0; keys[i] != NULL; i++) { + for (i = 0; i < nkeys; i++) { count++; memmove(&options.identity_files[1], &options.identity_files[0], @@ -1322,14 +1325,16 @@ load_public_identity_files(void) sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); options.num_identity_files++; options.identity_keys[0] = keys[i]; - options.identity_files[0] = sc_get_key_label(keys[i]); + options.identity_files[0] = + xstrdup(options.pkcs11_provider); /* XXX */ } if (options.num_identity_files > SSH_MAX_IDENTITY_FILES) options.num_identity_files = SSH_MAX_IDENTITY_FILES; i = count; xfree(keys); + /* XXX leaks some keys */ } -#endif /* SMARTCARD */ +#endif /* ENABLE_PKCS11 */ if ((pw = getpwuid(original_real_uid)) == NULL) fatal("load_public_identity_files: getpwuid failed"); pwname = xstrdup(pw->pw_name); diff --git a/ssh_config.5 b/ssh_config.5 index 01f5f4304..350a8eacd 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.126 2010/01/09 23:04:13 dtucker Exp $ -.Dd $Mdocdate: January 9 2010 $ +.\" $OpenBSD: ssh_config.5,v 1.127 2010/02/08 10:50:20 markus Exp $ +.Dd $Mdocdate: February 8 2010 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -711,6 +711,13 @@ or .Dq no . The default is .Dq no . +.It Cm PKCS11Provider +Specifies which PKCS#11 provider to use. +The argument to this keyword is the PKCS#11 shared libary +.Xr ssh 1 +should use to communicate with a PKCS#11 token used for storing the user's +private RSA key. +By default, no device is specified and PKCS#11 support is not activated. .It Cm Port Specifies the port number to connect on the remote host. The default is 22. @@ -927,13 +934,6 @@ channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server. This option applies to protocol version 2 only. -.It Cm SmartcardDevice -Specifies which smartcard device to use. -The argument to this keyword is the device -.Xr ssh 1 -should use to communicate with a smartcard used for storing the user's -private RSA key. -By default, no device is specified and smartcard support is not activated. .It Cm StrictHostKeyChecking If this flag is set to .Dq yes , -- cgit v1.2.3 From 048dc93617b7d005d8f7d42da1d52d8982408bdd Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:22:04 +1100 Subject: - jmc@cvs.openbsd.org 2010/02/08 22:03:05 [ssh-add.1 ssh-keygen.1 ssh.1 ssh.c] tweak previous; ok markus --- ChangeLog | 3 +++ ssh-add.1 | 8 ++++---- ssh-keygen.1 | 7 ++----- ssh.1 | 3 ++- ssh.c | 5 +++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 776116171..ffda446b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,9 @@ a forked a ssh-pkcs11-helper process. PKCS#11 is currently a compile time option. feedback and ok djm@; inspired by patches from Alon Bar-Lev + - jmc@cvs.openbsd.org 2010/02/08 22:03:05 + [ssh-add.1 ssh-keygen.1 ssh.1 ssh.c] + tweak previous; ok markus 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/ssh-add.1 b/ssh-add.1 index a5dc3311a..619209a19 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.49 2010/02/08 10:50:20 markus Exp $ +.\" $OpenBSD: ssh-add.1,v 1.50 2010/02/08 22:03:05 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -49,9 +49,9 @@ .Op Fl t Ar life .Op Ar .Nm ssh-add -.Fl s Ar reader +.Fl s Ar pkcs11 .Nm ssh-add -.Fl e Ar reader +.Fl e Ar pkcs11 .Sh DESCRIPTION .Nm adds RSA or DSA identities to the authentication agent, @@ -110,7 +110,7 @@ by the agent. .It Fl l Lists fingerprints of all identities currently represented by the agent. .It Fl s Ar pkcs11 -Add key provider by +Add key provided by .Ar pkcs11 . .It Fl t Ar life Set a maximum lifetime when adding identities to an agent. diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 7dc76976a..c0c323640 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.81 2010/02/08 10:50:20 markus Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.82 2010/02/08 22:03:05 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -79,7 +79,7 @@ .Fl B .Op Fl f Ar input_keyfile .Nm ssh-keygen -.Fl D Ar reader +.Fl D Ar pkcs11 .Nm ssh-keygen .Fl F Ar hostname .Op Fl f Ar known_hosts_file @@ -91,9 +91,6 @@ .Fl R Ar hostname .Op Fl f Ar known_hosts_file .Nm ssh-keygen -.Fl U Ar reader -.Op Fl f Ar input_keyfile -.Nm ssh-keygen .Fl r Ar hostname .Op Fl f Ar input_keyfile .Op Fl g diff --git a/ssh.1 b/ssh.1 index 97a2455ab..4424e1f60 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.291 2010/02/08 10:50:20 markus Exp $ +.\" $OpenBSD: ssh.1,v 1.292 2010/02/08 22:03:05 jmc Exp $ .Dd $Mdocdate: February 8 2010 $ .Dt SSH 1 .Os @@ -54,6 +54,7 @@ .Oc .Op Fl e Ar escape_char .Op Fl F Ar configfile +.Op Fl I Ar pkcs11 .Bk -words .Op Fl i Ar identity_file .Ek diff --git a/ssh.c b/ssh.c index 63523b42a..25ccdcaa5 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.333 2010/02/08 10:50:20 markus Exp $ */ +/* $OpenBSD: ssh.c,v 1.334 2010/02/08 22:03:05 jmc Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -187,7 +187,8 @@ usage(void) fprintf(stderr, "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n" -" [-i identity_file] [-L [bind_address:]port:host:hostport]\n" +" [-I pkcs11] [-i identity_file]\n" +" [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" " [-W host:port] [-w local_tun[:remote_tun]]\n" -- cgit v1.2.3 From a183c6edee2f5238e28607955e8ac95cef7f0d8c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:22:31 +1100 Subject: - djm@cvs.openbsd.org 2010/02/09 00:50:36 [ssh-agent.c] fallout from PKCS#11: unbreak -D --- ChangeLog | 3 +++ ssh-agent.c | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ffda446b9..506ea7dab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,9 @@ - jmc@cvs.openbsd.org 2010/02/08 22:03:05 [ssh-add.1 ssh-keygen.1 ssh.1 ssh.c] tweak previous; ok markus + - djm@cvs.openbsd.org 2010/02/09 00:50:36 + [ssh-agent.c] + fallout from PKCS#11: unbreak -D 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/ssh-agent.c b/ssh-agent.c index f745c2513..46a744f4e 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.163 2010/02/08 10:50:20 markus Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.164 2010/02/09 00:50:36 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -172,7 +172,8 @@ static void free_identity(Identity *id) { key_free(id->key); - xfree(id->provider); + if (id->provider != NULL) + xfree(id->provider); xfree(id->comment); xfree(id); } -- cgit v1.2.3 From 86cbb44d47c49b108b94854b02dd5c3eae19123d Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:22:57 +1100 Subject: - djm@cvs.openbsd.org 2010/02/09 00:50:59 [ssh-keygen.c] fix -Wall --- ChangeLog | 3 +++ ssh-keygen.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 506ea7dab..2ca5ec707 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,9 @@ - djm@cvs.openbsd.org 2010/02/09 00:50:36 [ssh-agent.c] fallout from PKCS#11: unbreak -D + - djm@cvs.openbsd.org 2010/02/09 00:50:59 + [ssh-keygen.c] + fix -Wall 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/ssh-keygen.c b/ssh-keygen.c index 005f9c7ab..b6b7a2d9f 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.177 2010/02/08 10:50:20 markus Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.178 2010/02/09 00:50:59 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -460,7 +460,7 @@ do_print_public(struct passwd *pw) } static void -do_download(struct passwd *pw, const char *pkcs11provider) +do_download(struct passwd *pw, char *pkcs11provider) { #ifdef ENABLE_PKCS11 Key **keys = NULL; -- cgit v1.2.3 From 8922106fe9df50810e4149a05f7e3f9585ec08cc Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:23:40 +1100 Subject: - djm@cvs.openbsd.org 2010/02/09 03:56:28 [buffer.c buffer.h] constify the arguments to buffer_len, buffer_ptr and buffer_dump --- ChangeLog | 3 +++ buffer.c | 8 ++++---- buffer.h | 8 ++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ca5ec707..872f06e9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,9 @@ - djm@cvs.openbsd.org 2010/02/09 00:50:59 [ssh-keygen.c] fix -Wall + - djm@cvs.openbsd.org 2010/02/09 03:56:28 + [buffer.c buffer.h] + constify the arguments to buffer_len, buffer_ptr and buffer_dump 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/buffer.c b/buffer.c index e02e1e35c..ae9700344 100644 --- a/buffer.c +++ b/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: buffer.c,v 1.32 2010/02/09 03:56:28 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -160,7 +160,7 @@ buffer_check_alloc(Buffer *buffer, u_int len) /* Returns the number of bytes of data in the buffer. */ u_int -buffer_len(Buffer *buffer) +buffer_len(const Buffer *buffer) { return buffer->end - buffer->offset; } @@ -228,7 +228,7 @@ buffer_consume_end(Buffer *buffer, u_int bytes) /* Returns a pointer to the first used byte in the buffer. */ void * -buffer_ptr(Buffer *buffer) +buffer_ptr(const Buffer *buffer) { return buffer->buf + buffer->offset; } @@ -236,7 +236,7 @@ buffer_ptr(Buffer *buffer) /* Dumps the contents of the buffer to stderr. */ void -buffer_dump(Buffer *buffer) +buffer_dump(const Buffer *buffer) { u_int i; u_char *ucp = buffer->buf; diff --git a/buffer.h b/buffer.h index ecad28973..4ef4f80b3 100644 --- a/buffer.h +++ b/buffer.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.h,v 1.18 2010/01/12 01:36:08 djm Exp $ */ +/* $OpenBSD: buffer.h,v 1.19 2010/02/09 03:56:28 djm Exp $ */ /* * Author: Tatu Ylonen @@ -27,8 +27,8 @@ void buffer_init(Buffer *); void buffer_clear(Buffer *); void buffer_free(Buffer *); -u_int buffer_len(Buffer *); -void *buffer_ptr(Buffer *); +u_int buffer_len(const Buffer *); +void *buffer_ptr(const Buffer *); void buffer_append(Buffer *, const void *, u_int); void *buffer_append_space(Buffer *, u_int); @@ -40,7 +40,7 @@ void buffer_get(Buffer *, void *, u_int); void buffer_consume(Buffer *, u_int); void buffer_consume_end(Buffer *, u_int); -void buffer_dump(Buffer *); +void buffer_dump(const Buffer *); int buffer_get_ret(Buffer *, void *, u_int); int buffer_consume_ret(Buffer *, u_int); -- cgit v1.2.3 From 47cf16b8df67ce02866eefbe855174fa7dfbd359 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:25:29 +1100 Subject: - djm@cvs.openbsd.org 2010/02/09 06:18:46 [auth.c] unbreak ChrootDirectory+internal-sftp by skipping check for executable shell when chrooting; reported by danh AT wzrd.com; ok dtucker@ --- ChangeLog | 4 ++++ auth.c | 57 +++++++++++++++++++++------------------------------------ 2 files changed, 25 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 872f06e9f..db0b19df4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,10 @@ - djm@cvs.openbsd.org 2010/02/09 03:56:28 [buffer.c buffer.h] constify the arguments to buffer_len, buffer_ptr and buffer_dump + - djm@cvs.openbsd.org 2010/02/09 06:18:46 + [auth.c] + unbreak ChrootDirectory+internal-sftp by skipping check for executable + shell when chrooting; reported by danh AT wzrd.com; ok dtucker@ 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/auth.c b/auth.c index da87807a8..3005f815e 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.83 2010/01/13 23:47:26 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.84 2010/02/09 06:18:46 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -95,7 +95,6 @@ allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; - char *shell, *tmp, *chroot_path; u_int i; #ifdef USE_SHADOW struct spwd *spw = NULL; @@ -153,43 +152,29 @@ allowed_user(struct passwd * pw) } /* - * Get the shell from the password data. An empty shell field is - * legal, and means /bin/sh. + * Deny if shell does not exist or is not executable unless we + * are chrooting. */ - shell = xstrdup((pw->pw_shell[0] == '\0') ? - _PATH_BSHELL : pw->pw_shell); - - /* - * Amend shell if chroot is requested. - */ - if (options.chroot_directory != NULL && - strcasecmp(options.chroot_directory, "none") != 0) { - tmp = tilde_expand_filename(options.chroot_directory, - pw->pw_uid); - chroot_path = percent_expand(tmp, "h", pw->pw_dir, - "u", pw->pw_name, (char *)NULL); - xfree(tmp); - xasprintf(&tmp, "%s/%s", chroot_path, shell); - xfree(shell); - shell = tmp; - free(chroot_path); - } - - /* deny if shell does not exists or is not executable */ - if (stat(shell, &st) != 0) { - logit("User %.100s not allowed because shell %.100s does not exist", - pw->pw_name, shell); - xfree(shell); - return 0; - } - if (S_ISREG(st.st_mode) == 0 || - (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { - logit("User %.100s not allowed because shell %.100s is not executable", - pw->pw_name, shell); + if (options.chroot_directory == NULL || + strcasecmp(options.chroot_directory, "none") == 0) { + char *shell = xstrdup((pw->pw_shell[0] == '\0') ? + _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ + + if (stat(shell, &st) != 0) { + logit("User %.100s not allowed because shell %.100s " + "does not exist", pw->pw_name, shell); + xfree(shell); + return 0; + } + if (S_ISREG(st.st_mode) == 0 || + (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { + logit("User %.100s not allowed because shell %.100s " + "is not executable", pw->pw_name, shell); + xfree(shell); + return 0; + } xfree(shell); - return 0; } - xfree(shell); if (options.num_deny_users > 0 || options.num_allow_users > 0 || options.num_deny_groups > 0 || options.num_allow_groups > 0) { -- cgit v1.2.3 From a76184445530cb13ded5827546756471d7d423e2 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:26:02 +1100 Subject: - markus@cvs.openbsd.org 2010/02/10 23:20:38 [ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5] pkcs#11 is no longer optional; improve wording; ok jmc@ --- ChangeLog | 3 +++ ssh-add.1 | 8 ++++---- ssh-keygen.1 | 9 ++++----- ssh.1 | 8 +++----- ssh_config.5 | 7 +++---- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index db0b19df4..1c532a6e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,9 @@ [auth.c] unbreak ChrootDirectory+internal-sftp by skipping check for executable shell when chrooting; reported by danh AT wzrd.com; ok dtucker@ + - markus@cvs.openbsd.org 2010/02/10 23:20:38 + [ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5] + pkcs#11 is no longer optional; improve wording; ok jmc@ 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/ssh-add.1 b/ssh-add.1 index 619209a19..0d5e39272 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.50 2010/02/08 22:03:05 jmc Exp $ +.\" $OpenBSD: ssh-add.1,v 1.51 2010/02/10 23:20:38 markus Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 8 2010 $ +.Dd $Mdocdate: February 10 2010 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -102,7 +102,7 @@ will append .Pa .pub and retry. .It Fl e Ar pkcs11 -Remove key provided by +Remove keys provided by the PKCS#11 shared library .Ar pkcs11 . .It Fl L Lists public key parameters of all identities currently represented @@ -110,7 +110,7 @@ by the agent. .It Fl l Lists fingerprints of all identities currently represented by the agent. .It Fl s Ar pkcs11 -Add key provided by +Add keys provided by the PKCS#11 shared library .Ar pkcs11 . .It Fl t Ar life Set a maximum lifetime when adding identities to an agent. diff --git a/ssh-keygen.1 b/ssh-keygen.1 index c0c323640..f09e1a100 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.82 2010/02/08 22:03:05 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.83 2010/02/10 23:20:38 markus Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 8 2010 $ +.Dd $Mdocdate: February 10 2010 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -199,9 +199,8 @@ This operation is only supported for RSA1 keys. The program will prompt for the file containing the private keys, for the passphrase if the key has one, and for the new comment. .It Fl D Ar pkcs11 -Download the RSA public keys stored in the -.Ar pkcs11 -provider. +Download the RSA public keys provided by the PKCS#11 shared library +.Ar pkcs11 . .It Fl e This option will read a private or public OpenSSH key file and print the key in diff --git a/ssh.1 b/ssh.1 index 4424e1f60..8fcc9b564 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.292 2010/02/08 22:03:05 jmc Exp $ -.Dd $Mdocdate: February 8 2010 $ +.\" $OpenBSD: ssh.1,v 1.293 2010/02/10 23:20:38 markus Exp $ +.Dd $Mdocdate: February 10 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -288,10 +288,8 @@ Allows remote hosts to connect to local forwarded ports. .It Fl I Ar pkcs11 Specify the PKCS#11 shared libarary .Nm -should use to communicate with a PKCS#11 token used for storing the user's +should use to communicate with a PKCS#11 token providing the user's private RSA key. -This option is only available if support for PKCS#11 -is compiled in (default is no support). .It Fl i Ar identity_file Selects a file from which the identity (private key) for RSA or DSA authentication is read. diff --git a/ssh_config.5 b/ssh_config.5 index 350a8eacd..7ab5d02fd 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.127 2010/02/08 10:50:20 markus Exp $ -.Dd $Mdocdate: February 8 2010 $ +.\" $OpenBSD: ssh_config.5,v 1.128 2010/02/10 23:20:38 markus Exp $ +.Dd $Mdocdate: February 10 2010 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -715,9 +715,8 @@ The default is Specifies which PKCS#11 provider to use. The argument to this keyword is the PKCS#11 shared libary .Xr ssh 1 -should use to communicate with a PKCS#11 token used for storing the user's +should use to communicate with a PKCS#11 token providing the user's private RSA key. -By default, no device is specified and PKCS#11 support is not activated. .It Cm Port Specifies the port number to connect on the remote host. The default is 22. -- cgit v1.2.3 From d400da5ba8d7e5822647c472c7dfbfecb55c2152 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:26:23 +1100 Subject: - jmc@cvs.openbsd.org 2010/02/11 13:23:29 [ssh.1] libarary -> library; --- ChangeLog | 3 +++ ssh.1 | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c532a6e4..f2bad9360 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,9 @@ - markus@cvs.openbsd.org 2010/02/10 23:20:38 [ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5] pkcs#11 is no longer optional; improve wording; ok jmc@ + - jmc@cvs.openbsd.org 2010/02/11 13:23:29 + [ssh.1] + libarary -> library; 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/ssh.1 b/ssh.1 index 8fcc9b564..6964cd09c 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.293 2010/02/10 23:20:38 markus Exp $ -.Dd $Mdocdate: February 10 2010 $ +.\" $OpenBSD: ssh.1,v 1.294 2010/02/11 13:23:29 jmc Exp $ +.Dd $Mdocdate: February 11 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -286,7 +286,7 @@ before placing itself in the background. .It Fl g Allows remote hosts to connect to local forwarded ports. .It Fl I Ar pkcs11 -Specify the PKCS#11 shared libarary +Specify the PKCS#11 shared library .Nm should use to communicate with a PKCS#11 token providing the user's private RSA key. -- cgit v1.2.3 From d8f60022727f1d57efe7261b856d5e84a4b28cbe Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:34:22 +1100 Subject: - (djm) [INSTALL Makefile.in README.smartcard configure.ac scard-opensc.c] [scard.c scard.h pkcs11.h scard/Makefile.in scard/Ssh.bin.uu scard/Ssh.java] Remove obsolete smartcard support --- ChangeLog | 3 + INSTALL | 6 +- Makefile.in | 13 +- README.smartcard | 93 ---- configure.ac | 73 +-- pkcs11.h | 1356 +++++++++++++++++++++++++++++++++++++++++++++++++++++ scard-opensc.c | 532 --------------------- scard.c | 571 ---------------------- scard.h | 39 -- scard/Makefile.in | 29 -- scard/Ssh.bin.uu | 17 - scard/Ssh.java | 164 ------- 12 files changed, 1367 insertions(+), 1529 deletions(-) delete mode 100644 README.smartcard create mode 100644 pkcs11.h delete mode 100644 scard-opensc.c delete mode 100644 scard.c delete mode 100644 scard.h delete mode 100644 scard/Makefile.in delete mode 100644 scard/Ssh.bin.uu delete mode 100644 scard/Ssh.java diff --git a/ChangeLog b/ChangeLog index f2bad9360..ce4ef1343 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,6 +37,9 @@ - jmc@cvs.openbsd.org 2010/02/11 13:23:29 [ssh.1] libarary -> library; + - (djm) [INSTALL Makefile.in README.smartcard configure.ac scard-opensc.c] + [scard.c scard.h pkcs11.h scard/Makefile.in scard/Ssh.bin.uu scard/Ssh.java] + Remove obsolete smartcard support 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/INSTALL b/INSTALL index 001ebb666..09dfd666d 100644 --- a/INSTALL +++ b/INSTALL @@ -208,10 +208,6 @@ are installed. --with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to real (AF_INET) IPv4 addresses. Works around some quirks on Linux. ---with-opensc=DIR ---with-sectok=DIR allows for OpenSC or sectok smartcard libraries to -be used with OpenSSH. See 'README.smartcard' for more details. - If you need to pass special options to the compiler or linker, you can specify these as environment variables before running ./configure. For example: @@ -266,4 +262,4 @@ Please refer to the "reporting bugs" section of the webpage at http://www.openssh.com/ -$Id: INSTALL,v 1.84 2007/08/17 12:52:05 dtucker Exp $ +$Id: INSTALL,v 1.85 2010/02/11 22:34:22 djm Exp $ diff --git a/Makefile.in b/Makefile.in index 0c45bfca6..1e4f64a64 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.304 2010/02/11 22:21:02 djm Exp $ +# $Id: Makefile.in,v 1.305 2010/02/11 22:34:22 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -72,8 +72,8 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ - kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ - entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o \ + kexgex.o kexdhc.o kexgexc.o msg.o progressmeter.o dns.o \ + entropy.o gss-genr.o umac.o jpake.o schnorr.o \ ssh-pkcs11.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ @@ -215,7 +215,6 @@ distclean: regressclean rm -f survey.sh openbsd-compat/regress/Makefile *~ rm -rf autom4te.cache (cd openbsd-compat && $(MAKE) distclean) - (cd scard && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ fi @@ -238,7 +237,6 @@ catman-do: distprep: catman-do $(AUTORECONF) -rm -rf autom4te.cache - (cd scard && $(MAKE) -f Makefile.in distprep) install: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files install-sysconf host-key check-config install-nokeys: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files install-sysconf @@ -247,10 +245,7 @@ install-nosysconf: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) insta check-config: -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config -scard-install: - (cd scard && env DESTDIR=$(DESTDIR) $(MAKE) DESTDIR=$(DESTDIR) install) - -install-files: scard-install +install-files: $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(srcdir)/mkinstalldirs $(DESTDIR)$(sbindir) $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir) diff --git a/README.smartcard b/README.smartcard deleted file mode 100644 index fdf83ecab..000000000 --- a/README.smartcard +++ /dev/null @@ -1,93 +0,0 @@ -How to use smartcards with OpenSSH? - -OpenSSH contains experimental support for authentication using -Cyberflex smartcards and TODOS card readers, in addition to the cards -with PKCS#15 structure supported by OpenSC. To enable this you -need to: - -Using libsectok: - -(1) enable sectok support in OpenSSH: - - $ ./configure --with-sectok - -(2) If you have used a previous version of ssh with your card, you - must remove the old applet and keys. - - $ sectok - sectok> login -d - sectok> junload Ssh.bin - sectok> delete 0012 - sectok> delete sh - sectok> quit - -(3) load the Java Cardlet to the Cyberflex card and set card passphrase: - - $ sectok - sectok> login -d - sectok> jload /usr/libdata/ssh/Ssh.bin - sectok> setpass - Enter new AUT0 passphrase: - Re-enter passphrase: - sectok> quit - - Do not forget the passphrase. There is no way to - recover if you do. - - IMPORTANT WARNING: If you attempt to login with the - wrong passphrase three times in a row, you will - destroy your card. - -(4) load a RSA key to the card: - - $ ssh-keygen -f /path/to/rsakey -U 1 - (where 1 is the reader number, you can also try 0) - - In spite of the name, this does not generate a key. - It just loads an already existing key on to the card. - -(5) Optional: If you don't want to use a card passphrase, change the - acl on the private key file: - - $ sectok - sectok> login -d - sectok> acl 0012 world: w - world: w - AUT0: w inval - sectok> quit - - If you do this, anyone who has access to your card - can assume your identity. This is not recommended. - - -Using OpenSC: - -(1) install OpenSC: - - Sources and instructions are available from - http://www.opensc.org/ - -(2) enable OpenSC support in OpenSSH: - - $ ./configure --with-opensc[=/path/to/opensc] [options] - -(3) load a RSA key to the card: - - Not supported yet. - - -Common operations: - -(1) tell the ssh client to use the card reader: - - $ ssh -I 1 otherhost - -(2) or tell the agent (don't forget to restart) to use the smartcard: - - $ ssh-add -s 1 - - --markus, -Tue Jul 17 23:54:51 CEST 2001 - -$OpenBSD: README.smartcard,v 1.9 2003/11/21 11:57:02 djm Exp $ diff --git a/configure.ac b/configure.ac index 717d315fd..40b58c64f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.441 2010/02/11 22:21:02 djm Exp $ +# $Id: configure.ac,v 1.442 2010/02/11 22:34:22 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.441 $) +AC_REVISION($Revision: 1.442 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -3263,73 +3263,6 @@ if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then AC_DEFINE(HAVE_SYS_NERR, 1, [Define if your system defines sys_nerr]) fi -SCARD_MSG="no" -# Check whether user wants sectok support -AC_ARG_WITH(sectok, - [ --with-sectok Enable smartcard support using libsectok], - [ - if test "x$withval" != "xno" ; then - if test "x$withval" != "xyes" ; then - CPPFLAGS="$CPPFLAGS -I${withval}" - LDFLAGS="$LDFLAGS -L${withval}" - if test ! -z "$need_dash_r" ; then - LDFLAGS="$LDFLAGS -R${withval}" - fi - if test ! -z "$blibpath" ; then - blibpath="$blibpath:${withval}" - fi - fi - AC_CHECK_HEADERS(sectok.h) - if test "$ac_cv_header_sectok_h" != yes; then - AC_MSG_ERROR(Can't find sectok.h) - fi - AC_CHECK_LIB(sectok, sectok_open) - if test "$ac_cv_lib_sectok_sectok_open" != yes; then - AC_MSG_ERROR(Can't find libsectok) - fi - AC_DEFINE(SMARTCARD, 1, - [Define if you want smartcard support]) - AC_DEFINE(USE_SECTOK, 1, - [Define if you want smartcard support - using sectok]) - SCARD_MSG="yes, using sectok" - fi - ] -) - -# Check whether user wants OpenSC support -OPENSC_CONFIG="no" -AC_ARG_WITH(opensc, - [ --with-opensc[[=PFX]] Enable smartcard support using OpenSC (optionally in PATH)], - [ - if test "x$withval" != "xno" ; then - AC_PATH_PROG(PKGCONFIG, pkg-config, no) - AC_MSG_CHECKING(how to get opensc config) - if test "x$withval" != "xyes" -a "x$PKGCONFIG" = "xno"; then - OPENSC_CONFIG="$withval/bin/opensc-config" - elif test -f "$withval/src/libopensc/libopensc.pc"; then - OPENSC_CONFIG="$PKGCONFIG $withval/src/libopensc/libopensc.pc" - elif test "x$PKGCONFIG" != "xno"; then - OPENSC_CONFIG="$PKGCONFIG libopensc" - else - AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no) - fi - AC_MSG_RESULT($OPENSC_CONFIG) - if test "$OPENSC_CONFIG" != "no"; then - LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags` - LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs` - CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS" - LIBS="$LIBS $LIBOPENSC_LIBS" - AC_DEFINE(SMARTCARD) - AC_DEFINE(USE_OPENSC, 1, - [Define if you want smartcard support - using OpenSC]) - SCARD_MSG="yes, using OpenSC" - fi - fi - ] -) - # Check libraries needed by DNS fingerprint support AC_SEARCH_LIBS(getrrsetbyname, resolv, [AC_DEFINE(HAVE_GETRRSETBYNAME, 1, @@ -4204,7 +4137,7 @@ fi AC_EXEEXT AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ openbsd-compat/Makefile openbsd-compat/regress/Makefile \ - scard/Makefile ssh_prng_cmds survey.sh]) + ssh_prng_cmds survey.sh]) AC_OUTPUT # Print summary of options diff --git a/pkcs11.h b/pkcs11.h new file mode 100644 index 000000000..223f20ff3 --- /dev/null +++ b/pkcs11.h @@ -0,0 +1,1356 @@ +/* pkcs11.h + Copyright 2006, 2007 g10 Code GmbH + Copyright 2006 Andreas Jellinghaus + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. */ + +/* Please submit changes back to the Scute project at + http://www.scute.org/ (or send them to marcus@g10code.com), so that + they can be picked up by other projects from there as well. */ + +/* This file is a modified implementation of the PKCS #11 standard by + RSA Security Inc. It is mostly a drop-in replacement, with the + following change: + + This header file does not require any macro definitions by the user + (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros + for you (if useful, some are missing, let me know if you need + more). + + There is an additional API available that does comply better to the + GNU coding standard. It can be switched on by defining + CRYPTOKI_GNU before including this header file. For this, the + following changes are made to the specification: + + All structure types are changed to a "struct ck_foo" where CK_FOO + is the type name in PKCS #11. + + All non-structure types are changed to ck_foo_t where CK_FOO is the + lowercase version of the type name in PKCS #11. The basic types + (CK_ULONG et al.) are removed without substitute. + + All members of structures are modified in the following way: Type + indication prefixes are removed, and underscore characters are + inserted before words. Then the result is lowercased. + + Note that function names are still in the original case, as they + need for ABI compatibility. + + CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use + . + + If CRYPTOKI_COMPAT is defined before including this header file, + then none of the API changes above take place, and the API is the + one defined by the PKCS #11 standard. */ + +#ifndef PKCS11_H +#define PKCS11_H 1 + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* The version of cryptoki we implement. The revision is changed with + each modification of this file. If you do not use the "official" + version of this file, please consider deleting the revision macro + (you may use a macro with a different name to keep track of your + versions). */ +#define CRYPTOKI_VERSION_MAJOR 2 +#define CRYPTOKI_VERSION_MINOR 20 +#define CRYPTOKI_VERSION_REVISION 6 + + +/* Compatibility interface is default, unless CRYPTOKI_GNU is + given. */ +#ifndef CRYPTOKI_GNU +#ifndef CRYPTOKI_COMPAT +#define CRYPTOKI_COMPAT 1 +#endif +#endif + +/* System dependencies. */ + +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) + +/* There is a matching pop below. */ +#pragma pack(push, cryptoki, 1) + +#ifdef CRYPTOKI_EXPORTS +#define CK_SPEC __declspec(dllexport) +#else +#define CK_SPEC __declspec(dllimport) +#endif + +#else + +#define CK_SPEC + +#endif + + +#ifdef CRYPTOKI_COMPAT + /* If we are in compatibility mode, switch all exposed names to the + PKCS #11 variant. There are corresponding #undefs below. */ + +#define ck_flags_t CK_FLAGS +#define ck_version _CK_VERSION + +#define ck_info _CK_INFO +#define cryptoki_version cryptokiVersion +#define manufacturer_id manufacturerID +#define library_description libraryDescription +#define library_version libraryVersion + +#define ck_notification_t CK_NOTIFICATION +#define ck_slot_id_t CK_SLOT_ID + +#define ck_slot_info _CK_SLOT_INFO +#define slot_description slotDescription +#define hardware_version hardwareVersion +#define firmware_version firmwareVersion + +#define ck_token_info _CK_TOKEN_INFO +#define serial_number serialNumber +#define max_session_count ulMaxSessionCount +#define session_count ulSessionCount +#define max_rw_session_count ulMaxRwSessionCount +#define rw_session_count ulRwSessionCount +#define max_pin_len ulMaxPinLen +#define min_pin_len ulMinPinLen +#define total_public_memory ulTotalPublicMemory +#define free_public_memory ulFreePublicMemory +#define total_private_memory ulTotalPrivateMemory +#define free_private_memory ulFreePrivateMemory +#define utc_time utcTime + +#define ck_session_handle_t CK_SESSION_HANDLE +#define ck_user_type_t CK_USER_TYPE +#define ck_state_t CK_STATE + +#define ck_session_info _CK_SESSION_INFO +#define slot_id slotID +#define device_error ulDeviceError + +#define ck_object_handle_t CK_OBJECT_HANDLE +#define ck_object_class_t CK_OBJECT_CLASS +#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE +#define ck_key_type_t CK_KEY_TYPE +#define ck_certificate_type_t CK_CERTIFICATE_TYPE +#define ck_attribute_type_t CK_ATTRIBUTE_TYPE + +#define ck_attribute _CK_ATTRIBUTE +#define value pValue +#define value_len ulValueLen + +#define ck_date _CK_DATE + +#define ck_mechanism_type_t CK_MECHANISM_TYPE + +#define ck_mechanism _CK_MECHANISM +#define parameter pParameter +#define parameter_len ulParameterLen + +#define ck_mechanism_info _CK_MECHANISM_INFO +#define min_key_size ulMinKeySize +#define max_key_size ulMaxKeySize + +#define ck_rv_t CK_RV +#define ck_notify_t CK_NOTIFY + +#define ck_function_list _CK_FUNCTION_LIST + +#define ck_createmutex_t CK_CREATEMUTEX +#define ck_destroymutex_t CK_DESTROYMUTEX +#define ck_lockmutex_t CK_LOCKMUTEX +#define ck_unlockmutex_t CK_UNLOCKMUTEX + +#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS +#define create_mutex CreateMutex +#define destroy_mutex DestroyMutex +#define lock_mutex LockMutex +#define unlock_mutex UnlockMutex +#define reserved pReserved + +#endif /* CRYPTOKI_COMPAT */ + + + +typedef unsigned long ck_flags_t; + +struct ck_version +{ + unsigned char major; + unsigned char minor; +}; + + +struct ck_info +{ + struct ck_version cryptoki_version; + unsigned char manufacturer_id[32]; + ck_flags_t flags; + unsigned char library_description[32]; + struct ck_version library_version; +}; + + +typedef unsigned long ck_notification_t; + +#define CKN_SURRENDER (0) + + +typedef unsigned long ck_slot_id_t; + + +struct ck_slot_info +{ + unsigned char slot_description[64]; + unsigned char manufacturer_id[32]; + ck_flags_t flags; + struct ck_version hardware_version; + struct ck_version firmware_version; +}; + + +#define CKF_TOKEN_PRESENT (1 << 0) +#define CKF_REMOVABLE_DEVICE (1 << 1) +#define CKF_HW_SLOT (1 << 2) +#define CKF_ARRAY_ATTRIBUTE (1 << 30) + + +struct ck_token_info +{ + unsigned char label[32]; + unsigned char manufacturer_id[32]; + unsigned char model[16]; + unsigned char serial_number[16]; + ck_flags_t flags; + unsigned long max_session_count; + unsigned long session_count; + unsigned long max_rw_session_count; + unsigned long rw_session_count; + unsigned long max_pin_len; + unsigned long min_pin_len; + unsigned long total_public_memory; + unsigned long free_public_memory; + unsigned long total_private_memory; + unsigned long free_private_memory; + struct ck_version hardware_version; + struct ck_version firmware_version; + unsigned char utc_time[16]; +}; + + +#define CKF_RNG (1 << 0) +#define CKF_WRITE_PROTECTED (1 << 1) +#define CKF_LOGIN_REQUIRED (1 << 2) +#define CKF_USER_PIN_INITIALIZED (1 << 3) +#define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5) +#define CKF_CLOCK_ON_TOKEN (1 << 6) +#define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8) +#define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9) +#define CKF_TOKEN_INITIALIZED (1 << 10) +#define CKF_SECONDARY_AUTHENTICATION (1 << 11) +#define CKF_USER_PIN_COUNT_LOW (1 << 16) +#define CKF_USER_PIN_FINAL_TRY (1 << 17) +#define CKF_USER_PIN_LOCKED (1 << 18) +#define CKF_USER_PIN_TO_BE_CHANGED (1 << 19) +#define CKF_SO_PIN_COUNT_LOW (1 << 20) +#define CKF_SO_PIN_FINAL_TRY (1 << 21) +#define CKF_SO_PIN_LOCKED (1 << 22) +#define CKF_SO_PIN_TO_BE_CHANGED (1 << 23) + +#define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) +#define CK_EFFECTIVELY_INFINITE (0) + + +typedef unsigned long ck_session_handle_t; + +#define CK_INVALID_HANDLE (0) + + +typedef unsigned long ck_user_type_t; + +#define CKU_SO (0) +#define CKU_USER (1) +#define CKU_CONTEXT_SPECIFIC (2) + + +typedef unsigned long ck_state_t; + +#define CKS_RO_PUBLIC_SESSION (0) +#define CKS_RO_USER_FUNCTIONS (1) +#define CKS_RW_PUBLIC_SESSION (2) +#define CKS_RW_USER_FUNCTIONS (3) +#define CKS_RW_SO_FUNCTIONS (4) + + +struct ck_session_info +{ + ck_slot_id_t slot_id; + ck_state_t state; + ck_flags_t flags; + unsigned long device_error; +}; + +#define CKF_RW_SESSION (1 << 1) +#define CKF_SERIAL_SESSION (1 << 2) + + +typedef unsigned long ck_object_handle_t; + + +typedef unsigned long ck_object_class_t; + +#define CKO_DATA (0) +#define CKO_CERTIFICATE (1) +#define CKO_PUBLIC_KEY (2) +#define CKO_PRIVATE_KEY (3) +#define CKO_SECRET_KEY (4) +#define CKO_HW_FEATURE (5) +#define CKO_DOMAIN_PARAMETERS (6) +#define CKO_MECHANISM (7) +#define CKO_VENDOR_DEFINED ((unsigned long) (1 << 31)) + + +typedef unsigned long ck_hw_feature_type_t; + +#define CKH_MONOTONIC_COUNTER (1) +#define CKH_CLOCK (2) +#define CKH_USER_INTERFACE (3) +#define CKH_VENDOR_DEFINED ((unsigned long) (1 << 31)) + + +typedef unsigned long ck_key_type_t; + +#define CKK_RSA (0) +#define CKK_DSA (1) +#define CKK_DH (2) +#define CKK_ECDSA (3) +#define CKK_EC (3) +#define CKK_X9_42_DH (4) +#define CKK_KEA (5) +#define CKK_GENERIC_SECRET (0x10) +#define CKK_RC2 (0x11) +#define CKK_RC4 (0x12) +#define CKK_DES (0x13) +#define CKK_DES2 (0x14) +#define CKK_DES3 (0x15) +#define CKK_CAST (0x16) +#define CKK_CAST3 (0x17) +#define CKK_CAST128 (0x18) +#define CKK_RC5 (0x19) +#define CKK_IDEA (0x1a) +#define CKK_SKIPJACK (0x1b) +#define CKK_BATON (0x1c) +#define CKK_JUNIPER (0x1d) +#define CKK_CDMF (0x1e) +#define CKK_AES (0x1f) +#define CKK_BLOWFISH (0x20) +#define CKK_TWOFISH (0x21) +#define CKK_VENDOR_DEFINED ((unsigned long) (1 << 31)) + +typedef unsigned long ck_certificate_type_t; + +#define CKC_X_509 (0) +#define CKC_X_509_ATTR_CERT (1) +#define CKC_WTLS (2) +#define CKC_VENDOR_DEFINED ((unsigned long) (1 << 31)) + + +typedef unsigned long ck_attribute_type_t; + +#define CKA_CLASS (0) +#define CKA_TOKEN (1) +#define CKA_PRIVATE (2) +#define CKA_LABEL (3) +#define CKA_APPLICATION (0x10) +#define CKA_VALUE (0x11) +#define CKA_OBJECT_ID (0x12) +#define CKA_CERTIFICATE_TYPE (0x80) +#define CKA_ISSUER (0x81) +#define CKA_SERIAL_NUMBER (0x82) +#define CKA_AC_ISSUER (0x83) +#define CKA_OWNER (0x84) +#define CKA_ATTR_TYPES (0x85) +#define CKA_TRUSTED (0x86) +#define CKA_CERTIFICATE_CATEGORY (0x87) +#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88) +#define CKA_URL (0x89) +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a) +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b) +#define CKA_CHECK_VALUE (0x90) +#define CKA_KEY_TYPE (0x100) +#define CKA_SUBJECT (0x101) +#define CKA_ID (0x102) +#define CKA_SENSITIVE (0x103) +#define CKA_ENCRYPT (0x104) +#define CKA_DECRYPT (0x105) +#define CKA_WRAP (0x106) +#define CKA_UNWRAP (0x107) +#define CKA_SIGN (0x108) +#define CKA_SIGN_RECOVER (0x109) +#define CKA_VERIFY (0x10a) +#define CKA_VERIFY_RECOVER (0x10b) +#define CKA_DERIVE (0x10c) +#define CKA_START_DATE (0x110) +#define CKA_END_DATE (0x111) +#define CKA_MODULUS (0x120) +#define CKA_MODULUS_BITS (0x121) +#define CKA_PUBLIC_EXPONENT (0x122) +#define CKA_PRIVATE_EXPONENT (0x123) +#define CKA_PRIME_1 (0x124) +#define CKA_PRIME_2 (0x125) +#define CKA_EXPONENT_1 (0x126) +#define CKA_EXPONENT_2 (0x127) +#define CKA_COEFFICIENT (0x128) +#define CKA_PRIME (0x130) +#define CKA_SUBPRIME (0x131) +#define CKA_BASE (0x132) +#define CKA_PRIME_BITS (0x133) +#define CKA_SUB_PRIME_BITS (0x134) +#define CKA_VALUE_BITS (0x160) +#define CKA_VALUE_LEN (0x161) +#define CKA_EXTRACTABLE (0x162) +#define CKA_LOCAL (0x163) +#define CKA_NEVER_EXTRACTABLE (0x164) +#define CKA_ALWAYS_SENSITIVE (0x165) +#define CKA_KEY_GEN_MECHANISM (0x166) +#define CKA_MODIFIABLE (0x170) +#define CKA_ECDSA_PARAMS (0x180) +#define CKA_EC_PARAMS (0x180) +#define CKA_EC_POINT (0x181) +#define CKA_SECONDARY_AUTH (0x200) +#define CKA_AUTH_PIN_FLAGS (0x201) +#define CKA_ALWAYS_AUTHENTICATE (0x202) +#define CKA_WRAP_WITH_TRUSTED (0x210) +#define CKA_HW_FEATURE_TYPE (0x300) +#define CKA_RESET_ON_INIT (0x301) +#define CKA_HAS_RESET (0x302) +#define CKA_PIXEL_X (0x400) +#define CKA_PIXEL_Y (0x401) +#define CKA_RESOLUTION (0x402) +#define CKA_CHAR_ROWS (0x403) +#define CKA_CHAR_COLUMNS (0x404) +#define CKA_COLOR (0x405) +#define CKA_BITS_PER_PIXEL (0x406) +#define CKA_CHAR_SETS (0x480) +#define CKA_ENCODING_METHODS (0x481) +#define CKA_MIME_TYPES (0x482) +#define CKA_MECHANISM_TYPE (0x500) +#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501) +#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502) +#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503) +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211) +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212) +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600) +#define CKA_VENDOR_DEFINED ((unsigned long) (1 << 31)) + + +struct ck_attribute +{ + ck_attribute_type_t type; + void *value; + unsigned long value_len; +}; + + +struct ck_date +{ + unsigned char year[4]; + unsigned char month[2]; + unsigned char day[2]; +}; + + +typedef unsigned long ck_mechanism_type_t; + +#define CKM_RSA_PKCS_KEY_PAIR_GEN (0) +#define CKM_RSA_PKCS (1) +#define CKM_RSA_9796 (2) +#define CKM_RSA_X_509 (3) +#define CKM_MD2_RSA_PKCS (4) +#define CKM_MD5_RSA_PKCS (5) +#define CKM_SHA1_RSA_PKCS (6) +#define CKM_RIPEMD128_RSA_PKCS (7) +#define CKM_RIPEMD160_RSA_PKCS (8) +#define CKM_RSA_PKCS_OAEP (9) +#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa) +#define CKM_RSA_X9_31 (0xb) +#define CKM_SHA1_RSA_X9_31 (0xc) +#define CKM_RSA_PKCS_PSS (0xd) +#define CKM_SHA1_RSA_PKCS_PSS (0xe) +#define CKM_DSA_KEY_PAIR_GEN (0x10) +#define CKM_DSA (0x11) +#define CKM_DSA_SHA1 (0x12) +#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20) +#define CKM_DH_PKCS_DERIVE (0x21) +#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30) +#define CKM_X9_42_DH_DERIVE (0x31) +#define CKM_X9_42_DH_HYBRID_DERIVE (0x32) +#define CKM_X9_42_MQV_DERIVE (0x33) +#define CKM_SHA256_RSA_PKCS (0x40) +#define CKM_SHA384_RSA_PKCS (0x41) +#define CKM_SHA512_RSA_PKCS (0x42) +#define CKM_SHA256_RSA_PKCS_PSS (0x43) +#define CKM_SHA384_RSA_PKCS_PSS (0x44) +#define CKM_SHA512_RSA_PKCS_PSS (0x45) +#define CKM_RC2_KEY_GEN (0x100) +#define CKM_RC2_ECB (0x101) +#define CKM_RC2_CBC (0x102) +#define CKM_RC2_MAC (0x103) +#define CKM_RC2_MAC_GENERAL (0x104) +#define CKM_RC2_CBC_PAD (0x105) +#define CKM_RC4_KEY_GEN (0x110) +#define CKM_RC4 (0x111) +#define CKM_DES_KEY_GEN (0x120) +#define CKM_DES_ECB (0x121) +#define CKM_DES_CBC (0x122) +#define CKM_DES_MAC (0x123) +#define CKM_DES_MAC_GENERAL (0x124) +#define CKM_DES_CBC_PAD (0x125) +#define CKM_DES2_KEY_GEN (0x130) +#define CKM_DES3_KEY_GEN (0x131) +#define CKM_DES3_ECB (0x132) +#define CKM_DES3_CBC (0x133) +#define CKM_DES3_MAC (0x134) +#define CKM_DES3_MAC_GENERAL (0x135) +#define CKM_DES3_CBC_PAD (0x136) +#define CKM_CDMF_KEY_GEN (0x140) +#define CKM_CDMF_ECB (0x141) +#define CKM_CDMF_CBC (0x142) +#define CKM_CDMF_MAC (0x143) +#define CKM_CDMF_MAC_GENERAL (0x144) +#define CKM_CDMF_CBC_PAD (0x145) +#define CKM_MD2 (0x200) +#define CKM_MD2_HMAC (0x201) +#define CKM_MD2_HMAC_GENERAL (0x202) +#define CKM_MD5 (0x210) +#define CKM_MD5_HMAC (0x211) +#define CKM_MD5_HMAC_GENERAL (0x212) +#define CKM_SHA_1 (0x220) +#define CKM_SHA_1_HMAC (0x221) +#define CKM_SHA_1_HMAC_GENERAL (0x222) +#define CKM_RIPEMD128 (0x230) +#define CKM_RIPEMD128_HMAC (0x231) +#define CKM_RIPEMD128_HMAC_GENERAL (0x232) +#define CKM_RIPEMD160 (0x240) +#define CKM_RIPEMD160_HMAC (0x241) +#define CKM_RIPEMD160_HMAC_GENERAL (0x242) +#define CKM_SHA256 (0x250) +#define CKM_SHA256_HMAC (0x251) +#define CKM_SHA256_HMAC_GENERAL (0x252) +#define CKM_SHA384 (0x260) +#define CKM_SHA384_HMAC (0x261) +#define CKM_SHA384_HMAC_GENERAL (0x262) +#define CKM_SHA512 (0x270) +#define CKM_SHA512_HMAC (0x271) +#define CKM_SHA512_HMAC_GENERAL (0x272) +#define CKM_CAST_KEY_GEN (0x300) +#define CKM_CAST_ECB (0x301) +#define CKM_CAST_CBC (0x302) +#define CKM_CAST_MAC (0x303) +#define CKM_CAST_MAC_GENERAL (0x304) +#define CKM_CAST_CBC_PAD (0x305) +#define CKM_CAST3_KEY_GEN (0x310) +#define CKM_CAST3_ECB (0x311) +#define CKM_CAST3_CBC (0x312) +#define CKM_CAST3_MAC (0x313) +#define CKM_CAST3_MAC_GENERAL (0x314) +#define CKM_CAST3_CBC_PAD (0x315) +#define CKM_CAST5_KEY_GEN (0x320) +#define CKM_CAST128_KEY_GEN (0x320) +#define CKM_CAST5_ECB (0x321) +#define CKM_CAST128_ECB (0x321) +#define CKM_CAST5_CBC (0x322) +#define CKM_CAST128_CBC (0x322) +#define CKM_CAST5_MAC (0x323) +#define CKM_CAST128_MAC (0x323) +#define CKM_CAST5_MAC_GENERAL (0x324) +#define CKM_CAST128_MAC_GENERAL (0x324) +#define CKM_CAST5_CBC_PAD (0x325) +#define CKM_CAST128_CBC_PAD (0x325) +#define CKM_RC5_KEY_GEN (0x330) +#define CKM_RC5_ECB (0x331) +#define CKM_RC5_CBC (0x332) +#define CKM_RC5_MAC (0x333) +#define CKM_RC5_MAC_GENERAL (0x334) +#define CKM_RC5_CBC_PAD (0x335) +#define CKM_IDEA_KEY_GEN (0x340) +#define CKM_IDEA_ECB (0x341) +#define CKM_IDEA_CBC (0x342) +#define CKM_IDEA_MAC (0x343) +#define CKM_IDEA_MAC_GENERAL (0x344) +#define CKM_IDEA_CBC_PAD (0x345) +#define CKM_GENERIC_SECRET_KEY_GEN (0x350) +#define CKM_CONCATENATE_BASE_AND_KEY (0x360) +#define CKM_CONCATENATE_BASE_AND_DATA (0x362) +#define CKM_CONCATENATE_DATA_AND_BASE (0x363) +#define CKM_XOR_BASE_AND_DATA (0x364) +#define CKM_EXTRACT_KEY_FROM_KEY (0x365) +#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370) +#define CKM_SSL3_MASTER_KEY_DERIVE (0x371) +#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372) +#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373) +#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374) +#define CKM_TLS_MASTER_KEY_DERIVE (0x375) +#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376) +#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377) +#define CKM_SSL3_MD5_MAC (0x380) +#define CKM_SSL3_SHA1_MAC (0x381) +#define CKM_MD5_KEY_DERIVATION (0x390) +#define CKM_MD2_KEY_DERIVATION (0x391) +#define CKM_SHA1_KEY_DERIVATION (0x392) +#define CKM_PBE_MD2_DES_CBC (0x3a0) +#define CKM_PBE_MD5_DES_CBC (0x3a1) +#define CKM_PBE_MD5_CAST_CBC (0x3a2) +#define CKM_PBE_MD5_CAST3_CBC (0x3a3) +#define CKM_PBE_MD5_CAST5_CBC (0x3a4) +#define CKM_PBE_MD5_CAST128_CBC (0x3a4) +#define CKM_PBE_SHA1_CAST5_CBC (0x3a5) +#define CKM_PBE_SHA1_CAST128_CBC (0x3a5) +#define CKM_PBE_SHA1_RC4_128 (0x3a6) +#define CKM_PBE_SHA1_RC4_40 (0x3a7) +#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8) +#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9) +#define CKM_PBE_SHA1_RC2_128_CBC (0x3aa) +#define CKM_PBE_SHA1_RC2_40_CBC (0x3ab) +#define CKM_PKCS5_PBKD2 (0x3b0) +#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0) +#define CKM_KEY_WRAP_LYNKS (0x400) +#define CKM_KEY_WRAP_SET_OAEP (0x401) +#define CKM_SKIPJACK_KEY_GEN (0x1000) +#define CKM_SKIPJACK_ECB64 (0x1001) +#define CKM_SKIPJACK_CBC64 (0x1002) +#define CKM_SKIPJACK_OFB64 (0x1003) +#define CKM_SKIPJACK_CFB64 (0x1004) +#define CKM_SKIPJACK_CFB32 (0x1005) +#define CKM_SKIPJACK_CFB16 (0x1006) +#define CKM_SKIPJACK_CFB8 (0x1007) +#define CKM_SKIPJACK_WRAP (0x1008) +#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009) +#define CKM_SKIPJACK_RELAYX (0x100a) +#define CKM_KEA_KEY_PAIR_GEN (0x1010) +#define CKM_KEA_KEY_DERIVE (0x1011) +#define CKM_FORTEZZA_TIMESTAMP (0x1020) +#define CKM_BATON_KEY_GEN (0x1030) +#define CKM_BATON_ECB128 (0x1031) +#define CKM_BATON_ECB96 (0x1032) +#define CKM_BATON_CBC128 (0x1033) +#define CKM_BATON_COUNTER (0x1034) +#define CKM_BATON_SHUFFLE (0x1035) +#define CKM_BATON_WRAP (0x1036) +#define CKM_ECDSA_KEY_PAIR_GEN (0x1040) +#define CKM_EC_KEY_PAIR_GEN (0x1040) +#define CKM_ECDSA (0x1041) +#define CKM_ECDSA_SHA1 (0x1042) +#define CKM_ECDH1_DERIVE (0x1050) +#define CKM_ECDH1_COFACTOR_DERIVE (0x1051) +#define CKM_ECMQV_DERIVE (0x1052) +#define CKM_JUNIPER_KEY_GEN (0x1060) +#define CKM_JUNIPER_ECB128 (0x1061) +#define CKM_JUNIPER_CBC128 (0x1062) +#define CKM_JUNIPER_COUNTER (0x1063) +#define CKM_JUNIPER_SHUFFLE (0x1064) +#define CKM_JUNIPER_WRAP (0x1065) +#define CKM_FASTHASH (0x1070) +#define CKM_AES_KEY_GEN (0x1080) +#define CKM_AES_ECB (0x1081) +#define CKM_AES_CBC (0x1082) +#define CKM_AES_MAC (0x1083) +#define CKM_AES_MAC_GENERAL (0x1084) +#define CKM_AES_CBC_PAD (0x1085) +#define CKM_DSA_PARAMETER_GEN (0x2000) +#define CKM_DH_PKCS_PARAMETER_GEN (0x2001) +#define CKM_X9_42_DH_PARAMETER_GEN (0x2002) +#define CKM_VENDOR_DEFINED ((unsigned long) (1 << 31)) + + +struct ck_mechanism +{ + ck_mechanism_type_t mechanism; + void *parameter; + unsigned long parameter_len; +}; + + +struct ck_mechanism_info +{ + unsigned long min_key_size; + unsigned long max_key_size; + ck_flags_t flags; +}; + +#define CKF_HW (1 << 0) +#define CKF_ENCRYPT (1 << 8) +#define CKF_DECRYPT (1 << 9) +#define CKF_DIGEST (1 << 10) +#define CKF_SIGN (1 << 11) +#define CKF_SIGN_RECOVER (1 << 12) +#define CKF_VERIFY (1 << 13) +#define CKF_VERIFY_RECOVER (1 << 14) +#define CKF_GENERATE (1 << 15) +#define CKF_GENERATE_KEY_PAIR (1 << 16) +#define CKF_WRAP (1 << 17) +#define CKF_UNWRAP (1 << 18) +#define CKF_DERIVE (1 << 19) +#define CKF_EXTENSION ((unsigned long) (1 << 31)) + + +/* Flags for C_WaitForSlotEvent. */ +#define CKF_DONT_BLOCK (1) + + +typedef unsigned long ck_rv_t; + + +typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, + ck_notification_t event, void *application); + +/* Forward reference. */ +struct ck_function_list; + +#define _CK_DECLARE_FUNCTION(name, args) \ +typedef ck_rv_t (*CK_ ## name) args; \ +ck_rv_t CK_SPEC name args + +_CK_DECLARE_FUNCTION (C_Initialize, (void *init_args)); +_CK_DECLARE_FUNCTION (C_Finalize, (void *reserved)); +_CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info)); +_CK_DECLARE_FUNCTION (C_GetFunctionList, + (struct ck_function_list **function_list)); + +_CK_DECLARE_FUNCTION (C_GetSlotList, + (unsigned char token_present, ck_slot_id_t *slot_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION (C_GetSlotInfo, + (ck_slot_id_t slot_id, struct ck_slot_info *info)); +_CK_DECLARE_FUNCTION (C_GetTokenInfo, + (ck_slot_id_t slot_id, struct ck_token_info *info)); +_CK_DECLARE_FUNCTION (C_WaitForSlotEvent, + (ck_flags_t flags, ck_slot_id_t *slot, void *reserved)); +_CK_DECLARE_FUNCTION (C_GetMechanismList, + (ck_slot_id_t slot_id, + ck_mechanism_type_t *mechanism_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION (C_GetMechanismInfo, + (ck_slot_id_t slot_id, ck_mechanism_type_t type, + struct ck_mechanism_info *info)); +_CK_DECLARE_FUNCTION (C_InitToken, + (ck_slot_id_t slot_id, unsigned char *pin, + unsigned long pin_len, unsigned char *label)); +_CK_DECLARE_FUNCTION (C_InitPIN, + (ck_session_handle_t session, unsigned char *pin, + unsigned long pin_len)); +_CK_DECLARE_FUNCTION (C_SetPIN, + (ck_session_handle_t session, unsigned char *old_pin, + unsigned long old_len, unsigned char *new_pin, + unsigned long new_len)); + +_CK_DECLARE_FUNCTION (C_OpenSession, + (ck_slot_id_t slot_id, ck_flags_t flags, + void *application, ck_notify_t notify, + ck_session_handle_t *session)); +_CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id)); +_CK_DECLARE_FUNCTION (C_GetSessionInfo, + (ck_session_handle_t session, + struct ck_session_info *info)); +_CK_DECLARE_FUNCTION (C_GetOperationState, + (ck_session_handle_t session, + unsigned char *operation_state, + unsigned long *operation_state_len)); +_CK_DECLARE_FUNCTION (C_SetOperationState, + (ck_session_handle_t session, + unsigned char *operation_state, + unsigned long operation_state_len, + ck_object_handle_t encryption_key, + ck_object_handle_t authentiation_key)); +_CK_DECLARE_FUNCTION (C_Login, + (ck_session_handle_t session, ck_user_type_t user_type, + unsigned char *pin, unsigned long pin_len)); +_CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_CreateObject, + (ck_session_handle_t session, + struct ck_attribute *templ, + unsigned long count, ck_object_handle_t *object)); +_CK_DECLARE_FUNCTION (C_CopyObject, + (ck_session_handle_t session, ck_object_handle_t object, + struct ck_attribute *templ, unsigned long count, + ck_object_handle_t *new_object)); +_CK_DECLARE_FUNCTION (C_DestroyObject, + (ck_session_handle_t session, + ck_object_handle_t object)); +_CK_DECLARE_FUNCTION (C_GetObjectSize, + (ck_session_handle_t session, + ck_object_handle_t object, + unsigned long *size)); +_CK_DECLARE_FUNCTION (C_GetAttributeValue, + (ck_session_handle_t session, + ck_object_handle_t object, + struct ck_attribute *templ, + unsigned long count)); +_CK_DECLARE_FUNCTION (C_SetAttributeValue, + (ck_session_handle_t session, + ck_object_handle_t object, + struct ck_attribute *templ, + unsigned long count)); +_CK_DECLARE_FUNCTION (C_FindObjectsInit, + (ck_session_handle_t session, + struct ck_attribute *templ, + unsigned long count)); +_CK_DECLARE_FUNCTION (C_FindObjects, + (ck_session_handle_t session, + ck_object_handle_t *object, + unsigned long max_object_count, + unsigned long *object_count)); +_CK_DECLARE_FUNCTION (C_FindObjectsFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_EncryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Encrypt, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *encrypted_data, + unsigned long *encrypted_data_len)); +_CK_DECLARE_FUNCTION (C_EncryptUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len, + unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION (C_EncryptFinal, + (ck_session_handle_t session, + unsigned char *last_encrypted_part, + unsigned long *last_encrypted_part_len)); + +_CK_DECLARE_FUNCTION (C_DecryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Decrypt, + (ck_session_handle_t session, + unsigned char *encrypted_data, + unsigned long encrypted_data_len, + unsigned char *data, unsigned long *data_len)); +_CK_DECLARE_FUNCTION (C_DecryptUpdate, + (ck_session_handle_t session, + unsigned char *encrypted_part, + unsigned long encrypted_part_len, + unsigned char *part, unsigned long *part_len)); +_CK_DECLARE_FUNCTION (C_DecryptFinal, + (ck_session_handle_t session, + unsigned char *last_part, + unsigned long *last_part_len)); + +_CK_DECLARE_FUNCTION (C_DigestInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism)); +_CK_DECLARE_FUNCTION (C_Digest, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *digest, + unsigned long *digest_len)); +_CK_DECLARE_FUNCTION (C_DigestUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len)); +_CK_DECLARE_FUNCTION (C_DigestKey, + (ck_session_handle_t session, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_DigestFinal, + (ck_session_handle_t session, + unsigned char *digest, + unsigned long *digest_len)); + +_CK_DECLARE_FUNCTION (C_SignInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Sign, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_SignUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len)); +_CK_DECLARE_FUNCTION (C_SignFinal, + (ck_session_handle_t session, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_SignRecoverInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_SignRecover, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); + +_CK_DECLARE_FUNCTION (C_VerifyInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Verify, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_VerifyUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len)); +_CK_DECLARE_FUNCTION (C_VerifyFinal, + (ck_session_handle_t session, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_VerifyRecoverInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_VerifyRecover, + (ck_session_handle_t session, + unsigned char *signature, + unsigned long signature_len, + unsigned char *data, + unsigned long *data_len)); + +_CK_DECLARE_FUNCTION (C_DigestEncryptUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len, + unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION (C_DecryptDigestUpdate, + (ck_session_handle_t session, + unsigned char *encrypted_part, + unsigned long encrypted_part_len, + unsigned char *part, + unsigned long *part_len)); +_CK_DECLARE_FUNCTION (C_SignEncryptUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len, + unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate, + (ck_session_handle_t session, + unsigned char *encrypted_part, + unsigned long encrypted_part_len, + unsigned char *part, + unsigned long *part_len)); + +_CK_DECLARE_FUNCTION (C_GenerateKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + struct ck_attribute *templ, + unsigned long count, + ck_object_handle_t *key)); +_CK_DECLARE_FUNCTION (C_GenerateKeyPair, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + struct ck_attribute *public_key_template, + unsigned long public_key_attribute_count, + struct ck_attribute *private_key_template, + unsigned long private_key_attribute_count, + ck_object_handle_t *public_key, + ck_object_handle_t *private_key)); +_CK_DECLARE_FUNCTION (C_WrapKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t wrapping_key, + ck_object_handle_t key, + unsigned char *wrapped_key, + unsigned long *wrapped_key_len)); +_CK_DECLARE_FUNCTION (C_UnwrapKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t unwrapping_key, + unsigned char *wrapped_key, + unsigned long wrapped_key_len, + struct ck_attribute *templ, + unsigned long attribute_count, + ck_object_handle_t *key)); +_CK_DECLARE_FUNCTION (C_DeriveKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t base_key, + struct ck_attribute *templ, + unsigned long attribute_count, + ck_object_handle_t *key)); + +_CK_DECLARE_FUNCTION (C_SeedRandom, + (ck_session_handle_t session, unsigned char *seed, + unsigned long seed_len)); +_CK_DECLARE_FUNCTION (C_GenerateRandom, + (ck_session_handle_t session, + unsigned char *random_data, + unsigned long random_len)); + +_CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); + + +struct ck_function_list +{ + struct ck_version version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; +}; + + +typedef ck_rv_t (*ck_createmutex_t) (void **mutex); +typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); +typedef ck_rv_t (*ck_lockmutex_t) (void *mutex); +typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex); + + +struct ck_c_initialize_args +{ + ck_createmutex_t create_mutex; + ck_destroymutex_t destroy_mutex; + ck_lockmutex_t lock_mutex; + ck_unlockmutex_t unlock_mutex; + ck_flags_t flags; + void *reserved; +}; + + +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0) +#define CKF_OS_LOCKING_OK (1 << 1) + +#define CKR_OK (0) +#define CKR_CANCEL (1) +#define CKR_HOST_MEMORY (2) +#define CKR_SLOT_ID_INVALID (3) +#define CKR_GENERAL_ERROR (5) +#define CKR_FUNCTION_FAILED (6) +#define CKR_ARGUMENTS_BAD (7) +#define CKR_NO_EVENT (8) +#define CKR_NEED_TO_CREATE_THREADS (9) +#define CKR_CANT_LOCK (0xa) +#define CKR_ATTRIBUTE_READ_ONLY (0x10) +#define CKR_ATTRIBUTE_SENSITIVE (0x11) +#define CKR_ATTRIBUTE_TYPE_INVALID (0x12) +#define CKR_ATTRIBUTE_VALUE_INVALID (0x13) +#define CKR_DATA_INVALID (0x20) +#define CKR_DATA_LEN_RANGE (0x21) +#define CKR_DEVICE_ERROR (0x30) +#define CKR_DEVICE_MEMORY (0x31) +#define CKR_DEVICE_REMOVED (0x32) +#define CKR_ENCRYPTED_DATA_INVALID (0x40) +#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41) +#define CKR_FUNCTION_CANCELED (0x50) +#define CKR_FUNCTION_NOT_PARALLEL (0x51) +#define CKR_FUNCTION_NOT_SUPPORTED (0x54) +#define CKR_KEY_HANDLE_INVALID (0x60) +#define CKR_KEY_SIZE_RANGE (0x62) +#define CKR_KEY_TYPE_INCONSISTENT (0x63) +#define CKR_KEY_NOT_NEEDED (0x64) +#define CKR_KEY_CHANGED (0x65) +#define CKR_KEY_NEEDED (0x66) +#define CKR_KEY_INDIGESTIBLE (0x67) +#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68) +#define CKR_KEY_NOT_WRAPPABLE (0x69) +#define CKR_KEY_UNEXTRACTABLE (0x6a) +#define CKR_MECHANISM_INVALID (0x70) +#define CKR_MECHANISM_PARAM_INVALID (0x71) +#define CKR_OBJECT_HANDLE_INVALID (0x82) +#define CKR_OPERATION_ACTIVE (0x90) +#define CKR_OPERATION_NOT_INITIALIZED (0x91) +#define CKR_PIN_INCORRECT (0xa0) +#define CKR_PIN_INVALID (0xa1) +#define CKR_PIN_LEN_RANGE (0xa2) +#define CKR_PIN_EXPIRED (0xa3) +#define CKR_PIN_LOCKED (0xa4) +#define CKR_SESSION_CLOSED (0xb0) +#define CKR_SESSION_COUNT (0xb1) +#define CKR_SESSION_HANDLE_INVALID (0xb3) +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4) +#define CKR_SESSION_READ_ONLY (0xb5) +#define CKR_SESSION_EXISTS (0xb6) +#define CKR_SESSION_READ_ONLY_EXISTS (0xb7) +#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8) +#define CKR_SIGNATURE_INVALID (0xc0) +#define CKR_SIGNATURE_LEN_RANGE (0xc1) +#define CKR_TEMPLATE_INCOMPLETE (0xd0) +#define CKR_TEMPLATE_INCONSISTENT (0xd1) +#define CKR_TOKEN_NOT_PRESENT (0xe0) +#define CKR_TOKEN_NOT_RECOGNIZED (0xe1) +#define CKR_TOKEN_WRITE_PROTECTED (0xe2) +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0) +#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1) +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2) +#define CKR_USER_ALREADY_LOGGED_IN (0x100) +#define CKR_USER_NOT_LOGGED_IN (0x101) +#define CKR_USER_PIN_NOT_INITIALIZED (0x102) +#define CKR_USER_TYPE_INVALID (0x103) +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104) +#define CKR_USER_TOO_MANY_TYPES (0x105) +#define CKR_WRAPPED_KEY_INVALID (0x110) +#define CKR_WRAPPED_KEY_LEN_RANGE (0x112) +#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113) +#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114) +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115) +#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120) +#define CKR_RANDOM_NO_RNG (0x121) +#define CKR_DOMAIN_PARAMS_INVALID (0x130) +#define CKR_BUFFER_TOO_SMALL (0x150) +#define CKR_SAVED_STATE_INVALID (0x160) +#define CKR_INFORMATION_SENSITIVE (0x170) +#define CKR_STATE_UNSAVEABLE (0x180) +#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190) +#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191) +#define CKR_MUTEX_BAD (0x1a0) +#define CKR_MUTEX_NOT_LOCKED (0x1a1) +#define CKR_FUNCTION_REJECTED (0x200) +#define CKR_VENDOR_DEFINED ((unsigned long) (1 << 31)) + + + +/* Compatibility layer. */ + +#ifdef CRYPTOKI_COMPAT + +#undef CK_DEFINE_FUNCTION +#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name + +/* For NULL. */ +#include + +typedef unsigned char CK_BYTE; +typedef unsigned char CK_CHAR; +typedef unsigned char CK_UTF8CHAR; +typedef unsigned char CK_BBOOL; +typedef unsigned long int CK_ULONG; +typedef long int CK_LONG; +typedef CK_BYTE *CK_BYTE_PTR; +typedef CK_CHAR *CK_CHAR_PTR; +typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR; +typedef CK_ULONG *CK_ULONG_PTR; +typedef void *CK_VOID_PTR; +typedef void **CK_VOID_PTR_PTR; +#define CK_FALSE 0 +#define CK_TRUE 1 +#ifndef CK_DISABLE_TRUE_FALSE +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#endif + +typedef struct ck_version CK_VERSION; +typedef struct ck_version *CK_VERSION_PTR; + +typedef struct ck_info CK_INFO; +typedef struct ck_info *CK_INFO_PTR; + +typedef ck_slot_id_t *CK_SLOT_ID_PTR; + +typedef struct ck_slot_info CK_SLOT_INFO; +typedef struct ck_slot_info *CK_SLOT_INFO_PTR; + +typedef struct ck_token_info CK_TOKEN_INFO; +typedef struct ck_token_info *CK_TOKEN_INFO_PTR; + +typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; + +typedef struct ck_session_info CK_SESSION_INFO; +typedef struct ck_session_info *CK_SESSION_INFO_PTR; + +typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; + +typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; + +typedef struct ck_attribute CK_ATTRIBUTE; +typedef struct ck_attribute *CK_ATTRIBUTE_PTR; + +typedef struct ck_date CK_DATE; +typedef struct ck_date *CK_DATE_PTR; + +typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; + +typedef struct ck_mechanism CK_MECHANISM; +typedef struct ck_mechanism *CK_MECHANISM_PTR; + +typedef struct ck_mechanism_info CK_MECHANISM_INFO; +typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; + +typedef struct ck_function_list CK_FUNCTION_LIST; +typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; +typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; + +typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; +typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; + +#define NULL_PTR NULL + +/* Delete the helper macros defined at the top of the file. */ +#undef ck_flags_t +#undef ck_version + +#undef ck_info +#undef cryptoki_version +#undef manufacturer_id +#undef library_description +#undef library_version + +#undef ck_notification_t +#undef ck_slot_id_t + +#undef ck_slot_info +#undef slot_description +#undef hardware_version +#undef firmware_version + +#undef ck_token_info +#undef serial_number +#undef max_session_count +#undef session_count +#undef max_rw_session_count +#undef rw_session_count +#undef max_pin_len +#undef min_pin_len +#undef total_public_memory +#undef free_public_memory +#undef total_private_memory +#undef free_private_memory +#undef utc_time + +#undef ck_session_handle_t +#undef ck_user_type_t +#undef ck_state_t + +#undef ck_session_info +#undef slot_id +#undef device_error + +#undef ck_object_handle_t +#undef ck_object_class_t +#undef ck_hw_feature_type_t +#undef ck_key_type_t +#undef ck_certificate_type_t +#undef ck_attribute_type_t + +#undef ck_attribute +#undef value +#undef value_len + +#undef ck_date + +#undef ck_mechanism_type_t + +#undef ck_mechanism +#undef parameter +#undef parameter_len + +#undef ck_mechanism_info +#undef min_key_size +#undef max_key_size + +#undef ck_rv_t +#undef ck_notify_t + +#undef ck_function_list + +#undef ck_createmutex_t +#undef ck_destroymutex_t +#undef ck_lockmutex_t +#undef ck_unlockmutex_t + +#undef ck_c_initialize_args +#undef create_mutex +#undef destroy_mutex +#undef lock_mutex +#undef unlock_mutex +#undef reserved + +#endif /* CRYPTOKI_COMPAT */ + + +/* System dependencies. */ +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) +#pragma pack(pop, cryptoki) +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* PKCS11_H */ diff --git a/scard-opensc.c b/scard-opensc.c deleted file mode 100644 index 36dae05fd..000000000 --- a/scard-opensc.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2002 Juha Yrjölä. All rights reserved. - * Copyright (c) 2001 Markus Friedl. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -#if defined(SMARTCARD) && defined(USE_OPENSC) - -#include - -#include -#include - -#include -#include - -#include -#include - -#include "key.h" -#include "log.h" -#include "xmalloc.h" -#include "misc.h" -#include "scard.h" - -#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE) -#define USE_ENGINE -#define RSA_get_default_method RSA_get_default_openssl_method -#else -#endif - -#ifdef USE_ENGINE -#include -#define sc_get_rsa sc_get_engine -#else -#define sc_get_rsa sc_get_rsa_method -#endif - -static int sc_reader_id; -static sc_context_t *ctx = NULL; -static sc_card_t *card = NULL; -static sc_pkcs15_card_t *p15card = NULL; - -static char *sc_pin = NULL; - -struct sc_priv_data -{ - struct sc_pkcs15_id cert_id; - int ref_count; -}; - -void -sc_close(void) -{ - if (p15card) { - sc_pkcs15_unbind(p15card); - p15card = NULL; - } - if (card) { - sc_disconnect_card(card, 0); - card = NULL; - } - if (ctx) { - sc_release_context(ctx); - ctx = NULL; - } -} - -static int -sc_init(void) -{ - int r; - - r = sc_establish_context(&ctx, "openssh"); - if (r) - goto err; - if (sc_reader_id >= ctx->reader_count) { - r = SC_ERROR_NO_READERS_FOUND; - error("Illegal reader number %d (max %d)", sc_reader_id, - ctx->reader_count -1); - goto err; - } - r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card); - if (r) - goto err; - r = sc_pkcs15_bind(card, &p15card); - if (r) - goto err; - return 0; -err: - sc_close(); - return r; -} - -/* private key operations */ - -static int -sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out, - unsigned int usage) -{ - int r; - struct sc_priv_data *priv; - struct sc_pkcs15_object *key_obj; - struct sc_pkcs15_prkey_info *key; - struct sc_pkcs15_object *pin_obj; - struct sc_pkcs15_pin_info *pin; - - priv = (struct sc_priv_data *) RSA_get_app_data(rsa); - if (priv == NULL) - return -1; - if (p15card == NULL) { - sc_close(); - r = sc_init(); - if (r) { - error("SmartCard init failed: %s", sc_strerror(r)); - goto err; - } - } - r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id, - usage, &key_obj); - if (r) { - error("Unable to find private key from SmartCard: %s", - sc_strerror(r)); - goto err; - } - key = key_obj->data; - r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, - &pin_obj); - if (r == SC_ERROR_OBJECT_NOT_FOUND) { - /* no pin required */ - r = sc_lock(card); - if (r) { - error("Unable to lock smartcard: %s", sc_strerror(r)); - goto err; - } - *key_obj_out = key_obj; - return 0; - } else if (r) { - error("Unable to find PIN object from SmartCard: %s", - sc_strerror(r)); - goto err; - } - pin = pin_obj->data; - r = sc_lock(card); - if (r) { - error("Unable to lock smartcard: %s", sc_strerror(r)); - goto err; - } - if (sc_pin != NULL) { - r = sc_pkcs15_verify_pin(p15card, pin, sc_pin, - strlen(sc_pin)); - if (r) { - sc_unlock(card); - error("PIN code verification failed: %s", - sc_strerror(r)); - goto err; - } - } - *key_obj_out = key_obj; - return 0; -err: - sc_close(); - return -1; -} - -#define SC_USAGE_DECRYPT SC_PKCS15_PRKEY_USAGE_DECRYPT | \ - SC_PKCS15_PRKEY_USAGE_UNWRAP - -static int -sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - struct sc_pkcs15_object *key_obj; - int r; - - if (padding != RSA_PKCS1_PADDING) - return -1; - r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT); - if (r) - return -1; - r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1, - from, flen, to, flen); - sc_unlock(card); - if (r < 0) { - error("sc_pkcs15_decipher() failed: %s", sc_strerror(r)); - goto err; - } - return r; -err: - sc_close(); - return -1; -} - -#define SC_USAGE_SIGN SC_PKCS15_PRKEY_USAGE_SIGN | \ - SC_PKCS15_PRKEY_USAGE_SIGNRECOVER - -static int -sc_sign(int type, u_char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, RSA *rsa) -{ - struct sc_pkcs15_object *key_obj; - int r; - unsigned long flags = 0; - - /* XXX: sc_prkey_op_init will search for a pkcs15 private - * key object with the sign or signrecover usage flag set. - * If the signing key has only the non-repudiation flag set - * the key will be rejected as using a non-repudiation key - * for authentication is not recommended. Note: This does not - * prevent the use of a non-repudiation key for authentication - * if the sign or signrecover flag is set as well. - */ - r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN); - if (r) - return -1; - /* FIXME: length of sigret correct? */ - /* FIXME: check 'type' and modify flags accordingly */ - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; - r = sc_pkcs15_compute_signature(p15card, key_obj, flags, - m, m_len, sigret, RSA_size(rsa)); - sc_unlock(card); - if (r < 0) { - error("sc_pkcs15_compute_signature() failed: %s", - sc_strerror(r)); - goto err; - } - *siglen = r; - return 1; -err: - sc_close(); - return 0; -} - -static int -sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - error("Private key encryption not supported"); - return -1; -} - -/* called on free */ - -static int (*orig_finish)(RSA *rsa) = NULL; - -static int -sc_finish(RSA *rsa) -{ - struct sc_priv_data *priv; - - priv = RSA_get_app_data(rsa); - priv->ref_count--; - if (priv->ref_count == 0) { - free(priv); - sc_close(); - } - if (orig_finish) - orig_finish(rsa); - return 1; -} - -/* engine for overloading private key operations */ - -static RSA_METHOD * -sc_get_rsa_method(void) -{ - static RSA_METHOD smart_rsa; - const RSA_METHOD *def = RSA_get_default_method(); - - /* use the OpenSSL version */ - memcpy(&smart_rsa, def, sizeof(smart_rsa)); - - smart_rsa.name = "opensc"; - - /* overload */ - smart_rsa.rsa_priv_enc = sc_private_encrypt; - smart_rsa.rsa_priv_dec = sc_private_decrypt; - smart_rsa.rsa_sign = sc_sign; - - /* save original */ - orig_finish = def->finish; - smart_rsa.finish = sc_finish; - - return &smart_rsa; -} - -#ifdef USE_ENGINE -static ENGINE * -sc_get_engine(void) -{ - static ENGINE *smart_engine = NULL; - - if ((smart_engine = ENGINE_new()) == NULL) - fatal("ENGINE_new failed"); - - ENGINE_set_id(smart_engine, "opensc"); - ENGINE_set_name(smart_engine, "OpenSC"); - - ENGINE_set_RSA(smart_engine, sc_get_rsa_method()); - ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method()); - ENGINE_set_DH(smart_engine, DH_get_default_openssl_method()); - ENGINE_set_RAND(smart_engine, RAND_SSLeay()); - ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp); - - return smart_engine; -} -#endif - -static void -convert_rsa_to_rsa1(Key * in, Key * out) -{ - struct sc_priv_data *priv; - - out->rsa->flags = in->rsa->flags; - out->flags = in->flags; - RSA_set_method(out->rsa, RSA_get_method(in->rsa)); - BN_copy(out->rsa->n, in->rsa->n); - BN_copy(out->rsa->e, in->rsa->e); - priv = RSA_get_app_data(in->rsa); - priv->ref_count++; - RSA_set_app_data(out->rsa, priv); - return; -} - -static int -sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) -{ - int r; - sc_pkcs15_cert_t *cert = NULL; - struct sc_priv_data *priv = NULL; - sc_pkcs15_cert_info_t *cinfo = cert_obj->data; - - X509 *x509 = NULL; - EVP_PKEY *pubkey = NULL; - u8 *p; - char *tmp; - - debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]); - r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); - if (r) { - logit("Certificate read failed: %s", sc_strerror(r)); - goto err; - } - x509 = X509_new(); - if (x509 == NULL) { - r = -1; - goto err; - } - p = cert->data; - if (!d2i_X509(&x509, &p, cert->data_len)) { - logit("Unable to parse X.509 certificate"); - r = -1; - goto err; - } - sc_pkcs15_free_certificate(cert); - cert = NULL; - pubkey = X509_get_pubkey(x509); - X509_free(x509); - x509 = NULL; - if (pubkey->type != EVP_PKEY_RSA) { - logit("Public key is of unknown type"); - r = -1; - goto err; - } - k->rsa = EVP_PKEY_get1_RSA(pubkey); - EVP_PKEY_free(pubkey); - - k->rsa->flags |= RSA_FLAG_SIGN_VER; - RSA_set_method(k->rsa, sc_get_rsa_method()); - priv = xmalloc(sizeof(struct sc_priv_data)); - priv->cert_id = cinfo->id; - priv->ref_count = 1; - RSA_set_app_data(k->rsa, priv); - - k->flags = KEY_FLAG_EXT; - tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX); - debug("fingerprint %d %s", key_size(k), tmp); - xfree(tmp); - - return 0; -err: - if (cert) - sc_pkcs15_free_certificate(cert); - if (pubkey) - EVP_PKEY_free(pubkey); - if (x509) - X509_free(x509); - return r; -} - -Key ** -sc_get_keys(const char *id, const char *pin) -{ - Key *k, **keys; - int i, r, real_count = 0, key_count; - sc_pkcs15_id_t cert_id; - sc_pkcs15_object_t *certs[32]; - char *buf = xstrdup(id), *p; - - debug("sc_get_keys called: id = %s", id); - - if (sc_pin != NULL) - xfree(sc_pin); - sc_pin = (pin == NULL) ? NULL : xstrdup(pin); - - cert_id.len = 0; - if ((p = strchr(buf, ':')) != NULL) { - *p = 0; - p++; - sc_pkcs15_hex_string_to_id(p, &cert_id); - } - r = sscanf(buf, "%d", &sc_reader_id); - xfree(buf); - if (r != 1) - goto err; - if (p15card == NULL) { - sc_close(); - r = sc_init(); - if (r) { - error("Smartcard init failed: %s", sc_strerror(r)); - goto err; - } - } - if (cert_id.len) { - r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]); - if (r < 0) - goto err; - key_count = 1; - } else { - r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, - certs, 32); - if (r == 0) { - logit("No certificates found on smartcard"); - r = -1; - goto err; - } else if (r < 0) { - error("Certificate enumeration failed: %s", - sc_strerror(r)); - goto err; - } - key_count = r; - } - if (key_count > 1024) - fatal("Too many keys (%u), expected <= 1024", key_count); - keys = xcalloc(key_count * 2 + 1, sizeof(Key *)); - for (i = 0; i < key_count; i++) { - sc_pkcs15_object_t *tmp_obj = NULL; - cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id; - if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj)) - /* skip the public key (certificate) if no - * corresponding private key is present */ - continue; - k = key_new(KEY_RSA); - if (k == NULL) - break; - r = sc_read_pubkey(k, certs[i]); - if (r) { - error("sc_read_pubkey failed: %s", sc_strerror(r)); - key_free(k); - continue; - } - keys[real_count] = k; - real_count++; - k = key_new(KEY_RSA1); - if (k == NULL) - break; - convert_rsa_to_rsa1(keys[real_count-1], k); - keys[real_count] = k; - real_count++; - } - keys[real_count] = NULL; - - return keys; -err: - sc_close(); - return NULL; -} - -int -sc_put_key(Key *prv, const char *id) -{ - error("key uploading not yet supported"); - return -1; -} - -char * -sc_get_key_label(Key *key) -{ - int r; - const struct sc_priv_data *priv; - struct sc_pkcs15_object *key_obj; - - priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa); - if (priv == NULL || p15card == NULL) { - logit("SmartCard key not loaded"); - /* internal error => return default label */ - return xstrdup("smartcard key"); - } - r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj); - if (r) { - logit("Unable to find private key from SmartCard: %s", - sc_strerror(r)); - return xstrdup("smartcard key"); - } - if (key_obj == NULL || key_obj->label == NULL) - /* the optional PKCS#15 label does not exists - * => return the default label */ - return xstrdup("smartcard key"); - return xstrdup(key_obj->label); -} - -#endif /* SMARTCARD */ diff --git a/scard.c b/scard.c deleted file mode 100644 index 9fd3ca1b4..000000000 --- a/scard.c +++ /dev/null @@ -1,571 +0,0 @@ -/* $OpenBSD: scard.c,v 1.36 2006/11/06 21:25:28 markus Exp $ */ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -#if defined(SMARTCARD) && defined(USE_SECTOK) - -#include - -#include -#include -#include - -#include - -#include "xmalloc.h" -#include "key.h" -#include "log.h" -#include "misc.h" -#include "scard.h" - -#if OPENSSL_VERSION_NUMBER < 0x00907000L -#define USE_ENGINE -#define RSA_get_default_method RSA_get_default_openssl_method -#else -#endif - -#ifdef USE_ENGINE -#include -#define sc_get_rsa sc_get_engine -#else -#define sc_get_rsa sc_get_rsa_method -#endif - -#define CLA_SSH 0x05 -#define INS_DECRYPT 0x10 -#define INS_GET_KEYLENGTH 0x20 -#define INS_GET_PUBKEY 0x30 -#define INS_GET_RESPONSE 0xc0 - -#define MAX_BUF_SIZE 256 - -u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63}; - -static int sc_fd = -1; -static char *sc_reader_id = NULL; -static char *sc_pin = NULL; -static int cla = 0x00; /* class */ - -static void sc_mk_digest(const char *pin, u_char *digest); -static int get_AUT0(u_char *aut0); -static int try_AUT0(void); - -/* interface to libsectok */ - -static int -sc_open(void) -{ - int sw; - - if (sc_fd >= 0) - return sc_fd; - - sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw); - if (sc_fd < 0) { - error("sectok_open failed: %s", sectok_get_sw(sw)); - return SCARD_ERROR_FAIL; - } - if (! sectok_cardpresent(sc_fd)) { - debug("smartcard in reader %s not present, skipping", - sc_reader_id); - sc_close(); - return SCARD_ERROR_NOCARD; - } - if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) { - error("sectok_reset failed: %s", sectok_get_sw(sw)); - sc_fd = -1; - return SCARD_ERROR_FAIL; - } - if ((cla = cyberflex_inq_class(sc_fd)) < 0) - cla = 0; - - debug("sc_open ok %d", sc_fd); - return sc_fd; -} - -static int -sc_enable_applet(void) -{ - static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e}; - int sw = 0; - - /* select applet id */ - sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw); - if (!sectok_swOK(sw)) { - error("sectok_apdu failed: %s", sectok_get_sw(sw)); - sc_close(); - return -1; - } - return 0; -} - -static int -sc_init(void) -{ - int status; - - status = sc_open(); - if (status == SCARD_ERROR_NOCARD) { - return SCARD_ERROR_NOCARD; - } - if (status < 0) { - error("sc_open failed"); - return status; - } - if (sc_enable_applet() < 0) { - error("sc_enable_applet failed"); - return SCARD_ERROR_APPLET; - } - return 0; -} - -static int -sc_read_pubkey(Key * k) -{ - u_char buf[2], *n; - char *p; - int len, sw, status = -1; - - len = sw = 0; - n = NULL; - - if (sc_fd < 0) { - if (sc_init() < 0) - goto err; - } - - /* get key size */ - sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL, - sizeof(buf), buf, &sw); - if (!sectok_swOK(sw)) { - error("could not obtain key length: %s", sectok_get_sw(sw)); - goto err; - } - len = (buf[0] << 8) | buf[1]; - len /= 8; - debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw)); - - n = xmalloc(len); - /* get n */ - sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw); - - if (sw == 0x6982) { - if (try_AUT0() < 0) - goto err; - sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw); - } - if (!sectok_swOK(sw)) { - error("could not obtain public key: %s", sectok_get_sw(sw)); - goto err; - } - - debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw)); - - if (BN_bin2bn(n, len, k->rsa->n) == NULL) { - error("c_read_pubkey: BN_bin2bn failed"); - goto err; - } - - /* currently the java applet just stores 'n' */ - if (!BN_set_word(k->rsa->e, 35)) { - error("c_read_pubkey: BN_set_word(e, 35) failed"); - goto err; - } - - status = 0; - p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX); - debug("fingerprint %u %s", key_size(k), p); - xfree(p); - -err: - if (n != NULL) - xfree(n); - sc_close(); - return status; -} - -/* private key operations */ - -static int -sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - u_char *padded = NULL; - int sw, len, olen, status = -1; - - debug("sc_private_decrypt called"); - - olen = len = sw = 0; - if (sc_fd < 0) { - status = sc_init(); - if (status < 0) - goto err; - } - if (padding != RSA_PKCS1_PADDING) - goto err; - - len = BN_num_bytes(rsa->n); - padded = xmalloc(len); - - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw); - - if (sw == 0x6982) { - if (try_AUT0() < 0) - goto err; - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw); - } - if (!sectok_swOK(sw)) { - error("sc_private_decrypt: INS_DECRYPT failed: %s", - sectok_get_sw(sw)); - goto err; - } - olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1, - len); -err: - if (padded) - xfree(padded); - sc_close(); - return (olen >= 0 ? olen : status); -} - -static int -sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, - int padding) -{ - u_char *padded = NULL; - int sw, len, status = -1; - - len = sw = 0; - if (sc_fd < 0) { - status = sc_init(); - if (status < 0) - goto err; - } - if (padding != RSA_PKCS1_PADDING) - goto err; - - debug("sc_private_encrypt called"); - len = BN_num_bytes(rsa->n); - padded = xmalloc(len); - - if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) { - error("RSA_padding_add_PKCS1_type_1 failed"); - goto err; - } - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw); - if (sw == 0x6982) { - if (try_AUT0() < 0) - goto err; - sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw); - } - if (!sectok_swOK(sw)) { - error("sc_private_encrypt: INS_DECRYPT failed: %s", - sectok_get_sw(sw)); - goto err; - } -err: - if (padded) - xfree(padded); - sc_close(); - return (len >= 0 ? len : status); -} - -/* called on free */ - -static int (*orig_finish)(RSA *rsa) = NULL; - -static int -sc_finish(RSA *rsa) -{ - if (orig_finish) - orig_finish(rsa); - sc_close(); - return 1; -} - -/* engine for overloading private key operations */ - -static RSA_METHOD * -sc_get_rsa_method(void) -{ - static RSA_METHOD smart_rsa; - const RSA_METHOD *def = RSA_get_default_method(); - - /* use the OpenSSL version */ - memcpy(&smart_rsa, def, sizeof(smart_rsa)); - - smart_rsa.name = "sectok"; - - /* overload */ - smart_rsa.rsa_priv_enc = sc_private_encrypt; - smart_rsa.rsa_priv_dec = sc_private_decrypt; - - /* save original */ - orig_finish = def->finish; - smart_rsa.finish = sc_finish; - - return &smart_rsa; -} - -#ifdef USE_ENGINE -static ENGINE * -sc_get_engine(void) -{ - static ENGINE *smart_engine = NULL; - - if ((smart_engine = ENGINE_new()) == NULL) - fatal("ENGINE_new failed"); - - ENGINE_set_id(smart_engine, "sectok"); - ENGINE_set_name(smart_engine, "libsectok"); - - ENGINE_set_RSA(smart_engine, sc_get_rsa_method()); - ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method()); - ENGINE_set_DH(smart_engine, DH_get_default_openssl_method()); - ENGINE_set_RAND(smart_engine, RAND_SSLeay()); - ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp); - - return smart_engine; -} -#endif - -void -sc_close(void) -{ - if (sc_fd >= 0) { - sectok_close(sc_fd); - sc_fd = -1; - } -} - -Key ** -sc_get_keys(const char *id, const char *pin) -{ - Key *k, *n, **keys; - int status, nkeys = 2; - - if (sc_reader_id != NULL) - xfree(sc_reader_id); - sc_reader_id = xstrdup(id); - - if (sc_pin != NULL) - xfree(sc_pin); - sc_pin = (pin == NULL) ? NULL : xstrdup(pin); - - k = key_new(KEY_RSA); - if (k == NULL) { - return NULL; - } - status = sc_read_pubkey(k); - if (status == SCARD_ERROR_NOCARD) { - key_free(k); - return NULL; - } - if (status < 0) { - error("sc_read_pubkey failed"); - key_free(k); - return NULL; - } - keys = xcalloc((nkeys+1), sizeof(Key *)); - - n = key_new(KEY_RSA1); - if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || - (BN_copy(n->rsa->e, k->rsa->e) == NULL)) - fatal("sc_get_keys: BN_copy failed"); - RSA_set_method(n->rsa, sc_get_rsa()); - n->flags |= KEY_FLAG_EXT; - keys[0] = n; - - n = key_new(KEY_RSA); - if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || - (BN_copy(n->rsa->e, k->rsa->e) == NULL)) - fatal("sc_get_keys: BN_copy failed"); - RSA_set_method(n->rsa, sc_get_rsa()); - n->flags |= KEY_FLAG_EXT; - keys[1] = n; - - keys[2] = NULL; - - key_free(k); - return keys; -} - -#define NUM_RSA_KEY_ELEMENTS 5+1 -#define COPY_RSA_KEY(x, i) \ - do { \ - len = BN_num_bytes(prv->rsa->x); \ - elements[i] = xmalloc(len); \ - debug("#bytes %d", len); \ - if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \ - goto done; \ - } while (0) - -static void -sc_mk_digest(const char *pin, u_char *digest) -{ - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, pin, strlen(pin)); - EVP_DigestFinal(&md, digest, NULL); -} - -static int -get_AUT0(u_char *aut0) -{ - char *pass; - - pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN); - if (pass == NULL) - return -1; - if (!strcmp(pass, "-")) { - memcpy(aut0, DEFAUT0, sizeof DEFAUT0); - return 0; - } - sc_mk_digest(pass, aut0); - memset(pass, 0, strlen(pass)); - xfree(pass); - return 0; -} - -static int -try_AUT0(void) -{ - u_char aut0[EVP_MAX_MD_SIZE]; - - /* permission denied; try PIN if provided */ - if (sc_pin && strlen(sc_pin) > 0) { - sc_mk_digest(sc_pin, aut0); - if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) { - error("smartcard passphrase incorrect"); - return (-1); - } - } else { - /* try default AUT0 key */ - if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) { - /* default AUT0 key failed; prompt for passphrase */ - if (get_AUT0(aut0) < 0 || - cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) { - error("smartcard passphrase incorrect"); - return (-1); - } - } - } - return (0); -} - -int -sc_put_key(Key *prv, const char *id) -{ - u_char *elements[NUM_RSA_KEY_ELEMENTS]; - u_char key_fid[2]; - u_char AUT0[EVP_MAX_MD_SIZE]; - int len, status = -1, i, fd = -1, ret; - int sw = 0, cla = 0x00; - - for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) - elements[i] = NULL; - - COPY_RSA_KEY(q, 0); - COPY_RSA_KEY(p, 1); - COPY_RSA_KEY(iqmp, 2); - COPY_RSA_KEY(dmq1, 3); - COPY_RSA_KEY(dmp1, 4); - COPY_RSA_KEY(n, 5); - len = BN_num_bytes(prv->rsa->n); - fd = sectok_friendly_open(id, STONOWAIT, &sw); - if (fd < 0) { - error("sectok_open failed: %s", sectok_get_sw(sw)); - goto done; - } - if (! sectok_cardpresent(fd)) { - error("smartcard in reader %s not present", id); - goto done; - } - ret = sectok_reset(fd, 0, NULL, &sw); - if (ret <= 0) { - error("sectok_reset failed: %s", sectok_get_sw(sw)); - goto done; - } - if ((cla = cyberflex_inq_class(fd)) < 0) { - error("cyberflex_inq_class failed"); - goto done; - } - memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0)); - if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { - if (get_AUT0(AUT0) < 0 || - cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { - memset(AUT0, 0, sizeof(DEFAUT0)); - error("smartcard passphrase incorrect"); - goto done; - } - } - memset(AUT0, 0, sizeof(DEFAUT0)); - key_fid[0] = 0x00; - key_fid[1] = 0x12; - if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements, - &sw) < 0) { - error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw)); - goto done; - } - if (!sectok_swOK(sw)) - goto done; - logit("cyberflex_load_rsa_priv done"); - key_fid[0] = 0x73; - key_fid[1] = 0x68; - if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5], - &sw) < 0) { - error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw)); - goto done; - } - if (!sectok_swOK(sw)) - goto done; - logit("cyberflex_load_rsa_pub done"); - status = 0; - -done: - memset(elements[0], '\0', BN_num_bytes(prv->rsa->q)); - memset(elements[1], '\0', BN_num_bytes(prv->rsa->p)); - memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp)); - memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1)); - memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1)); - memset(elements[5], '\0', BN_num_bytes(prv->rsa->n)); - - for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) - if (elements[i]) - xfree(elements[i]); - if (fd != -1) - sectok_close(fd); - return (status); -} - -char * -sc_get_key_label(Key *key) -{ - return xstrdup("smartcard key"); -} - -#endif /* SMARTCARD && USE_SECTOK */ diff --git a/scard.h b/scard.h deleted file mode 100644 index 82efe4839..000000000 --- a/scard.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $OpenBSD: scard.h,v 1.14 2006/08/03 03:34:42 deraadt Exp $ */ - -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SCARD_H -#define SCARD_H - -#define SCARD_ERROR_FAIL -1 -#define SCARD_ERROR_NOCARD -2 -#define SCARD_ERROR_APPLET -3 - -Key **sc_get_keys(const char *, const char *); -void sc_close(void); -int sc_put_key(Key *, const char *); -char *sc_get_key_label(Key *); - -#endif diff --git a/scard/Makefile.in b/scard/Makefile.in deleted file mode 100644 index 8519e208b..000000000 --- a/scard/Makefile.in +++ /dev/null @@ -1,29 +0,0 @@ -# $Id: Makefile.in,v 1.5 2006/10/23 21:44:47 tim Exp $ - -prefix=@prefix@ -datadir=@datadir@ -datarootdir=@datarootdir@ -srcdir=@srcdir@ -top_srcdir=@top_srcdir@ - -INSTALL=@INSTALL@ - -VPATH=@srcdir@ - -all: - -#Ssh.bin: Ssh.bin.uu -# uudecode Ssh.bin.uu - -clean: -# rm -rf Ssh.bin - -distprep: - uudecode Ssh.bin.uu - -distclean: clean - rm -f Makefile *~ - -install: $(srcdir)/Ssh.bin - $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir) - $(INSTALL) -m 0644 $(srcdir)/Ssh.bin $(DESTDIR)$(datadir)/Ssh.bin diff --git a/scard/Ssh.bin.uu b/scard/Ssh.bin.uu deleted file mode 100644 index ea3986a69..000000000 --- a/scard/Ssh.bin.uu +++ /dev/null @@ -1,17 +0,0 @@ -begin 644 Ssh.bin -M`P)!&P`801X`>``!`E@"`/Y@\`4`_J'P!0!!&T$=`?Z@\`4`01M!'`'^>/,! -M`4$;01X!_G#S%P'^0],1`?Y@\!0`_G/S'0#^<]4``D$;L`4`_F'3``#^8=,% -M`/ZAT`$!_J#0)P'^H],*`?ZCTPD`_G/5"P7^8=,'`OZAT`H`_J#0$@3^:-,@ -M`T$;`P`%`/Y@`\A```/`0__(%`@8!`0H``&`` -M0205!!D)I$L`"0J0`&``*!4$&58``````.P````%____P````.D````0```` -M,P```"````#'````,````(T````R````V!4#&0A*``D*;@!@`"@5!QD*`/\] -M(6``1A)*``D*9P!@`"@*/P!@`$LK"1)@`$LK!6``4!P$#00#2@`.#01@`%5@ -M`%I@`"@37``>%0@2%0A>`%\($F``9%(`:`H_`&``2RL*7@`R10`/$UP`'@H`R`D07@`W!%>P!?_R`0$$`@`\```37P`` -M$V+^H2U?``5=``H38OZ@+5\`#UT`%!-B_G@M"@0`7P`970`>"@0`8``C10`) -/"F<`8``H$UX`+5D````` -` -end diff --git a/scard/Ssh.java b/scard/Ssh.java deleted file mode 100644 index 6418957c2..000000000 --- a/scard/Ssh.java +++ /dev/null @@ -1,164 +0,0 @@ -// $Id: Ssh.java,v 1.3 2002/05/22 04:24:02 djm Exp $ -// -// Ssh.java -// SSH / smartcard integration project, smartcard side -// -// Tomoko Fukuzawa, created, Feb., 2000 -// -// Naomaru Itoi, modified, Apr., 2000 -// - -// copyright 2000 -// the regents of the university of michigan -// all rights reserved -// -// permission is granted to use, copy, create derivative works -// and redistribute this software and such derivative works -// for any purpose, so long as the name of the university of -// michigan is not used in any advertising or publicity -// pertaining to the use or distribution of this software -// without specific, written prior authorization. if the -// above copyright notice or any other identification of the -// university of michigan is included in any copy of any -// portion of this software, then the disclaimer below must -// also be included. -// -// this software is provided as is, without representation -// from the university of michigan as to its fitness for any -// purpose, and without warranty by the university of -// michigan of any kind, either express or implied, including -// without limitation the implied warranties of -// merchantability and fitness for a particular purpose. the -// regents of the university of michigan shall not be liable -// for any damages, including special, indirect, incidental, or -// consequential damages, with respect to any claim arising -// out of or in connection with the use of the software, even -// if it has been or is hereafter advised of the possibility of -// such damages. - -import javacard.framework.*; -import javacardx.framework.*; -import javacardx.crypto.*; - -public class Ssh extends javacard.framework.Applet -{ - // Change this when the applet changes; hi byte is major, low byte is minor - static final short applet_version = (short)0x0102; - - /* constants declaration */ - // code of CLA byte in the command APDU header - static final byte Ssh_CLA =(byte)0x05; - - // codes of INS byte in the command APDU header - static final byte DECRYPT = (byte) 0x10; - static final byte GET_KEYLENGTH = (byte) 0x20; - static final byte GET_PUBKEY = (byte) 0x30; - static final byte GET_VERSION = (byte) 0x32; - static final byte GET_RESPONSE = (byte) 0xc0; - - static final short keysize = 1024; - static final short root_fid = (short)0x3f00; - static final short privkey_fid = (short)0x0012; - static final short pubkey_fid = (short)(('s'<<8)|'h'); - - /* instance variables declaration */ - AsymKey rsakey; - CyberflexFile file; - CyberflexOS os; - - private Ssh() - { - file = new CyberflexFile(); - os = new CyberflexOS(); - - rsakey = new RSA_CRT_PrivateKey (keysize); - - if ( ! rsakey.isSupportedLength (keysize) ) - ISOException.throwIt (ISO.SW_WRONG_LENGTH); - - register(); - } // end of the constructor - - public boolean select() { - if (!rsakey.isInitialized()) - rsakey.setKeyInstance ((short)0xc8, (short)0x10); - - return true; - } - - public static void install(APDU apdu) - { - new Ssh(); // create a Ssh applet instance (card) - } // end of install method - - public static void main(String args[]) { - ISOException.throwIt((short) 0x9000); - } - - public void process(APDU apdu) - { - // APDU object carries a byte array (buffer) to - // transfer incoming and outgoing APDU header - // and data bytes between card and CAD - byte buffer[] = apdu.getBuffer(); - short size, st; - - // verify that if the applet can accept this - // APDU message - // NI: change suggested by Wayne Dyksen, Purdue - if (buffer[ISO.OFFSET_INS] == ISO.INS_SELECT) - ISOException.throwIt(ISO.SW_NO_ERROR); - - switch (buffer[ISO.OFFSET_INS]) { - case DECRYPT: - if (buffer[ISO.OFFSET_CLA] != Ssh_CLA) - ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED); - //decrypt (apdu); - size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF); - - if (apdu.setIncomingAndReceive() != size) - ISOException.throwIt (ISO.SW_WRONG_LENGTH); - - // check access; depends on bit 2 (x/a) - file.selectFile(root_fid); - file.selectFile(privkey_fid); - st = os.checkAccess(ACL.EXECUTE); - if (st != ST.ACCESS_CLEARED) { - CyberflexAPDU.prepareSW1SW2(st); - ISOException.throwIt(CyberflexAPDU.getSW1SW2()); - } - - rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size, - buffer, (short) ISO.OFFSET_CDATA); - - apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size); - break; - case GET_PUBKEY: - file.selectFile(root_fid); // select root - file.selectFile(pubkey_fid); // select public key file - size = (short)(file.getFileSize() - 16); - st = os.readBinaryFile(buffer, (short)0, (short)0, size); - if (st == ST.SUCCESS) - apdu.setOutgoingAndSend((short)0, size); - else { - CyberflexAPDU.prepareSW1SW2(st); - ISOException.throwIt(CyberflexAPDU.getSW1SW2()); - } - break; - case GET_KEYLENGTH: - Util.setShort(buffer, (short)0, keysize); - apdu.setOutgoingAndSend ((short)0, (short)2); - break; - case GET_VERSION: - Util.setShort(buffer, (short)0, applet_version); - apdu.setOutgoingAndSend ((short)0, (short)2); - break; - case GET_RESPONSE: - break; - default: - ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED); - } - - } // end of process method - -} // end of class Ssh -- cgit v1.2.3 From 8ad0fbd98e5ffd98c25f88881981336508ae90d7 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 09:49:06 +1100 Subject: - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] Make it compile on OSX --- ChangeLog | 2 ++ ssh-pkcs11-client.c | 6 +++++- ssh-pkcs11-helper.c | 9 +++++++-- ssh-pkcs11.c | 12 +++++++++--- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce4ef1343..f56dad3ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,8 @@ - (djm) [INSTALL Makefile.in README.smartcard configure.ac scard-opensc.c] [scard.c scard.h pkcs11.h scard/Makefile.in scard/Ssh.bin.uu scard/Ssh.java] Remove obsolete smartcard support + - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] + Make it compile on OSX 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 6ffdd9364..d376153fa 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -14,8 +14,12 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "includes.h" + #include -#include +#ifdef HAVE_SYS_TIME_H +# include +#endif #include #include diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index f9962709b..464209641 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -14,9 +14,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "includes.h" + #include -#include +#ifdef HAVE_SYS_TIME_H +# include +#endif + +#include "openbsd-compat/sys-queue.h" #include #include diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index f82454329..2f6c9cec8 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -14,14 +14,20 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "includes.h" + #include -#include +#ifdef HAVE_SYS_TIME_H +# include +#endif #include #include #include #include +#include "openbsd-compat/sys-queue.h" + #define CRYPTOKI_COMPAT #include "pkcs11.h" @@ -190,14 +196,14 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, CK_ULONG tlen = 0, nfound = 0; CK_RV rv; CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; - CK_BBOOL true = CK_TRUE; + CK_BBOOL true_val = CK_TRUE; CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 }; CK_ATTRIBUTE key_filter[] = { {CKA_CLASS, &private_key_class, sizeof(private_key_class) }, {CKA_ID, NULL, 0}, - {CKA_SIGN, &true, sizeof(true) } + {CKA_SIGN, &true_val, sizeof(true_val) } }; char *pin, prompt[1024]; int rval = -1; -- cgit v1.2.3 From dfa4156dbd4aa45464b2ea6b867bcaa483bed134 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 10:06:28 +1100 Subject: - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] Use ssh_get_progname to fill __progname --- ChangeLog | 2 ++ ssh-pkcs11-client.c | 4 ++++ ssh-pkcs11-helper.c | 15 +++++++++++++++ ssh-pkcs11.c | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/ChangeLog b/ChangeLog index f56dad3ca..c5dc75262 100644 --- a/ChangeLog +++ b/ChangeLog @@ -42,6 +42,8 @@ Remove obsolete smartcard support - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] Make it compile on OSX + - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] + Use ssh_get_progname to fill __progname 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index d376153fa..37050e04d 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -16,6 +16,8 @@ #include "includes.h" +#ifdef ENABLE_PKCS11 + #include #ifdef HAVE_SYS_TIME_H # include @@ -231,3 +233,5 @@ pkcs11_del_provider(char *name) buffer_free(&msg); return (ret); } + +#endif /* ENABLE_PKCS11 */ diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 464209641..3b44f7c30 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -16,6 +16,8 @@ #include "includes.h" +#ifdef ENABLE_PKCS11 + #include #ifdef HAVE_SYS_TIME_H # include @@ -277,6 +279,8 @@ main(int argc, char **argv) extern char *optarg; extern char *__progname; + __progname = ssh_get_progname(argv[0]); + log_init(__progname, log_level, log_facility, log_stderr); in = STDIN_FILENO; @@ -352,3 +356,14 @@ main(int argc, char **argv) process(); } } +#else /* ENABLE_PKCS11 */ +int +main(int argc, char **argv) +{ + extern char *__progname; + + __progname = ssh_get_progname(argv[0]); + log_init(__progname, SYSLOG_LEVEL_ERROR, SYSLOG_FACILITY_AUTH, 0); + fatal("PKCS#11 support disabled at compile time"); +} +#endif /* ENABLE_PKCS11 */ diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 2f6c9cec8..821e9f840 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -16,6 +16,8 @@ #include "includes.h" +#ifdef ENABLE_PKCS11 + #include #ifdef HAVE_SYS_TIME_H # include @@ -548,3 +550,5 @@ fail: dlclose(handle); return (-1); } + +#endif /* ENABLE_PKCS11 */ -- cgit v1.2.3 From b3c9f78711bde96415d22046af2c0f8c071a7e6f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 12 Feb 2010 10:11:34 +1100 Subject: - (djm) [configure.ac] Enable PKCS#11 support only when we find a working dlopen() --- ChangeLog | 2 ++ configure.ac | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c5dc75262..83259b5fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -44,6 +44,8 @@ Make it compile on OSX - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] Use ssh_get_progname to fill __progname + - (djm) [configure.ac] Enable PKCS#11 support only when we find a working + dlopen() 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/configure.ac b/configure.ac index 40b58c64f..f4c25683c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.442 2010/02/11 22:34:22 djm Exp $ +# $Id: configure.ac,v 1.443 2010/02/11 23:11:34 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.442 $) +AC_REVISION($Revision: 1.443 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1420,6 +1420,11 @@ AC_CHECK_FUNCS( \ waitpid \ ) +# PKCS#11 support requires dlopen() and co +AC_SEARCH_LIBS(dlopen, dl, + AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support]) +) + # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS(gai_strerror,[ AC_DEFINE(HAVE_GAI_STRERROR) @@ -4130,10 +4135,6 @@ else AC_SUBST(TEST_SSH_IPV6, yes) fi -if test "x$enable_pkcs11" != "xno" ; then - AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support]) -fi - AC_EXEEXT AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ openbsd-compat/Makefile openbsd-compat/regress/Makefile \ -- cgit v1.2.3 From 05abd2c96876b959f4a2f71671652064fcedda0d Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:16:08 +1100 Subject: - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] [ssh-pkcs11.h] Add $OpenBSD$ RCS idents so we can sync portable --- ChangeLog | 4 ++++ pkcs11.h | 1 + ssh-pkcs11-client.c | 1 + ssh-pkcs11-helper.c | 1 + ssh-pkcs11.c | 1 + ssh-pkcs11.h | 1 + 6 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 83259b5fd..ac08efa4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20100224 + - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] + [ssh-pkcs11.h] Add $OpenBSD$ RCS idents so we can sync portable + 20100212 - (djm) OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/02/02 22:49:34 diff --git a/pkcs11.h b/pkcs11.h index 223f20ff3..2cde5b3f4 100644 --- a/pkcs11.h +++ b/pkcs11.h @@ -1,3 +1,4 @@ +/* $OpenBSD: pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */ /* pkcs11.h Copyright 2006, 2007 g10 Code GmbH Copyright 2006 Andreas Jellinghaus diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 37050e04d..650c37342 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,3 +1,4 @@ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.2 2010/02/24 06:12:53 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 3b44f7c30..1684ab0c2 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -1,3 +1,4 @@ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.3 2010/02/24 06:12:53 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 821e9f840..7536f92a6 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,3 +1,4 @@ +/* $OpenBSD: ssh-pkcs11.c,v 1.4 2010/02/24 06:12:53 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h index fae41a7b5..59f456adf 100644 --- a/ssh-pkcs11.h +++ b/ssh-pkcs11.h @@ -1,3 +1,4 @@ +/* $OpenBSD: ssh-pkcs11.h,v 1.2 2010/02/24 06:12:53 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * -- cgit v1.2.3 From a80f1404bb8f9164f65daacd246231e7a476d7b9 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:17:58 +1100 Subject: - djm@cvs.openbsd.org 2010/02/11 20:37:47 [pathnames.h] correct comment --- ChangeLog | 4 ++++ pathnames.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ac08efa4b..27a99d72f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ 20100224 - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] [ssh-pkcs11.h] Add $OpenBSD$ RCS idents so we can sync portable + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/02/11 20:37:47 + [pathnames.h] + correct comment 20100212 - (djm) OpenBSD CVS Sync diff --git a/pathnames.h b/pathnames.h index 32b9e065b..9e50950fe 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.18 2010/02/08 10:50:20 markus Exp $ */ +/* $OpenBSD: pathnames.h,v 1.19 2010/02/11 20:37:47 djm Exp $ */ /* * Author: Tatu Ylonen @@ -125,7 +125,7 @@ #define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" #endif -/* Location of ssh-keysign for hostbased authentication */ +/* Location of ssh-pkcs11-helper to support keys in tokens */ #ifndef _PATH_SSH_PKCS11_HELPER #define _PATH_SSH_PKCS11_HELPER "/usr/libexec/ssh-pkcs11-helper" #endif -- cgit v1.2.3 From b6bd3c2ca8a52a6ff777c8d7a69a8c2e7e51a1f8 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:24:56 +1100 Subject: - dtucker@cvs.openbsd.org 2009/11/09 04:20:04 [regress/Makefile] add regression test for ssh-keygen pubkey conversions --- ChangeLog | 3 +++ regress/Makefile | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 27a99d72f..5076fba68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ - djm@cvs.openbsd.org 2010/02/11 20:37:47 [pathnames.h] correct comment + - dtucker@cvs.openbsd.org 2009/11/09 04:20:04 + [regress/Makefile] + add regression test for ssh-keygen pubkey conversions 20100212 - (djm) OpenBSD CVS Sync diff --git a/regress/Makefile b/regress/Makefile index 7d4e2ab4e..761cc286a 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.49 2009/08/13 00:57:17 djm Exp $ +# $OpenBSD: Makefile,v 1.50 2009/11/09 04:20:04 dtucker Exp $ REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec tests: $(REGRESS_TARGETS) @@ -34,6 +34,7 @@ LTESTS= connect \ agent-ptrace \ keyscan \ keygen-change \ + keygen-convert \ key-options \ scp \ sftp \ -- cgit v1.2.3 From 0dff9c7e6d1fd0025ad7b137d2201f9f8bdaadc5 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:25:58 +1100 Subject: - dtucker@cvs.openbsd.org 2010/01/11 02:53:44 [regress/forwarding.sh] regress test for stdio forwarding --- ChangeLog | 3 +++ regress/forwarding.sh | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5076fba68..33e052bbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,9 @@ - dtucker@cvs.openbsd.org 2009/11/09 04:20:04 [regress/Makefile] add regression test for ssh-keygen pubkey conversions + - dtucker@cvs.openbsd.org 2010/01/11 02:53:44 + [regress/forwarding.sh] + regress test for stdio forwarding 20100212 - (djm) OpenBSD CVS Sync diff --git a/regress/forwarding.sh b/regress/forwarding.sh index 9ffbb3dd4..6dec991a6 100644 --- a/regress/forwarding.sh +++ b/regress/forwarding.sh @@ -1,4 +1,4 @@ -# $OpenBSD: forwarding.sh,v 1.6 2006/07/11 18:51:21 markus Exp $ +# $OpenBSD: forwarding.sh,v 1.7 2010/01/11 02:53:44 dtucker Exp $ # Placed in the Public Domain. tid="local and remote forwarding" @@ -93,3 +93,13 @@ for p in 1 2; do fi sleep 10 done + +for p in 2; do + trace "stdio forwarding proto $p" + cmd="${SSH} -$p -F $OBJ/ssh_config" + $cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" \ + somehost true + if [ $? != 0 ]; then + fail "stdio forwarding proto $p" + fi +done -- cgit v1.2.3 From bb4ae5583bffe27d9485198e199bea9767701bb1 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:26:38 +1100 Subject: - djm@cvs.openbsd.org 2010/02/09 04:57:36 [regress/addrmatch.sh] clean up droppings --- ChangeLog | 3 +++ regress/addrmatch.sh | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33e052bbb..0765008f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,9 @@ - dtucker@cvs.openbsd.org 2010/01/11 02:53:44 [regress/forwarding.sh] regress test for stdio forwarding + - djm@cvs.openbsd.org 2010/02/09 04:57:36 + [regress/addrmatch.sh] + clean up droppings 20100212 - (djm) OpenBSD CVS Sync diff --git a/regress/addrmatch.sh b/regress/addrmatch.sh index cbff82e5c..23ddd65ce 100644 --- a/regress/addrmatch.sh +++ b/regress/addrmatch.sh @@ -1,9 +1,9 @@ -# $OpenBSD: addrmatch.sh,v 1.2 2008/12/07 22:17:48 djm Exp $ +# $OpenBSD: addrmatch.sh,v 1.3 2010/02/09 04:57:36 djm Exp $ # Placed in the Public Domain. tid="address match" -mv $OBJ/sshd_proxy $OBJ/sshd_proxy_orig +mv $OBJ/sshd_proxy $OBJ/sshd_proxy_bak run_trial() { @@ -18,7 +18,7 @@ run_trial() fi } -cp $OBJ/sshd_proxy_orig $OBJ/sshd_proxy +cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy cat >>$OBJ/sshd_proxy < Date: Wed, 24 Feb 2010 17:28:45 +1100 Subject: - djm@cvs.openbsd.org 2010/02/09 06:29:02 [regress/Makefile] turn on all the malloc(3) checking options when running regression tests. this has caught a few bugs for me in the past; ok dtucker@ --- ChangeLog | 4 ++++ regress/Makefile | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0765008f2..5595fdbbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,10 @@ - djm@cvs.openbsd.org 2010/02/09 04:57:36 [regress/addrmatch.sh] clean up droppings + - djm@cvs.openbsd.org 2010/02/09 06:29:02 + [regress/Makefile] + turn on all the malloc(3) checking options when running regression + tests. this has caught a few bugs for me in the past; ok dtucker@ 20100212 - (djm) OpenBSD CVS Sync diff --git a/regress/Makefile b/regress/Makefile index 761cc286a..42e84d4c5 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.50 2009/11/09 04:20:04 dtucker Exp $ +# $OpenBSD: Makefile,v 1.51 2010/02/09 06:29:02 djm Exp $ REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec tests: $(REGRESS_TARGETS) @@ -68,6 +68,9 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \ putty.rsa2 +# Enable all malloc(3) randomisations and checks +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + t1: ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv @@ -106,13 +109,13 @@ t-exec: ${LTESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ for TEST in ""$?; do \ echo "run test $${TEST}" ... 1>&2; \ - (env SUDO=${SUDO} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ + (env SUDO=${SUDO} TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ done t-exec-interop: ${INTEROP_TESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ for TEST in ""$?; do \ echo "run test $${TEST}" ... 1>&2; \ - (env SUDO=${SUDO} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ + (env SUDO=${SUDO} TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ done -- cgit v1.2.3 From c1739211a6ce790e72262db90ba4b1d0ce79d1f4 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:29:34 +1100 Subject: - djm@cvs.openbsd.org 2010/02/24 06:21:56 [regress/test-exec.sh] wait for sshd to fully stop in cleanup() function; avoids races in tests that do multiple start_sshd/cleanup cycles; "I hate pidfiles" deraadt@ --- ChangeLog | 4 ++++ regress/test-exec.sh | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5595fdbbc..5c637af17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,10 @@ [regress/Makefile] turn on all the malloc(3) checking options when running regression tests. this has caught a few bugs for me in the past; ok dtucker@ + - djm@cvs.openbsd.org 2010/02/24 06:21:56 + [regress/test-exec.sh] + wait for sshd to fully stop in cleanup() function; avoids races in tests + that do multiple start_sshd/cleanup cycles; "I hate pidfiles" deraadt@ 20100212 - (djm) OpenBSD CVS Sync diff --git a/regress/test-exec.sh b/regress/test-exec.sh index 804a29696..b3a19389d 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.36 2009/10/08 18:04:27 markus Exp $ +# $OpenBSD: test-exec.sh,v 1.37 2010/02/24 06:21:56 djm Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -172,9 +172,17 @@ cleanup () echo no sshd running else if [ $pid -lt 2 ]; then - echo bad pid for ssd: $pid + echo bad pid for ssh: $pid else $SUDO kill $pid + trace "wait for sshd to exit" + i=0; + while [ -f $PIDFILE -a $i -lt 5 ]; do + i=`expr $i + 1` + sleep $i + done + test -f $PIDFILE && \ + fatal "sshd didn't exit port $PORT pid $pid" fi fi fi -- cgit v1.2.3 From cfa42d2fd2077cce168b81c77f63776bd87a68b3 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:31:20 +1100 Subject: - markus@cvs.openbsd.org 2010/02/08 10:52:47 [regress/agent-pkcs11.sh] test for PKCS#11 support (currently disabled) --- ChangeLog | 3 +++ regress/agent-pkcs11.sh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 regress/agent-pkcs11.sh diff --git a/ChangeLog b/ChangeLog index 5c637af17..34ec72c63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,9 @@ [regress/test-exec.sh] wait for sshd to fully stop in cleanup() function; avoids races in tests that do multiple start_sshd/cleanup cycles; "I hate pidfiles" deraadt@ + - markus@cvs.openbsd.org 2010/02/08 10:52:47 + [regress/agent-pkcs11.sh] + test for PKCS#11 support (currently disabled) 20100212 - (djm) OpenBSD CVS Sync diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh new file mode 100644 index 000000000..db33ab37e --- /dev/null +++ b/regress/agent-pkcs11.sh @@ -0,0 +1,69 @@ +# $OpenBSD: agent-pkcs11.sh,v 1.1 2010/02/08 10:52:47 markus Exp $ +# Placed in the Public Domain. + +tid="pkcs11 agent test" + +TEST_SSH_PIN="" +TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 + +# setup environment for soft-pkcs11 token +SOFTPKCS11RC=$OBJ/pkcs11.info +export SOFTPKCS11RC +# prevent ssh-agent from calling ssh-askpass +SSH_ASKPASS=/usr/bin/true +export SSH_ASKPASS +unset DISPLAY + +# start command w/o tty, so ssh-add accepts pin from stdin +notty() { + perl -e 'use POSIX; POSIX::setsid(); + if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@" +} + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +if [ $r -ne 0 ]; then + fail "could not start ssh-agent: exit code $r" +else + trace "generating key/cert" + rm -f $OBJ/pkcs11.key $OBJ/pkcs11.crt + openssl genrsa -out $OBJ/pkcs11.key 2048 > /dev/null 2>&1 + chmod 600 $OBJ/pkcs11.key + openssl req -key $OBJ/pkcs11.key -new -x509 \ + -out $OBJ/pkcs11.crt -text -subj '/CN=pkcs11 test' > /dev/null + printf "a\ta\t$OBJ/pkcs11.crt\t$OBJ/pkcs11.key" > $SOFTPKCS11RC + # add to authorized keys + ${SSHKEYGEN} -y -f $OBJ/pkcs11.key > $OBJ/authorized_keys_$USER + + trace "add pkcs11 key to agent" + echo ${TEST_SSH_PIN} | notty ${SSHADD} -s ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -s failed: exit code $r" + fi + + trace "pkcs11 list via agent" + ${SSHADD} -l > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" + fi + + trace "pkcs11 connect via agent" + ${SSH} -2 -F $OBJ/ssh_proxy somehost exit 5 + r=$? + if [ $r -ne 5 ]; then + fail "ssh connect failed (exit code $r)" + fi + + trace "remove pkcs11 keys" + echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" + fi + + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -- cgit v1.2.3 From 8eff8e8f59de5807e1db73bdfd86a0780595f01c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 17:33:30 +1100 Subject: - dtucker@cvs.openbsd.org 2009/11/09 04:20:04 [regress/Makefile keygen-convert.sh] add regression test for ssh-keygen pubkey conversions --- regress/keygen-convert.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 regress/keygen-convert.sh diff --git a/regress/keygen-convert.sh b/regress/keygen-convert.sh new file mode 100644 index 000000000..ad0e9c637 --- /dev/null +++ b/regress/keygen-convert.sh @@ -0,0 +1,33 @@ +# $OpenBSD: keygen-convert.sh,v 1.1 2009/11/09 04:20:04 dtucker Exp $ +# Placed in the Public Domain. + +tid="convert keys" + +for t in rsa dsa; do + # generate user key for agent + trace "generating $t key" + rm -f $OBJ/$t-key + ${SSHKEYGEN} -q -N "" -t $t -f $OBJ/$t-key + + trace "export $t private to rfc4716 public" + ${SSHKEYGEN} -q -e -f $OBJ/$t-key >$OBJ/$t-key-rfc || \ + fail "export $t private to rfc4716 public" + + trace "export $t public to rfc4716 public" + ${SSHKEYGEN} -q -e -f $OBJ/$t-key.pub >$OBJ/$t-key-rfc.pub || \ + fail "$t public to rfc4716 public" + + cmp $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub || \ + fail "$t rfc4716 exports differ between public and private" + + trace "import $t rfc4716 public" + ${SSHKEYGEN} -q -i -f $OBJ/$t-key-rfc >$OBJ/$t-rfc-imported || \ + fail "$t import rfc4716 public" + + cut -f1,2 -d " " $OBJ/$t-key.pub >$OBJ/$t-key-nocomment.pub + cmp $OBJ/$t-key-nocomment.pub $OBJ/$t-rfc-imported || \ + fail "$t imported differs from original" + + rm -f $OBJ/$t-key $OBJ/$t-key.pub $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub \ + $OBJ/$t-rfc-imported $OBJ/$t-key-nocomment.pub +done -- cgit v1.2.3 From 43001b3b3b51ab55755a0c75c4f49b2d752e1635 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 18:18:51 +1100 Subject: - (djm) [Makefile.in ssh-pkcs11-helper.8] Add manpage for PKCS#11 helper --- ChangeLog | 1 + Makefile.in | 8 +++++--- ssh-pkcs11-helper.8 | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 ssh-pkcs11-helper.8 diff --git a/ChangeLog b/ChangeLog index 34ec72c63..761c1913a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,7 @@ - markus@cvs.openbsd.org 2010/02/08 10:52:47 [regress/agent-pkcs11.sh] test for PKCS#11 support (currently disabled) + - (djm) [Makefile.in ssh-pkcs11-helper.8] Add manpage for PKCS#11 helper 20100212 - (djm) OpenBSD CVS Sync diff --git a/Makefile.in b/Makefile.in index 1e4f64a64..69e3567da 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.305 2010/02/11 22:34:22 djm Exp $ +# $Id: Makefile.in,v 1.306 2010/02/24 07:18:51 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -93,8 +93,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o -MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out -MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 +MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out +MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 MANTYPE = @MANTYPE@ CONFIGFILES=sshd_config.out ssh_config.out moduli.out @@ -285,6 +285,7 @@ install-files: $(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1 $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 + $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 -rm -f $(DESTDIR)$(bindir)/slogin ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 @@ -383,6 +384,7 @@ uninstall: -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 tests interop-tests: $(TARGETS) diff --git a/ssh-pkcs11-helper.8 b/ssh-pkcs11-helper.8 new file mode 100644 index 000000000..9bdaadc01 --- /dev/null +++ b/ssh-pkcs11-helper.8 @@ -0,0 +1,43 @@ +.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.3 2010/02/10 23:20:38 markus Exp $ +.\" +.\" Copyright (c) 2010 Markus Friedl. All rights reserved. +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 10 2010 $ +.Dt SSH-PKCS11-HELPER 8 +.Os +.Sh NAME +.Nm ssh-pkcs11-helper +.Nd ssh-agent helper program for PKCS#11 support +.Sh SYNOPSIS +.Nm +.Sh DESCRIPTION +.Nm +is used by +.Xr ssh-agent 1 +to access keys provided by a PKCS#11 token. +.Pp +.Nm +is not intended to be invoked by the user, but from +.Xr ssh-agent 1 . +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 +.Sh HISTORY +.Nm +first appeared in +.Ox 4.7 . +.Sh AUTHORS +.An Markus Friedl Aq markus@openbsd.org -- cgit v1.2.3 From d27d85d5320bb946d4bb734dcf45a8d20bad6020 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 24 Feb 2010 18:21:45 +1100 Subject: contrib/caldera/openssh.spec contrib/redhat/openssh.spec contrib/suse/openssh.spec --- ChangeLog | 2 ++ contrib/caldera/openssh.spec | 4 +++- contrib/redhat/openssh.spec | 2 ++ contrib/suse/openssh.spec | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 761c1913a..10c074c26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,8 @@ [regress/agent-pkcs11.sh] test for PKCS#11 support (currently disabled) - (djm) [Makefile.in ssh-pkcs11-helper.8] Add manpage for PKCS#11 helper + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Add PKCS#11 helper binary and manpage 20100212 - (djm) OpenBSD CVS Sync diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec index 9ced32faf..e6c030c0d 100644 --- a/contrib/caldera/openssh.spec +++ b/contrib/caldera/openssh.spec @@ -319,6 +319,7 @@ fi %{_bindir}/ssh-keyscan %dir %{_libexecdir} %attr(4711,root,root) %{_libexecdir}/ssh-keysign +%{_libexecdir}/ssh-pkcs11-helper %{_sbindir}/ssh-host-keygen %dir %{_defaultdocdir}/%{name}-%{version} %{_defaultdocdir}/%{name}-%{version}/CREDITS @@ -330,6 +331,7 @@ fi %{_defaultdocdir}/%{name}-%{version}/faq.html %{_mandir}/man1/* %{_mandir}/man8/ssh-keysign.8.gz +%{_mandir}/man8/ssh-pkcs11-helper.8.gz %{_mandir}/man5/ssh_config.5.gz %Files server @@ -358,4 +360,4 @@ fi * Mon Jan 01 1998 ... Template Version: 1.31 -$Id: openssh.spec,v 1.67 2009/10/02 01:49:05 djm Exp $ +$Id: openssh.spec,v 1.68 2010/02/24 07:21:46 djm Exp $ diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 1bdaf2d93..a15afc7ee 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -345,7 +345,9 @@ fi %attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1* %attr(0755,root,root) %dir %{_libexecdir}/openssh %attr(4711,root,root) %{_libexecdir}/openssh/ssh-keysign +%attr(0755,root,root) %{_libexecdir}/openssh/ssh-pkcs11-helper %attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8* +%attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8* %endif %if %{scard} %attr(0755,root,root) %dir %{_datadir}/openssh diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 12661eeae..c09246d1f 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -220,6 +220,7 @@ fi %attr(0755,root,root) %dir %{_libdir}/ssh %attr(0755,root,root) %{_libdir}/ssh/sftp-server %attr(4711,root,root) %{_libdir}/ssh/ssh-keysign +%attr(0755,root,root) %{_libdir}/ssh/ssh-pkcs11-helper %attr(0644,root,root) %doc %{_mandir}/man1/scp.1* %attr(0644,root,root) %doc %{_mandir}/man1/sftp.1* %attr(-,root,root) %doc %{_mandir}/man1/slogin.1* @@ -233,6 +234,7 @@ fi %attr(0644,root,root) %doc %{_mandir}/man5/sshd_config.5* %attr(0644,root,root) %doc %{_mandir}/man8/sftp-server.8* %attr(0644,root,root) %doc %{_mandir}/man8/ssh-keysign.8* +%attr(0644,root,root) %doc %{_mandir}/man8/ssh-pkcs11-helper.8* %attr(0644,root,root) %doc %{_mandir}/man8/sshd.8* %attr(0644,root,root) /var/adm/fillup-templates/sysconfig.ssh -- cgit v1.2.3 From 0a80ca190a39943029719facf7edb990def7ae62 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 27 Feb 2010 07:55:05 +1100 Subject: - OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/02/26 20:29:54 [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys addrmatch.c auth-options.c] [auth-options.h auth.h auth2-pubkey.c authfd.c dns.c dns.h hostfile.c] [hostfile.h kex.h kexdhs.c kexgexs.c key.c key.h match.h monitor.c] [myproposal.h servconf.c servconf.h ssh-add.c ssh-agent.c ssh-dss.c] [ssh-keygen.1 ssh-keygen.c ssh-rsa.c ssh.1 ssh.c ssh2.h sshconnect.c] [sshconnect2.c sshd.8 sshd.c sshd_config.5] Add support for certificate key types for users and hosts. OpenSSH certificate key types are not X.509 certificates, but a much simpler format that encodes a public key, identity information and some validity constraints and signs it with a CA key. CA keys are regular SSH keys. This certificate style avoids the attack surface of X.509 certificates and is very easy to deploy. Certified host keys allow automatic acceptance of new host keys when a CA certificate is marked as sh/known_hosts. see VERIFYING HOST KEYS in ssh(1) for details. Certified user keys allow authentication of users when the signing CA key is marked as trusted in authorized_keys. See "AUTHORIZED_KEYS FILE FORMAT" in sshd(8) for details. Certificates are minted using ssh-keygen(1), documentation is in the "CERTIFICATES" section of that manpage. Documentation on the format of certificates is in the file PROTOCOL.certkeys feedback and ok markus@ --- ChangeLog | 33 +++ PROTOCOL | 23 ++- PROTOCOL.agent | 24 ++- PROTOCOL.certkeys | 191 ++++++++++++++++++ addrmatch.c | 78 ++++++- auth-options.c | 150 +++++++++++++- auth-options.h | 4 +- auth.h | 5 +- auth2-pubkey.c | 37 +++- authfd.c | 24 ++- dns.c | 8 +- dns.h | 6 +- hostfile.c | 31 ++- hostfile.h | 4 +- kex.h | 5 +- kexdhs.c | 19 +- kexgexs.c | 20 +- key.c | 595 ++++++++++++++++++++++++++++++++++++++++++++++++++---- key.h | 32 ++- match.h | 4 +- monitor.c | 5 +- myproposal.h | 6 +- servconf.c | 19 +- servconf.h | 5 +- ssh-add.c | 34 +++- ssh-agent.c | 24 ++- ssh-dss.c | 10 +- ssh-keygen.1 | 178 +++++++++++++++- ssh-keygen.c | 433 ++++++++++++++++++++++++++++++++++++--- ssh-rsa.c | 10 +- ssh.1 | 23 ++- ssh.c | 71 +++++-- ssh2.h | 5 +- sshconnect.c | 78 +++++-- sshconnect2.c | 4 +- sshd.8 | 25 ++- sshd.c | 117 +++++++++-- sshd_config.5 | 12 +- 38 files changed, 2164 insertions(+), 188 deletions(-) create mode 100644 PROTOCOL.certkeys diff --git a/ChangeLog b/ChangeLog index 10c074c26..fec38e028 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +20100226 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/02/26 20:29:54 + [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys addrmatch.c auth-options.c] + [auth-options.h auth.h auth2-pubkey.c authfd.c dns.c dns.h hostfile.c] + [hostfile.h kex.h kexdhs.c kexgexs.c key.c key.h match.h monitor.c] + [myproposal.h servconf.c servconf.h ssh-add.c ssh-agent.c ssh-dss.c] + [ssh-keygen.1 ssh-keygen.c ssh-rsa.c ssh.1 ssh.c ssh2.h sshconnect.c] + [sshconnect2.c sshd.8 sshd.c sshd_config.5] + Add support for certificate key types for users and hosts. + + OpenSSH certificate key types are not X.509 certificates, but a much + simpler format that encodes a public key, identity information and + some validity constraints and signs it with a CA key. CA keys are + regular SSH keys. This certificate style avoids the attack surface + of X.509 certificates and is very easy to deploy. + + Certified host keys allow automatic acceptance of new host keys + when a CA certificate is marked as trusted in ~/.ssh/known_hosts. + see VERIFYING HOST KEYS in ssh(1) for details. + + Certified user keys allow authentication of users when the signing + CA key is marked as trusted in authorized_keys. See "AUTHORIZED_KEYS + FILE FORMAT" in sshd(8) for details. + + Certificates are minted using ssh-keygen(1), documentation is in + the "CERTIFICATES" section of that manpage. + + Documentation on the format of certificates is in the file + PROTOCOL.certkeys + + feedback and ok markus@ + 20100224 - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] [ssh-pkcs11.h] Add $OpenBSD$ RCS idents so we can sync portable diff --git a/PROTOCOL b/PROTOCOL index 9b74b9475..5fc31eade 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -31,7 +31,14 @@ The method is documented in: http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt -3. connection: Channel write close extension "eow@openssh.com" +3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com" and + "ssh-dsa-cert-v00@openssh.com" + +OpenSSH introduces two new public key algorithms to support certificate +authentication for users and hostkeys. These methods are documented in +the file PROTOCOL.certkeys + +4. connection: Channel write close extension "eow@openssh.com" The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF message to allow an endpoint to signal its peer that it will send no @@ -70,7 +77,7 @@ message is only sent to OpenSSH peers (identified by banner). Other SSH implementations may be whitelisted to receive this message upon request. -4. connection: disallow additional sessions extension +5. connection: disallow additional sessions extension "no-more-sessions@openssh.com" Most SSH connections will only ever request a single session, but a @@ -98,7 +105,7 @@ of this message, the no-more-sessions request is only sent to OpenSSH servers (identified by banner). Other SSH implementations may be whitelisted to receive this message upon request. -5. connection: Tunnel forward extension "tun@openssh.com" +6. connection: Tunnel forward extension "tun@openssh.com" OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com" channel type. This channel type supports forwarding of network packets @@ -159,7 +166,7 @@ The contents of the "data" field for layer 2 packets is: The "frame" field contains an IEEE 802.3 Ethernet frame, including header. -6. sftp: Reversal of arguments to SSH_FXP_SYMLINK +7. sftp: Reversal of arguments to SSH_FXP_SYMLINK When OpenSSH's sftp-server was implemented, the order of the arguments to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, @@ -172,7 +179,7 @@ SSH_FXP_SYMLINK as follows: string targetpath string linkpath -7. sftp: Server extension announcement in SSH_FXP_VERSION +8. sftp: Server extension announcement in SSH_FXP_VERSION OpenSSH's sftp-server lists the extensions it supports using the standard extension announcement mechanism in the SSH_FXP_VERSION server @@ -193,7 +200,7 @@ ever changed in an incompatible way. The server MAY advertise the same extension with multiple versions (though this is unlikely). Clients MUST check the version number before attempting to use the extension. -8. sftp: Extension request "posix-rename@openssh.com" +9. sftp: Extension request "posix-rename@openssh.com" This operation provides a rename operation with POSIX semantics, which are different to those provided by the standard SSH_FXP_RENAME in @@ -210,7 +217,7 @@ rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". -9. sftp: Extension requests "statvfs@openssh.com" and +10. sftp: Extension requests "statvfs@openssh.com" and "fstatvfs@openssh.com" These requests correspond to the statvfs and fstatvfs POSIX system @@ -251,4 +258,4 @@ The values of the f_flag bitmask are as follows: Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are advertised in the SSH_FXP_VERSION hello with version "2". -$OpenBSD: PROTOCOL,v 1.14 2010/01/09 00:57:10 djm Exp $ +$OpenBSD: PROTOCOL,v 1.15 2010/02/26 20:29:54 djm Exp $ diff --git a/PROTOCOL.agent b/PROTOCOL.agent index 49adbdd5c..b34fcd318 100644 --- a/PROTOCOL.agent +++ b/PROTOCOL.agent @@ -173,6 +173,15 @@ be added using the following request string key_comment constraint[] key_constraints +DSA certificates may be added with: + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-dss-cert-v00@openssh.com" + string certificate + mpint dsa_private_key + string key_comment + constraint[] key_constraints + RSA keys may be added with this request: byte SSH2_AGENTC_ADD_IDENTITY or @@ -187,6 +196,19 @@ RSA keys may be added with this request: string key_comment constraint[] key_constraints +RSA certificates may be added with this request: + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-rsa-cert-v00@openssh.com" + string certificate + mpint rsa_d + mpint rsa_iqmp + mpint rsa_p + mpint rsa_q + string key_comment + constraint[] key_constraints + Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse order to the protocol 1 add keys message. As with the corresponding protocol 1 "add key" request, the private key is overspecified to avoid @@ -513,4 +535,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys. SSH_AGENT_CONSTRAIN_LIFETIME 1 SSH_AGENT_CONSTRAIN_CONFIRM 2 -$OpenBSD: PROTOCOL.agent,v 1.4 2008/07/01 23:12:47 stevesk Exp $ +$OpenBSD: PROTOCOL.agent,v 1.5 2010/02/26 20:29:54 djm Exp $ diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys new file mode 100644 index 000000000..0b887a240 --- /dev/null +++ b/PROTOCOL.certkeys @@ -0,0 +1,191 @@ +This document describes a simple public-key certificate authentication +system for use by SSH. + +Background +---------- + +The SSH protocol currently supports a simple public key authentication +mechanism. Unlike other public key implementations, SSH eschews the +use of X.509 certificates and uses raw keys. This approach has some +benefits relating to simplicity of configuration and minimisation +of attack surface, but it does not support the important use-cases +of centrally managed, passwordless authentication and centrally +certified host keys. + +These protocol extensions build on the simple public key authentication +system already in SSH to allow certificate-based authentication. +The certificates used are not traditional X.509 certificates, with +numerous options and complex encoding rules, but something rather +more minimal: a key, some identity information and usage constraints +that have been signed with some other trusted key. + +A sshd server may be configured to allow authentication via certified +keys, by extending the existing ~/.ssh/authorized_keys mechanism +to allow specification of certification authority keys in addition +to raw user keys. The ssh client will support automatic verification +of acceptance of certified host keys, by adding a similar ability +to specify CA keys in ~/.ssh/known_hosts. + +Certified keys are represented using two new key types: +ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com that +include certification information along with the public key that is used +to sign challenges. ssh-keygen performs the CA signing operation. + +Protocol extensions +------------------- + +The SSH wire protocol includes several extensibility mechanisms. +These modifications shall take advantage of namespaced public key +algorithm names to add support for certificate authentication without +breaking the protocol - implementations that do not support the +extensions will simply ignore them. + +Authentication using the new key formats described below proceeds +using the existing SSH "publickey" authentication method described +in RFC4252 section 7. + +New public key formats +---------------------- + +The ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com key +types take a similar same high-level format (note: data types and +encoding are as per RFC4251 section 5). The serialised wire encoding of +these certificates is also used for storing them on disk. + +#define SSH_CERT_TYPE_USER 1 +#define SSH_CERT_TYPE_HOST 2 + +RSA certificate + + string "ssh-rsa-cert-v00@openssh.com" + mpint e + mpint n + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string constraints + string nonce + string reserved + string signature key + string signature + +DSA certificate + + string "ssh-dss-cert-v00@openssh.com" + mpint p + mpint q + mpint g + mpint y + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string constraints + string nonce + string reserved + string signature key + string signature + +e and n are the RSA exponent and public modulus respectively. + +p, q, g, y are the DSA parameters as described in FIPS-186-2. + +type specifies whether this certificate is for identification of a user +or a host using a SSH_CERT_TYPE_... value. + +key id is a free-form text field that is filled in by the CA at the time +of signing; the intention is that the contents of this field are used to +identify the identity principal in log messages. + +"valid principals" is a string containing zero or more principals as +strings packed inside it. These principals list the names for which this +certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and +usernames for SSH_CERT_TYPE_USER certificates. As a special case, a +zero-length "valid principals" field means the certificate is valid for +any principal of the specified type. XXX DNS wildcards? + +"valid after" and "valid before" specify a validity period for the +certificate. Each represents a time in seconds since 1970-01-01 +00:00:00. A certificate is considered valid if: + valid after <= current time < valid before + +constraints is a set of zero or more key constraints encoded as below. + +The nonce field is a CA-provided random bitstring of arbitrary length +(but typically 16 or 32 bytes) included to make attacks that depend on +inducing collisions in the signature hash infeasible. + +The reserved field is current unused and is ignored in this version of +the protocol. + +signature key contains the CA key used to sign the certificate. +The valid key types for CA keys are ssh-rsa and ssh-dss. "Chained" +certificates, where the signature key type is a certificate type itself +are NOT supported. Note that it is possible for a RSA certificate key to +be signed by a DSS CA key and vice-versa. + +signature is computed over all preceding fields from the initial string +up to, and including the signature key. Signatures are computed and +encoded according to the rules defined for the CA's public key algorithm +(RFC4253 section 6.6 for ssh-rsa and ssh-dss). + +Constraints +----------- + +The constraints section of the certificate specifies zero or more +constraints on the certificates validity. The format of this field +is a sequence of zero or more tuples: + + string name + string data + +The name field identifies the constraint and the data field encodes +constraint-specific information (see below). All constraints are +"critical", if an implementation does not recognise a constraint +then the validating party should refuse to accept the certificate. + +The supported constraints and the contents and structure of their +data fields are: + +Name Format Description +----------------------------------------------------------------------------- +force-command string Specifies a command that is executed + (replacing any the user specified on the + ssh command-line) whenever this key is + used for authentication. + +permit-X11-forwarding empty Flag indicating that X11 forwarding + should be permitted. X11 forwarding will + be refused if this constraint is absent. + +permit-agent-forwarding empty Flag indicating that agent forwarding + should be allowed. Agent forwarding + must not be permitted unless this + constraint is present. + +permit-port-forwarding empty Flag indicating that port-forwarding + should be allowed. If this constraint is + not present then no port forwarding will + be allowed. + +permit-pty empty Flag indicating that PTY allocation + should be permitted. In the absence of + this constraint PTY allocation will be + disabled. + +permit-user-rc empty Flag indicating that execution of + ~/.ssh/rc should be permitted. Execution + of this script will not be permitted if + this constraint is not present. + +source-address string Comma-separated list of source addresses + from which this certificate is accepted + for authentication. Addresses are + specified in CIDR format (nn.nn.nn.nn/nn + or hhhh::hhhh/nn). + If this constraint is not present then + certificates may be presented from any + source address. diff --git a/addrmatch.c b/addrmatch.c index d39885b7b..5b6773cce 100644 --- a/addrmatch.c +++ b/addrmatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addrmatch.c,v 1.4 2008/12/10 03:55:20 stevesk Exp $ */ +/* $OpenBSD: addrmatch.c,v 1.5 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -126,6 +126,8 @@ addr_netmask(int af, u_int l, struct xaddr *n) switch (af) { case AF_INET: n->af = AF_INET; + if (l == 0) + return 0; n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff); return 0; case AF_INET6: @@ -422,3 +424,77 @@ addr_match_list(const char *addr, const char *_list) return ret; } + +/* + * Match "addr" against list CIDR list "_list". Lexical wildcards and + * negation are not supported. If "addr" == NULL, will verify structure + * of "_list". + * + * Returns 1 on match found (never returned when addr == NULL). + * Returns 0 on if no match found, or no errors found when addr == NULL. + * Returns -1 on error + */ +int +addr_match_cidr_list(const char *addr, const char *_list) +{ + char *list, *cp, *o; + struct xaddr try_addr, match_addr; + u_int masklen; + int ret = 0, r; + + if (addr != NULL && addr_pton(addr, &try_addr) != 0) { + debug2("%s: couldn't parse address %.100s", __func__, addr); + return 0; + } + if ((o = list = strdup(_list)) == NULL) + return -1; + while ((cp = strsep(&list, ",")) != NULL) { + if (*cp == '\0') { + error("%s: empty entry in list \"%.100s\"", + __func__, o); + ret = -1; + break; + } + + /* + * NB. This function is called in pre-auth with untrusted data, + * so be extra paranoid about junk reaching getaddrino (via + * addr_pton_cidr). + */ + + /* Stop junk from reaching getaddrinfo. +3 is for masklen */ + if (strlen(cp) > INET6_ADDRSTRLEN + 3) { + error("%s: list entry \"%.100s\" too long", + __func__, cp); + ret = -1; + break; + } +#define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/" + if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) { + error("%s: list entry \"%.100s\" contains invalid " + "characters", __func__, cp); + ret = -1; + } + + /* Prefer CIDR address matching */ + r = addr_pton_cidr(cp, &match_addr, &masklen); + if (r == -1) { + error("Invalid network entry \"%.100s\"", cp); + ret = -1; + break; + } else if (r == -2) { + error("Inconsistent mask length for " + "network \"%.100s\"", cp); + ret = -1; + break; + } else if (r == 0 && addr != NULL) { + if (addr_netmatch(&try_addr, &match_addr, + masklen) == 0) + ret = 1; + continue; + } + } + xfree(o); + + return ret; +} diff --git a/auth-options.c b/auth-options.c index ab085c233..396bda62f 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.45 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -44,6 +44,7 @@ int no_agent_forwarding_flag = 0; int no_x11_forwarding_flag = 0; int no_pty_flag = 0; int no_user_rc = 0; +int key_is_cert_authority = 0; /* "command=" option. */ char *forced_command = NULL; @@ -64,6 +65,7 @@ auth_clear_options(void) no_pty_flag = 0; no_x11_forwarding_flag = 0; no_user_rc = 0; + key_is_cert_authority = 0; while (custom_environment) { struct envstring *ce = custom_environment; custom_environment = ce->next; @@ -96,6 +98,12 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) return 1; while (*opts && *opts != ' ' && *opts != '\t') { + cp = "cert-authority"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + key_is_cert_authority = 1; + opts += strlen(cp); + goto next_option; + } cp = "no-port-forwarding"; if (strncasecmp(opts, cp, strlen(cp)) == 0) { auth_debug_add("Port forwarding disabled."); @@ -374,3 +382,143 @@ bad_option: /* deny access */ return 0; } + +/* + * Set options from certificate constraints. These supersede user key options + * so this must be called after auth_parse_options(). + */ +int +auth_cert_constraints(Buffer *c_orig, struct passwd *pw) +{ + u_char *name = NULL, *data_blob = NULL; + u_int len; + Buffer c, data; + int ret = -1; + + int cert_no_port_forwarding_flag = 1; + int cert_no_agent_forwarding_flag = 1; + int cert_no_x11_forwarding_flag = 1; + int cert_no_pty_flag = 1; + int cert_no_user_rc = 1; + char *cert_forced_command = NULL; + int cert_source_address_done = 0; + + buffer_init(&data); + + /* Make copy to avoid altering original */ + buffer_init(&c); + buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig)); + + while (buffer_len(&c) > 0) { + if ((name = buffer_get_string_ret(&c, NULL)) == NULL || + (data_blob = buffer_get_string_ret(&c, &len)) == NULL) { + error("Certificate constraints corrupt"); + goto out; + } + buffer_append(&data, data_blob, len); + debug3("found certificate constraint \"%.100s\" len %u", + name, len); + if (strcmp(name, "permit-X11-forwarding") == 0) + cert_no_x11_forwarding_flag = 0; + else if (strcmp(name, "permit-agent-forwarding") == 0) + cert_no_agent_forwarding_flag = 0; + else if (strcmp(name, "permit-port-forwarding") == 0) + cert_no_port_forwarding_flag = 0; + else if (strcmp(name, "permit-pty") == 0) + cert_no_pty_flag = 0; + else if (strcmp(name, "permit-user-rc") == 0) + cert_no_user_rc = 0; + else if (strcmp(name, "force-command") == 0) { + char *command = buffer_get_string_ret(&data, NULL); + + if (command == NULL) { + error("Certificate constraint \"%s\" corrupt", + name); + goto out; + } + if (cert_forced_command != NULL) { + error("Certificate has multiple " + "forced-command constraints"); + xfree(command); + goto out; + } + cert_forced_command = command; + } else if (strcmp(name, "source-address") == 0) { + char *allowed = buffer_get_string_ret(&data, NULL); + const char *remote_ip = get_remote_ipaddr(); + + if (allowed == NULL) { + error("Certificate constraint \"%s\" corrupt", + name); + goto out; + } + if (cert_source_address_done++) { + error("Certificate has multiple " + "source-address constraints"); + xfree(allowed); + goto out; + } + switch (addr_match_cidr_list(remote_ip, allowed)) { + case 1: + /* accepted */ + xfree(allowed); + break; + case 0: + /* no match */ + logit("Authentication tried for %.100s with " + "valid certificate but not from a " + "permitted host (ip=%.200s).", + pw->pw_name, remote_ip); + auth_debug_add("Your address '%.200s' is not " + "permitted to use this certificate for " + "login.", remote_ip); + xfree(allowed); + goto out; + case -1: + error("Certificate source-address contents " + "invalid"); + xfree(allowed); + goto out; + } + } else { + error("Certificate constraint \"%s\" is not supported", + name); + goto out; + } + + if (buffer_len(&data) != 0) { + error("Certificate constraint \"%s\" corrupt " + "(extra data)", name); + goto out; + } + buffer_clear(&data); + xfree(name); + xfree(data_blob); + name = data_blob = NULL; + } + + /* successfully parsed all constraints */ + ret = 0; + + no_port_forwarding_flag |= cert_no_port_forwarding_flag; + no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; + no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; + no_pty_flag |= cert_no_pty_flag; + no_user_rc |= cert_no_user_rc; + /* CA-specified forced command supersedes key option */ + if (cert_forced_command != NULL) { + if (forced_command != NULL) + xfree(forced_command); + forced_command = cert_forced_command; + } + + out: + if (name != NULL) + xfree(name); + if (data_blob != NULL) + xfree(data_blob); + buffer_free(&data); + buffer_free(&c); + return ret; +} + diff --git a/auth-options.h b/auth-options.h index 14488f72d..694edc842 100644 --- a/auth-options.h +++ b/auth-options.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.h,v 1.17 2008/03/26 21:28:14 djm Exp $ */ +/* $OpenBSD: auth-options.h,v 1.18 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen @@ -30,8 +30,10 @@ extern int no_user_rc; extern char *forced_command; extern struct envstring *custom_environment; extern int forced_tun_device; +extern int key_is_cert_authority; int auth_parse_options(struct passwd *, char *, char *, u_long); void auth_clear_options(void); +int auth_cert_constraints(Buffer *, struct passwd *); #endif diff --git a/auth.h b/auth.h index bebfb672d..117485ca9 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.63 2009/08/15 18:56:34 fgsch Exp $ */ +/* $OpenBSD: auth.h,v 1.64 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -178,7 +178,8 @@ check_key_in_hostfiles(struct passwd *, Key *, const char *, /* hostkey handling */ Key *get_hostkey_by_index(int); -Key *get_hostkey_by_type(int); +Key *get_hostkey_public_by_type(int); +Key *get_hostkey_private_by_type(int); int get_hostkey_index(Key *); int ssh1_session_key(BIGNUM *); diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 2886f1275..66ca5266b 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.19 2008/07/03 21:46:58 otto Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.20 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include "xmalloc.h" @@ -178,6 +180,7 @@ static int user_key_allowed2(struct passwd *pw, Key *key, char *file) { char line[SSH_MAX_PUBKEY_BYTES]; + const char *reason; int found_key = 0; FILE *f; u_long linenum = 0; @@ -196,11 +199,13 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) } found_key = 0; - found = key_new(key->type); + found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { char *cp, *key_options = NULL; + auth_clear_options(); + /* Skip leading whitespace, empty and comment lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; @@ -227,8 +232,32 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) continue; } } - if (key_equal(found, key) && - auth_parse_options(pw, key_options, file, linenum) == 1) { + if (auth_parse_options(pw, key_options, file, linenum) != 1) + continue; + if (key->type == KEY_RSA_CERT || key->type == KEY_DSA_CERT) { + if (!key_is_cert_authority) + continue; + if (!key_equal(found, key->cert->signature_key)) + continue; + debug("matching CA found: file %s, line %lu", + file, linenum); + fp = key_fingerprint(found, SSH_FP_MD5, + SSH_FP_HEX); + verbose("Found matching %s CA: %s", + key_type(found), fp); + xfree(fp); + if (key_cert_check_authority(key, 0, 0, pw->pw_name, + &reason) != 0) { + error("%s", reason); + auth_debug_add("%s", reason); + continue; + } + if (auth_cert_constraints(&key->cert->constraints, + pw) != 0) + continue; + found_key = 1; + break; + } else if (!key_is_cert_authority && key_equal(found, key)) { found_key = 1; debug("matching key found: file %s, line %lu", file, linenum); diff --git a/authfd.c b/authfd.c index 78a53c7a6..28a8cf2d7 100644 --- a/authfd.c +++ b/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.81 2009/08/27 17:44:52 djm Exp $ */ +/* $OpenBSD: authfd.c,v 1.82 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -483,6 +483,16 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) buffer_put_bignum2(b, key->rsa->p); buffer_put_bignum2(b, key->rsa->q); break; + case KEY_RSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, key->rsa->d); + buffer_put_bignum2(b, key->rsa->iqmp); + buffer_put_bignum2(b, key->rsa->p); + buffer_put_bignum2(b, key->rsa->q); + break; case KEY_DSA: buffer_put_bignum2(b, key->dsa->p); buffer_put_bignum2(b, key->dsa->q); @@ -490,6 +500,13 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) buffer_put_bignum2(b, key->dsa->pub_key); buffer_put_bignum2(b, key->dsa->priv_key); break; + case KEY_DSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, key->dsa->priv_key); + break; } buffer_put_cstring(b, comment); } @@ -517,7 +534,9 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, ssh_encode_identity_rsa1(&msg, key->rsa, comment); break; case KEY_RSA: + case KEY_RSA_CERT: case KEY_DSA: + case KEY_DSA_CERT: type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; @@ -565,7 +584,8 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key) buffer_put_int(&msg, BN_num_bits(key->rsa->n)); buffer_put_bignum(&msg, key->rsa->e); buffer_put_bignum(&msg, key->rsa->n); - } else if (key->type == KEY_DSA || key->type == KEY_RSA) { + } else if (key_type_plain(key->type) == KEY_DSA || + key_type_plain(key->type) == KEY_RSA) { key_to_blob(key, &blob, &blen); buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); buffer_put_string(&msg, blob, blen); diff --git a/dns.c b/dns.c index a7da03fa3..2e7bb5aae 100644 --- a/dns.c +++ b/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.25 2008/06/12 00:03:49 dtucker Exp $ */ +/* $OpenBSD: dns.c,v 1.26 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -75,7 +75,7 @@ dns_result_totext(unsigned int res) */ static int dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, - u_char **digest, u_int *digest_len, const Key *key) + u_char **digest, u_int *digest_len, Key *key) { int success = 0; @@ -172,7 +172,7 @@ is_numeric_hostname(const char *hostname) */ int verify_host_key_dns(const char *hostname, struct sockaddr *address, - const Key *hostkey, int *flags) + Key *hostkey, int *flags) { u_int counter; int result; @@ -271,7 +271,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, * Export the fingerprint of a key as a DNS resource record */ int -export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic) +export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) { u_int8_t rdata_pubkey_algorithm = 0; u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; diff --git a/dns.h b/dns.h index b2633a1fe..90cfd7b92 100644 --- a/dns.h +++ b/dns.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: dns.h,v 1.11 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -46,7 +46,7 @@ enum sshfp_hashes { #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 -int verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *); -int export_dns_rr(const char *, const Key *, FILE *, int); +int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); +int export_dns_rr(const char *, Key *, FILE *, int); #endif /* DNS_H */ diff --git a/hostfile.c b/hostfile.c index cd28bf446..fc7f84c79 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.46 2009/10/11 23:03:15 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.47 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -199,7 +199,7 @@ check_host_in_hostfile_by_key_or_type(const char *filename, { FILE *f; char line[8192]; - int linenum = 0; + int linenum = 0, want_cert = key_is_cert(key); u_int kbits; char *cp, *cp2, *hashed_host; HostStatus end_return; @@ -229,6 +229,23 @@ check_host_in_hostfile_by_key_or_type(const char *filename, if (!*cp || *cp == '#' || *cp == '\n') continue; + /* + * Ignore CA keys when looking for raw keys. + * Ignore raw keys when looking for CA keys. + */ + if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && + (cp[sizeof(CA_MARKER) - 1] == ' ' || + cp[sizeof(CA_MARKER) - 1] == '\t')) { + if (want_cert) { + /* Skip the marker and following whitespace */ + cp += sizeof(CA_MARKER); + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + } else + continue; + } else if (want_cert) + continue; + /* Find the end of the host name portion. */ for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) ; @@ -273,8 +290,14 @@ check_host_in_hostfile_by_key_or_type(const char *filename, continue; /* Check if the current key is the same as the given key. */ - if (key_equal(key, found)) { - /* Ok, they match. */ + if (want_cert && key_equal(key->cert->signature_key, found)) { + /* Found CA cert for key */ + debug3("check_host_in_hostfile: CA match line %d", + linenum); + fclose(f); + return HOST_OK; + } else if (!want_cert && key_equal(key, found)) { + /* Found identical key */ debug3("check_host_in_hostfile: match line %d", linenum); fclose(f); return HOST_OK; diff --git a/hostfile.h b/hostfile.h index d1983b3e0..ebac1e4f1 100644 --- a/hostfile.h +++ b/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.17 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen @@ -28,6 +28,8 @@ int lookup_key_in_hostfile_by_type(const char *, const char *, #define HASH_MAGIC "|1|" #define HASH_DELIM '|' +#define CA_MARKER "@cert-authority" + char *host_hash(const char *, const char *, u_int); #endif diff --git a/kex.h b/kex.h index 1fa13799d..62fa2ea50 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.48 2009/10/24 11:13:54 andreas Exp $ */ +/* $OpenBSD: kex.h,v 1.49 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -126,7 +126,8 @@ struct Kex { char *client_version_string; char *server_version_string; int (*verify_host_key)(Key *); - Key *(*load_host_key)(int); + Key *(*load_host_public_key)(int); + Key *(*load_host_private_key)(int); int (*host_key_index)(Key *); void (*kex[KEX_MAX])(Kex *); }; diff --git a/kexdhs.c b/kexdhs.c index a6719f672..e722877d5 100644 --- a/kexdhs.c +++ b/kexdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhs.c,v 1.10 2009/06/21 07:37:15 dtucker Exp $ */ +/* $OpenBSD: kexdhs.c,v 1.11 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -50,7 +50,7 @@ kexdh_server(Kex *kex) { BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; DH *dh; - Key *server_host_key; + Key *server_host_public, *server_host_private; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; u_int sbloblen, klen, hashlen, slen; int kout; @@ -71,11 +71,16 @@ kexdh_server(Kex *kex) debug("expecting SSH2_MSG_KEXDH_INIT"); packet_read_expect(SSH2_MSG_KEXDH_INIT); - if (kex->load_host_key == NULL) + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) fatal("Cannot load hostkey"); - server_host_key = kex->load_host_key(kex->hostkey_type); - if (server_host_key == NULL) + server_host_public = kex->load_host_public_key(kex->hostkey_type); + if (server_host_public == NULL) fatal("Unsupported hostkey type %d", kex->hostkey_type); + server_host_private = kex->load_host_private_key(kex->hostkey_type); + if (server_host_private == NULL) + fatal("Missing private key for hostkey type %d", + kex->hostkey_type); /* key, cert */ if ((dh_client_pub = BN_new()) == NULL) @@ -113,7 +118,7 @@ kexdh_server(Kex *kex) memset(kbuf, 0, klen); xfree(kbuf); - key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); + key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); /* calc H */ kex_dh_hash( @@ -137,7 +142,7 @@ kexdh_server(Kex *kex) } /* sign H */ - if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, + if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, hashlen)) < 0) fatal("kexdh_server: key_sign failed"); diff --git a/kexgexs.c b/kexgexs.c index 8515568b3..f4156af96 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.12 2009/06/21 07:37:15 dtucker Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.13 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -52,18 +52,24 @@ void kexgex_server(Kex *kex) { BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - Key *server_host_key; + Key *server_host_public, *server_host_private; DH *dh; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; u_int sbloblen, klen, slen, hashlen; int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1; int type, kout; - if (kex->load_host_key == NULL) + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) fatal("Cannot load hostkey"); - server_host_key = kex->load_host_key(kex->hostkey_type); - if (server_host_key == NULL) + server_host_public = kex->load_host_public_key(kex->hostkey_type); + if (server_host_public == NULL) fatal("Unsupported hostkey type %d", kex->hostkey_type); + server_host_private = kex->load_host_private_key(kex->hostkey_type); + if (server_host_private == NULL) + fatal("Missing private key for hostkey type %d", + kex->hostkey_type); + type = packet_read(); switch (type) { @@ -149,7 +155,7 @@ kexgex_server(Kex *kex) memset(kbuf, 0, klen); xfree(kbuf); - key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); + key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) omin = min = omax = max = -1; @@ -179,7 +185,7 @@ kexgex_server(Kex *kex) } /* sign H */ - if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, + if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, hashlen)) < 0) fatal("kexgex_server: key_sign failed"); diff --git a/key.c b/key.c index 5aea416b3..387190b53 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.82 2010/01/13 01:10:56 dtucker Exp $ */ +/* $OpenBSD: key.c,v 1.83 2010/02/26 20:29:54 djm Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -52,6 +52,21 @@ #include "uuencode.h" #include "buffer.h" #include "log.h" +#include "ssh2.h" + +static struct KeyCert * +cert_new(void) +{ + struct KeyCert *cert; + + cert = xcalloc(1, sizeof(*cert)); + buffer_init(&cert->certblob); + buffer_init(&cert->constraints); + cert->key_id = NULL; + cert->principals = NULL; + cert->signature_key = NULL; + return cert; +} Key * key_new(int type) @@ -63,9 +78,11 @@ key_new(int type) k->type = type; k->dsa = NULL; k->rsa = NULL; + k->cert = NULL; switch (k->type) { case KEY_RSA1: case KEY_RSA: + case KEY_RSA_CERT: if ((rsa = RSA_new()) == NULL) fatal("key_new: RSA_new failed"); if ((rsa->n = BN_new()) == NULL) @@ -75,6 +92,7 @@ key_new(int type) k->rsa = rsa; break; case KEY_DSA: + case KEY_DSA_CERT: if ((dsa = DSA_new()) == NULL) fatal("key_new: DSA_new failed"); if ((dsa->p = BN_new()) == NULL) @@ -93,16 +111,20 @@ key_new(int type) fatal("key_new: bad key type %d", k->type); break; } + + if (key_is_cert(k)) + k->cert = cert_new(); + return k; } -Key * -key_new_private(int type) +void +key_add_private(Key *k) { - Key *k = key_new(type); switch (k->type) { case KEY_RSA1: case KEY_RSA: + case KEY_RSA_CERT: if ((k->rsa->d = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); if ((k->rsa->iqmp = BN_new()) == NULL) @@ -117,6 +139,7 @@ key_new_private(int type) fatal("key_new_private: BN_new failed"); break; case KEY_DSA: + case KEY_DSA_CERT: if ((k->dsa->priv_key = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); break; @@ -125,9 +148,34 @@ key_new_private(int type) default: break; } +} + +Key * +key_new_private(int type) +{ + Key *k = key_new(type); + + key_add_private(k); return k; } +static void +cert_free(struct KeyCert *cert) +{ + u_int i; + + buffer_free(&cert->certblob); + buffer_free(&cert->constraints); + if (cert->key_id != NULL) + xfree(cert->key_id); + for (i = 0; i < cert->nprincipals; i++) + xfree(cert->principals[i]); + if (cert->principals != NULL) + xfree(cert->principals); + if (cert->signature_key != NULL) + key_free(cert->signature_key); +} + void key_free(Key *k) { @@ -136,11 +184,13 @@ key_free(Key *k) switch (k->type) { case KEY_RSA1: case KEY_RSA: + case KEY_RSA_CERT: if (k->rsa != NULL) RSA_free(k->rsa); k->rsa = NULL; break; case KEY_DSA: + case KEY_DSA_CERT: if (k->dsa != NULL) DSA_free(k->dsa); k->dsa = NULL; @@ -151,20 +201,49 @@ key_free(Key *k) fatal("key_free: bad key type %d", k->type); break; } + if (key_is_cert(k)) { + if (k->cert != NULL) + cert_free(k->cert); + k->cert = NULL; + } + xfree(k); } +static int +cert_compare(struct KeyCert *a, struct KeyCert *b) +{ + if (a == NULL && b == NULL) + return 1; + if (a == NULL || b == NULL) + return 0; + if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) + return 0; + if (memcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), + buffer_len(&a->certblob)) != 0) + return 0; + return 1; +} + +/* + * Compare public portions of key only, allowing comparisons between + * certificates and plain keys too. + */ int -key_equal(const Key *a, const Key *b) +key_equal_public(const Key *a, const Key *b) { - if (a == NULL || b == NULL || a->type != b->type) + if (a == NULL || b == NULL || + key_type_plain(a->type) != key_type_plain(b->type)) return 0; + switch (a->type) { case KEY_RSA1: + case KEY_RSA_CERT: case KEY_RSA: return a->rsa != NULL && b->rsa != NULL && BN_cmp(a->rsa->e, b->rsa->e) == 0 && BN_cmp(a->rsa->n, b->rsa->n) == 0; + case KEY_DSA_CERT: case KEY_DSA: return a->dsa != NULL && b->dsa != NULL && BN_cmp(a->dsa->p, b->dsa->p) == 0 && @@ -177,16 +256,27 @@ key_equal(const Key *a, const Key *b) /* NOTREACHED */ } +int +key_equal(const Key *a, const Key *b) +{ + if (a == NULL || b == NULL || a->type != b->type) + return 0; + if (key_is_cert(a)) { + if (!cert_compare(a->cert, b->cert)) + return 0; + } + return key_equal_public(a, b); +} + u_char* -key_fingerprint_raw(const Key *k, enum fp_type dgst_type, - u_int *dgst_raw_length) +key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) { const EVP_MD *md = NULL; EVP_MD_CTX ctx; u_char *blob = NULL; u_char *retval = NULL; u_int len = 0; - int nlen, elen; + int nlen, elen, otype; *dgst_raw_length = 0; @@ -214,6 +304,14 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type, case KEY_RSA: key_to_blob(k, &blob, &len); break; + case KEY_DSA_CERT: + case KEY_RSA_CERT: + /* We want a fingerprint of the _key_ not of the cert */ + otype = k->type; + k->type = key_type_plain(k->type); + key_to_blob(k, &blob, &len); + k->type = otype; + break; case KEY_UNSPEC: return retval; default: @@ -408,7 +506,7 @@ key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) } char * -key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) +key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) { char *retval = NULL; u_char *dgst_raw; @@ -533,6 +631,8 @@ key_read(Key *ret, char **cpp) case KEY_UNSPEC: case KEY_RSA: case KEY_DSA: + case KEY_DSA_CERT: + case KEY_RSA_CERT: space = strchr(cp, ' '); if (space == NULL) { debug3("key_read: missing whitespace"); @@ -577,25 +677,36 @@ key_read(Key *ret, char **cpp) return -1; } /*XXXX*/ - if (ret->type == KEY_RSA) { + if (key_is_cert(ret)) { + if (!key_is_cert(k)) { + error("key_read: loaded key is not a cert"); + key_free(k); + return -1; + } + if (ret->cert != NULL) + cert_free(ret->cert); + ret->cert = k->cert; + k->cert = NULL; + } + if (key_type_plain(ret->type) == KEY_RSA) { if (ret->rsa != NULL) RSA_free(ret->rsa); ret->rsa = k->rsa; k->rsa = NULL; - success = 1; #ifdef DEBUG_PK RSA_print_fp(stderr, ret->rsa, 8); #endif - } else { + } + if (key_type_plain(ret->type) == KEY_DSA) { if (ret->dsa != NULL) DSA_free(ret->dsa); ret->dsa = k->dsa; k->dsa = NULL; - success = 1; #ifdef DEBUG_PK DSA_print_fp(stderr, ret->dsa, 8); #endif } + success = 1; /*XXXX*/ key_free(k); if (success != 1) @@ -622,28 +733,53 @@ key_write(const Key *key, FILE *f) u_char *blob; char *uu; - if (key->type == KEY_RSA1 && key->rsa != NULL) { + if (key_is_cert(key)) { + if (key->cert == NULL) { + error("%s: no cert data", __func__); + return 0; + } + if (buffer_len(&key->cert->certblob) == 0) { + error("%s: no signed certificate blob", __func__); + return 0; + } + } + + switch (key->type) { + case KEY_RSA1: + if (key->rsa == NULL) + return 0; /* size of modulus 'n' */ bits = BN_num_bits(key->rsa->n); fprintf(f, "%u", bits); if (write_bignum(f, key->rsa->e) && - write_bignum(f, key->rsa->n)) { - success = 1; - } else { - error("key_write: failed for RSA key"); - } - } else if ((key->type == KEY_DSA && key->dsa != NULL) || - (key->type == KEY_RSA && key->rsa != NULL)) { - key_to_blob(key, &blob, &len); - uu = xmalloc(2*len); - n = uuencode(blob, len, uu, 2*len); - if (n > 0) { - fprintf(f, "%s %s", key_ssh_name(key), uu); - success = 1; - } - xfree(blob); - xfree(uu); + write_bignum(f, key->rsa->n)) + return 1; + error("key_write: failed for RSA key"); + return 0; + case KEY_DSA: + case KEY_DSA_CERT: + if (key->dsa == NULL) + return 0; + break; + case KEY_RSA: + case KEY_RSA_CERT: + if (key->rsa == NULL) + return 0; + break; + default: + return 0; } + + key_to_blob(key, &blob, &len); + uu = xmalloc(2*len); + n = uuencode(blob, len, uu, 2*len); + if (n > 0) { + fprintf(f, "%s %s", key_ssh_name(key), uu); + success = 1; + } + xfree(blob); + xfree(uu); + return success; } @@ -657,6 +793,10 @@ key_type(const Key *k) return "RSA"; case KEY_DSA: return "DSA"; + case KEY_RSA_CERT: + return "RSA-CERT"; + case KEY_DSA_CERT: + return "DSA-CERT"; } return "unknown"; } @@ -669,6 +809,10 @@ key_ssh_name(const Key *k) return "ssh-rsa"; case KEY_DSA: return "ssh-dss"; + case KEY_RSA_CERT: + return "ssh-rsa-cert-v00@openssh.com"; + case KEY_DSA_CERT: + return "ssh-dss-cert-v00@openssh.com"; } return "ssh-unknown"; } @@ -679,8 +823,10 @@ key_size(const Key *k) switch (k->type) { case KEY_RSA1: case KEY_RSA: + case KEY_RSA_CERT: return BN_num_bits(k->rsa->n); case KEY_DSA: + case KEY_DSA_CERT: return BN_num_bits(k->dsa->p); } return 0; @@ -723,6 +869,9 @@ key_generate(int type, u_int bits) case KEY_RSA1: k->rsa = rsa_generate_private_key(bits); break; + case KEY_RSA_CERT: + case KEY_DSA_CERT: + fatal("key_generate: cert keys cannot be generated directly"); default: fatal("key_generate: unknown type %d", type); } @@ -730,12 +879,55 @@ key_generate(int type, u_int bits) return k; } +void +key_cert_copy(const Key *from_key, struct Key *to_key) +{ + u_int i; + const struct KeyCert *from; + struct KeyCert *to; + + if (to_key->cert != NULL) { + cert_free(to_key->cert); + to_key->cert = NULL; + } + + if ((from = from_key->cert) == NULL) + return; + + to = to_key->cert = cert_new(); + + buffer_append(&to->certblob, buffer_ptr(&from->certblob), + buffer_len(&from->certblob)); + + buffer_append(&to->constraints, buffer_ptr(&from->constraints), + buffer_len(&from->constraints)); + + to->type = from->type; + to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); + to->valid_after = from->valid_after; + to->valid_before = from->valid_before; + to->signature_key = from->signature_key == NULL ? + NULL : key_from_private(from->signature_key); + + to->nprincipals = from->nprincipals; + if (to->nprincipals > CERT_MAX_PRINCIPALS) + fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)", + __func__, to->nprincipals, CERT_MAX_PRINCIPALS); + if (to->nprincipals > 0) { + to->principals = xcalloc(from->nprincipals, + sizeof(*to->principals)); + for (i = 0; i < to->nprincipals; i++) + to->principals[i] = xstrdup(from->principals[i]); + } +} + Key * key_from_private(const Key *k) { Key *n = NULL; switch (k->type) { case KEY_DSA: + case KEY_DSA_CERT: n = key_new(k->type); if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || (BN_copy(n->dsa->q, k->dsa->q) == NULL) || @@ -745,6 +937,7 @@ key_from_private(const Key *k) break; case KEY_RSA: case KEY_RSA1: + case KEY_RSA_CERT: n = key_new(k->type); if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || (BN_copy(n->rsa->e, k->rsa->e) == NULL)) @@ -754,6 +947,8 @@ key_from_private(const Key *k) fatal("key_from_private: unknown type %d", k->type); break; } + if (key_is_cert(k)) + key_cert_copy(k, n); return n; } @@ -770,6 +965,10 @@ key_type_from_name(char *name) return KEY_RSA; } else if (strcmp(name, "ssh-dss") == 0) { return KEY_DSA; + } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { + return KEY_RSA_CERT; + } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { + return KEY_DSA_CERT; } debug2("key_type_from_name: unknown key type '%s'", name); return KEY_UNSPEC; @@ -797,6 +996,117 @@ key_names_valid2(const char *names) return 1; } +static int +cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) +{ + u_char *principals, *constraints, *sig_key, *sig; + u_int signed_len, plen, clen, sklen, slen; + Buffer tmp; + char *principal; + int ret = -1; + + buffer_init(&tmp); + + /* Copy the entire key blob for verification and later serialisation */ + buffer_append(&key->cert->certblob, blob, blen); + + principals = constraints = sig_key = sig = NULL; + if (buffer_get_int_ret(&key->cert->type, b) != 0 || + (key->cert->key_id = buffer_get_string_ret(b, NULL)) == NULL || + (principals = buffer_get_string_ret(b, &plen)) == NULL || + buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || + buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || + (constraints = buffer_get_string_ret(b, &clen)) == NULL || + /* skip nonce */ buffer_get_string_ptr_ret(b, NULL) == NULL || + /* skip reserved */ buffer_get_string_ptr_ret(b, NULL) == NULL || + (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { + error("%s: parse error", __func__); + goto out; + } + + /* Signature is left in the buffer so we can calculate this length */ + signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); + + if ((sig = buffer_get_string_ret(b, &slen)) == NULL) { + error("%s: parse error", __func__); + goto out; + } + + if (key->cert->type != SSH2_CERT_TYPE_USER && + key->cert->type != SSH2_CERT_TYPE_HOST) { + error("Unknown certificate type %u", key->cert->type); + goto out; + } + + buffer_append(&tmp, principals, plen); + while (buffer_len(&tmp) > 0) { + if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { + error("Too many principals"); + goto out; + } + if ((principal = buffer_get_string_ret(&tmp, NULL)) == NULL) { + error("Principals data invalid"); + goto out; + } + key->cert->principals = xrealloc(key->cert->principals, + key->cert->nprincipals + 1, sizeof(*key->cert->principals)); + key->cert->principals[key->cert->nprincipals++] = principal; + } + + buffer_clear(&tmp); + + buffer_append(&key->cert->constraints, constraints, clen); + buffer_append(&tmp, constraints, clen); + /* validate structure */ + while (buffer_len(&tmp) != 0) { + if (buffer_get_string_ptr(&tmp, NULL) == NULL || + buffer_get_string_ptr(&tmp, NULL) == NULL) { + error("Constraints data invalid"); + goto out; + } + } + buffer_clear(&tmp); + + if ((key->cert->signature_key = key_from_blob(sig_key, + sklen)) == NULL) { + error("Signature key invalid"); + goto out; + } + if (key->cert->signature_key->type != KEY_RSA && + key->cert->signature_key->type != KEY_DSA) { + error("Invalid signature key type %s (%d)", + key_type(key->cert->signature_key), + key->cert->signature_key->type); + goto out; + } + + switch (key_verify(key->cert->signature_key, sig, slen, + buffer_ptr(&key->cert->certblob), signed_len)) { + case 1: + break; /* Good signature */ + case 0: + error("Invalid signature on certificate"); + goto out; + case -1: + error("Certificate signature verification failed"); + goto out; + } + + ret = 0; + + out: + buffer_free(&tmp); + if (principals != NULL) + xfree(principals); + if (constraints != NULL) + xfree(constraints); + if (sig_key != NULL) + xfree(sig_key); + if (sig != NULL) + xfree(sig); + return ret; +} + Key * key_from_blob(const u_char *blob, u_int blen) { @@ -819,10 +1129,12 @@ key_from_blob(const u_char *blob, u_int blen) switch (type) { case KEY_RSA: + case KEY_RSA_CERT: key = key_new(type); if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { error("key_from_blob: can't read rsa key"); + badkey: key_free(key); key = NULL; goto out; @@ -832,15 +1144,14 @@ key_from_blob(const u_char *blob, u_int blen) #endif break; case KEY_DSA: + case KEY_DSA_CERT: key = key_new(type); if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { error("key_from_blob: can't read dsa key"); - key_free(key); - key = NULL; - goto out; + goto badkey; } #ifdef DEBUG_PK DSA_print_fp(stderr, key->dsa, 8); @@ -853,6 +1164,10 @@ key_from_blob(const u_char *blob, u_int blen) error("key_from_blob: cannot handle type %s", ktype); goto out; } + if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) { + error("key_from_blob: can't parse cert data"); + goto badkey; + } rlen = buffer_len(&b); if (key != NULL && rlen != 0) error("key_from_blob: remaining bytes in key blob %d", rlen); @@ -875,6 +1190,12 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) } buffer_init(&b); switch (key->type) { + case KEY_DSA_CERT: + case KEY_RSA_CERT: + /* Use the existing blob */ + buffer_append(&b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + break; case KEY_DSA: buffer_put_cstring(&b, key_ssh_name(key)); buffer_put_bignum2(&b, key->dsa->p); @@ -911,8 +1232,10 @@ key_sign( const u_char *data, u_int datalen) { switch (key->type) { + case KEY_DSA_CERT: case KEY_DSA: return ssh_dss_sign(key, sigp, lenp, data, datalen); + case KEY_RSA_CERT: case KEY_RSA: return ssh_rsa_sign(key, sigp, lenp, data, datalen); default: @@ -935,8 +1258,10 @@ key_verify( return -1; switch (key->type) { + case KEY_DSA_CERT: case KEY_DSA: return ssh_dss_verify(key, signature, signaturelen, data, datalen); + case KEY_RSA_CERT: case KEY_RSA: return ssh_rsa_verify(key, signature, signaturelen, data, datalen); default: @@ -958,6 +1283,9 @@ key_demote(const Key *k) pk->rsa = NULL; switch (k->type) { + case KEY_RSA_CERT: + key_cert_copy(k, pk); + /* FALLTHROUGH */ case KEY_RSA1: case KEY_RSA: if ((pk->rsa = RSA_new()) == NULL) @@ -967,6 +1295,9 @@ key_demote(const Key *k) if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) fatal("key_demote: BN_dup failed"); break; + case KEY_DSA_CERT: + key_cert_copy(k, pk); + /* FALLTHROUGH */ case KEY_DSA: if ((pk->dsa = DSA_new()) == NULL) fatal("key_demote: DSA_new failed"); @@ -986,3 +1317,199 @@ key_demote(const Key *k) return (pk); } + +int +key_is_cert(const Key *k) +{ + return k != NULL && + (k->type == KEY_RSA_CERT || k->type == KEY_DSA_CERT); +} + +/* Return the cert-less equivalent to a certified key type */ +int +key_type_plain(int type) +{ + switch (type) { + case KEY_RSA_CERT: + return KEY_RSA; + case KEY_DSA_CERT: + return KEY_DSA; + default: + return type; + } +} + +/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */ +int +key_to_certified(Key *k) +{ + switch (k->type) { + case KEY_RSA: + k->cert = cert_new(); + k->type = KEY_RSA_CERT; + return 0; + case KEY_DSA: + k->cert = cert_new(); + k->type = KEY_DSA_CERT; + return 0; + default: + error("%s: key has incorrect type %s", __func__, key_type(k)); + return -1; + } +} + +/* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */ +int +key_drop_cert(Key *k) +{ + switch (k->type) { + case KEY_RSA_CERT: + cert_free(k->cert); + k->type = KEY_RSA; + return 0; + case KEY_DSA_CERT: + cert_free(k->cert); + k->type = KEY_DSA; + return 0; + default: + error("%s: key has incorrect type %s", __func__, key_type(k)); + return -1; + } +} + +/* Sign a KEY_RSA_CERT or KEY_DSA_CERT, (re-)generating the signed certblob */ +int +key_certify(Key *k, Key *ca) +{ + Buffer principals; + u_char *ca_blob, *sig_blob, nonce[32]; + u_int i, ca_len, sig_len; + + if (k->cert == NULL) { + error("%s: key lacks cert info", __func__); + return -1; + } + + if (!key_is_cert(k)) { + error("%s: certificate has unknown type %d", __func__, + k->cert->type); + return -1; + } + + if (ca->type != KEY_RSA && ca->type != KEY_DSA) { + error("%s: CA key has unsupported type %s", __func__, + key_type(ca)); + return -1; + } + + key_to_blob(ca, &ca_blob, &ca_len); + + buffer_clear(&k->cert->certblob); + buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); + + switch (k->type) { + case KEY_DSA_CERT: + buffer_put_bignum2(&k->cert->certblob, k->dsa->p); + buffer_put_bignum2(&k->cert->certblob, k->dsa->q); + buffer_put_bignum2(&k->cert->certblob, k->dsa->g); + buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); + break; + case KEY_RSA_CERT: + buffer_put_bignum2(&k->cert->certblob, k->rsa->e); + buffer_put_bignum2(&k->cert->certblob, k->rsa->n); + break; + default: + error("%s: key has incorrect type %s", __func__, key_type(k)); + buffer_clear(&k->cert->certblob); + xfree(ca_blob); + return -1; + } + + buffer_put_int(&k->cert->certblob, k->cert->type); + buffer_put_cstring(&k->cert->certblob, k->cert->key_id); + + buffer_init(&principals); + for (i = 0; i < k->cert->nprincipals; i++) + buffer_put_cstring(&principals, k->cert->principals[i]); + buffer_put_string(&k->cert->certblob, buffer_ptr(&principals), + buffer_len(&principals)); + buffer_free(&principals); + + buffer_put_int64(&k->cert->certblob, k->cert->valid_after); + buffer_put_int64(&k->cert->certblob, k->cert->valid_before); + buffer_put_string(&k->cert->certblob, + buffer_ptr(&k->cert->constraints), + buffer_len(&k->cert->constraints)); + + arc4random_buf(&nonce, sizeof(nonce)); + buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); + buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ + buffer_put_string(&k->cert->certblob, ca_blob, ca_len); + xfree(ca_blob); + + /* Sign the whole mess */ + if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob), + buffer_len(&k->cert->certblob)) != 0) { + error("%s: signature operation failed", __func__); + buffer_clear(&k->cert->certblob); + return -1; + } + /* Append signature and we are done */ + buffer_put_string(&k->cert->certblob, sig_blob, sig_len); + xfree(sig_blob); + + return 0; +} + +int +key_cert_check_authority(const Key *k, int want_host, int require_principal, + const char *name, const char **reason) +{ + u_int i, principal_matches; + time_t now = time(NULL); + + if (want_host) { + if (k->cert->type != SSH2_CERT_TYPE_HOST) { + *reason = "Certificate invalid: not a host certificate"; + return -1; + } + } else { + if (k->cert->type != SSH2_CERT_TYPE_USER) { + *reason = "Certificate invalid: not a user certificate"; + return -1; + } + } + if (now < 0) { + error("%s: system clock lies before epoch", __func__); + *reason = "Certificate invalid: not yet valid"; + return -1; + } + if ((u_int64_t)now < k->cert->valid_after) { + *reason = "Certificate invalid: not yet valid"; + return -1; + } + if ((u_int64_t)now >= k->cert->valid_before) { + *reason = "Certificate invalid: expired"; + return -1; + } + if (k->cert->nprincipals == 0) { + if (require_principal) { + *reason = "Certificate lacks principal list"; + return -1; + } + } else { + principal_matches = 0; + for (i = 0; i < k->cert->nprincipals; i++) { + if (strcmp(name, k->cert->principals[i]) == 0) { + principal_matches = 1; + break; + } + } + if (!principal_matches) { + *reason = "Certificate invalid: name is not a listed " + "principal"; + return -1; + } + } + return 0; +} diff --git a/key.h b/key.h index 14aac79c2..6a2e049af 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.27 2008/06/11 21:01:35 grunk Exp $ */ +/* $OpenBSD: key.h,v 1.28 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -26,6 +26,7 @@ #ifndef KEY_H #define KEY_H +#include "buffer.h" #include #include @@ -34,6 +35,8 @@ enum types { KEY_RSA1, KEY_RSA, KEY_DSA, + KEY_RSA_CERT, + KEY_DSA_CERT, KEY_UNSPEC }; enum fp_type { @@ -49,20 +52,35 @@ enum fp_rep { /* key is stored in external hardware */ #define KEY_FLAG_EXT 0x0001 +#define CERT_MAX_PRINCIPALS 256 +struct KeyCert { + Buffer certblob; /* Kept around for use on wire */ + u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */ + char *key_id; + u_int nprincipals; + char **principals; + u_int64_t valid_after, valid_before; + Buffer constraints; + Key *signature_key; +}; + struct Key { int type; int flags; RSA *rsa; DSA *dsa; + struct KeyCert *cert; }; Key *key_new(int); +void key_add_private(Key *); Key *key_new_private(int); void key_free(Key *); Key *key_demote(const Key *); +int key_equal_public(const Key *, const Key *); int key_equal(const Key *, const Key *); -char *key_fingerprint(const Key *, enum fp_type, enum fp_rep); -u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *); +char *key_fingerprint(Key *, enum fp_type, enum fp_rep); +u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *); const char *key_type(const Key *); int key_write(const Key *, FILE *); int key_read(Key *, char **); @@ -71,6 +89,14 @@ u_int key_size(const Key *); Key *key_generate(int, u_int); Key *key_from_private(const Key *); int key_type_from_name(char *); +int key_is_cert(const Key *); +int key_type_plain(int); +int key_to_certified(Key *); +int key_drop_cert(Key *); +int key_certify(Key *, Key *); +void key_cert_copy(const Key *, struct Key *); +int key_cert_check_authority(const Key *, int, int, const char *, + const char **); Key *key_from_blob(const u_char *, u_int); int key_to_blob(const Key *, u_char **, u_int *); diff --git a/match.h b/match.h index 18f683070..3d7f70fc0 100644 --- a/match.h +++ b/match.h @@ -1,4 +1,4 @@ -/* $OpenBSD: match.h,v 1.14 2008/06/10 03:57:27 djm Exp $ */ +/* $OpenBSD: match.h,v 1.15 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen @@ -23,5 +23,5 @@ char *match_list(const char *, const char *, u_int *); /* addrmatch.c */ int addr_match_list(const char *, const char *); - +int addr_match_cidr_list(const char *, const char *); #endif diff --git a/monitor.c b/monitor.c index ace25c404..f67cb7670 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.104 2009/06/12 20:43:22 andreas Exp $ */ +/* $OpenBSD: monitor.c,v 1.105 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -1721,7 +1721,8 @@ mm_get_kex(Buffer *m) kex->flags = buffer_get_int(m); kex->client_version_string = buffer_get_string(m, NULL); kex->server_version_string = buffer_get_string(m, NULL); - kex->load_host_key=&get_hostkey_by_type; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; return (kex); diff --git a/myproposal.h b/myproposal.h index 7bca3bcae..98f27fd15 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.23 2009/01/23 07:58:11 djm Exp $ */ +/* $OpenBSD: myproposal.h,v 1.24 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -40,7 +40,9 @@ "diffie-hellman-group1-sha1" #endif -#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" +#define KEX_DEFAULT_PK_ALG "ssh-rsa-cert-v00@openssh.com," \ + "ssh-dss-cert-v00@openssh.com," \ + "ssh-rsa,ssh-dss" #define KEX_DEFAULT_ENCRYPT \ "aes128-ctr,aes192-ctr,aes256-ctr," \ diff --git a/servconf.c b/servconf.c index 09296c9cf..0a6cdb655 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.202 2010/01/13 03:48:12 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.203 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -65,6 +65,7 @@ initialize_server_options(ServerOptions *options) options->listen_addrs = NULL; options->address_family = -1; options->num_host_key_files = 0; + options->num_host_cert_files = 0; options->pid_file = NULL; options->server_key_bits = -1; options->login_grace_time = -1; @@ -152,6 +153,7 @@ fill_default_server_options(ServerOptions *options) _PATH_HOST_DSA_KEY_FILE; } } + /* No certificates by default */ if (options->num_ports == 0) options->ports[options->num_ports++] = SSH_DEFAULT_PORT; if (options->listen_addrs == NULL) @@ -305,7 +307,7 @@ typedef enum { sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, - sZeroKnowledgePasswordAuthentication, + sZeroKnowledgePasswordAuthentication, sHostCertificate, sDeprecated, sUnsupported } ServerOpCodes; @@ -424,6 +426,7 @@ static struct { { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, + { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; @@ -816,6 +819,16 @@ process_server_config_line(ServerOptions *options, char *line, } break; + case sHostCertificate: + intptr = &options->num_host_cert_files; + if (*intptr >= MAX_HOSTKEYS) + fatal("%s line %d: too many host certificates " + "specified (max %d).", filename, linenum, + MAX_HOSTCERTS); + charptr = &options->host_cert_files[*intptr]; + goto parse_filename; + break; + case sPidFile: charptr = &options->pid_file; goto parse_filename; @@ -1651,6 +1664,8 @@ dump_config(ServerOptions *o) /* string array arguments */ dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, o->host_key_files); + dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, + o->host_cert_files); dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); diff --git a/servconf.h b/servconf.h index c9b8619cd..c5c9c6ecd 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.90 2010/01/13 03:48:13 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.91 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen @@ -24,6 +24,7 @@ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ #define MAX_HOSTKEYS 256 /* Max # hostkeys. */ +#define MAX_HOSTCERTS 256 /* Max # host certificates. */ #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ #define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */ @@ -49,6 +50,8 @@ typedef struct { int address_family; /* Address family used by the server. */ char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */ int num_host_key_files; /* Number of files for host keys. */ + char *host_cert_files[MAX_HOSTCERTS]; /* Files containing host certs. */ + int num_host_cert_files; /* Number of files for host certs. */ char *pid_file; /* Where to put our pid */ int server_key_bits;/* Size of the server key. */ int login_grace_time; /* Disconnect if no auth in this time diff --git a/ssh-add.c b/ssh-add.c index 90e5be20b..a7963223a 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.92 2010/02/08 10:50:20 markus Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.93 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -138,9 +138,9 @@ delete_all(AuthenticationConnection *ac) static int add_file(AuthenticationConnection *ac, const char *filename) { - Key *private; + Key *private, *cert; char *comment = NULL; - char msg[1024]; + char msg[1024], *certpath; int fd, perms_ok, ret = -1; if ((fd = open(filename, O_RDONLY)) < 0) { @@ -199,6 +199,34 @@ add_file(AuthenticationConnection *ac, const char *filename) fprintf(stderr, "Could not add identity: %s\n", filename); } + + /* Now try to add the certificate flavour too */ + xasprintf(&certpath, "%s-cert.pub", filename); + if ((cert = key_load_public(certpath, NULL)) != NULL) { + /* Graft with private bits */ + if (key_to_certified(private) != 0) + fatal("%s: key_to_certified failed", __func__); + key_cert_copy(cert, private); + key_free(cert); + + if (ssh_add_identity_constrained(ac, private, comment, + lifetime, confirm)) { + fprintf(stderr, "Certificate added: %s (%s)\n", + certpath, private->cert->key_id); + if (lifetime != 0) + fprintf(stderr, "Lifetime set to %d seconds\n", + lifetime); + if (confirm != 0) + fprintf(stderr, "The user has to confirm each " + "use of the key\n"); + } else { + error("Certificate %s (%s) add failed", certpath, + private->cert->key_id); + } + } else + fprintf(stderr, "Unable to load certificate %s", certpath); + + xfree(certpath); xfree(comment); key_free(private); diff --git a/ssh-agent.c b/ssh-agent.c index 46a744f4e..b5c565271 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.164 2010/02/09 00:50:36 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.165 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -468,6 +468,8 @@ process_add_identity(SocketEntry *e, int version) int type, success = 0, death = 0, confirm = 0; char *type_name, *comment; Key *k = NULL; + u_char *cert; + u_int len; switch (version) { case 1: @@ -498,6 +500,14 @@ process_add_identity(SocketEntry *e, int version) buffer_get_bignum2(&e->request, k->dsa->pub_key); buffer_get_bignum2(&e->request, k->dsa->priv_key); break; + case KEY_DSA_CERT: + cert = buffer_get_string(&e->request, &len); + if ((k = key_from_blob(cert, len)) == NULL) + fatal("Certificate parse failed"); + xfree(cert); + key_add_private(k); + buffer_get_bignum2(&e->request, k->dsa->priv_key); + break; case KEY_RSA: k = key_new_private(type); buffer_get_bignum2(&e->request, k->rsa->n); @@ -510,6 +520,17 @@ process_add_identity(SocketEntry *e, int version) /* Generate additional parameters */ rsa_generate_additional_parameters(k->rsa); break; + case KEY_RSA_CERT: + cert = buffer_get_string(&e->request, &len); + if ((k = key_from_blob(cert, len)) == NULL) + fatal("Certificate parse failed"); + xfree(cert); + key_add_private(k); + buffer_get_bignum2(&e->request, k->rsa->d); + buffer_get_bignum2(&e->request, k->rsa->iqmp); + buffer_get_bignum2(&e->request, k->rsa->p); + buffer_get_bignum2(&e->request, k->rsa->q); + break; default: buffer_clear(&e->request); goto send; @@ -519,6 +540,7 @@ process_add_identity(SocketEntry *e, int version) /* enable blinding */ switch (k->type) { case KEY_RSA: + case KEY_RSA_CERT: case KEY_RSA1: if (RSA_blinding_on(k->rsa, NULL) != 1) { error("process_add_identity: RSA_blinding_on failed"); diff --git a/ssh-dss.c b/ssh-dss.c index 51a06e98f..449f493b4 100644 --- a/ssh-dss.c +++ b/ssh-dss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-dss.c,v 1.24 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: ssh-dss.c,v 1.25 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -53,7 +53,9 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp, u_int rlen, slen, len, dlen; Buffer b; - if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + if (key == NULL || + (key->type != KEY_DSA && key->type != KEY_DSA_CERT) || + key->dsa == NULL) { error("ssh_dss_sign: no DSA key"); return -1; } @@ -116,7 +118,9 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, int rlen, ret; Buffer b; - if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + if (key == NULL || + (key->type != KEY_DSA && key->type != KEY_DSA_CERT) || + key->dsa == NULL) { error("ssh_dss_verify: no DSA key"); return -1; } diff --git a/ssh-keygen.1 b/ssh-keygen.1 index f09e1a100..772caf7ad 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.83 2010/02/10 23:20:38 markus Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.84 2010/02/26 20:29:54 djm Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 10 2010 $ +.Dd $Mdocdate: February 26 2010 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -106,6 +106,14 @@ .Op Fl v .Op Fl a Ar num_trials .Op Fl W Ar generator +.Nm ssh-keygen +.Fl s Ar ca_key +.Fl I Ar certificate_identity +.Op Fl h +.Op Fl n Ar principals +.Op Fl O Ar constraint +.Op Fl V Ar validity_interval +.Ar .Sh DESCRIPTION .Nm generates, manages and converts authentication keys for @@ -245,6 +253,17 @@ but they do not reveal identifying information should the file's contents be disclosed. This option will not modify existing hashed hostnames and is therefore safe to use on files that mix hashed and non-hashed names. +.It Fl h +When signing a key, create a host certificate instead of a user +certificate. +Please see the +.Sx CERTIFICATES +section for details. +.It Fl I +Specify the key identity when signing a public key. +Please see the +.Sx CERTIFICATES +section for details. .It Fl i This option will read an unencrypted private (or public) key file in SSH2-compatible format and print an OpenSSH compatible private @@ -268,6 +287,67 @@ Specify the amount of memory to use (in megabytes) when generating candidate moduli for DH-GEX. .It Fl N Ar new_passphrase Provides the new passphrase. +.It Fl n Ar principals +Specify one or more principals (user or host names) to be included in +a certificate when signing a key. +Multiple principals may be specified, separated by commas. +Please see the +.Sx CERTIFICATES +section for details. +.It Fl O Ar constraint +Specify a certificate constraint when signing a key. +This option may be specified multiple times. +Please see the +.Sx CERTIFICATES +section for details. +The constraints that are valid for user certificates are: +.Bl -tag -width Ds +.It Ic no-x11-forwarding +Disable X11 forwarding. (permitted by default) +.It Ic no-agent-forwarding +Disable +.Xr ssh-agent 1 +forwarding. (permitted by default) +.It Ic no-port-forwarding +Disable port forwarding. (permitted by default) +.It Ic no-pty +Disable PTY allocation. (permitted by default) +.It Ic no-user-rc +Disable execution of +.Pa ~/.ssh/rc +by +.Xr sshd 8 . +(permitted by default) +.It Ic clear +Clear all enabled permissions. +This is useful for clearing the default set of permissions so permissions may +be added individually. +.It Ic permit-x11-forwarding +Allows X11 forwarding. +.It Ic permit-port-forwarding +Allows port forwarding. +.It Ic permit-pty +Allows PTY allocation. +.It Ic permit-user-rc +Allows execution of +.Pa ~/.ssh/rc +by +.Xr sshd 8 . +.It Ic force-command=command +Forces the execution of +.Ar command +instead of any shell or command specified by the user when +the certificate is used for authentication. +.It Ic source-address=address_list +Restrict the source addresses from which the certificate is considered valid +from. +The +.Ar address_list +is a comma-separated list of one or more address/netmask pairs in CIDR +format. +.El +.Pp +At present, no constraints are valid for host keys. .It Fl P Ar passphrase Provides the (old) passphrase. .It Fl p @@ -297,6 +377,11 @@ Print the SSHFP fingerprint resource record named for the specified public key file. .It Fl S Ar start Specify start point (in hex) when generating candidate moduli for DH-GEX. +.It Fl s Ar ca_key +Certify (sign) a public key using the specified CA key. +Please see the +.Sx CERTIFICATES +section for details. .It Fl T Ar output_file Test DH group exchange candidate primes (generated using the .Fl G @@ -310,6 +395,29 @@ for protocol version 1 and or .Dq dsa for protocol version 2. +.It Fl V Ar validity_interval +Specify a validity interval when signing a certificate. +A validity interval may consist of a single time, indicating that the +certificate is valid beginning now and expiring at that time, or may consist +of two times separated by a colon to indicate an explicit time interval. +The start time may be specified as a date in YYYYMMDD format, a time +in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting +of a minus sign followed by a relative time in the format described in the +.Sx TIME FORMATS +section of +.Xr ssh_config 5 . +The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or +a relative time starting with a plus character. +.Pp +For example: +.Dq +52w1d +(valid from now to 52 weeks and one day from now), +.Dq -4w:+4w +(valid from four weeks ago to four weeks from now), +.Dq 20100101123000:20110101123000 +(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011), +.Dq -1d:20110101 +(valid from yesterday to midnight, January 1st, 2011). .It Fl v Verbose mode. Causes @@ -380,6 +488,72 @@ Screened DH groups may be installed in .Pa /etc/moduli . It is important that this file contains moduli of a range of bit lengths and that both ends of a connection share common moduli. +.Sh CERTIFICATES +.Nm +supports signing of keys to produce certificates that may be used for +user or host authentication. +Certificates consist of a public key, some identity information, zero or +more principal (user or host) names and an optional set of constraints that +are signed by a Certification Authority (CA) key. +Clients or servers may then trust only the CA key and verify its signature +on a certificate rather than trusting many user/host keys. +Note that OpenSSH certificates are a different, and much simpler, format to +the X.509 certificates used in +.Xr ssl 8 . +.Pp +.Nm +supports two types of certificates: user and host. +User certificates authenticate users to servers, whereas host certificates +authenticate server hosts to users. To generate a user certificate: +.Pp +.Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub +.Pp +The resultant certificate will be placed in +.Pa /path/to/user_key_cert.pub . +A host certificate requires the +.Fl h +option: +.Pp +.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub +.Pp +The host certificate will be output to +.Pa /path/to/host_key_cert.pub . +In both cases, +.Ar key_id +is a "key identifier" that is logged by the server when the certificate +is used for authentication. +.Pp +Certificates may be limited to be valid for a set of principal (user/host) +names. +By default, generated certificates are valid for all users or hosts. +To generate a certificate for a specified set of principals: +.Pp +.Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub +.Dl $ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub +.Pp +Additional limitations on the validity and use of user certificates may +be specified through certificate constraints. +A constrained certificate may disable features of the SSH session, may be +valid only when presented from particular source addresses or may +force the use of a specific command. +For a list of valid certificate constraints, see the documentation for the +.Fl O +option above. +.Pp +Finally, certificates may be defined with a validity lifetime. +The +.Fl V +option allows specification of certificate start and end times. +A certificate that is presented at a time outside this range will not be +considered valid. +By default, certificates have a maximum validity interval. +.Pp +For certificates to be used for user or host authentication, the CA +public key must be trusted by +.Xr sshd 8 +or +.Xr ssh 1 . +Please refer to those manual pages for details. .Sh FILES .Bl -tag -width Ds .It Pa ~/.ssh/identity diff --git a/ssh-keygen.c b/ssh-keygen.c index b6b7a2d9f..60261c210 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.178 2010/02/09 00:50:59 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.179 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -48,6 +48,7 @@ #include "match.h" #include "hostfile.h" #include "dns.h" +#include "ssh2.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" @@ -98,6 +99,35 @@ char *identity_new_passphrase = NULL; /* This is set to the new comment if given on the command line. */ char *identity_comment = NULL; +/* Path to CA key when certifying keys. */ +char *ca_key_path = NULL; + +/* Key type when certifying */ +u_int cert_key_type = SSH2_CERT_TYPE_USER; + +/* "key ID" of signed key */ +char *cert_key_id = NULL; + +/* Comma-separated list of principal names for certifying keys */ +char *cert_principals = NULL; + +/* Validity period for certificates */ +u_int64_t cert_valid_from = 0; +u_int64_t cert_valid_to = ~0ULL; + +/* Certificate constraints */ +#define CONSTRAINT_X_FWD (1) +#define CONSTRAINT_AGENT_FWD (1<<1) +#define CONSTRAINT_PORT_FWD (1<<2) +#define CONSTRAINT_PTY (1<<3) +#define CONSTRAINT_USER_RC (1<<4) +#define CONSTRAINT_DEFAULT (CONSTRAINT_X_FWD|CONSTRAINT_AGENT_FWD| \ + CONSTRAINT_PORT_FWD|CONSTRAINT_PTY| \ + CONSTRAINT_USER_RC) +u_int32_t constraint_flags = CONSTRAINT_DEFAULT; +char *constraint_command = NULL; +char *constraint_src_addr = NULL; + /* Dump public key file in format used by real and the original SSH 2 */ int convert_to_ssh2 = 0; int convert_from_ssh2 = 0; @@ -591,7 +621,7 @@ do_fingerprint(struct passwd *pw) } static void -print_host(FILE *f, const char *name, Key *public, int hash) +printhost(FILE *f, const char *name, Key *public, int ca, int hash) { if (print_fingerprint) { enum fp_rep rep; @@ -611,7 +641,7 @@ print_host(FILE *f, const char *name, Key *public, int hash) } else { if (hash && (name = host_hash(name, NULL, 0)) == NULL) fatal("hash_host failed"); - fprintf(f, "%s ", name); + fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name); if (!key_write(public, f)) fatal("key_write failed"); fprintf(f, "\n"); @@ -622,10 +652,11 @@ static void do_known_hosts(struct passwd *pw, const char *name) { FILE *in, *out = stdout; - Key *public; + Key *pub; char *cp, *cp2, *kp, *kp2; char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; + int ca; if (!have_identity) { cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); @@ -681,9 +712,19 @@ do_known_hosts(struct passwd *pw, const char *name) fprintf(out, "%s\n", cp); continue; } + /* Check whether this is a CA key */ + if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && + (cp[sizeof(CA_MARKER) - 1] == ' ' || + cp[sizeof(CA_MARKER) - 1] == '\t')) { + ca = 1; + cp += sizeof(CA_MARKER); + } else + ca = 0; + /* Find the end of the host name portion. */ for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) ; + if (*kp == '\0' || *(kp + 1) == '\0') { error("line %d missing key: %.40s...", num, line); @@ -693,15 +734,15 @@ do_known_hosts(struct passwd *pw, const char *name) *kp++ = '\0'; kp2 = kp; - public = key_new(KEY_RSA1); - if (key_read(public, &kp) != 1) { + pub = key_new(KEY_RSA1); + if (key_read(pub, &kp) != 1) { kp = kp2; - key_free(public); - public = key_new(KEY_UNSPEC); - if (key_read(public, &kp) != 1) { + key_free(pub); + pub = key_new(KEY_UNSPEC); + if (key_read(pub, &kp) != 1) { error("line %d invalid key: %.40s...", num, line); - key_free(public); + key_free(pub); invalid = 1; continue; } @@ -719,43 +760,52 @@ do_known_hosts(struct passwd *pw, const char *name) c = (strcmp(cp2, cp) == 0); if (find_host && c) { printf("# Host %s found: " - "line %d type %s\n", name, - num, key_type(public)); - print_host(out, cp, public, 0); + "line %d type %s%s\n", name, + num, key_type(pub), + ca ? " (CA key)" : ""); + printhost(out, cp, pub, ca, 0); } - if (delete_host && !c) - print_host(out, cp, public, 0); + if (delete_host && !c && !ca) + printhost(out, cp, pub, ca, 0); } else if (hash_hosts) - print_host(out, cp, public, 0); + printhost(out, cp, pub, ca, 0); } else { if (find_host || delete_host) { c = (match_hostname(name, cp, strlen(cp)) == 1); if (find_host && c) { printf("# Host %s found: " - "line %d type %s\n", name, - num, key_type(public)); - print_host(out, name, public, - hash_hosts); + "line %d type %s%s\n", name, + num, key_type(pub), + ca ? " (CA key)" : ""); + printhost(out, name, pub, + ca, hash_hosts && !ca); } - if (delete_host && !c) - print_host(out, cp, public, 0); + if (delete_host && !c && !ca) + printhost(out, cp, pub, ca, 0); } else if (hash_hosts) { for (cp2 = strsep(&cp, ","); cp2 != NULL && *cp2 != '\0'; cp2 = strsep(&cp, ",")) { - if (strcspn(cp2, "*?!") != strlen(cp2)) + if (ca) { + fprintf(stderr, "Warning: " + "ignoring CA key for host: " + "%.64s\n", cp2); + printhost(out, cp2, pub, ca, 0); + } else if (strcspn(cp2, "*?!") != + strlen(cp2)) { fprintf(stderr, "Warning: " "ignoring host name with " "metacharacters: %.64s\n", cp2); - else - print_host(out, cp2, public, 1); + printhost(out, cp2, pub, ca, 0); + } else + printhost(out, cp2, pub, ca, 1); } has_unhashed = 1; } } - key_free(public); + key_free(pub); } fclose(in); @@ -1012,6 +1062,293 @@ do_change_comment(struct passwd *pw) exit(0); } +static const char * +fmt_validity(void) +{ + char from[32], to[32]; + static char ret[64]; + time_t tt; + struct tm *tm; + + *from = *to = '\0'; + if (cert_valid_from == 0 && + cert_valid_to == 0xffffffffffffffffULL) + return "forever"; + + if (cert_valid_from != 0) { + /* XXX revisit INT_MAX in 2038 :) */ + tt = cert_valid_from > INT_MAX ? INT_MAX : cert_valid_from; + tm = localtime(&tt); + strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); + } + if (cert_valid_to != 0xffffffffffffffffULL) { + /* XXX revisit INT_MAX in 2038 :) */ + tt = cert_valid_to > INT_MAX ? INT_MAX : cert_valid_to; + tm = localtime(&tt); + strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); + } + + if (cert_valid_from == 0) { + snprintf(ret, sizeof(ret), "before %s", to); + return ret; + } + if (cert_valid_to == 0xffffffffffffffffULL) { + snprintf(ret, sizeof(ret), "after %s", from); + return ret; + } + + snprintf(ret, sizeof(ret), "from %s to %s", from, to); + return ret; +} + +static void +add_flag_constraint(Buffer *c, const char *name) +{ + debug3("%s: %s", __func__, name); + buffer_put_cstring(c, name); + buffer_put_string(c, NULL, 0); +} + +static void +add_string_constraint(Buffer *c, const char *name, const char *value) +{ + Buffer b; + + debug3("%s: %s=%s", __func__, name, value); + buffer_init(&b); + buffer_put_cstring(&b, value); + + buffer_put_cstring(c, name); + buffer_put_string(c, buffer_ptr(&b), buffer_len(&b)); + + buffer_free(&b); +} + +static void +prepare_constraint_buf(Buffer *c) +{ + + buffer_clear(c); + if ((constraint_flags & CONSTRAINT_X_FWD) != 0) + add_flag_constraint(c, "permit-X11-forwarding"); + if ((constraint_flags & CONSTRAINT_AGENT_FWD) != 0) + add_flag_constraint(c, "permit-agent-forwarding"); + if ((constraint_flags & CONSTRAINT_PORT_FWD) != 0) + add_flag_constraint(c, "permit-port-forwarding"); + if ((constraint_flags & CONSTRAINT_PTY) != 0) + add_flag_constraint(c, "permit-pty"); + if ((constraint_flags & CONSTRAINT_USER_RC) != 0) + add_flag_constraint(c, "permit-user-rc"); + if (constraint_command != NULL) + add_string_constraint(c, "forced-command", constraint_command); + if (constraint_src_addr != NULL) + add_string_constraint(c, "source-address", constraint_src_addr); +} + +static void +do_ca_sign(struct passwd *pw, int argc, char **argv) +{ + int i, fd; + u_int n; + Key *ca, *public; + char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; + FILE *f; + + tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); + if ((ca = load_identity(tmp)) == NULL) + fatal("Couldn't load CA key \"%s\"", tmp); + xfree(tmp); + + for (i = 0; i < argc; i++) { + /* Split list of principals */ + n = 0; + if (cert_principals != NULL) { + otmp = tmp = xstrdup(cert_principals); + plist = NULL; + for (; (cp = strsep(&tmp, ",")) != NULL; n++) { + plist = xrealloc(plist, n + 1, sizeof(*plist)); + if (*(plist[n] = xstrdup(cp)) == '\0') + fatal("Empty principal name"); + } + xfree(otmp); + } + + tmp = tilde_expand_filename(argv[i], pw->pw_uid); + if ((public = key_load_public(tmp, &comment)) == NULL) + fatal("%s: unable to open \"%s\"", __func__, tmp); + if (public->type != KEY_RSA && public->type != KEY_DSA) + fatal("%s: key \"%s\" type %s cannot be certified", + __func__, tmp, key_type(public)); + + /* Prepare certificate to sign */ + if (key_to_certified(public) != 0) + fatal("Could not upgrade key %s to certificate", tmp); + public->cert->type = cert_key_type; + public->cert->key_id = xstrdup(cert_key_id); + public->cert->nprincipals = n; + public->cert->principals = plist; + public->cert->valid_after = cert_valid_from; + public->cert->valid_before = cert_valid_to; + prepare_constraint_buf(&public->cert->constraints); + public->cert->signature_key = key_from_private(ca); + + if (key_certify(public, ca) != 0) + fatal("Couldn't not certify key %s", tmp); + + if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) + *cp = '\0'; + xasprintf(&out, "%s-cert.pub", tmp); + xfree(tmp); + + if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) + fatal("Could not open \"%s\" for writing: %s", out, + strerror(errno)); + if ((f = fdopen(fd, "w")) == NULL) + fatal("%s: fdopen: %s", __func__, strerror(errno)); + if (!key_write(public, f)) + fatal("Could not write certified key to %s", out); + fprintf(f, " %s\n", comment); + fclose(f); + + if (!quiet) + logit("Signed %s key %s: id \"%s\"%s%s valid %s", + cert_key_type == SSH2_CERT_TYPE_USER?"user":"host", + out, cert_key_id, + cert_principals != NULL ? " for " : "", + cert_principals != NULL ? cert_principals : "", + fmt_validity()); + + key_free(public); + xfree(out); + } + exit(0); +} + +static u_int64_t +parse_relative_time(const char *s, time_t now) +{ + int64_t mul, secs; + + mul = *s == '-' ? -1 : 1; + + if ((secs = convtime(s + 1)) == -1) + fatal("Invalid relative certificate time %s", s); + if (mul == -1 && secs > now) + fatal("Certificate time %s cannot be represented", s); + return now + (u_int64_t)(secs * mul); +} + +static u_int64_t +parse_absolute_time(const char *s) +{ + struct tm tm; + time_t tt; + + if (strlen(s) != 8 && strlen(s) != 14) + fatal("Invalid certificate time format %s", s); + + bzero(&tm, sizeof(tm)); + if (strptime(s, + strlen(s) == 8 ? "%Y%m%d" : "%Y%m%d%H%M%S", &tm) == NULL) + fatal("Invalid certificate time %s", s); + if ((tt = mktime(&tm)) < 0) + fatal("Certificate time %s cannot be represented", s); + return (u_int64_t)tt; +} + +static void +parse_cert_times(char *timespec) +{ + char *from, *to; + time_t now = time(NULL); + int64_t secs; + + /* +timespec relative to now */ + if (*timespec == '+' && strchr(timespec, ':') == NULL) { + if ((secs = convtime(timespec + 1)) == -1) + fatal("Invalid relative certificate life %s", timespec); + cert_valid_to = now + secs; + /* + * Backdate certificate one minute to avoid problems on hosts + * with poorly-synchronised clocks. + */ + cert_valid_from = ((now - 59)/ 60) * 60; + return; + } + + /* + * from:to, where + * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS + * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS + */ + from = xstrdup(timespec); + to = strchr(from, ':'); + if (to == NULL || from == to || *(to + 1) == '\0') + fatal("Invalid certificate life specification %s", optarg); + *to++ = '\0'; + + if (*from == '-' || *from == '+') + cert_valid_from = parse_relative_time(from, now); + else + cert_valid_from = parse_absolute_time(from); + + if (*to == '-' || *to == '+') + cert_valid_to = parse_relative_time(to, cert_valid_from); + else + cert_valid_to = parse_absolute_time(to); + + if (cert_valid_to <= cert_valid_from) + fatal("Empty certificate validity interval"); + xfree(from); +} + +static void +add_cert_constraint(char *opt) +{ + char *val; + + if (strcmp(opt, "clear") == 0) + constraint_flags = 0; + else if (strcasecmp(opt, "no-x11-forwarding") == 0) + constraint_flags &= ~CONSTRAINT_X_FWD; + else if (strcasecmp(opt, "permit-x11-forwarding") == 0) + constraint_flags |= CONSTRAINT_X_FWD; + else if (strcasecmp(opt, "no-agent-forwarding") == 0) + constraint_flags &= ~CONSTRAINT_AGENT_FWD; + else if (strcasecmp(opt, "permit-agent-forwarding") == 0) + constraint_flags |= CONSTRAINT_AGENT_FWD; + else if (strcasecmp(opt, "no-port-forwarding") == 0) + constraint_flags &= ~CONSTRAINT_PORT_FWD; + else if (strcasecmp(opt, "permit-port-forwarding") == 0) + constraint_flags |= CONSTRAINT_PORT_FWD; + else if (strcasecmp(opt, "no-pty") == 0) + constraint_flags &= ~CONSTRAINT_PTY; + else if (strcasecmp(opt, "permit-pty") == 0) + constraint_flags |= CONSTRAINT_PTY; + else if (strcasecmp(opt, "no-user-rc") == 0) + constraint_flags &= ~CONSTRAINT_USER_RC; + else if (strcasecmp(opt, "permit-user-rc") == 0) + constraint_flags |= CONSTRAINT_USER_RC; + else if (strncasecmp(opt, "force-command=", 14) == 0) { + val = opt + 14; + if (*val == '\0') + fatal("Empty force-command constraint"); + if (constraint_command != NULL) + fatal("force-command already specified"); + constraint_command = xstrdup(val); + } else if (strncasecmp(opt, "source-address=", 15) == 0) { + val = opt + 15; + if (*val == '\0') + fatal("Empty source-address constraint"); + if (constraint_src_addr != NULL) + fatal("source-address already specified"); + if (addr_match_cidr_list(NULL, val) != 0) + fatal("Invalid source-address list"); + constraint_src_addr = xstrdup(val); + } else + fatal("Unsupported certificate constraint \"%s\"", opt); +} + static void usage(void) { @@ -1031,18 +1368,24 @@ usage(void) fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n"); fprintf(stderr, " -g Use generic DNS resource record format.\n"); fprintf(stderr, " -H Hash names in known_hosts file.\n"); + fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n"); + fprintf(stderr, " -I key_id Key identifier to include in certificate.\n"); fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n"); fprintf(stderr, " -l Show fingerprint of key file.\n"); fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); + fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); fprintf(stderr, " -N phrase Provide new passphrase.\n"); + fprintf(stderr, " -O cnstr Specify a certificate constraint.\n"); fprintf(stderr, " -P phrase Provide old passphrase.\n"); fprintf(stderr, " -p Change passphrase of private key file.\n"); fprintf(stderr, " -q Quiet.\n"); fprintf(stderr, " -R hostname Remove host from known_hosts file.\n"); fprintf(stderr, " -r hostname Print DNS resource record.\n"); + fprintf(stderr, " -s ca_key Certify keys with CA key.\n"); fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n"); fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n"); fprintf(stderr, " -t type Specify type of key to create.\n"); + fprintf(stderr, " -V from:to Specify certificate validity interval.\n"); fprintf(stderr, " -v Verbose.\n"); fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); fprintf(stderr, " -y Read private key file and print public key.\n"); @@ -1094,8 +1437,8 @@ main(int argc, char **argv) exit(1); } - while ((opt = getopt(argc, argv, - "degiqpclBHvxXyF:b:f:t:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) { + while ((opt = getopt(argc, argv, "degiqpclBHhvxXyF:b:f:t:D:I:P:N:n:" + "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) { switch (opt) { case 'b': bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr); @@ -1110,6 +1453,9 @@ main(int argc, char **argv) case 'H': hash_hosts = 1; break; + case 'I': + cert_key_id = optarg; + break; case 'R': delete_host = 1; rr_hostname = optarg; @@ -1120,6 +1466,9 @@ main(int argc, char **argv) case 'B': print_bubblebabble = 1; break; + case 'n': + cert_principals = optarg; + break; case 'p': change_passphrase = 1; break; @@ -1141,6 +1490,9 @@ main(int argc, char **argv) case 'N': identity_new_passphrase = optarg; break; + case 'O': + add_cert_constraint(optarg); + break; case 'C': identity_comment = optarg; break; @@ -1152,6 +1504,10 @@ main(int argc, char **argv) /* export key */ convert_to_ssh2 = 1; break; + case 'h': + cert_key_type = SSH2_CERT_TYPE_HOST; + constraint_flags = 0; + break; case 'i': case 'X': /* import key */ @@ -1163,6 +1519,9 @@ main(int argc, char **argv) case 'd': key_type_name = "dsa"; break; + case 's': + ca_key_path = optarg; + break; case 't': key_type_name = optarg; break; @@ -1217,6 +1576,9 @@ main(int argc, char **argv) if (BN_hex2bn(&start, optarg) == 0) fatal("Invalid start point."); break; + case 'V': + parse_cert_times(optarg); + break; case '?': default: usage(); @@ -1226,7 +1588,15 @@ main(int argc, char **argv) /* reinit */ log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1); - if (optind < argc) { + argv += optind; + argc -= optind; + + if (ca_key_path != NULL) { + if (argc < 1) { + printf("Too few arguments.\n"); + usage(); + } + } else if (argc > 0) { printf("Too many arguments.\n"); usage(); } @@ -1238,6 +1608,11 @@ main(int argc, char **argv) printf("Cannot use -l with -D or -R.\n"); usage(); } + if (ca_key_path != NULL) { + if (cert_key_id == NULL) + fatal("Must specify key id (-I) when certifying"); + do_ca_sign(pw, argc, argv); + } if (delete_host || hash_hosts || find_host) do_known_hosts(pw, rr_hostname); if (print_fingerprint || print_bubblebabble) diff --git a/ssh-rsa.c b/ssh-rsa.c index 0e16ff85f..842857fee 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.39 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.40 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -46,7 +46,9 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, int ok, nid; Buffer b; - if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) { + if (key == NULL || + (key->type != KEY_RSA && key->type != KEY_RSA_CERT) || + key->rsa == NULL) { error("ssh_rsa_sign: no RSA key"); return -1; } @@ -113,7 +115,9 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, u_int len, dlen, modlen; int rlen, ret, nid; - if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) { + if (key == NULL || + (key->type != KEY_RSA && key->type != KEY_RSA_CERT) || + key->rsa == NULL) { error("ssh_rsa_verify: no RSA key"); return -1; } diff --git a/ssh.1 b/ssh.1 index 6964cd09c..7d8f92aba 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.294 2010/02/11 13:23:29 jmc Exp $ -.Dd $Mdocdate: February 11 2010 $ +.\" $OpenBSD: ssh.1,v 1.295 2010/02/26 20:29:54 djm Exp $ +.Dd $Mdocdate: February 26 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -1103,6 +1103,25 @@ See the option in .Xr ssh_config 5 for more information. +.Pp +Host keys may also be presented as certificates signed by a trusted +certification authority (CA). +In this case, trust of the CA key alone is sufficient for the host key +to be accepted. +To specify a public key as a trusted CA key in a known hosts file, +it should be added after a +.Dq @cert-authority +tag and a set of one or more domain-name wildcards separated by commas. +For example: +.Pp +.Dl @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... +.Pp +See the +.Sx CERTIFICATES +section of +.Xr ssh-keygen 1 +for more details. +.Pp .Sh SSH-BASED VIRTUAL PRIVATE NETWORKS .Nm contains support for Virtual Private Network (VPN) tunnelling diff --git a/ssh.c b/ssh.c index 25ccdcaa5..b9553d3e1 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.334 2010/02/08 22:03:05 jmc Exp $ */ +/* $OpenBSD: ssh.c,v 1.335 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1306,34 +1306,35 @@ load_public_identity_files(void) int i = 0; Key *public; struct passwd *pw; + u_int n_ids; + char *identity_files[SSH_MAX_IDENTITY_FILES]; + Key *identity_keys[SSH_MAX_IDENTITY_FILES]; #ifdef ENABLE_PKCS11 Key **keys; int nkeys; +#endif /* PKCS11 */ + n_ids = 0; + bzero(identity_files, sizeof(identity_files)); + bzero(identity_keys, sizeof(identity_keys)); + +#ifdef ENABLE_PKCS11 if (options.pkcs11_provider != NULL && options.num_identity_files < SSH_MAX_IDENTITY_FILES && (pkcs11_init(!options.batch_mode) == 0) && (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, &keys)) > 0) { - int count = 0; for (i = 0; i < nkeys; i++) { - count++; - memmove(&options.identity_files[1], - &options.identity_files[0], - sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1)); - memmove(&options.identity_keys[1], - &options.identity_keys[0], - sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); - options.num_identity_files++; - options.identity_keys[0] = keys[i]; - options.identity_files[0] = + if (n_ids >= SSH_MAX_IDENTITY_FILES) { + key_free(keys[i]); + continue; + } + identity_keys[n_ids] = keys[i]; + identity_files[n_ids] = xstrdup(options.pkcs11_provider); /* XXX */ + n_ids++; } - if (options.num_identity_files > SSH_MAX_IDENTITY_FILES) - options.num_identity_files = SSH_MAX_IDENTITY_FILES; - i = count; xfree(keys); - /* XXX leaks some keys */ } #endif /* ENABLE_PKCS11 */ if ((pw = getpwuid(original_real_uid)) == NULL) @@ -1343,7 +1344,11 @@ load_public_identity_files(void) if (gethostname(thishost, sizeof(thishost)) == -1) fatal("load_public_identity_files: gethostname: %s", strerror(errno)); - for (; i < options.num_identity_files; i++) { + for (i = 0; i < options.num_identity_files; i++) { + if (n_ids >= SSH_MAX_IDENTITY_FILES) { + xfree(options.identity_files[i]); + continue; + } cp = tilde_expand_filename(options.identity_files[i], original_real_uid); filename = percent_expand(cp, "d", pwdir, @@ -1354,9 +1359,37 @@ load_public_identity_files(void) debug("identity file %s type %d", filename, public ? public->type : -1); xfree(options.identity_files[i]); - options.identity_files[i] = filename; - options.identity_keys[i] = public; + identity_files[n_ids] = filename; + identity_keys[n_ids] = public; + + if (++n_ids >= SSH_MAX_IDENTITY_FILES) + continue; + + /* Try to add the certificate variant too */ + xasprintf(&cp, "%s-cert", filename); + public = key_load_public(cp, NULL); + debug("identity file %s type %d", cp, + public ? public->type : -1); + if (public == NULL) { + xfree(cp); + continue; + } + if (!key_is_cert(public)) { + debug("%s: key %s type %s is not a certificate", + __func__, cp, key_type(public)); + key_free(public); + xfree(cp); + continue; + } + identity_keys[n_ids] = public; + /* point to the original path, most likely the private key */ + identity_files[n_ids] = xstrdup(filename); + n_ids++; } + options.num_identity_files = n_ids; + memcpy(options.identity_files, identity_files, sizeof(identity_files)); + memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); + bzero(pwname, strlen(pwname)); xfree(pwname); bzero(pwdir, strlen(pwdir)); diff --git a/ssh2.h b/ssh2.h index b01af7b1a..3ffaf686b 100644 --- a/ssh2.h +++ b/ssh2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh2.h,v 1.12 2009/10/24 11:19:17 andreas Exp $ */ +/* $OpenBSD: ssh2.h,v 1.13 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -173,3 +173,6 @@ #define SSH2_MSG_KEX_ROAMING_AUTH_OK 33 #define SSH2_MSG_KEX_ROAMING_AUTH_FAIL 34 +/* Certificate types for OpenSSH certificate keys extension */ +#define SSH2_CERT_TYPE_USER 1 +#define SSH2_CERT_TYPE_HOST 2 diff --git a/sshconnect.c b/sshconnect.c index 63c4650f7..35c2f49be 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.218 2010/01/13 00:19:04 dtucker Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.219 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -58,6 +58,7 @@ #include "misc.h" #include "dns.h" #include "roaming.h" +#include "ssh2.h" #include "version.h" char *client_version_string = NULL; @@ -576,6 +577,23 @@ confirm(const char *prompt) } } +static int +check_host_cert(const char *host, const Key *host_key) +{ + const char *reason; + + if (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) { + error("%s", reason); + return 0; + } + if (buffer_len(&host_key->cert->constraints) != 0) { + error("Certificate for %s contains unsupported constraint(s)", + host); + return 0; + } + return 1; +} + /* * check whether the supplied host key is valid, return -1 if the key * is not valid. the user_hostfile will not be updated if 'readonly' is true. @@ -588,13 +606,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Key *host_key, int readonly, const char *user_hostfile, const char *system_hostfile) { - Key *file_key; - const char *type = key_type(host_key); + Key *file_key, *raw_key = NULL; + const char *type; char *ip = NULL, *host = NULL; char hostline[1000], *hostp, *fp, *ra; HostStatus host_status; HostStatus ip_status; - int r, local = 0, host_ip_differ = 0; + int r, want_cert, local = 0, host_ip_differ = 0; int salen; char ntop[NI_MAXHOST]; char msg[1024]; @@ -667,11 +685,15 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, host = put_host_port(hostname, port); } + retry: + want_cert = key_is_cert(host_key); + type = key_type(host_key); + /* * Store the host key from the known host file in here so that we can * compare it with the key for the IP address. */ - file_key = key_new(host_key->type); + file_key = key_new(key_is_cert(host_key) ? KEY_UNSPEC : host_key->type); /* * Check if the host key is present in the user's list of known @@ -687,9 +709,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, } /* * Also perform check for the ip address, skip the check if we are - * localhost or the hostname was an ip address to begin with + * localhost, looking for a certificate, or the hostname was an ip + * address to begin with. */ - if (options.check_host_ip) { + if (!want_cert && options.check_host_ip) { Key *ip_key = key_new(host_key->type); ip_file = user_hostfile; @@ -713,11 +736,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, switch (host_status) { case HOST_OK: /* The host is known and the key matches. */ - debug("Host '%.200s' is known and matches the %s host key.", - host, type); - debug("Found key in %s:%d", host_file, host_line); + debug("Host '%.200s' is known and matches the %s host %s.", + host, type, want_cert ? "certificate" : "key"); + debug("Found %s in %s:%d", + want_cert ? "certificate" : "key", host_file, host_line); + if (want_cert && !check_host_cert(hostname, host_key)) + goto fail; if (options.check_host_ip && ip_status == HOST_NEW) { - if (readonly) + if (readonly || want_cert) logit("%s host key for IP address " "'%.128s' not in list of known hosts.", type, ip); @@ -749,7 +775,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, break; } } - if (readonly) + if (readonly || want_cert) goto fail; /* The host is new. */ if (options.strict_host_key_checking == 1) { @@ -834,6 +860,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, "list of known hosts.", hostp, type); break; case HOST_CHANGED: + if (want_cert) { + /* + * This is only a debug() since it is valid to have + * CAs with wildcard DNS matches that don't match + * all hosts that one might visit. + */ + debug("Host certificate authority does not " + "match %s in %s:%d", CA_MARKER, + host_file, host_line); + goto fail; + } if (readonly == ROQUIET) goto fail; if (options.check_host_ip && host_ip_differ) { @@ -970,6 +1007,20 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, return 0; fail: + if (want_cert) { + /* + * No matching certificate. Downgrade cert to raw key and + * search normally. + */ + debug("No matching CA found. Retry with plain key"); + raw_key = key_from_private(host_key); + if (key_drop_cert(raw_key) != 0) + fatal("Couldn't drop certificate"); + host_key = raw_key; + goto retry; + } + if (raw_key != NULL) + key_free(raw_key); xfree(ip); xfree(host); return -1; @@ -982,7 +1033,8 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) struct stat st; int flags = 0; - if (options.verify_host_key_dns && + /* XXX certs are not yet supported for DNS */ + if (!key_is_cert(host_key) && options.verify_host_key_dns && verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { if (flags & DNS_VERIFY_FOUND) { diff --git a/sshconnect2.c b/sshconnect2.c index e81064dae..2a5943e7e 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.179 2010/01/13 01:20:20 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.180 2010/02/26 20:29:54 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -1311,6 +1311,8 @@ pubkey_prepare(Authctxt *authctxt) key = options.identity_keys[i]; if (key && key->type == KEY_RSA1) continue; + if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER) + continue; options.identity_keys[i] = NULL; id = xcalloc(1, sizeof(*id)); id->key = key; diff --git a/sshd.8 b/sshd.8 index 76b7e2987..fcd5195db 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.250 2010/01/30 21:08:33 djm Exp $ -.Dd $Mdocdate: January 30 2010 $ +.\" $OpenBSD: sshd.8,v 1.251 2010/02/26 20:29:54 djm Exp $ +.Dd $Mdocdate: February 26 2010 $ .Dt SSHD 8 .Os .Sh NAME @@ -47,6 +47,7 @@ .Op Fl 46DdeiqTt .Op Fl b Ar bits .Op Fl C Ar connection_spec +.Op Fl c Ar host_certificate_file .Op Fl f Ar config_file .Op Fl g Ar login_grace_time .Op Fl h Ar host_key_file @@ -101,6 +102,15 @@ to use IPv6 addresses only. .It Fl b Ar bits Specifies the number of bits in the ephemeral protocol version 1 server key (default 1024). +.It Fl c Ar host_certificate_file +Specifies a path to a certificate file to identify +.Nm +during key exchange. +The certificate file must match a host key file specified using the +.Fl -h +option or the +.Cm HostKey +configuration directive. .It Fl C Ar connection_spec Specify the connection parameters to use for the .Fl T @@ -498,6 +508,13 @@ No spaces are permitted, except within double quotes. The following option specifications are supported (note that option keywords are case-insensitive): .Bl -tag -width Ds +.It Cm from="cert-authority" +Specifies that the listed key is a certification authority (CA) that is +trusted to validate signed certificates for user authentication. +.Pp +Certificates may encode access restrictions similar to these key options. +If both certificate restrictions and key options are present, the most +restrictive union of the two is applied. .It Cm command="command" Specifies that the command is executed whenever this key is used for authentication. @@ -517,6 +534,10 @@ The command originally supplied by the client is available in the .Ev SSH_ORIGINAL_COMMAND environment variable. Note that this option applies to shell, command or subsystem execution. +Also note that this command may be superseded by either a +.Xr sshd_config 5 +.Cm ForceCommand +directive or a command embedded in a certificate. .It Cm environment="NAME=value" Specifies that the string is to be added to the environment when logging in using this key. diff --git a/sshd.c b/sshd.c index bf2e76cc8..0c3c04e4e 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.372 2010/01/29 00:20:41 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.373 2010/02/26 20:29:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -205,6 +205,7 @@ struct { Key *server_key; /* ephemeral server key */ Key *ssh1_host_key; /* ssh1 host key */ Key **host_keys; /* all private host keys */ + Key **host_certificates; /* all public host certificates */ int have_ssh1_key; int have_ssh2_key; u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; @@ -545,6 +546,10 @@ destroy_sensitive_data(void) key_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = NULL; } + if (sensitive_data.host_certificates[i]) { + key_free(sensitive_data.host_certificates[i]); + sensitive_data.host_certificates[i] = NULL; + } } sensitive_data.ssh1_host_key = NULL; memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); @@ -571,6 +576,7 @@ demote_sensitive_data(void) if (tmp->type == KEY_RSA1) sensitive_data.ssh1_host_key = tmp; } + /* Certs do not need demotion */ } /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ @@ -717,10 +723,11 @@ list_hostkey_types(void) const char *p; char *ret; int i; + Key *key; buffer_init(&b); for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; + key = sensitive_data.host_keys[i]; if (key == NULL) continue; switch (key->type) { @@ -732,6 +739,19 @@ list_hostkey_types(void) buffer_append(&b, p, strlen(p)); break; } + /* If the private key has a cert peer, then list that too */ + key = sensitive_data.host_certificates[i]; + if (key == NULL) + continue; + switch (key->type) { + case KEY_RSA_CERT: + case KEY_DSA_CERT: + if (buffer_len(&b) > 0) + buffer_append(&b, ",", 1); + p = key_ssh_name(key); + buffer_append(&b, p, strlen(p)); + break; + } } buffer_append(&b, "\0", 1); ret = xstrdup(buffer_ptr(&b)); @@ -740,19 +760,36 @@ list_hostkey_types(void) return ret; } -Key * -get_hostkey_by_type(int type) +static Key * +get_hostkey_by_type(int type, int need_private) { int i; + Key *key; for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; + if (type == KEY_RSA_CERT || type == KEY_DSA_CERT) + key = sensitive_data.host_certificates[i]; + else + key = sensitive_data.host_keys[i]; if (key != NULL && key->type == type) - return key; + return need_private ? + sensitive_data.host_keys[i] : key; } return NULL; } +Key * +get_hostkey_public_by_type(int type) +{ + return get_hostkey_by_type(type, 0); +} + +Key * +get_hostkey_private_by_type(int type) +{ + return get_hostkey_by_type(type, 1); +} + Key * get_hostkey_by_index(int ind) { @@ -767,8 +804,13 @@ get_hostkey_index(Key *key) int i; for (i = 0; i < options.num_host_key_files; i++) { - if (key == sensitive_data.host_keys[i]) - return (i); + if (key_is_cert(key)) { + if (key == sensitive_data.host_certificates[i]) + return (i); + } else { + if (key == sensitive_data.host_keys[i]) + return (i); + } } return (-1); } @@ -807,9 +849,9 @@ usage(void) fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); fprintf(stderr, -"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n" -" [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n" -" [-o option] [-p port] [-u len]\n" +"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" +" [-f config_file] [-g login_grace_time] [-h host_key_file]\n" +" [-k key_gen_time] [-o option] [-p port] [-u len]\n" ); exit(1); } @@ -1236,7 +1278,7 @@ main(int ac, char **av) { extern char *optarg; extern int optind; - int opt, i, on = 1; + int opt, i, j, on = 1; int sock_in = -1, sock_out = -1, newsock = -1; const char *remote_ip; char *test_user = NULL, *test_host = NULL, *test_addr = NULL; @@ -1289,6 +1331,14 @@ main(int ac, char **av) case 'f': config_file_name = optarg; break; + case 'c': + if (options.num_host_cert_files >= MAX_HOSTCERTS) { + fprintf(stderr, "too many host certificates.\n"); + exit(1); + } + options.host_cert_files[options.num_host_cert_files++] = + derelativise_path(optarg); + break; case 'd': if (debug_flag == 0) { debug_flag = 1; @@ -1536,6 +1586,46 @@ main(int ac, char **av) exit(1); } + /* + * Load certificates. They are stored in an array at identical + * indices to the public keys that they relate to. + */ + sensitive_data.host_certificates = xcalloc(options.num_host_key_files, + sizeof(Key *)); + for (i = 0; i < options.num_host_key_files; i++) + sensitive_data.host_certificates[i] = NULL; + + for (i = 0; i < options.num_host_cert_files; i++) { + key = key_load_public(options.host_cert_files[i], NULL); + if (key == NULL) { + error("Could not load host certificate: %s", + options.host_cert_files[i]); + continue; + } + if (!key_is_cert(key)) { + error("Certificate file is not a certificate: %s", + options.host_cert_files[i]); + key_free(key); + continue; + } + /* Find matching private key */ + for (j = 0; j < options.num_host_key_files; j++) { + if (key_equal_public(key, + sensitive_data.host_keys[j])) { + sensitive_data.host_certificates[j] = key; + break; + } + } + if (j >= options.num_host_key_files) { + error("No matching private key for certificate: %s", + options.host_cert_files[i]); + key_free(key); + continue; + } + sensitive_data.host_certificates[j] = key; + debug("host certificate: #%d type %d %s", j, key->type, + key_type(key)); + } /* Check certain values for sanity. */ if (options.protocol & SSH_PROTO_1) { if (options.server_key_bits < 512 || @@ -2205,7 +2295,8 @@ do_ssh2_kex(void) kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; - kex->load_host_key=&get_hostkey_by_type; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; xxx_kex = kex; diff --git a/sshd_config.5 b/sshd_config.5 index bf3319c4d..001114655 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.116 2010/01/09 23:04:13 dtucker Exp $ -.Dd $Mdocdate: January 9 2010 $ +.\" $OpenBSD: sshd_config.5,v 1.117 2010/02/26 20:29:54 djm Exp $ +.Dd $Mdocdate: February 26 2010 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -411,6 +411,14 @@ uses the name supplied by the client rather than attempting to resolve the name from the TCP connection itself. The default is .Dq no . +.It Cm HostCertificate +Specifies a file containing a public host certificate. +The certificate's public key must match a private host key already specified +by +.Cm HostKey . +The default behaviour of +.Xr sshd 8 +is not to load any certificates. .It Cm HostKey Specifies a file containing a private host key used by SSH. -- cgit v1.2.3 From 58ac6de9648ea1e4d99061013965e0581abff101 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 27 Feb 2010 07:57:12 +1100 Subject: - djm@cvs.openbsd.org 2010/02/26 20:33:21 [Makefile regress/cert-hostkey.sh regress/cert-userkey.sh] regression tests for certified keys --- ChangeLog | 3 ++ regress/Makefile | 7 ++- regress/cert-hostkey.sh | 122 ++++++++++++++++++++++++++++++++++++++++++++++++ regress/cert-userkey.sh | 89 +++++++++++++++++++++++++++++++++++ 4 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 regress/cert-hostkey.sh create mode 100644 regress/cert-userkey.sh diff --git a/ChangeLog b/ChangeLog index fec38e028..703c347fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,9 @@ PROTOCOL.certkeys feedback and ok markus@ + - djm@cvs.openbsd.org 2010/02/26 20:33:21 + [Makefile regress/cert-hostkey.sh regress/cert-userkey.sh] + regression tests for certified keys 20100224 - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] diff --git a/regress/Makefile b/regress/Makefile index 42e84d4c5..de8e9fd33 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.51 2010/02/09 06:29:02 djm Exp $ +# $OpenBSD: Makefile,v 1.52 2010/02/26 20:33:21 djm Exp $ REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec tests: $(REGRESS_TARGETS) @@ -52,7 +52,9 @@ LTESTS= connect \ addrmatch \ localcommand \ forcecommand \ - portnum + portnum \ + cert-hostkey \ + cert-userkey INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp @@ -66,6 +68,7 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ ls.copy banner.in banner.out empty.in \ scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \ sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \ + known_hosts-cert host_ca_key* cert_host_key* \ putty.rsa2 # Enable all malloc(3) randomisations and checks diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh new file mode 100644 index 000000000..14cd2230b --- /dev/null +++ b/regress/cert-hostkey.sh @@ -0,0 +1,122 @@ +# $OpenBSD: cert-hostkey.sh,v 1.1 2010/02/26 20:33:21 djm Exp $ +# Placed in the Public Domain. + +tid="certified host keys" + +rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +HOSTS='localhost-with-alias,127.0.0.1,::1' + +# Create a CA key and add it to known hosts +${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ + fail "ssh-keygen of host_ca_key failed" +( + echo -n '@cert-authority ' + echo -n "$HOSTS " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert + +# Generate and sign host keys +for ktype in rsa dsa ; do + verbose "$tid: sign host ${ktype} cert" + # Generate and sign a host key + ${SSHKEYGEN} -q -N '' -t ${ktype} \ + -f $OBJ/cert_host_key_${ktype} || \ + fail "ssh-keygen of cert_host_key_${ktype} failed" + ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key \ + -I "regress host key for $USER" \ + -n $HOSTS $OBJ/cert_host_key_${ktype} || + fail "couldn't sign cert_host_key_${ktype}" +done + +# Basic connect tests +for privsep in yes no ; do + for ktype in rsa dsa ; do + verbose "$tid: host ${ktype} cert connect privsep $privsep" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + echo UsePrivilegeSeparation $privsep + ) > $OBJ/sshd_proxy + + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + done +done + +test_one() { + ident=$1 + result=$2 + sign_opts=$3 + + verbose "$tid: test host cert connect $ident expect $result" + + ${SSHKEYGEN} -q -s $OBJ/host_ca_key -I "regress host key for $USER" \ + $sign_opts \ + $OBJ/cert_host_key_rsa || + fail "couldn't sign cert_host_key_rsa" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_rsa + echo HostCertificate $OBJ/cert_host_key_rsa-cert.pub + ) > $OBJ/sshd_proxy + + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + rc=$? + if [ "x$result" = "xsuccess" ] ; then + if [ $rc -ne 0 ]; then + fail "ssh cert connect $ident failed unexpectedly" + fi + else + if [ $rc -eq 0 ]; then + fail "ssh cert connect $ident succeeded unexpectedly" + fi + fi +} + +test_one "user-certificate" failure "-n $HOSTS" +test_one "empty principals" success "-h" +test_one "wrong principals" failure "-h -n foo" +test_one "cert not yet valid" failure "-h -V20200101:20300101" +test_one "cert expired" failure "-h -V19800101:19900101" +test_one "cert valid interval" success "-h -V-1w:+2w" +test_one "cert has constraints" failure "-h -Oforce-command=false" + +# Check downgrade of cert to raw key when no CA found +rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key* +for ktype in rsa dsa ; do + verbose "$tid: host ${ktype} cert downgrade to raw key" + # Generate and sign a host key + ${SSHKEYGEN} -q -N '' -t ${ktype} \ + -f $OBJ/cert_host_key_${ktype} || \ + fail "ssh-keygen of cert_host_key_${ktype} failed" + ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key -I "regress host key for $USER" \ + -n $HOSTS $OBJ/cert_host_key_${ktype} || + fail "couldn't sign cert_host_key_${ktype}" + ( + echo -n "$HOSTS " + cat $OBJ/cert_host_key_${ktype}.pub + ) > $OBJ/known_hosts-cert + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + ) > $OBJ/sshd_proxy + + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi +done + +rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh new file mode 100644 index 000000000..307e7236f --- /dev/null +++ b/regress/cert-userkey.sh @@ -0,0 +1,89 @@ +# $OpenBSD: cert-userkey.sh,v 1.1 2010/02/26 20:33:21 djm Exp $ +# Placed in the Public Domain. + +tid="certified user keys" + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak + +# Create a CA key and add it to authorized_keys +${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ + fail "ssh-keygen of user_ca_key failed" +( + echo -n 'cert-authority ' + cat $OBJ/user_ca_key.pub +) > $OBJ/authorized_keys_$USER + +# Generate and sign user keys +for ktype in rsa dsa ; do + verbose "$tid: sign user ${ktype} cert" + ${SSHKEYGEN} -q -N '' -t ${ktype} \ + -f $OBJ/cert_user_key_${ktype} || \ + fail "ssh-keygen of cert_user_key_${ktype} failed" + ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I \ + "regress user key for $USER" \ + -n $USER $OBJ/cert_user_key_${ktype} || + fail "couldn't sign cert_user_key_${ktype}" + +done + +# Basic connect tests +for privsep in yes no ; do + for ktype in rsa dsa ; do + verbose "$tid: user ${ktype} cert connect privsep $privsep" + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + ) > $OBJ/sshd_proxy + + ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ + somehost true + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + done +done + +verbose "$tid: ensure CA key does not authenticate user" +${SSH} -2i $OBJ/user_ca_key -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 +if [ $? -eq 0 ]; then + fail "ssh cert connect with CA key succeeded unexpectedly" +fi + +test_one() { + ident=$1 + result=$2 + sign_opts=$3 + + verbose "$tid: test user cert connect $ident expect $result" + + ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ + $sign_opts \ + $OBJ/cert_user_key_rsa || + fail "couldn't sign cert_user_key_rsa" + + ${SSH} -2i $OBJ/cert_user_key_rsa -F $OBJ/ssh_proxy \ + somehost true >/dev/null 2>&1 + rc=$? + if [ "x$result" = "xsuccess" ] ; then + if [ $rc -ne 0 ]; then + fail "ssh cert connect $ident failed unexpectedly" + fi + else + if [ $rc -eq 0 ]; then + fail "ssh cert connect $ident succeeded unexpectedly" + fi + fi + cleanup +} + +test_one "host-certificate" failure "-h" +test_one "empty principals" success "" +test_one "wrong principals" failure "-n foo" +test_one "cert not yet valid" failure "-V20200101:20300101" +test_one "cert expired" failure "-V19800101:19900101" +test_one "cert valid interval" success "-V-1w:+2w" +test_one "wrong source-address" failure "-Osource-address=10.0.0.0/8" +test_one "force-command" failure "-Oforce-command=false" + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -- cgit v1.2.3 From 09a24db2d7e89c2fe72c1754181b6cc6e62949d7 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 28 Feb 2010 03:28:05 +1100 Subject: - (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded --- ChangeLog | 3 +++ ssh-pkcs11-helper.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 703c347fb..931683219 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +20100227 +- (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded + 20100226 - OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/02/26 20:29:54 diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 1684ab0c2..54786c62a 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -280,6 +280,8 @@ main(int argc, char **argv) extern char *optarg; extern char *__progname; + init_rng(); + seed_rng(); __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); -- cgit v1.2.3 From d05951fceee3fe19fc0bea29006a6409419b609f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 28 Feb 2010 03:29:33 +1100 Subject: - (djm) [openbsd-compat/bsd-cygwin_util.c] Reduce the set of environment variables copied into sshd child processes. From vinschen AT redhat.com --- ChangeLog | 4 +++- openbsd-compat/bsd-cygwin_util.c | 9 --------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 931683219..760fff736 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 20100227 -- (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded + - (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded + - (djm) [openbsd-compat/bsd-cygwin_util.c] Reduce the set of environment + variables copied into sshd child processes. From vinschen AT redhat.com 20100226 - OpenBSD CVS Sync diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index e90c1597f..e9fa3a0e2 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -85,23 +85,14 @@ static struct wenv { size_t namelen; } wenv_arr[] = { { NL("ALLUSERSPROFILE=") }, - { NL("COMMONPROGRAMFILES=") }, { NL("COMPUTERNAME=") }, { NL("COMSPEC=") }, { NL("CYGWIN=") }, - { NL("NUMBER_OF_PROCESSORS=") }, { NL("OS=") }, { NL("PATH=") }, { NL("PATHEXT=") }, - { NL("PROCESSOR_ARCHITECTURE=") }, - { NL("PROCESSOR_IDENTIFIER=") }, - { NL("PROCESSOR_LEVEL=") }, - { NL("PROCESSOR_REVISION=") }, - { NL("PROGRAMFILES=") }, { NL("SYSTEMDRIVE=") }, { NL("SYSTEMROOT=") }, - { NL("TMP=") }, - { NL("TEMP=") }, { NL("WINDIR=") } }; -- cgit v1.2.3 From acc9b29486dfd649dfda474e5c1a03b317449f1c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 1 Mar 2010 04:36:54 +1100 Subject: - (djm) [auth.c] On Cygwin, refuse usernames that have differences in case from that matched in the system password database. On this platform, passwords are stored case-insensitively, but sshd requires exact case matching for Match blocks in sshd_config(5). Based on a patch from vinschen AT redhat.com. --- ChangeLog | 7 +++++++ auth.c | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index 760fff736..06f519868 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20100228 + - (djm) [auth.c] On Cygwin, refuse usernames that have differences in + case from that matched in the system password database. On this + platform, passwords are stored case-insensitively, but sshd requires + exact case matching for Match blocks in sshd_config(5). Based on + a patch from vinschen AT redhat.com. + 20100227 - (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded - (djm) [openbsd-compat/bsd-cygwin_util.c] Reduce the set of environment diff --git a/auth.c b/auth.c index 3005f815e..ab9c69fb8 100644 --- a/auth.c +++ b/auth.c @@ -535,6 +535,19 @@ getpwnamallow(const char *user) get_canonical_hostname(options.use_dns), get_remote_ipaddr()); pw = getpwnam(user); +#ifdef HAVE_CYGWIN + /* + * Windows usernames are case-insensitive. To avoid later problems + * when trying to match the username, the user is only allowed to + * login if the username is given in the same case as stored in the + * user database. + */ + if (pw != NULL && strcmp(user, pw->pw_name) != 0) { + logit("Login name %.100s does not match stored username %.100s", + user, pw->pw_name); + pw = NULL; + } +#endif if (pw == NULL) { logit("Invalid user %.100s from %.100s", user, get_remote_ipaddr()); -- cgit v1.2.3 From bff24b8ad29f4b5427ffbe017acafdb3efc1b951 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sun, 28 Feb 2010 14:51:56 -0800 Subject: - (tim) [ssh-pkcs11-helper.c] Move declarations before calling functions to make older compilers (gcc 2.95) happy. --- ChangeLog | 2 ++ ssh-pkcs11-helper.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 06f519868..74bfc0469 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ platform, passwords are stored case-insensitively, but sshd requires exact case matching for Match blocks in sshd_config(5). Based on a patch from vinschen AT redhat.com. + - (tim) [ssh-pkcs11-helper.c] Move declarations before calling functions + to make older compilers (gcc 2.95) happy. 20100227 - (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 54786c62a..d3bfb9838 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -274,12 +274,12 @@ main(int argc, char **argv) LogLevel log_level = SYSLOG_LEVEL_ERROR; char buf[4*4096]; - TAILQ_INIT(&pkcs11_keylist); - pkcs11_init(0); - extern char *optarg; extern char *__progname; + TAILQ_INIT(&pkcs11_keylist); + pkcs11_init(0); + init_rng(); seed_rng(); __progname = ssh_get_progname(argv[0]); -- cgit v1.2.3 From c614c78c53a38d2a603fb1b01fb419b965b24e50 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 1 Mar 2010 12:49:05 +1100 Subject: - (dtucker) [regress/{cert-hostkey,cfgmatch,cipher-speed}.sh} Replace "echo -n" with "echon" for portability. --- ChangeLog | 4 ++++ regress/cert-hostkey.sh | 6 +++--- regress/cfgmatch.sh | 4 ++-- regress/cipher-speed.sh | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74bfc0469..3ce434723 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20100301 + - (dtucker) [regress/{cert-hostkey,cfgmatch,cipher-speed}.sh} Replace + "echo -n" with "echon" for portability. + 20100228 - (djm) [auth.c] On Cygwin, refuse usernames that have differences in case from that matched in the system password database. On this diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index 14cd2230b..9539a927f 100644 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh @@ -12,8 +12,8 @@ HOSTS='localhost-with-alias,127.0.0.1,::1' ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ fail "ssh-keygen of host_ca_key failed" ( - echo -n '@cert-authority ' - echo -n "$HOSTS " + echon '@cert-authority ' + echon "$HOSTS " cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert @@ -102,7 +102,7 @@ for ktype in rsa dsa ; do -n $HOSTS $OBJ/cert_host_key_${ktype} || fail "couldn't sign cert_host_key_${ktype}" ( - echo -n "$HOSTS " + echon "$HOSTS " cat $OBJ/cert_host_key_${ktype}.pub ) > $OBJ/known_hosts-cert ( diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh index 35c5e52a1..96badd51b 100644 --- a/regress/cfgmatch.sh +++ b/regress/cfgmatch.sh @@ -57,9 +57,9 @@ for p in 1 2; do done # Retry previous with key option, should also be denied. -echo -n 'permitopen="127.0.0.1:'$PORT'" ' >$OBJ/authorized_keys_$USER +echon 'permitopen="127.0.0.1:'$PORT'" ' >$OBJ/authorized_keys_$USER cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER -echo -n 'permitopen="127.0.0.1:'$PORT'" ' >>$OBJ/authorized_keys_$USER +echon 'permitopen="127.0.0.1:'$PORT'" ' >>$OBJ/authorized_keys_$USER cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER for p in 1 2; do rm -f $pidfile diff --git a/regress/cipher-speed.sh b/regress/cipher-speed.sh index d39a829d4..85de6d585 100644 --- a/regress/cipher-speed.sh +++ b/regress/cipher-speed.sh @@ -19,7 +19,7 @@ ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc for c in $ciphers; do for m in $macs; do trace "proto 2 cipher $c mac $m" for x in $tries; do - echo -n "$c/$m:\t" + echon "$c/$m:\t" ( ${SSH} -o 'compression no' \ -F $OBJ/ssh_proxy -2 -m $m -c $c somehost \ exec sh -c \'"dd of=/dev/null obs=32k"\' \ @@ -35,7 +35,7 @@ ciphers="3des blowfish" for c in $ciphers; do trace "proto 1 cipher $c" for x in $tries; do - echo -n "$c:\t" + echon "$c:\t" ( ${SSH} -o 'compression no' \ -F $OBJ/ssh_proxy -1 -c $c somehost \ exec sh -c \'"dd of=/dev/null obs=32k"\' \ -- cgit v1.2.3 From 9af0cb9accbf42aca8f87d3f3bfffcac20c2f5b4 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 1 Mar 2010 15:52:49 +1100 Subject: - (dtucker) [openbsd-compat/port-linux.c] Make failure to write to the OOM adjust log at verbose only, since according to cjwatson in bug #1470 some virtualization platforms don't allow writes. --- ChangeLog | 3 +++ openbsd-compat/port-linux.c | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ce434723..1a318e049 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ 20100301 - (dtucker) [regress/{cert-hostkey,cfgmatch,cipher-speed}.sh} Replace "echo -n" with "echon" for portability. + - (dtucker) [openbsd-compat/port-linux.c] Make failure to write to the OOM + adjust log at verbose only, since according to cjwatson in bug #1470 + some virtualization platforms don't allow writes. 20100228 - (djm) [auth.c] On Cygwin, refuse usernames that have differences in diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index cda751dea..89b9a7340 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -1,4 +1,4 @@ -/* $Id: port-linux.c,v 1.7 2009/12/08 02:39:48 dtucker Exp $ */ +/* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh @@ -229,11 +229,11 @@ oom_adjust_setup(void) debug3("%s", __func__); if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) { if (fscanf(fp, "%d", &oom_adj_save) != 1) - logit("error reading %s: %s", OOM_ADJ_PATH, strerror(errno)); + verbose("error reading %s: %s", OOM_ADJ_PATH, strerror(errno)); else { rewind(fp); if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0) - logit("error writing %s: %s", + verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno)); else verbose("Set %s from %d to %d", @@ -254,7 +254,7 @@ oom_adjust_restore(void) return; if (fprintf(fp, "%d\n", oom_adj_save) <= 0) - logit("error writing %s: %s", OOM_ADJ_PATH, strerror(errno)); + verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno)); else verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save); -- cgit v1.2.3 From c5b0cb3b7d4f784ef95461d5848219d991264027 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Mon, 1 Mar 2010 15:57:42 -0800 Subject: - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from http://git.savannah.gnu.org/gitweb/ (2009-12-30 and 2010-01-22 respectively). --- ChangeLog | 5 ++ config.guess | 238 +++++++++++++++++++++++++++-------------------------------- config.sub | 81 +++++++++++++++----- 3 files changed, 173 insertions(+), 151 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1a318e049..be91454f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +20100302 + - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from + http://git.savannah.gnu.org/gitweb/ (2009-12-30 and 2010-01-22 + respectively). + 20100301 - (dtucker) [regress/{cert-hostkey,cfgmatch,cipher-speed}.sh} Replace "echo -n" with "echon" for portability. diff --git a/config.guess b/config.guess index c7607c74f..c2246a4f7 100755 --- a/config.guess +++ b/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. -timestamp='2008-04-14' +timestamp='2009-12-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,16 +27,16 @@ timestamp='2008-04-14' # the same distribution terms that you use for the rest of that program. -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` @@ -56,8 +56,9 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -170,7 +171,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -324,14 +325,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize @@ -640,7 +660,7 @@ EOF # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null + grep -q __LP64__ then HP_ARCH="hppa2.0w" else @@ -791,12 +811,12 @@ EOF i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - *:Interix*:[3456]*) + *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; - EM64T | authenticamd) + authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) @@ -806,6 +826,9 @@ EOF [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we @@ -835,6 +858,20 @@ EOF i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ @@ -857,6 +894,17 @@ EOF frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; @@ -866,74 +914,33 @@ EOF m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - mips:Linux:*:*) + mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU - #undef mips - #undef mipsel + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel + CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips + CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + padre:Linux:*:*) + echo sparc-unknown-linux-gnu exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level @@ -943,8 +950,11 @@ EOF *) echo hppa-unknown-linux-gnu ;; esac exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux @@ -967,66 +977,6 @@ EOF xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both @@ -1055,7 +1005,7 @@ EOF i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) @@ -1099,8 +1049,11 @@ EOF pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 @@ -1138,6 +1091,16 @@ EOF 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; @@ -1150,7 +1113,7 @@ EOF rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) @@ -1243,6 +1206,16 @@ EOF *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} @@ -1324,6 +1297,9 @@ EOF i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 diff --git a/config.sub b/config.sub index a649350a6..c2d125724 100755 --- a/config.sub +++ b/config.sub @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. -timestamp='2008-06-16' +timestamp='2010-01-22' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -32,13 +32,16 @@ timestamp='2008-06-16' # Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. @@ -72,8 +75,9 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -122,6 +126,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` @@ -148,10 +153,13 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) + -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; + -bluegene*) + os=-cnk + ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 @@ -249,6 +257,7 @@ case $basic_machine in | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ @@ -270,6 +279,7 @@ case $basic_machine in | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ + | moxie \ | mt \ | msp430 \ | nios | nios2 \ @@ -278,20 +288,22 @@ case $basic_machine in | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ + | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ + | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) + | z8k | z80) basic_machine=$basic_machine-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12) + m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none @@ -331,9 +343,10 @@ case $basic_machine in | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ @@ -361,21 +374,23 @@ case $basic_machine in | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile-* | tilegx-* \ | tron-* \ + | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ - | z8k-*) + | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) @@ -443,6 +458,10 @@ case $basic_machine in basic_machine=m68k-apollo os=-bsd ;; + aros) + basic_machine=i386-pc + os=-aros + ;; aux) basic_machine=m68k-apple os=-aux @@ -459,6 +478,10 @@ case $basic_machine in basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; c90) basic_machine=c90-cray os=-unicos @@ -711,6 +734,9 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + microblaze) + basic_machine=microblaze-xilinx + ;; mingw32) basic_machine=i386-pc os=-mingw32 @@ -1061,6 +1087,11 @@ case $basic_machine in basic_machine=tic6x-unknown os=-coff ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; tile*) basic_machine=tile-unknown os=-linux-gnu @@ -1140,6 +1171,10 @@ case $basic_machine in basic_machine=z8k-unknown os=-sim ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -1178,7 +1213,7 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) @@ -1228,6 +1263,9 @@ case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; @@ -1248,10 +1286,11 @@ case $os in # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ + | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ @@ -1270,7 +1309,7 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1403,6 +1442,8 @@ case $os in -dicos*) os=-dicos ;; + -nacl*) + ;; -none) ;; *) @@ -1600,7 +1641,7 @@ case $basic_machine in -sunos*) vendor=sun ;; - -aix*) + -cnk*|-aix*) vendor=ibm ;; -beos*) -- cgit v1.2.3 From 25b97dd454600dde697634c1c871a97f64045d5f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 3 Mar 2010 10:24:00 +1100 Subject: - (djm) [PROTOCOL.certkeys] Add RCS Ident --- ChangeLog | 3 +++ PROTOCOL.certkeys | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index be91454f2..c8b36eb15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +20100303 + - (djm) [PROTOCOL.certkeys] Add RCS Ident + 20100302 - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from http://git.savannah.gnu.org/gitweb/ (2009-12-30 and 2010-01-22 diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys index 0b887a240..1e24fa025 100644 --- a/PROTOCOL.certkeys +++ b/PROTOCOL.certkeys @@ -189,3 +189,5 @@ source-address string Comma-separated list of source addresses If this constraint is not present then certificates may be presented from any source address. + +$OpenBSD: PROTOCOL.certkeys,v 1.2 2010/03/02 23:22:44 djm Exp $ -- cgit v1.2.3 From 15f5b560b1542fa087d7462be416616104ab0be8 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 3 Mar 2010 10:25:21 +1100 Subject: - jmc@cvs.openbsd.org 2010/02/26 22:09:28 [ssh-keygen.1 ssh.1 sshd.8] tweak previous; --- ChangeLog | 4 ++++ ssh-keygen.1 | 21 ++++++++++++--------- ssh.1 | 3 +-- sshd.8 | 20 ++++++++++---------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8b36eb15..aad1cd29b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident + - OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2010/02/26 22:09:28 + [ssh-keygen.1 ssh.1 sshd.8] + tweak previous; 20100302 - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 772caf7ad..d704f0660 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.84 2010/02/26 20:29:54 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.85 2010/02/26 22:09:28 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -107,6 +107,7 @@ .Op Fl a Ar num_trials .Op Fl W Ar generator .Nm ssh-keygen +.Bk -words .Fl s Ar ca_key .Fl I Ar certificate_identity .Op Fl h @@ -114,6 +115,7 @@ .Op Fl O Ar constraint .Op Fl V Ar validity_interval .Ar +.Ek .Sh DESCRIPTION .Nm generates, manages and converts authentication keys for @@ -259,7 +261,7 @@ certificate. Please see the .Sx CERTIFICATES section for details. -.It Fl I +.It Fl I Ar certificate_identity Specify the key identity when signing a public key. Please see the .Sx CERTIFICATES @@ -303,21 +305,21 @@ section for details. The constraints that are valid for user certificates are: .Bl -tag -width Ds .It Ic no-x11-forwarding -Disable X11 forwarding. (permitted by default) +Disable X11 forwarding (permitted by default). .It Ic no-agent-forwarding Disable .Xr ssh-agent 1 -forwarding. (permitted by default) +forwarding (permitted by default). .It Ic no-port-forwarding -Disable port forwarding. (permitted by default) +Disable port forwarding (permitted by default). .It Ic no-pty -Disable PTY allocation. (permitted by default) +Disable PTY allocation (permitted by default). .It Ic no-user-rc Disable execution of .Pa ~/.ssh/rc by -.Xr sshd 8 . -(permitted by default) +.Xr sshd 8 +(permitted by default). .It Ic clear Clear all enabled permissions. This is useful for clearing the default set of permissions so permissions may @@ -504,7 +506,8 @@ the X.509 certificates used in .Nm supports two types of certificates: user and host. User certificates authenticate users to servers, whereas host certificates -authenticate server hosts to users. To generate a user certificate: +authenticate server hosts to users. +To generate a user certificate: .Pp .Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub .Pp diff --git a/ssh.1 b/ssh.1 index 7d8f92aba..183dc277f 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.295 2010/02/26 20:29:54 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.296 2010/02/26 22:09:28 jmc Exp $ .Dd $Mdocdate: February 26 2010 $ .Dt SSH 1 .Os @@ -1121,7 +1121,6 @@ See the section of .Xr ssh-keygen 1 for more details. -.Pp .Sh SSH-BASED VIRTUAL PRIVATE NETWORKS .Nm contains support for Virtual Private Network (VPN) tunnelling diff --git a/sshd.8 b/sshd.8 index fcd5195db..88a86f958 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.251 2010/02/26 20:29:54 djm Exp $ +.\" $OpenBSD: sshd.8,v 1.252 2010/02/26 22:09:28 jmc Exp $ .Dd $Mdocdate: February 26 2010 $ .Dt SSHD 8 .Os @@ -102,15 +102,6 @@ to use IPv6 addresses only. .It Fl b Ar bits Specifies the number of bits in the ephemeral protocol version 1 server key (default 1024). -.It Fl c Ar host_certificate_file -Specifies a path to a certificate file to identify -.Nm -during key exchange. -The certificate file must match a host key file specified using the -.Fl -h -option or the -.Cm HostKey -configuration directive. .It Fl C Ar connection_spec Specify the connection parameters to use for the .Fl T @@ -129,6 +120,15 @@ and All are required and may be supplied in any order, either with multiple .Fl C options or as a comma-separated list. +.It Fl c Ar host_certificate_file +Specifies a path to a certificate file to identify +.Nm +during key exchange. +The certificate file must match a host key file specified using the +.Fl h +option or the +.Cm HostKey +configuration directive. .It Fl D When this option is specified, .Nm -- cgit v1.2.3 From 0bd41861bb695824f2070ad7dbe3ed08d6c27e0a Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 3 Mar 2010 10:25:41 +1100 Subject: - otto@cvs.openbsd.org 2010/03/01 11:07:06 [ssh-add.c] zap what seems to be a left-over debug message; ok markus@ --- ChangeLog | 3 +++ ssh-add.c | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index aad1cd29b..a00b680f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,9 @@ - jmc@cvs.openbsd.org 2010/02/26 22:09:28 [ssh-keygen.1 ssh.1 sshd.8] tweak previous; + - otto@cvs.openbsd.org 2010/03/01 11:07:06 + [ssh-add.c] + zap what seems to be a left-over debug message; ok markus@ 20100302 - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from diff --git a/ssh-add.c b/ssh-add.c index a7963223a..ad9f7a83e 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.93 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.94 2010/03/01 11:07:06 otto Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -223,8 +223,7 @@ add_file(AuthenticationConnection *ac, const char *filename) error("Certificate %s (%s) add failed", certpath, private->cert->key_id); } - } else - fprintf(stderr, "Unable to load certificate %s", certpath); + } xfree(certpath); xfree(comment); -- cgit v1.2.3 From fb84e5950e34a65e53ecb893af2fa2a3d6cce229 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 3 Mar 2010 10:26:04 +1100 Subject: - djm@cvs.openbsd.org 2010/03/02 23:20:57 [ssh-keygen.c] POSIX strptime is stricter than OpenBSD's so do a little dance to appease it. --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index a00b680f0..911467dd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ - otto@cvs.openbsd.org 2010/03/01 11:07:06 [ssh-add.c] zap what seems to be a left-over debug message; ok markus@ + - djm@cvs.openbsd.org 2010/03/02 23:20:57 + [ssh-keygen.c] + POSIX strptime is stricter than OpenBSD's so do a little dance to + appease it. 20100302 - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from -- cgit v1.2.3 From 2ca342b84bca89e35931cbe34f19d7ab4d200d9b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 3 Mar 2010 12:14:15 +1100 Subject: - djm@cvs.openbsd.org 2010/03/02 23:20:57 [ssh-keygen.c] POSIX strptime is stricter than OpenBSD's so do a little dance to appease it. --- ssh-keygen.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/ssh-keygen.c b/ssh-keygen.c index 60261c210..7dc10808c 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.179 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.180 2010/03/02 23:20:57 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1243,13 +1243,29 @@ parse_absolute_time(const char *s) { struct tm tm; time_t tt; + char buf[32], *fmt; - if (strlen(s) != 8 && strlen(s) != 14) + /* + * POSIX strptime says "The application shall ensure that there + * is white-space or other non-alphanumeric characters between + * any two conversion specifications" so arrange things this way. + */ + switch (strlen(s)) { + case 8: + fmt = "%Y/%m/%d"; + snprintf(buf, sizeof(buf), "%.4s/%.2s/%.2s", s, s + 4, s + 6); + break; + case 14: + fmt = "%Y/%m/%d %H:%M:%S"; + snprintf(buf, sizeof(buf), "%.4s/%.2s/%.2s %.2s:%.2s:%.2s", + s, s + 4, s + 6, s + 8, s + 10, s + 12); + break; + default: fatal("Invalid certificate time format %s", s); + } bzero(&tm, sizeof(tm)); - if (strptime(s, - strlen(s) == 8 ? "%Y%m%d" : "%Y%m%d%H%M%S", &tm) == NULL) + if (strptime(buf, fmt, &tm) == NULL) fatal("Invalid certificate time %s", s); if ((tt = mktime(&tm)) < 0) fatal("Certificate time %s cannot be represented", s); -- cgit v1.2.3 From 386dbc05e9c8c34dde5abe62a7804b4747b0de06 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 3 Mar 2010 13:22:41 +1100 Subject: - (djm) [regress/cert-userkey.sh] s/echo -n/echon/ here too --- ChangeLog | 1 + regress/cert-userkey.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 911467dd0..21417e6be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ [ssh-keygen.c] POSIX strptime is stricter than OpenBSD's so do a little dance to appease it. + - (djm) [regress/cert-userkey.sh] s/echo -n/echon/ here too 20100302 - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index 307e7236f..9588e0b6b 100644 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -10,7 +10,7 @@ cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ fail "ssh-keygen of user_ca_key failed" ( - echo -n 'cert-authority ' + echon 'cert-authority ' cat $OBJ/user_ca_key.pub ) > $OBJ/authorized_keys_$USER -- cgit v1.2.3 From 910f209c1d08b9b91f744c571fbf805206f04729 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 14:17:22 +1100 Subject: - (djm) [ssh-keygen.c] Use correct local variable, instead of maybe-undefined global "optarg" --- ChangeLog | 4 ++++ ssh-keygen.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 21417e6be..c5398522b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20100304 + - (djm) [ssh-keygen.c] Use correct local variable, instead of + maybe-undefined global "optarg" + 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident - OpenBSD CVS Sync diff --git a/ssh-keygen.c b/ssh-keygen.c index 7dc10808c..f910dce38 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1300,7 +1300,7 @@ parse_cert_times(char *timespec) from = xstrdup(timespec); to = strchr(from, ':'); if (to == NULL || from == to || *(to + 1) == '\0') - fatal("Invalid certificate life specification %s", optarg); + fatal("Invalid certificate life specification %s", timespec); *to++ = '\0'; if (*from == '-' || *from == '+') -- cgit v1.2.3 From 661ffc1fd6d7c2d1f99ee0ab6918b10e53fe4f82 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:09:24 +1100 Subject: - (djm) [contrib/redhat/openssh.spec] Replace obsolete BuildPreReq on XFree86-devel with neutral /usr/include/X11/Xlib.h; imorgan AT nas.nasa.gov in bz#1731 --- ChangeLog | 3 +++ contrib/redhat/openssh.spec | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c5398522b..1e82d21b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ 20100304 - (djm) [ssh-keygen.c] Use correct local variable, instead of maybe-undefined global "optarg" + - (djm) [contrib/redhat/openssh.spec] Replace obsolete BuildPreReq + on XFree86-devel with neutral /usr/include/X11/Xlib.h; + imorgan AT nas.nasa.gov in bz#1731 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index a15afc7ee..4bec90078 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -94,7 +94,7 @@ BuildPreReq: glibc-devel, pam BuildPreReq: /usr/include/security/pam_appl.h %endif %if ! %{no_x11_askpass} -BuildPreReq: XFree86-devel +BuildPreReq: /usr/include/X11/Xlib.h %endif %if ! %{no_gnome_askpass} BuildPreReq: pkgconfig -- cgit v1.2.3 From d45f3b6cc75e5cf8b31f1ee2f51164c7410b2669 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:09:46 +1100 Subject: - (djm) [.cvsignore] Ignore ssh-pkcs11-helper --- .cvsignore | 1 + ChangeLog | 1 + 2 files changed, 2 insertions(+) diff --git a/.cvsignore b/.cvsignore index b893c972d..8dd3ddff9 100644 --- a/.cvsignore +++ b/.cvsignore @@ -21,6 +21,7 @@ ssh-agent ssh-keygen ssh-keyscan ssh-keysign +ssh-pkcs11-helper ssh-rand-helper ssh_prng_cmds sshd diff --git a/ChangeLog b/ChangeLog index 1e82d21b3..bde8dece5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ - (djm) [contrib/redhat/openssh.spec] Replace obsolete BuildPreReq on XFree86-devel with neutral /usr/include/X11/Xlib.h; imorgan AT nas.nasa.gov in bz#1731 + - (djm) [.cvsignore] Ignore ssh-pkcs11-helper 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident -- cgit v1.2.3 From e1abf4d6bc4bea0bb76e6ff89ca6048122e90d81 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:41:29 +1100 Subject: - (djm) [regress/Makefile] Cleanup sshd_proxy_orig --- ChangeLog | 1 + regress/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bde8dece5..248fdfa91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ on XFree86-devel with neutral /usr/include/X11/Xlib.h; imorgan AT nas.nasa.gov in bz#1731 - (djm) [.cvsignore] Ignore ssh-pkcs11-helper + - (djm) [regress/Makefile] Cleanup sshd_proxy_orig 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/regress/Makefile b/regress/Makefile index de8e9fd33..d25a64555 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -69,7 +69,7 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \ sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \ known_hosts-cert host_ca_key* cert_host_key* \ - putty.rsa2 + putty.rsa2 sshd_proxy_orig # Enable all malloc(3) randomisations and checks TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" -- cgit v1.2.3 From 41396573afc94d64973d9eb824ca510d39260b3e Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:51:11 +1100 Subject: - OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/03/03 01:44:36 [auth-options.c key.c] reject strings with embedded ASCII nul chars in certificate key IDs, principal names and constraints --- ChangeLog | 5 +++++ auth-options.c | 28 ++++++++++++++++++++-------- key.c | 36 +++++++++++++++++++++++------------- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 248fdfa91..36ef5c911 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,11 @@ imorgan AT nas.nasa.gov in bz#1731 - (djm) [.cvsignore] Ignore ssh-pkcs11-helper - (djm) [regress/Makefile] Cleanup sshd_proxy_orig + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/03/03 01:44:36 + [auth-options.c key.c] + reject strings with embedded ASCII nul chars in certificate key IDs, + principal names and constraints 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/auth-options.c b/auth-options.c index 396bda62f..d14624bf4 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.45 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.46 2010/03/03 01:44:36 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -391,7 +391,7 @@ int auth_cert_constraints(Buffer *c_orig, struct passwd *pw) { u_char *name = NULL, *data_blob = NULL; - u_int len; + u_int nlen, dlen, clen; Buffer c, data; int ret = -1; @@ -410,14 +410,18 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig)); while (buffer_len(&c) > 0) { - if ((name = buffer_get_string_ret(&c, NULL)) == NULL || - (data_blob = buffer_get_string_ret(&c, &len)) == NULL) { + if ((name = buffer_get_string_ret(&c, &nlen)) == NULL || + (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) { error("Certificate constraints corrupt"); goto out; } - buffer_append(&data, data_blob, len); + buffer_append(&data, data_blob, dlen); debug3("found certificate constraint \"%.100s\" len %u", - name, len); + name, dlen); + if (strlen(name) != nlen) { + error("Certificate constraint name contains \\0"); + goto out; + } if (strcmp(name, "permit-X11-forwarding") == 0) cert_no_x11_forwarding_flag = 0; else if (strcmp(name, "permit-agent-forwarding") == 0) @@ -429,13 +433,17 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) else if (strcmp(name, "permit-user-rc") == 0) cert_no_user_rc = 0; else if (strcmp(name, "force-command") == 0) { - char *command = buffer_get_string_ret(&data, NULL); + char *command = buffer_get_string_ret(&data, &clen); if (command == NULL) { error("Certificate constraint \"%s\" corrupt", name); goto out; } + if (strlen(command) != clen) { + error("force-command constrain contains \\0"); + goto out; + } if (cert_forced_command != NULL) { error("Certificate has multiple " "forced-command constraints"); @@ -444,7 +452,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) } cert_forced_command = command; } else if (strcmp(name, "source-address") == 0) { - char *allowed = buffer_get_string_ret(&data, NULL); + char *allowed = buffer_get_string_ret(&data, &clen); const char *remote_ip = get_remote_ipaddr(); if (allowed == NULL) { @@ -452,6 +460,10 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) name); goto out; } + if (strlen(allowed) != clen) { + error("source-address constrain contains \\0"); + goto out; + } if (cert_source_address_done++) { error("Certificate has multiple " "source-address constraints"); diff --git a/key.c b/key.c index 387190b53..e6266fa58 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.83 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: key.c,v 1.84 2010/03/03 01:44:36 djm Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1000,7 +1000,7 @@ static int cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) { u_char *principals, *constraints, *sig_key, *sig; - u_int signed_len, plen, clen, sklen, slen; + u_int signed_len, plen, clen, sklen, slen, kidlen; Buffer tmp; char *principal; int ret = -1; @@ -1012,7 +1012,7 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) principals = constraints = sig_key = sig = NULL; if (buffer_get_int_ret(&key->cert->type, b) != 0 || - (key->cert->key_id = buffer_get_string_ret(b, NULL)) == NULL || + (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL || (principals = buffer_get_string_ret(b, &plen)) == NULL || buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || @@ -1024,6 +1024,11 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) goto out; } + if (kidlen != strlen(key->cert->key_id)) { + error("%s: key ID contains \\0 character", __func__); + goto out; + } + /* Signature is left in the buffer so we can calculate this length */ signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); @@ -1041,11 +1046,16 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) buffer_append(&tmp, principals, plen); while (buffer_len(&tmp) > 0) { if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { - error("Too many principals"); + error("%s: Too many principals", __func__); goto out; } - if ((principal = buffer_get_string_ret(&tmp, NULL)) == NULL) { - error("Principals data invalid"); + if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) { + error("%s: Principals data invalid", __func__); + goto out; + } + if (strlen(principal) != plen) { + error("%s: Principal contains \\0 character", + __func__); goto out; } key->cert->principals = xrealloc(key->cert->principals, @@ -1061,7 +1071,7 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) while (buffer_len(&tmp) != 0) { if (buffer_get_string_ptr(&tmp, NULL) == NULL || buffer_get_string_ptr(&tmp, NULL) == NULL) { - error("Constraints data invalid"); + error("%s: Constraints data invalid", __func__); goto out; } } @@ -1069,12 +1079,12 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) if ((key->cert->signature_key = key_from_blob(sig_key, sklen)) == NULL) { - error("Signature key invalid"); + error("%s: Signature key invalid", __func__); goto out; } if (key->cert->signature_key->type != KEY_RSA && key->cert->signature_key->type != KEY_DSA) { - error("Invalid signature key type %s (%d)", + error("%s: Invalid signature key type %s (%d)", __func__, key_type(key->cert->signature_key), key->cert->signature_key->type); goto out; @@ -1083,17 +1093,17 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) switch (key_verify(key->cert->signature_key, sig, slen, buffer_ptr(&key->cert->certblob), signed_len)) { case 1: + ret = 0; break; /* Good signature */ case 0: - error("Invalid signature on certificate"); + error("%s: Invalid signature on certificate", __func__); goto out; case -1: - error("Certificate signature verification failed"); + error("%s: Certificate signature verification failed", + __func__); goto out; } - ret = 0; - out: buffer_free(&tmp); if (principals != NULL) -- cgit v1.2.3 From cd38c9c5551094261775b99994fa0c12d333c94c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:51:37 +1100 Subject: - djm@cvs.openbsd.org 2010/03/03 22:49:50 [sshd.8] the authorized_keys option for CA keys is "cert-authority", not "from=cert-authority". spotted by imorgan AT nas.nasa.gov --- ChangeLog | 4 ++++ sshd.8 | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 36ef5c911..fd1ff6484 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,10 @@ [auth-options.c key.c] reject strings with embedded ASCII nul chars in certificate key IDs, principal names and constraints + - djm@cvs.openbsd.org 2010/03/03 22:49:50 + [sshd.8] + the authorized_keys option for CA keys is "cert-authority", not + "from=cert-authority". spotted by imorgan AT nas.nasa.gov 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/sshd.8 b/sshd.8 index 88a86f958..d31538176 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.252 2010/02/26 22:09:28 jmc Exp $ -.Dd $Mdocdate: February 26 2010 $ +.\" $OpenBSD: sshd.8,v 1.253 2010/03/03 22:49:50 djm Exp $ +.Dd $Mdocdate: March 3 2010 $ .Dt SSHD 8 .Os .Sh NAME @@ -508,7 +508,7 @@ No spaces are permitted, except within double quotes. The following option specifications are supported (note that option keywords are case-insensitive): .Bl -tag -width Ds -.It Cm from="cert-authority" +.It Cm cert-authority Specifies that the listed key is a certification authority (CA) that is trusted to validate signed certificates for user authentication. .Pp -- cgit v1.2.3 From fe588e3c8434e6c9017b649dad71ef282a5dac01 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:52:00 +1100 Subject: - djm@cvs.openbsd.org 2010/03/03 22:50:40 [PROTOCOL.certkeys] s/similar same/similar/; from imorgan AT nas.nasa.gov --- ChangeLog | 3 +++ PROTOCOL.certkeys | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd1ff6484..7bd29758c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,9 @@ [sshd.8] the authorized_keys option for CA keys is "cert-authority", not "from=cert-authority". spotted by imorgan AT nas.nasa.gov + - djm@cvs.openbsd.org 2010/03/03 22:50:40 + [PROTOCOL.certkeys] + s/similar same/similar/; from imorgan AT nas.nasa.gov 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys index 1e24fa025..1ed9e2064 100644 --- a/PROTOCOL.certkeys +++ b/PROTOCOL.certkeys @@ -48,7 +48,7 @@ New public key formats ---------------------- The ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com key -types take a similar same high-level format (note: data types and +types take a similar high-level format (note: data types and encoding are as per RFC4251 section 5). The serialised wire encoding of these certificates is also used for storing them on disk. @@ -190,4 +190,4 @@ source-address string Comma-separated list of source addresses certificates may be presented from any source address. -$OpenBSD: PROTOCOL.certkeys,v 1.2 2010/03/02 23:22:44 djm Exp $ +$OpenBSD: PROTOCOL.certkeys,v 1.3 2010/03/03 22:50:40 djm Exp $ -- cgit v1.2.3 From 2befbad9b3c8fc6e4e564c062870229bc722734c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:52:18 +1100 Subject: - djm@cvs.openbsd.org 2010/03/04 01:44:57 [key.c] use buffer_get_string_ptr_ret() where we are checking the return value explicitly instead of the fatal()-causing buffer_get_string_ptr() --- ChangeLog | 4 ++++ key.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7bd29758c..0b5663ba4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,10 @@ - djm@cvs.openbsd.org 2010/03/03 22:50:40 [PROTOCOL.certkeys] s/similar same/similar/; from imorgan AT nas.nasa.gov + - djm@cvs.openbsd.org 2010/03/04 01:44:57 + [key.c] + use buffer_get_string_ptr_ret() where we are checking the return + value explicitly instead of the fatal()-causing buffer_get_string_ptr() 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/key.c b/key.c index e6266fa58..0d0c912e6 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.84 2010/03/03 01:44:36 djm Exp $ */ +/* $OpenBSD: key.c,v 1.85 2010/03/04 01:44:57 djm Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1069,8 +1069,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) buffer_append(&tmp, constraints, clen); /* validate structure */ while (buffer_len(&tmp) != 0) { - if (buffer_get_string_ptr(&tmp, NULL) == NULL || - buffer_get_string_ptr(&tmp, NULL) == NULL) { + if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || + buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { error("%s: Constraints data invalid", __func__); goto out; } -- cgit v1.2.3 From 1aed65eb27feec505997c98621bdf158f9ab8b99 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:53:35 +1100 Subject: - djm@cvs.openbsd.org 2010/03/04 10:36:03 [auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c] [authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h] [ssh-keygen.c ssh.1 sshconnect.c sshd_config.5] Add a TrustedUserCAKeys option to sshd_config to specify CA keys that are trusted to authenticate users (in addition than doing it per-user in authorized_keys). Add a RevokedKeys option to sshd_config and a @revoked marker to known_hosts to allow keys to me revoked and banned for user or host authentication. feedback and ok markus@ --- ChangeLog | 13 +++++++ auth-rh-rsa.c | 5 ++- auth-rsa.c | 5 ++- auth.c | 31 ++++++++++++++++- auth.h | 3 +- auth2-hostbased.c | 5 ++- auth2-pubkey.c | 53 +++++++++++++++++++++++++++- authfile.c | 64 +++++++++++++++++++++++++++++++++- authfile.h | 3 +- hostfile.c | 102 +++++++++++++++++++++++++++++++++++++++++++----------- hostfile.h | 5 +-- servconf.c | 19 +++++++++- servconf.h | 4 ++- ssh-keygen.c | 2 +- ssh.1 | 20 +++++++++-- sshconnect.c | 24 +++++++++++-- sshd_config.5 | 25 +++++++++++-- 17 files changed, 343 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b5663ba4..07d4aeb05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,19 @@ [key.c] use buffer_get_string_ptr_ret() where we are checking the return value explicitly instead of the fatal()-causing buffer_get_string_ptr() + - djm@cvs.openbsd.org 2010/03/04 10:36:03 + [auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c] + [authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h] + [ssh-keygen.c ssh.1 sshconnect.c sshd_config.5] + Add a TrustedUserCAKeys option to sshd_config to specify CA keys that + are trusted to authenticate users (in addition than doing it per-user + in authorized_keys). + + Add a RevokedKeys option to sshd_config and a @revoked marker to + known_hosts to allow keys to me revoked and banned for user or host + authentication. + + feedback and ok markus@ 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c index eca750275..b21a0f4a2 100644 --- a/auth-rh-rsa.c +++ b/auth-rh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rh-rsa.c,v 1.42 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth-rh-rsa.c,v 1.43 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -44,6 +44,9 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost, { HostStatus host_status; + if (auth_key_is_revoked(client_host_key)) + return 0; + /* Check if we would accept it using rhosts authentication. */ if (!auth_rhosts(pw, cuser)) return 0; diff --git a/auth-rsa.c b/auth-rsa.c index bf5462076..65571a890 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rsa.c,v 1.73 2008/07/02 12:03:51 dtucker Exp $ */ +/* $OpenBSD: auth-rsa.c,v 1.74 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -94,6 +94,9 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) MD5_CTX md; int len; + if (auth_key_is_revoked(key)) + return 0; + /* don't allow short keys */ if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits", diff --git a/auth.c b/auth.c index ab9c69fb8..e680efbcc 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.84 2010/02/09 06:18:46 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.85 2010/03/04 10:36:03 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -69,6 +69,7 @@ #ifdef GSSAPI #include "ssh-gss.h" #endif +#include "authfile.h" #include "monitor_wrap.h" /* import */ @@ -582,6 +583,34 @@ getpwnamallow(const char *user) return (NULL); } +/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ +int +auth_key_is_revoked(Key *key) +{ + char *key_fp; + + if (options.revoked_keys_file == NULL) + return 0; + + switch (key_in_file(key, options.revoked_keys_file, 0)) { + case 0: + /* key not revoked */ + return 0; + case -1: + /* Error opening revoked_keys_file: refuse all keys */ + error("Revoked keys file is unreadable: refusing public key " + "authentication"); + return 1; + case 1: + /* Key revoked */ + key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + error("%s key %s is revoked", key_type(key), key_fp); + xfree(key_fp); + return 1; + } + fatal("key_in_file returned junk"); +} + void auth_debug_add(const char *fmt,...) { diff --git a/auth.h b/auth.h index 117485ca9..a65b87dd1 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.64 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: auth.h,v 1.65 2010/03/04 10:36:03 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -171,6 +171,7 @@ char *authorized_keys_file(struct passwd *); char *authorized_keys_file2(struct passwd *); FILE *auth_openkeyfile(const char *, struct passwd *, int); +int auth_key_is_revoked(Key *); HostStatus check_key_in_hostfiles(struct passwd *, Key *, const char *, diff --git a/auth2-hostbased.c b/auth2-hostbased.c index 041051c53..721646520 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.12 2008/07/17 08:51:07 djm Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.13 2010/03/04 10:36:03 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -145,6 +145,9 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, HostStatus host_status; int len; + if (auth_key_is_revoked(key)) + return 0; + resolvedname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 66ca5266b..51aa77487 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.20 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -56,6 +56,7 @@ #endif #include "monitor_wrap.h" #include "misc.h" +#include "authfile.h" /* import */ extern ServerOptions options; @@ -276,6 +277,47 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) return found_key; } +/* Authenticate a certificate key against TrustedUserCAKeys */ +static int +user_cert_trusted_ca(struct passwd *pw, Key *key) +{ + char *key_fp, *ca_fp; + const char *reason; + int ret = 0; + + if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) + return 0; + + key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + + if (key_in_file(key->cert->signature_key, + options.trusted_user_ca_keys, 1) != 1) { + debug2("%s: CA %s %s is not listed in %s", __func__, + key_type(key->cert->signature_key), ca_fp, + options.trusted_user_ca_keys); + goto out; + } + if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) { + error("%s", reason); + auth_debug_add("%s", reason); + goto out; + } + if (auth_cert_constraints(&key->cert->constraints, pw) != 0) + goto out; + + verbose("%s certificate %s allowed by trusted %s key %s", + key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp); + ret = 1; + + out: + if (key_fp != NULL) + xfree(key_fp); + if (ca_fp != NULL) + xfree(ca_fp); + return ret; +} + /* check whether given key is in .ssh/authorized_keys* */ int user_key_allowed(struct passwd *pw, Key *key) @@ -283,6 +325,15 @@ user_key_allowed(struct passwd *pw, Key *key) int success; char *file; + if (auth_key_is_revoked(key)) + return 0; + if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) + return 0; + + success = user_cert_trusted_ca(pw, key); + if (success) + return success; + file = authorized_keys_file(pw); success = user_key_allowed2(pw, key, file); xfree(file); diff --git a/authfile.c b/authfile.c index 2c615709d..224c6aa80 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.79 2010/01/12 00:16:47 dtucker Exp $ */ +/* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -692,3 +692,65 @@ key_load_public(const char *filename, char **commentp) key_free(pub); return NULL; } + +/* + * Returns 1 if the specified "key" is listed in the file "filename", + * 0 if the key is not listed or -1 on error. + * If strict_type is set then the key type must match exactly, + * otherwise a comparison that ignores certficiate data is performed. + */ +int +key_in_file(Key *key, const char *filename, int strict_type) +{ + FILE *f; + char line[SSH_MAX_PUBKEY_BYTES]; + char *cp; + u_long linenum = 0; + int ret = 0; + Key *pub; + int (*key_compare)(const Key *, const Key *) = strict_type ? + key_equal : key_equal_public; + + if ((f = fopen(filename, "r")) == NULL) { + if (errno == ENOENT) { + debug("%s: keyfile \"%s\" missing", __func__, filename); + return 0; + } else { + error("%s: could not open keyfile \"%s\": %s", __func__, + filename, strerror(errno)); + return -1; + } + } + + while (read_keyfile_line(f, filename, line, sizeof(line), + &linenum) != -1) { + cp = line; + + /* Skip leading whitespace. */ + for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) + ; + + /* Skip comments and empty lines */ + switch (*cp) { + case '#': + case '\n': + case '\0': + continue; + } + + pub = key_new(KEY_UNSPEC); + if (key_read(pub, &cp) != 1) { + key_free(pub); + continue; + } + if (key_compare(key, pub)) { + ret = 1; + key_free(pub); + break; + } + key_free(pub); + } + fclose(f); + return ret; +} + diff --git a/authfile.h b/authfile.h index a6c74934d..6dfa478e7 100644 --- a/authfile.h +++ b/authfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.h,v 1.13 2006/04/25 08:02:27 dtucker Exp $ */ +/* $OpenBSD: authfile.h,v 1.14 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen @@ -22,5 +22,6 @@ Key *key_load_private(const char *, const char *, char **); Key *key_load_private_type(int, const char *, const char *, char **, int *); Key *key_load_private_pem(int, int, const char *, char **); int key_perm_ok(int, const char *); +int key_in_file(Key *, const char *, int); #endif diff --git a/hostfile.c b/hostfile.c index fc7f84c79..afab6dad1 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.47 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -183,6 +183,41 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen return 1; } +static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA } +check_markers(char **cpp) +{ + char marker[32], *sp, *cp = *cpp; + int ret = MRK_NONE; + + while (*cp == '@') { + /* Only one marker is allowed */ + if (ret != MRK_NONE) + return MRK_ERROR; + /* Markers are terminated by whitespace */ + if ((sp = strchr(cp, ' ')) == NULL && + (sp = strchr(cp, '\t')) == NULL) + return MRK_ERROR; + /* Extract marker for comparison */ + if (sp <= cp + 1 || sp >= cp + sizeof(marker)) + return MRK_ERROR; + memcpy(marker, cp, sp - cp); + marker[sp - cp] = '\0'; + if (strcmp(marker, CA_MARKER) == 0) + ret = MRK_CA; + else if (strcmp(marker, REVOKE_MARKER) == 0) + ret = MRK_REVOKE; + else + return MRK_ERROR; + + /* Skip past marker and any whitespace that follows it */ + cp = sp; + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + } + *cpp = cp; + return ret; +} + /* * Checks whether the given host (which must be in all lowercase) is already * in the list of our known hosts. Returns HOST_OK if the host is known and @@ -195,17 +230,21 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen static HostStatus check_host_in_hostfile_by_key_or_type(const char *filename, - const char *host, const Key *key, int keytype, Key *found, int *numret) + const char *host, const Key *key, int keytype, Key *found, + int want_revocation, int *numret) { FILE *f; char line[8192]; - int linenum = 0, want_cert = key_is_cert(key); + int want, have, linenum = 0, want_cert = key_is_cert(key); u_int kbits; char *cp, *cp2, *hashed_host; HostStatus end_return; debug3("check_host_in_hostfile: host %s filename %s", host, filename); + if (want_revocation && (key == NULL || keytype != 0 || found != NULL)) + fatal("%s: invalid arguments", __func__); + /* Open the file containing the list of known hosts. */ f = fopen(filename, "r"); if (!f) @@ -229,21 +268,18 @@ check_host_in_hostfile_by_key_or_type(const char *filename, if (!*cp || *cp == '#' || *cp == '\n') continue; - /* - * Ignore CA keys when looking for raw keys. - * Ignore raw keys when looking for CA keys. - */ - if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && - (cp[sizeof(CA_MARKER) - 1] == ' ' || - cp[sizeof(CA_MARKER) - 1] == '\t')) { - if (want_cert) { - /* Skip the marker and following whitespace */ - cp += sizeof(CA_MARKER); - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - } else - continue; - } else if (want_cert) + if (want_revocation) + want = MRK_REVOKE; + else if (want_cert) + want = MRK_CA; + else + want = MRK_NONE; + + if ((have = check_markers(&cp)) == MRK_ERROR) { + verbose("%s: invalid marker at %s:%d", + __func__, filename, linenum); + continue; + } else if (want != have) continue; /* Find the end of the host name portion. */ @@ -267,6 +303,9 @@ check_host_in_hostfile_by_key_or_type(const char *filename, /* Got a match. Skip host name. */ cp = cp2; + if (want_revocation) + found = key_new(KEY_UNSPEC); + /* * Extract the key from the line. This will skip any leading * whitespace. Ignore badly formatted lines. @@ -289,6 +328,24 @@ check_host_in_hostfile_by_key_or_type(const char *filename, if (!hostfile_check_key(kbits, found, host, filename, linenum)) continue; + if (want_revocation) { + if (key_is_cert(key) && + key_equal_public(key->cert->signature_key, found)) { + verbose("check_host_in_hostfile: revoked CA " + "line %d", linenum); + key_free(found); + return HOST_REVOKED; + } + if (key_equal_public(key, found)) { + verbose("check_host_in_hostfile: revoked key " + "line %d", linenum); + key_free(found); + return HOST_REVOKED; + } + key_free(found); + continue; + } + /* Check if the current key is the same as the given key. */ if (want_cert && key_equal(key->cert->signature_key, found)) { /* Found CA cert for key */ @@ -325,8 +382,11 @@ check_host_in_hostfile(const char *filename, const char *host, const Key *key, { if (key == NULL) fatal("no key to look up"); - return (check_host_in_hostfile_by_key_or_type(filename, host, key, 0, - found, numret)); + if (check_host_in_hostfile_by_key_or_type(filename, host, + key, 0, NULL, 1, NULL) == HOST_REVOKED) + return HOST_REVOKED; + return check_host_in_hostfile_by_key_or_type(filename, host, key, 0, + found, 0, numret); } int @@ -334,7 +394,7 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host, int keytype, Key *found, int *numret) { return (check_host_in_hostfile_by_key_or_type(filename, host, NULL, - keytype, found, numret) == HOST_FOUND); + keytype, found, 0, numret) == HOST_FOUND); } /* diff --git a/hostfile.h b/hostfile.h index ebac1e4f1..1d460c1a9 100644 --- a/hostfile.h +++ b/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.17 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.18 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen @@ -15,7 +15,7 @@ #define HOSTFILE_H typedef enum { - HOST_OK, HOST_NEW, HOST_CHANGED, HOST_FOUND + HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND } HostStatus; int hostfile_read_key(char **, u_int *, Key *); @@ -29,6 +29,7 @@ int lookup_key_in_hostfile_by_type(const char *, const char *, #define HASH_DELIM '|' #define CA_MARKER "@cert-authority" +#define REVOKE_MARKER "@revoked" char *host_hash(const char *, const char *, u_int); diff --git a/servconf.c b/servconf.c index 0a6cdb655..f9e2f2dfd 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.203 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.204 2010/03/04 10:36:03 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -129,6 +129,8 @@ initialize_server_options(ServerOptions *options) options->adm_forced_command = NULL; options->chroot_directory = NULL; options->zero_knowledge_password_authentication = -1; + options->revoked_keys_file = NULL; + options->trusted_user_ca_keys = NULL; } void @@ -308,6 +310,7 @@ typedef enum { sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sZeroKnowledgePasswordAuthentication, sHostCertificate, + sRevokedKeys, sTrustedUserCAKeys, sDeprecated, sUnsupported } ServerOpCodes; @@ -427,6 +430,8 @@ static struct { { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, + { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, + { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1323,6 +1328,14 @@ process_server_config_line(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; + case sTrustedUserCAKeys: + charptr = &options->trusted_user_ca_keys; + goto parse_filename; + + case sRevokedKeys: + charptr = &options->revoked_keys_file; + goto parse_filename; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1437,6 +1450,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) return; M_CP_STROPT(adm_forced_command); M_CP_STROPT(chroot_directory); + M_CP_STROPT(trusted_user_ca_keys); + M_CP_STROPT(revoked_keys_file); } #undef M_CP_INTOPT @@ -1656,6 +1671,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2); dump_cfg_string(sForceCommand, o->adm_forced_command); dump_cfg_string(sChrootDirectory, o->chroot_directory); + dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); + dump_cfg_string(sRevokedKeys, o->revoked_keys_file); /* string arguments requiring a lookup */ dump_cfg_string(sLogLevel, log_level_name(o->log_level)); diff --git a/servconf.h b/servconf.h index c5c9c6ecd..860009f9c 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.91 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.92 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen @@ -154,6 +154,8 @@ typedef struct { int num_permitted_opens; char *chroot_directory; + char *revoked_keys_file; + char *trusted_user_ca_keys; } ServerOptions; void initialize_server_options(ServerOptions *); diff --git a/ssh-keygen.c b/ssh-keygen.c index f910dce38..c2120bbc1 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.180 2010/03/02 23:20:57 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.181 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland diff --git a/ssh.1 b/ssh.1 index 183dc277f..e8a4e5953 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.296 2010/02/26 22:09:28 jmc Exp $ -.Dd $Mdocdate: February 26 2010 $ +.\" $OpenBSD: ssh.1,v 1.297 2010/03/04 10:36:03 djm Exp $ +.Dd $Mdocdate: March 4 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -1121,6 +1121,22 @@ See the section of .Xr ssh-keygen 1 for more details. +.Pp +Keys may be also be marked as revoked using the +.Dq @revoked +marker. +Revoked keys will always trigger a warning when encountered and the host +that presented them will be treated as untrusted. +For example: +.Pp +.Dl @revoked * ssh-rsa AAAAB5W... +.Pp +Revoking a key revokes it for direct use and as a certification authority. +Do not use both the +.Dq @cert-authority and +.Dq @revoked +markers on the same line. +.Pp .Sh SSH-BASED VIRTUAL PRIVATE NETWORKS .Nm contains support for Virtual Private Network (VPN) tunnelling diff --git a/sshconnect.c b/sshconnect.c index 35c2f49be..9de52224d 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.219 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.220 2010/03/04 10:36:03 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -859,6 +859,25 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, logit("Warning: Permanently added '%.200s' (%s) to the " "list of known hosts.", hostp, type); break; + case HOST_REVOKED: + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: REVOKED HOST KEY DETECTED! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("The %s host key for %s is marked as revoked.", type, host); + error("This could mean that a stolen key is being used to"); + error("impersonate this host."); + + /* + * If strict host key checking is in use, the user will have + * to edit the key manually and we can only abort. + */ + if (options.strict_host_key_checking) { + error("%s host key for %.200s was revoked and you have " + "requested strict checking.", type, host); + goto fail; + } + goto continue_unsafe; + case HOST_CHANGED: if (want_cert) { /* @@ -908,6 +927,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, goto fail; } + continue_unsafe: /* * If strict host key checking has not been requested, allow * the connection but without MITM-able authentication or @@ -1007,7 +1027,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, return 0; fail: - if (want_cert) { + if (want_cert && host_status != HOST_REVOKED) { /* * No matching certificate. Downgrade cert to raw key and * search normally. diff --git a/sshd_config.5 b/sshd_config.5 index 001114655..07e74e2b7 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.117 2010/02/26 20:29:54 djm Exp $ -.Dd $Mdocdate: February 26 2010 $ +.\" $OpenBSD: sshd_config.5,v 1.118 2010/03/04 10:36:03 djm Exp $ +.Dd $Mdocdate: March 4 2010 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -814,6 +814,11 @@ Specifies whether public key authentication is allowed. The default is .Dq yes . Note that this option applies to protocol version 2 only. +.It Cm RevokedKeys +Specifies a list of revoked public keys. +Keys listed in this file will be refused for public key authentication. +Note that if this file is not readable, then public key authentication will +be refused for all users. .It Cm RhostsRSAAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful RSA host authentication is allowed. @@ -889,6 +894,22 @@ This avoids infinitely hanging sessions. .Pp To disable TCP keepalive messages, the value should be set to .Dq no . +.It Cm TrustedUserCAKeys +Specifies a file containing public keys of certificate authorities that are +trusted sign user certificates for authentication. +Keys are listed one per line, empty lines and comments starting with +.Ql # +are allowed. +If a certificate is presented for authentication and has its signing CA key +listed in this file, then it may be used for authentication for any user +listed in the certificate's principals list. +Note that certificates that lack a list of principals will not be permitted +for authentication using +.Cm TrustedUserCAKeys . +For more details in certificates, please see the +.Sx CERTIFICATES +section in +.Xr ssh-keygen 1 . .It Cm UseDNS Specifies whether .Xr sshd 8 -- cgit v1.2.3 From 017d1e777ef197eab866b9d0046e000a46baf10b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:57:21 +1100 Subject: - djm@cvs.openbsd.org 2010/03/03 00:47:23 [regress/cert-hostkey.sh regress/cert-userkey.sh] add an extra test to ensure that authentication with the wrong certificate fails as it should (and it does) --- ChangeLog | 4 ++++ regress/cert-hostkey.sh | 29 ++++++++++++++++++++++++++++- regress/cert-userkey.sh | 18 ++++++++++++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07d4aeb05..116ce569a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,10 @@ authentication. feedback and ok markus@ + - djm@cvs.openbsd.org 2010/03/03 00:47:23 + [regress/cert-hostkey.sh regress/cert-userkey.sh] + add an extra test to ensure that authentication with the wrong + certificate fails as it should (and it does) 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index 9539a927f..9097a1359 100644 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cert-hostkey.sh,v 1.1 2010/02/26 20:33:21 djm Exp $ +# $OpenBSD: cert-hostkey.sh,v 1.2 2010/03/03 00:47:23 djm Exp $ # Placed in the Public Domain. tid="certified host keys" @@ -119,4 +119,31 @@ for ktype in rsa dsa ; do fi done +# Wrong certificate +( + echon '@cert-authority ' + echon "$HOSTS " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert +for ktype in rsa dsa ; do + # Self-sign key + ${SSHKEYGEN} -h -q -s $OBJ/cert_host_key_${ktype} \ + -I "regress host key for $USER" \ + -n $HOSTS $OBJ/cert_host_key_${ktype} || + fail "couldn't sign cert_host_key_${ktype}" + verbose "$tid: host ${ktype} connect wrong cert" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + ) > $OBJ/sshd_proxy + + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect $ident succeeded unexpectedly" + fi +done + rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index 9588e0b6b..874915205 100644 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cert-userkey.sh,v 1.1 2010/02/26 20:33:21 djm Exp $ +# $OpenBSD: cert-userkey.sh,v 1.2 2010/03/03 00:47:23 djm Exp $ # Placed in the Public Domain. tid="certified user keys" @@ -24,7 +24,6 @@ for ktype in rsa dsa ; do "regress user key for $USER" \ -n $USER $OBJ/cert_user_key_${ktype} || fail "couldn't sign cert_user_key_${ktype}" - done # Basic connect tests @@ -86,4 +85,19 @@ test_one "cert valid interval" success "-V-1w:+2w" test_one "wrong source-address" failure "-Osource-address=10.0.0.0/8" test_one "force-command" failure "-Oforce-command=false" +# Wrong certificate +for ktype in rsa dsa ; do + # Self-sign + ${SSHKEYGEN} -q -s $OBJ/cert_user_key_${ktype} -I \ + "regress user key for $USER" \ + -n $USER $OBJ/cert_user_key_${ktype} || + fail "couldn't sign cert_user_key_${ktype}" + verbose "$tid: user ${ktype} connect wrong cert" + ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ + somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect $ident succeeded unexpectedly" + fi +done + rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -- cgit v1.2.3 From 700dcfa3e0a98be44f2e3675849055984f04a70a Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 4 Mar 2010 21:58:01 +1100 Subject: - djm@cvs.openbsd.org 2010/03/04 10:38:23 [regress/cert-hostkey.sh regress/cert-userkey.sh] additional regression tests for revoked keys and TrustedUserCAKeys --- ChangeLog | 3 + regress/cert-hostkey.sh | 64 ++++++++++++++++++- regress/cert-userkey.sh | 161 +++++++++++++++++++++++++++++++++++------------- 3 files changed, 183 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index 116ce569a..f6c61d89d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,9 @@ [regress/cert-hostkey.sh regress/cert-userkey.sh] add an extra test to ensure that authentication with the wrong certificate fails as it should (and it does) + - djm@cvs.openbsd.org 2010/03/04 10:38:23 + [regress/cert-hostkey.sh regress/cert-userkey.sh] + additional regression tests for revoked keys and TrustedUserCAKeys 20100303 - (djm) [PROTOCOL.certkeys] Add RCS Ident diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index 9097a1359..3fda667cb 100644 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cert-hostkey.sh,v 1.2 2010/03/03 00:47:23 djm Exp $ +# $OpenBSD: cert-hostkey.sh,v 1.3 2010/03/04 10:38:23 djm Exp $ # Placed in the Public Domain. tid="certified host keys" @@ -50,6 +50,68 @@ for privsep in yes no ; do done done +# Revoked certificates with key present +( + echon '@cert-authority ' + echon "$HOSTS " + cat $OBJ/host_ca_key.pub + echon '@revoked ' + echon "* " + cat $OBJ/cert_host_key_rsa.pub + echon '@revoked ' + echon "* " + cat $OBJ/cert_host_key_dsa.pub +) > $OBJ/known_hosts-cert +for privsep in yes no ; do + for ktype in rsa dsa ; do + verbose "$tid: host ${ktype} revoked cert privsep $privsep" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + echo UsePrivilegeSeparation $privsep + ) > $OBJ/sshd_proxy + + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi + done +done + +# Revoked CA +( + echon '@cert-authority ' + echon "$HOSTS " + cat $OBJ/host_ca_key.pub + echon '@revoked ' + echon "* " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert +for ktype in rsa dsa ; do + verbose "$tid: host ${ktype} revoked cert" + ( + cat $OBJ/sshd_proxy_bak + echo HostKey $OBJ/cert_host_key_${ktype} + echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub + ) > $OBJ/sshd_proxy + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpectedly" + fi +done + +# Create a CA key and add it to known hosts +( + echon '@cert-authority ' + echon "$HOSTS " + cat $OBJ/host_ca_key.pub +) > $OBJ/known_hosts-cert + test_one() { ident=$1 result=$2 diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index 874915205..7a58e7b75 100644 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cert-userkey.sh,v 1.2 2010/03/03 00:47:23 djm Exp $ +# $OpenBSD: cert-userkey.sh,v 1.3 2010/03/04 10:38:23 djm Exp $ # Placed in the Public Domain. tid="certified user keys" @@ -6,13 +6,9 @@ tid="certified user keys" rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak -# Create a CA key and add it to authorized_keys +# Create a CA key ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ fail "ssh-keygen of user_ca_key failed" -( - echon 'cert-authority ' - cat $OBJ/user_ca_key.pub -) > $OBJ/authorized_keys_$USER # Generate and sign user keys for ktype in rsa dsa ; do @@ -26,64 +22,140 @@ for ktype in rsa dsa ; do fail "couldn't sign cert_user_key_${ktype}" done -# Basic connect tests -for privsep in yes no ; do +basic_tests() { + auth=$1 + if test "x$auth" = "xauthorized_keys" ; then + # Add CA to authorized_keys + ( + echon 'cert-authority ' + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + else + echo > $OBJ/authorized_keys_$USER + extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" + fi + for ktype in rsa dsa ; do - verbose "$tid: user ${ktype} cert connect privsep $privsep" + for privsep in yes no ; do + _prefix="${ktype} privsep $privsep $auth" + # Simple connect + verbose "$tid: ${_prefix} connect" + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + echo "$extra_sshd" + ) > $OBJ/sshd_proxy + + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true + if [ $? -ne 0 ]; then + fail "ssh cert connect failed" + fi + + # Revoked keys + verbose "$tid: ${_prefix} revoked key" + ( + cat $OBJ/sshd_proxy_bak + echo "UsePrivilegeSeparation $privsep" + echo "RevokedKeys $OBJ/cert_user_key_${ktype}.pub" + echo "$extra_sshd" + ) > $OBJ/sshd_proxy + ${SSH} -2i $OBJ/cert_user_key_${ktype} \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpecedly" + fi + done + + # Revoked CA + verbose "$tid: ${ktype} $auth revoked CA key" ( cat $OBJ/sshd_proxy_bak - echo "UsePrivilegeSeparation $privsep" + echo "RevokedKeys $OBJ/user_ca_key.pub" + echo "$extra_sshd" ) > $OBJ/sshd_proxy - ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ - somehost true - if [ $? -ne 0 ]; then - fail "ssh cert connect failed" + somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect succeeded unexpecedly" fi done -done + + verbose "$tid: $auth CA does not authenticate" + ( + cat $OBJ/sshd_proxy_bak + echo "$extra_sshd" + ) > $OBJ/sshd_proxy + verbose "$tid: ensure CA key does not authenticate user" + ${SSH} -2i $OBJ/user_ca_key \ + -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 + if [ $? -eq 0 ]; then + fail "ssh cert connect with CA key succeeded unexpectedly" + fi +} -verbose "$tid: ensure CA key does not authenticate user" -${SSH} -2i $OBJ/user_ca_key -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 -if [ $? -eq 0 ]; then - fail "ssh cert connect with CA key succeeded unexpectedly" -fi +basic_tests authorized_keys +basic_tests TrustedUserCAKeys test_one() { ident=$1 result=$2 sign_opts=$3 - - verbose "$tid: test user cert connect $ident expect $result" + auth_choice=$4 + + if test "x$auth_choice" = "x" ; then + auth_choice="authorized_keys TrustedUserCAKeys" + fi - ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ - $sign_opts \ - $OBJ/cert_user_key_rsa || - fail "couldn't sign cert_user_key_rsa" + for auth in $auth_choice ; do + cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy + if test "x$auth" = "xauthorized_keys" ; then + # Add CA to authorized_keys + ( + echon 'cert-authority ' + cat $OBJ/user_ca_key.pub + ) > $OBJ/authorized_keys_$USER + else + echo > $OBJ/authorized_keys_$USER + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" >> \ + $OBJ/sshd_proxy - ${SSH} -2i $OBJ/cert_user_key_rsa -F $OBJ/ssh_proxy \ - somehost true >/dev/null 2>&1 - rc=$? - if [ "x$result" = "xsuccess" ] ; then - if [ $rc -ne 0 ]; then - fail "ssh cert connect $ident failed unexpectedly" fi - else - if [ $rc -eq 0 ]; then - fail "ssh cert connect $ident succeeded unexpectedly" + + verbose "$tid: $ident auth $auth expect $result" + ${SSHKEYGEN} -q -s $OBJ/user_ca_key \ + -I "regress user key for $USER" \ + $sign_opts \ + $OBJ/cert_user_key_rsa || + fail "couldn't sign cert_user_key_rsa" + + ${SSH} -2i $OBJ/cert_user_key_rsa -F $OBJ/ssh_proxy \ + somehost true >/dev/null 2>&1 + rc=$? + if [ "x$result" = "xsuccess" ] ; then + if [ $rc -ne 0 ]; then + fail "$ident failed unexpectedly" + fi + else + if [ $rc -eq 0 ]; then + fail "$ident succeeded unexpectedly" + fi fi - fi - cleanup + done } -test_one "host-certificate" failure "-h" -test_one "empty principals" success "" +test_one "correct principal" success "-n ${USER}" +test_one "host-certificate" failure "-n ${USER} -h" test_one "wrong principals" failure "-n foo" -test_one "cert not yet valid" failure "-V20200101:20300101" -test_one "cert expired" failure "-V19800101:19900101" -test_one "cert valid interval" success "-V-1w:+2w" -test_one "wrong source-address" failure "-Osource-address=10.0.0.0/8" -test_one "force-command" failure "-Oforce-command=false" +test_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101" +test_one "cert expired" failure "-n ${USER} -V19800101:19900101" +test_one "cert valid interval" success "-n ${USER} -V-1w:+2w" +test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" +test_one "force-command" failure "-n ${USER} -Oforce-command=false" + +# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals +test_one "empty principals" success "" authorized_keys +test_one "empty principals" failure "" TrustedUserCAKeys # Wrong certificate for ktype in rsa dsa ; do @@ -101,3 +173,4 @@ for ktype in rsa dsa ; do done rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* + -- cgit v1.2.3 From 72b33820af596f78a7ea7ee1200ae4c46b6167e5 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 07:39:01 +1100 Subject: - jmc@cvs.openbsd.org 2010/03/04 12:51:25 [ssh.1 sshd_config.5] tweak previous; --- ChangeLog | 6 ++++++ ssh.1 | 8 ++++---- sshd_config.5 | 6 +++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6c61d89d..ab7f88fe2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20100305 + - OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2010/03/04 12:51:25 + [ssh.1 sshd_config.5] + tweak previous; + 20100304 - (djm) [ssh-keygen.c] Use correct local variable, instead of maybe-undefined global "optarg" diff --git a/ssh.1 b/ssh.1 index e8a4e5953..8c53d4b07 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.297 2010/03/04 10:36:03 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.298 2010/03/04 12:51:25 jmc Exp $ .Dd $Mdocdate: March 4 2010 $ .Dt SSH 1 .Os @@ -1122,7 +1122,7 @@ section of .Xr ssh-keygen 1 for more details. .Pp -Keys may be also be marked as revoked using the +Keys may also be marked as revoked using the .Dq @revoked marker. Revoked keys will always trigger a warning when encountered and the host @@ -1133,10 +1133,10 @@ For example: .Pp Revoking a key revokes it for direct use and as a certification authority. Do not use both the -.Dq @cert-authority and +.Dq @cert-authority +and .Dq @revoked markers on the same line. -.Pp .Sh SSH-BASED VIRTUAL PRIVATE NETWORKS .Nm contains support for Virtual Private Network (VPN) tunnelling diff --git a/sshd_config.5 b/sshd_config.5 index 07e74e2b7..a0427584d 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.118 2010/03/04 10:36:03 djm Exp $ +.\" $OpenBSD: sshd_config.5,v 1.119 2010/03/04 12:51:25 jmc Exp $ .Dd $Mdocdate: March 4 2010 $ .Dt SSHD_CONFIG 5 .Os @@ -897,7 +897,7 @@ To disable TCP keepalive messages, the value should be set to .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted sign user certificates for authentication. -Keys are listed one per line, empty lines and comments starting with +Keys are listed one per line; empty lines and comments starting with .Ql # are allowed. If a certificate is presented for authentication and has its signing CA key @@ -906,7 +906,7 @@ listed in the certificate's principals list. Note that certificates that lack a list of principals will not be permitted for authentication using .Cm TrustedUserCAKeys . -For more details in certificates, please see the +For more details on certificates, see the .Sx CERTIFICATES section in .Xr ssh-keygen 1 . -- cgit v1.2.3 From f2b70cad7585a67f7098119ccb6ae31573f2dc60 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 07:39:35 +1100 Subject: - djm@cvs.openbsd.org 2010/03/04 20:35:08 [ssh-keygen.1 ssh-keygen.c] Add a -L flag to print the contents of a certificate; ok markus@ --- ChangeLog | 3 ++ ssh-keygen.1 | 10 ++++-- ssh-keygen.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 114 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index ab7f88fe2..3f0ba4237 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ - jmc@cvs.openbsd.org 2010/03/04 12:51:25 [ssh.1 sshd_config.5] tweak previous; + - djm@cvs.openbsd.org 2010/03/04 20:35:08 + [ssh-keygen.1 ssh-keygen.c] + Add a -L flag to print the contents of a certificate; ok markus@ 20100304 - (djm) [ssh-keygen.c] Use correct local variable, instead of diff --git a/ssh-keygen.1 b/ssh-keygen.1 index d704f0660..dccf5eabc 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.85 2010/02/26 22:09:28 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.86 2010/03/04 20:35:08 djm Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 26 2010 $ +.Dd $Mdocdate: March 4 2010 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -115,6 +115,10 @@ .Op Fl O Ar constraint .Op Fl V Ar validity_interval .Ar +.Nm ssh-keygen +.Bk -words +.Fl L +.Op Fl f Ar input_keyfile .Ek .Sh DESCRIPTION .Nm @@ -275,6 +279,8 @@ also reads the RFC 4716 SSH Public Key File Format. This option allows importing keys from several commercial SSH implementations. +.It Fl L +Prints the contents of a certificate. .It Fl l Show fingerprint of specified public key file. Private RSA1 keys are also supported. diff --git a/ssh-keygen.c b/ssh-keygen.c index c2120bbc1..492c301d3 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.181 2010/03/04 10:36:03 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.182 2010/03/04 20:35:08 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -82,6 +82,9 @@ int find_host = 0; /* Flag indicating that we want to delete a host from a known_hosts file */ int delete_host = 0; +/* Flag indicating that we want to show the contents of a certificate */ +int show_cert = 0; + /* Flag indicating that we just want to see the key fingerprint */ int print_fingerprint = 0; int print_bubblebabble = 0; @@ -1063,7 +1066,7 @@ do_change_comment(struct passwd *pw) } static const char * -fmt_validity(void) +fmt_validity(u_int64_t valid_from, u_int64_t valid_to) { char from[32], to[32]; static char ret[64]; @@ -1071,28 +1074,27 @@ fmt_validity(void) struct tm *tm; *from = *to = '\0'; - if (cert_valid_from == 0 && - cert_valid_to == 0xffffffffffffffffULL) + if (valid_from == 0 && valid_to == 0xffffffffffffffffULL) return "forever"; - if (cert_valid_from != 0) { + if (valid_from != 0) { /* XXX revisit INT_MAX in 2038 :) */ - tt = cert_valid_from > INT_MAX ? INT_MAX : cert_valid_from; + tt = valid_from > INT_MAX ? INT_MAX : valid_from; tm = localtime(&tt); strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); } - if (cert_valid_to != 0xffffffffffffffffULL) { + if (valid_to != 0xffffffffffffffffULL) { /* XXX revisit INT_MAX in 2038 :) */ - tt = cert_valid_to > INT_MAX ? INT_MAX : cert_valid_to; + tt = valid_to > INT_MAX ? INT_MAX : valid_to; tm = localtime(&tt); strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); } - if (cert_valid_from == 0) { + if (valid_from == 0) { snprintf(ret, sizeof(ret), "before %s", to); return ret; } - if (cert_valid_to == 0xffffffffffffffffULL) { + if (valid_to == 0xffffffffffffffffULL) { snprintf(ret, sizeof(ret), "after %s", from); return ret; } @@ -1216,7 +1218,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) out, cert_key_id, cert_principals != NULL ? " for " : "", cert_principals != NULL ? cert_principals : "", - fmt_validity()); + fmt_validity(cert_valid_from, cert_valid_to)); key_free(public); xfree(out); @@ -1365,6 +1367,89 @@ add_cert_constraint(char *opt) fatal("Unsupported certificate constraint \"%s\"", opt); } +static void +do_show_cert(struct passwd *pw) +{ + Key *key; + struct stat st; + char *key_fp, *ca_fp; + Buffer constraints, constraint; + u_char *name, *data; + u_int i, dlen; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + if ((key = key_load_public(identity_file, NULL)) == NULL) + fatal("%s is not a public key", identity_file); + if (!key_is_cert(key)) + fatal("%s is not a certificate", identity_file); + + key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + ca_fp = key_fingerprint(key->cert->signature_key, + SSH_FP_MD5, SSH_FP_HEX); + + printf("%s:\n", identity_file); + printf(" %s certificate %s\n", key_type(key), key_fp); + printf(" Signed by %s CA %s\n", + key_type(key->cert->signature_key), ca_fp); + printf(" Key ID \"%s\"\n", key->cert->key_id); + printf(" Valid: %s\n", + fmt_validity(key->cert->valid_after, key->cert->valid_before)); + printf(" Principals: "); + if (key->cert->nprincipals == 0) + printf("(none)\n"); + else { + for (i = 0; i < key->cert->nprincipals; i++) + printf("\n %s", + key->cert->principals[i]); + printf("\n"); + } + printf(" Constraints: "); + if (buffer_len(&key->cert->constraints) == 0) + printf("(none)\n"); + else { + printf("\n"); + buffer_init(&constraints); + buffer_append(&constraints, + buffer_ptr(&key->cert->constraints), + buffer_len(&key->cert->constraints)); + buffer_init(&constraint); + while (buffer_len(&constraints) != 0) { + name = buffer_get_string(&constraints, NULL); + data = buffer_get_string_ptr(&constraints, &dlen); + buffer_append(&constraint, data, dlen); + printf(" %s", name); + if (strcmp(name, "permit-X11-forwarding") == 0 || + strcmp(name, "permit-agent-forwarding") == 0 || + strcmp(name, "permit-port-forwarding") == 0 || + strcmp(name, "permit-pty") == 0 || + strcmp(name, "permit-user-rc") == 0) + printf("\n"); + else if (strcmp(name, "force-command") == 0 || + strcmp(name, "source-address") == 0) { + data = buffer_get_string(&constraint, NULL); + printf(" %s\n", data); + xfree(data); + } else { + printf(" UNKNOWN CONSTRAINT (len %u)\n", + buffer_len(&constraint)); + buffer_clear(&constraint); + } + xfree(name); + if (buffer_len(&constraint) != 0) + fatal("Constraint corrupt: extra data at end"); + } + buffer_free(&constraint); + buffer_free(&constraints); + } + + exit(0); +} + static void usage(void) { @@ -1387,6 +1472,7 @@ usage(void) fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n"); fprintf(stderr, " -I key_id Key identifier to include in certificate.\n"); fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n"); + fprintf(stderr, " -L Print the contents of a certificate.\n"); fprintf(stderr, " -l Show fingerprint of key file.\n"); fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); @@ -1453,7 +1539,7 @@ main(int argc, char **argv) exit(1); } - while ((opt = getopt(argc, argv, "degiqpclBHhvxXyF:b:f:t:D:I:P:N:n:" + while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:" "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) { switch (opt) { case 'b': @@ -1476,6 +1562,9 @@ main(int argc, char **argv) delete_host = 1; rr_hostname = optarg; break; + case 'L': + show_cert = 1; + break; case 'l': print_fingerprint = 1; break; @@ -1629,6 +1718,8 @@ main(int argc, char **argv) fatal("Must specify key id (-I) when certifying"); do_ca_sign(pw, argc, argv); } + if (show_cert) + do_show_cert(pw); if (delete_host || hash_hosts || find_host) do_known_hosts(pw, rr_hostname); if (print_fingerprint || print_bubblebabble) -- cgit v1.2.3 From 179eee081a560f3e10506ae3a2facdc1c766f0f6 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Thu, 4 Mar 2010 12:48:05 -0800 Subject: - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ --- ChangeLog | 2 ++ ssh-pkcs11.c | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f0ba4237..254575307 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ - djm@cvs.openbsd.org 2010/03/04 20:35:08 [ssh-keygen.1 ssh-keygen.c] Add a -L flag to print the contents of a certificate; ok markus@ + - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older + compilers. OK djm@ 20100304 - (djm) [ssh-keygen.c] Use correct local variable, instead of diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 7536f92a6..f0192dcf1 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -204,13 +204,18 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, CKM_RSA_PKCS, NULL_PTR, 0 }; CK_ATTRIBUTE key_filter[] = { - {CKA_CLASS, &private_key_class, sizeof(private_key_class) }, + {CKA_CLASS, NULL, sizeof(private_key_class) }, {CKA_ID, NULL, 0}, - {CKA_SIGN, &true_val, sizeof(true_val) } + {CKA_SIGN, NULL, sizeof(true_val) } }; char *pin, prompt[1024]; int rval = -1; + /* some compilers complain about non-constant initializer so we + use NULL in CK_ATTRIBUTE above and set the values here */ + key_filter[0].pValue = &private_key_class; + key_filter[2].pValue = &true_val; + if ((k11 = RSA_get_app_data(rsa)) == NULL) { error("RSA_get_app_data failed for rsa %p", rsa); return (-1); @@ -371,7 +376,7 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp, CK_FUNCTION_LIST *f; CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubkey_filter[] = { - { CKA_CLASS, &pubkey_class, sizeof(pubkey_class) } + { CKA_CLASS, NULL, sizeof(pubkey_class) } }; CK_ATTRIBUTE attribs[] = { { CKA_ID, NULL, 0 }, @@ -379,6 +384,10 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp, { CKA_PUBLIC_EXPONENT, NULL, 0 } }; + /* some compilers complain about non-constant initializer so we + use NULL in CK_ATTRIBUTE above and set the value here */ + pubkey_filter[0].pValue = &pubkey_class; + f = p->function_list; session = p->slotinfo[slotidx].session; /* setup a filter the looks for public keys */ -- cgit v1.2.3 From 8f6c337563f2217b6704f0f40bed68cee349f8c4 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 10:41:26 +1100 Subject: - jmc@cvs.openbsd.org 2010/03/04 22:52:40 [ssh-keygen.1] fix Bk/Ek; --- ChangeLog | 3 +++ ssh-keygen.1 | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 254575307..1659e324a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,9 @@ - djm@cvs.openbsd.org 2010/03/04 20:35:08 [ssh-keygen.1 ssh-keygen.c] Add a -L flag to print the contents of a certificate; ok markus@ + - jmc@cvs.openbsd.org 2010/03/04 22:52:40 + [ssh-keygen.1] + fix Bk/Ek; - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ diff --git a/ssh-keygen.1 b/ssh-keygen.1 index dccf5eabc..069d87649 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.86 2010/03/04 20:35:08 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.87 2010/03/04 22:52:40 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -52,7 +52,6 @@ .Op Fl N Ar new_passphrase .Op Fl C Ar comment .Op Fl f Ar output_keyfile -.Ek .Nm ssh-keygen .Fl p .Op Fl P Ar old_passphrase @@ -107,7 +106,6 @@ .Op Fl a Ar num_trials .Op Fl W Ar generator .Nm ssh-keygen -.Bk -words .Fl s Ar ca_key .Fl I Ar certificate_identity .Op Fl h @@ -116,7 +114,6 @@ .Op Fl V Ar validity_interval .Ar .Nm ssh-keygen -.Bk -words .Fl L .Op Fl f Ar input_keyfile .Ek -- cgit v1.2.3 From c6db99ec14f511d8ee5efb3c1fee42ab1ab61c8e Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 10:41:45 +1100 Subject: - djm@cvs.openbsd.org 2010/03/04 23:17:25 [sshd_config.5] missing word; spotted by jmc@ --- ChangeLog | 3 +++ sshd_config.5 | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1659e324a..f8e1d0e2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,9 @@ - jmc@cvs.openbsd.org 2010/03/04 22:52:40 [ssh-keygen.1] fix Bk/Ek; + - djm@cvs.openbsd.org 2010/03/04 23:17:25 + [sshd_config.5] + missing word; spotted by jmc@ - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ diff --git a/sshd_config.5 b/sshd_config.5 index a0427584d..2f5410281 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.119 2010/03/04 12:51:25 jmc Exp $ +.\" $OpenBSD: sshd_config.5,v 1.120 2010/03/04 23:17:25 djm Exp $ .Dd $Mdocdate: March 4 2010 $ .Dt SSHD_CONFIG 5 .Os @@ -896,7 +896,7 @@ To disable TCP keepalive messages, the value should be set to .Dq no . .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are -trusted sign user certificates for authentication. +trusted to sign user certificates for authentication. Keys are listed one per line; empty lines and comments starting with .Ql # are allowed. -- cgit v1.2.3 From a7dab8bfe571e6ee0b53e0852336f8a758b95c61 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 10:42:05 +1100 Subject: - djm@cvs.openbsd.org 2010/03/04 23:19:29 [ssh.1 sshd.8] move section on CA and revoked keys from ssh.1 to sshd.8's known hosts format section and rework it a bit; requested by jmc@ --- ChangeLog | 4 ++++ ssh.1 | 35 +---------------------------------- sshd.8 | 50 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8e1d0e2e..c441b2013 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,10 @@ - djm@cvs.openbsd.org 2010/03/04 23:17:25 [sshd_config.5] missing word; spotted by jmc@ + - djm@cvs.openbsd.org 2010/03/04 23:19:29 + [ssh.1 sshd.8] + move section on CA and revoked keys from ssh.1 to sshd.8's known hosts + format section and rework it a bit; requested by jmc@ - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ diff --git a/ssh.1 b/ssh.1 index 8c53d4b07..b201d87de 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.298 2010/03/04 12:51:25 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.299 2010/03/04 23:19:29 djm Exp $ .Dd $Mdocdate: March 4 2010 $ .Dt SSH 1 .Os @@ -1104,39 +1104,6 @@ option in .Xr ssh_config 5 for more information. .Pp -Host keys may also be presented as certificates signed by a trusted -certification authority (CA). -In this case, trust of the CA key alone is sufficient for the host key -to be accepted. -To specify a public key as a trusted CA key in a known hosts file, -it should be added after a -.Dq @cert-authority -tag and a set of one or more domain-name wildcards separated by commas. -For example: -.Pp -.Dl @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... -.Pp -See the -.Sx CERTIFICATES -section of -.Xr ssh-keygen 1 -for more details. -.Pp -Keys may also be marked as revoked using the -.Dq @revoked -marker. -Revoked keys will always trigger a warning when encountered and the host -that presented them will be treated as untrusted. -For example: -.Pp -.Dl @revoked * ssh-rsa AAAAB5W... -.Pp -Revoking a key revokes it for direct use and as a certification authority. -Do not use both the -.Dq @cert-authority -and -.Dq @revoked -markers on the same line. .Sh SSH-BASED VIRTUAL PRIVATE NETWORKS .Nm contains support for Virtual Private Network (VPN) tunnelling diff --git a/sshd.8 b/sshd.8 index d31538176..577d19940 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.253 2010/03/03 22:49:50 djm Exp $ -.Dd $Mdocdate: March 3 2010 $ +.\" $OpenBSD: sshd.8,v 1.254 2010/03/04 23:19:29 djm Exp $ +.Dd $Mdocdate: March 4 2010 $ .Dt SSHD 8 .Os .Sh NAME @@ -634,10 +634,19 @@ be prepared by the administrator (optional), and the per-user file is maintained automatically: whenever the user connects from an unknown host, its key is added to the per-user file. .Pp -Each line in these files contains the following fields: hostnames, -bits, exponent, modulus, comment. +Each line in these files contains the following fields: markers (optional), +hostnames, bits, exponent, modulus, comment. The fields are separated by spaces. .Pp +The marker is optional, but if it is present then it must be one of +.Dq @cert-authority , +to indicate that the line contains a certification authority (CA) key, +or +.Dq @revoked , +to indicate that the key contained on the line is revoked and must not ever +be accepted. +Only one marker should be used on a key line. +.Pp Hostnames is a comma-separated list of patterns .Pf ( Ql * and @@ -677,8 +686,25 @@ Lines starting with and empty lines are ignored as comments. .Pp When performing host authentication, authentication is accepted if any -matching line has the proper key. -It is thus permissible (but not +matching line has the proper key; either one that matches exactly or, +if the server has presented a certificate for authentication, the key +of the certification authority that signed the certificate. +For a key to be trusted as a certification authority, it must use the +.Dq @cert-authority +marker described above. +.Pp +The known hosts file also provides a facility to mark keys as revoked, +for example when it is known that the associated private key has been +stolen. +Revoked keys are specified by including the +.Dq @revoked +marker at the beginning of the key line, and are never accepted for +authentication or as certification authorities, but instead will +produce a warning from +.Xr ssh 1 +when they are encountered. +.Pp +It is permissible (but not recommended) to have several lines or different host keys for the same names. This will inevitably happen when short forms of host names @@ -689,10 +715,16 @@ accepted if valid information can be found from either file. .Pp Note that the lines in these files are typically hundreds of characters long, and you definitely don't want to type in the host keys by hand. -Rather, generate them by a script +Rather, generate them by a script, +.Xr ssh-keyscan 1 or by taking .Pa /etc/ssh/ssh_host_key.pub and adding the host names at the front. +.Xr ssh-keygen 1 +also offers some basic automated editing for +.Pa ~/.ssh/known_hosts +including removing hosts matching a host name and converting all host +names to their hashed representations. .Pp An example ssh_known_hosts file: .Bd -literal -offset 3n @@ -702,6 +734,10 @@ cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....= # A hashed hostname |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa AAAA1234.....= +# A revoked key +@revoked * ssh-rsa AAAAB5W... +# A CA key, accepted for any host in *.mydomain.com or *.mydomain.org +@cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed .Sh FILES .Bl -tag -width Ds -compact -- cgit v1.2.3 From 689b872842ba2e64d2bf52abe0c9b1b1f6a6663f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 10:42:24 +1100 Subject: - djm@cvs.openbsd.org 2010/03/04 23:27:25 [auth-options.c ssh-keygen.c] "force-command" is not spelled "forced-command"; spotted by imorgan AT nas.nasa.gov --- ChangeLog | 4 ++++ auth-options.c | 4 ++-- ssh-keygen.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index c441b2013..7b50de5d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,10 @@ [ssh.1 sshd.8] move section on CA and revoked keys from ssh.1 to sshd.8's known hosts format section and rework it a bit; requested by jmc@ + - djm@cvs.openbsd.org 2010/03/04 23:27:25 + [auth-options.c ssh-keygen.c] + "force-command" is not spelled "forced-command"; spotted by + imorgan AT nas.nasa.gov - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ diff --git a/auth-options.c b/auth-options.c index d14624bf4..bcf5589d7 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.46 2010/03/03 01:44:36 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.47 2010/03/04 23:27:25 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -446,7 +446,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) } if (cert_forced_command != NULL) { error("Certificate has multiple " - "forced-command constraints"); + "force-command constraints"); xfree(command); goto out; } diff --git a/ssh-keygen.c b/ssh-keygen.c index 492c301d3..fc7ca4b0c 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.182 2010/03/04 20:35:08 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.183 2010/03/04 23:27:25 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1142,7 +1142,7 @@ prepare_constraint_buf(Buffer *c) if ((constraint_flags & CONSTRAINT_USER_RC) != 0) add_flag_constraint(c, "permit-user-rc"); if (constraint_command != NULL) - add_string_constraint(c, "forced-command", constraint_command); + add_string_constraint(c, "force-command", constraint_command); if (constraint_src_addr != NULL) add_string_constraint(c, "source-address", constraint_src_addr); } -- cgit v1.2.3 From 48b6021721fb2083898be696a72b261a9136c293 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 11:40:19 +1100 Subject: - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure on some platforms --- ChangeLog | 2 ++ ssh-rand-helper.c | 1 + 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7b50de5d3..ee1804fd8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,8 @@ imorgan AT nas.nasa.gov - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ + - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure + on some platforms 20100304 - (djm) [ssh-keygen.c] Use correct local variable, instead of diff --git a/ssh-rand-helper.c b/ssh-rand-helper.c index 0fcda7fff..fa5070499 100644 --- a/ssh-rand-helper.c +++ b/ssh-rand-helper.c @@ -818,6 +818,7 @@ main(int argc, char **argv) unsigned char *buf; int ret, ch, debug_level, output_hex, bytes; extern char *optarg; + extern int optind; LogLevel ll; __progname = ssh_get_progname(argv[0]); -- cgit v1.2.3 From b068d0ad6dd1cf63ecd636bb2e24ce4c74406cb2 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 14:03:03 +1100 Subject: - djm@cvs.openbsd.org 2010/03/05 02:58:11 [auth.c] make the warning for a revoked key louder and more noticable --- ChangeLog | 3 +++ auth.c | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee1804fd8..25a0f8716 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,9 @@ [auth-options.c ssh-keygen.c] "force-command" is not spelled "forced-command"; spotted by imorgan AT nas.nasa.gov + - djm@cvs.openbsd.org 2010/03/05 02:58:11 + [auth.c] + make the warning for a revoked key louder and more noticable - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure diff --git a/auth.c b/auth.c index e680efbcc..e8fbe9fd5 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.85 2010/03/04 10:36:03 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.86 2010/03/05 02:58:11 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -604,7 +604,8 @@ auth_key_is_revoked(Key *key) case 1: /* Key revoked */ key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); - error("%s key %s is revoked", key_type(key), key_fp); + error("WARNING: authentication attempt with a revoked " + "%s key %s ", key_type(key), key_fp); xfree(key_fp); return 1; } -- cgit v1.2.3 From 9527f228ae88a1b328163717f5d68904d86c5d98 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 15:04:35 +1100 Subject: - (djm) [configure.ac] set -fno-strict-aliasing for gcc4; ok dtucker@ --- ChangeLog | 1 + configure.ac | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 25a0f8716..efb7a0940 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,7 @@ compilers. OK djm@ - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure on some platforms + - (djm) [configure.ac] set -fno-strict-aliasing for gcc4; ok dtucker@ 20100304 - (djm) [ssh-keygen.c] Use correct local variable, instead of diff --git a/configure.ac b/configure.ac index f4c25683c..a9960a7ba 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.443 2010/02/11 23:11:34 djm Exp $ +# $Id: configure.ac,v 1.444 2010/03/05 04:04:35 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.443 $) +AC_REVISION($Revision: 1.444 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -108,7 +108,7 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then ;; 2.*) no_attrib_nonnull=1 ;; 3.*) CFLAGS="$CFLAGS -Wsign-compare -Wformat-security" ;; - 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign -Wformat-security" ;; + 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign -Wformat-security -fno-strict-aliasing" ;; *) ;; esac -- cgit v1.2.3 From 98339054f949ad87f15b4d618a421765d4097cd9 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 21:30:35 +1100 Subject: - jmc@cvs.openbsd.org 2010/03/05 06:50:35 [ssh.1 sshd.8] tweak previous; --- ChangeLog | 3 +++ ssh.1 | 5 ++--- sshd.8 | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index efb7a0940..99ec97956 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,9 @@ - djm@cvs.openbsd.org 2010/03/05 02:58:11 [auth.c] make the warning for a revoked key louder and more noticable + - jmc@cvs.openbsd.org 2010/03/05 06:50:35 + [ssh.1 sshd.8] + tweak previous; - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure diff --git a/ssh.1 b/ssh.1 index b201d87de..fd713e3b4 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.299 2010/03/04 23:19:29 djm Exp $ -.Dd $Mdocdate: March 4 2010 $ +.\" $OpenBSD: ssh.1,v 1.300 2010/03/05 06:50:34 jmc Exp $ +.Dd $Mdocdate: March 5 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -1103,7 +1103,6 @@ See the option in .Xr ssh_config 5 for more information. -.Pp .Sh SSH-BASED VIRTUAL PRIVATE NETWORKS .Nm contains support for Virtual Private Network (VPN) tunnelling diff --git a/sshd.8 b/sshd.8 index 577d19940..5f1966005 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.254 2010/03/04 23:19:29 djm Exp $ -.Dd $Mdocdate: March 4 2010 $ +.\" $OpenBSD: sshd.8,v 1.255 2010/03/05 06:50:35 jmc Exp $ +.Dd $Mdocdate: March 5 2010 $ .Dt SSHD 8 .Os .Sh NAME @@ -721,7 +721,7 @@ or by taking .Pa /etc/ssh/ssh_host_key.pub and adding the host names at the front. .Xr ssh-keygen 1 -also offers some basic automated editing for +also offers some basic automated editing for .Pa ~/.ssh/known_hosts including removing hosts matching a host name and converting all host names to their hashed representations. -- cgit v1.2.3 From 922b541329285cede860607c877f72663f3d2a9f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 21:30:54 +1100 Subject: - jmc@cvs.openbsd.org 2010/03/05 08:31:20 [ssh.1] document certificate authentication; help/ok djm --- ChangeLog | 3 +++ ssh.1 | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 99ec97956..5e1bb231b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,9 @@ - jmc@cvs.openbsd.org 2010/03/05 06:50:35 [ssh.1 sshd.8] tweak previous; + - jmc@cvs.openbsd.org 2010/03/05 08:31:20 + [ssh.1] + document certificate authentication; help/ok djm - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure diff --git a/ssh.1 b/ssh.1 index fd713e3b4..c1a408348 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.300 2010/03/05 06:50:34 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.301 2010/03/05 08:31:20 jmc Exp $ .Dd $Mdocdate: March 5 2010 $ .Dt SSH 1 .Os @@ -798,8 +798,20 @@ file, and has one key per line, though the lines can be very long. After this, the user can log in without giving the password. .Pp -The most convenient way to use public key authentication may be with an -authentication agent. +A variation on public key authentication +is available in the form of certificate authentication: +instead of a set of public/private keys, +signed certificates are used. +This has the advantage that a single trusted certification authority +can be used in place of many public/private keys. +See the +.Sx CERTIFICATES +section of +.Xr ssh-keygen 1 +for more information. +.Pp +The most convenient way to use public key or certificate authentication +may be with an authentication agent. See .Xr ssh-agent 1 for more information. -- cgit v1.2.3 From 5059d8d7e647ed6202e3d77f623774919b20eefc Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 5 Mar 2010 21:31:11 +1100 Subject: - djm@cvs.openbsd.org 2010/03/05 10:28:21 [ssh-add.1 ssh.1 ssh_config.5] mention loading of certificate files from [private]-cert.pub when they are present; feedback and ok jmc@ --- ChangeLog | 4 ++++ ssh-add.1 | 11 +++++++++-- ssh.1 | 7 ++++++- ssh_config.5 | 10 ++++++++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e1bb231b..0f062fa60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,10 @@ - jmc@cvs.openbsd.org 2010/03/05 08:31:20 [ssh.1] document certificate authentication; help/ok djm + - djm@cvs.openbsd.org 2010/03/05 10:28:21 + [ssh-add.1 ssh.1 ssh_config.5] + mention loading of certificate files from [private]-cert.pub when + they are present; feedback and ok jmc@ - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older compilers. OK djm@ - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure diff --git a/ssh-add.1 b/ssh-add.1 index 0d5e39272..d7cc53101 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.51 2010/02/10 23:20:38 markus Exp $ +.\" $OpenBSD: ssh-add.1,v 1.52 2010/03/05 10:28:21 djm Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 10 2010 $ +.Dd $Mdocdate: March 5 2010 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -61,7 +61,14 @@ When run without arguments, it adds the files .Pa ~/.ssh/id_dsa and .Pa ~/.ssh/identity . +After loading a private key, +.Nm +will try to load corresponding certificate information from the +filename obtained by appending +.Pa -cert.pub +to the name of the private key file. Alternative file names can be given on the command line. +.Pp If any file requires a passphrase, .Nm asks for the passphrase from the user. diff --git a/ssh.1 b/ssh.1 index c1a408348..3f815b8e7 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.301 2010/03/05 08:31:20 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.302 2010/03/05 10:28:21 djm Exp $ .Dd $Mdocdate: March 5 2010 $ .Dt SSH 1 .Os @@ -306,6 +306,11 @@ It is possible to have multiple .Fl i options (and multiple identities specified in configuration files). +.Nm +will also try to load certificate information from the filename obtained +by appending +.Pa -cert.pub +to identity filenames. .It Fl K Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server. diff --git a/ssh_config.5 b/ssh_config.5 index 7ab5d02fd..8cf02597d 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.128 2010/02/10 23:20:38 markus Exp $ -.Dd $Mdocdate: February 10 2010 $ +.\" $OpenBSD: ssh_config.5,v 1.129 2010/03/05 10:28:21 djm Exp $ +.Dd $Mdocdate: March 5 2010 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -559,6 +559,12 @@ and for protocol version 2. Additionally, any identities represented by the authentication agent will be used for authentication. +.Xr ssh 1 +will try to load certificate information from the filename obtained by +appending +.Pa -cert.pub +to the path of a specified +.Cm IdentityFile . .Pp The file name may use the tilde syntax to refer to a user's home directory or one of the following -- cgit v1.2.3 From b3d20a3ff0f822e2b39c3f6d31bfdea89f577465 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 7 Mar 2010 11:56:59 +1100 Subject: - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that it gets the passwd struct from the LAM that knows about the user which is not necessarily the default. Patch from Alexandre Letourneau. --- ChangeLog | 5 +++++ auth.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0f062fa60..63beb9482 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +20100307 + - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that + it gets the passwd struct from the LAM that knows about the user which is + not necessarily the default. Patch from Alexandre Letourneau. + 20100305 - OpenBSD CVS Sync - jmc@cvs.openbsd.org 2010/03/04 12:51:25 diff --git a/auth.c b/auth.c index e8fbe9fd5..89a936068 100644 --- a/auth.c +++ b/auth.c @@ -535,7 +535,15 @@ getpwnamallow(const char *user) parse_server_match_config(&options, user, get_canonical_hostname(options.use_dns), get_remote_ipaddr()); +#if defined(_AIX) && defined(HAVE_SETAUTHDB) + aix_setauthdb(user); +#endif + pw = getpwnam(user); + +#if defined(_AIX) && defined(HAVE_SETAUTHDB) + aix_restoreauthdb(); +#endif #ifdef HAVE_CYGWIN /* * Windows usernames are case-insensitive. To avoid later problems -- cgit v1.2.3 From c738e6c646aa0b588f50e953b4d3931c29e9ab28 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 7 Mar 2010 13:21:12 +1100 Subject: - (dtucker) [session.c] Bug #1567: move setpcred call to before chroot and do not set real uid, since that's needed for the chroot, and will be set by permanently_set_uid. --- ChangeLog | 3 +++ session.c | 22 ++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63beb9482..e9cb557d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that it gets the passwd struct from the LAM that knows about the user which is not necessarily the default. Patch from Alexandre Letourneau. + - (dtucker) [session.c] Bug #1567: move setpcred call to before chroot and + do not set real uid, since that's needed for the chroot, and will be set + by permanently_set_uid. 20100305 - OpenBSD CVS Sync diff --git a/session.c b/session.c index fd7acbe03..8f978faa6 100644 --- a/session.c +++ b/session.c @@ -1530,6 +1530,24 @@ do_setusercontext(struct passwd *pw) } # endif /* USE_LIBIAF */ #endif +#ifdef HAVE_SETPCRED + /* + * If we have a chroot directory, we set all creds except real + * uid which we will need for chroot. If we don't have a + * chroot directory, we don't override anything. + */ + { + char **creds, *chroot_creds[] = + { "REAL_USER=root", NULL }; + + if (options.chroot_directory != NULL && + strcasecmp(options.chroot_directory, "none") != 0) + creds = chroot_creds; + + if (setpcred(pw->pw_name, creds) == -1) + fatal("Failed to set process credentials"); + } +#endif /* HAVE_SETPCRED */ if (options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { @@ -1542,10 +1560,6 @@ do_setusercontext(struct passwd *pw) free(chroot_path); } -#ifdef HAVE_SETPCRED - if (setpcred(pw->pw_name, (char **)NULL) == -1) - fatal("Failed to set process credentials"); -#endif /* HAVE_SETPCRED */ #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { perror("unable to set user context (setuser)"); -- cgit v1.2.3 From ac0c4c9c1d511839b2c86ebe5994298b524ceffd Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 7 Mar 2010 13:32:16 +1100 Subject: - (dtucker) [session.c] Also initialize creds to NULL for handing to setpcred. --- ChangeLog | 2 ++ session.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e9cb557d7..f80d79aa3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,8 @@ - (dtucker) [session.c] Bug #1567: move setpcred call to before chroot and do not set real uid, since that's needed for the chroot, and will be set by permanently_set_uid. + - (dtucker) [session.c] Also initialize creds to NULL for handing to + setpcred. 20100305 - OpenBSD CVS Sync diff --git a/session.c b/session.c index 8f978faa6..b384b7d86 100644 --- a/session.c +++ b/session.c @@ -1537,7 +1537,7 @@ do_setusercontext(struct passwd *pw) * chroot directory, we don't override anything. */ { - char **creds, *chroot_creds[] = + char **creds = NULL, *chroot_creds[] = { "REAL_USER=root", NULL }; if (options.chroot_directory != NULL && -- cgit v1.2.3 From cd70e1b8137023539df57b175b733341d8f4d776 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 7 Mar 2010 23:05:17 +1100 Subject: - dtucker@cvs.openbsd.org 2010/03/07 11:57:13 [auth-rhosts.c monitor.c monitor_wrap.c session.c auth-options.c sshd.c] Hold authentication debug messages until after successful authentication. Fixes an info leak of environment variables specified in authorized_keys, reported by Jacob Appelbaum. ok djm@ --- ChangeLog | 6 ++++++ auth-options.c | 9 +-------- auth-rhosts.c | 10 ++-------- monitor.c | 17 +---------------- monitor_wrap.c | 19 +------------------ session.c | 4 +++- sshd.c | 3 ++- 7 files changed, 16 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index f80d79aa3..9afd093eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,12 @@ by permanently_set_uid. - (dtucker) [session.c] Also initialize creds to NULL for handing to setpcred. + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2010/03/07 11:57:13 + [auth-rhosts.c monitor.c monitor_wrap.c session.c auth-options.c sshd.c] + Hold authentication debug messages until after successful authentication. + Fixes an info leak of environment variables specified in authorized_keys, + reported by Jacob Appelbaum. ok djm@ 20100305 - OpenBSD CVS Sync diff --git a/auth-options.c b/auth-options.c index bcf5589d7..129301765 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.47 2010/03/04 23:27:25 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.48 2010/03/07 11:57:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -78,7 +78,6 @@ auth_clear_options(void) } forced_tun_device = -1; channel_clear_permitted_opens(); - auth_debug_reset(); } /* @@ -364,9 +363,6 @@ next_option: /* Process the next option. */ } - if (!use_privsep) - auth_debug_send(); - /* grant access */ return 1; @@ -376,9 +372,6 @@ bad_option: auth_debug_add("Bad options in %.100s file, line %lu: %.50s", file, linenum, opts); - if (!use_privsep) - auth_debug_send(); - /* deny access */ return 0; } diff --git a/auth-rhosts.c b/auth-rhosts.c index 5c1296701..06ae7f0b9 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rhosts.c,v 1.43 2008/06/13 14:18:51 dtucker Exp $ */ +/* $OpenBSD: auth-rhosts.c,v 1.44 2010/03/07 11:57:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -317,11 +317,5 @@ int auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, const char *ipaddr) { - int ret; - - auth_debug_reset(); - ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr); - if (!use_privsep) - auth_debug_send(); - return ret; + return auth_rhosts2_raw(pw, client_user, hostname, ipaddr); } diff --git a/monitor.c b/monitor.c index f67cb7670..334aedde5 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.105 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.106 2010/03/07 11:57:13 dtucker Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -997,17 +997,6 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) } #endif -static void -mm_append_debug(Buffer *m) -{ - if (auth_debug_init && buffer_len(&auth_debug)) { - debug3("%s: Appending debug messages for child", __func__); - buffer_append(m, buffer_ptr(&auth_debug), - buffer_len(&auth_debug)); - buffer_clear(&auth_debug); - } -} - int mm_answer_keyallowed(int sock, Buffer *m) { @@ -1090,8 +1079,6 @@ mm_answer_keyallowed(int sock, Buffer *m) buffer_put_int(m, allowed); buffer_put_int(m, forced_command != NULL); - mm_append_debug(m); - mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); if (type == MM_RSAHOSTKEY) @@ -1475,8 +1462,6 @@ mm_answer_rsa_keyallowed(int sock, Buffer *m) if (key != NULL) key_free(key); - mm_append_debug(m); - mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); diff --git a/monitor_wrap.c b/monitor_wrap.c index b8e8710f7..faeb02cfa 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.68 2009/06/22 05:39:28 dtucker Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.69 2010/03/07 11:57:13 dtucker Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -347,19 +347,6 @@ mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user, return (ret); } -static void -mm_send_debug(Buffer *m) -{ - char *msg; - - while (buffer_len(m)) { - msg = buffer_get_string(m, NULL); - debug3("%s: Sending debug: %s", __func__, msg); - packet_send_debug("%s", msg); - xfree(msg); - } -} - int mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) { @@ -393,9 +380,6 @@ mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) have_forced = buffer_get_int(&m); forced_command = have_forced ? xstrdup("true") : NULL; - /* Send potential debug messages */ - mm_send_debug(&m); - buffer_free(&m); return (allowed); @@ -1085,7 +1069,6 @@ mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) *rkey = key; xfree(blob); } - mm_send_debug(&m); buffer_free(&m); return (allowed); diff --git a/session.c b/session.c index b384b7d86..639405fec 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.251 2010/01/12 08:33:17 dtucker Exp $ */ +/* $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -271,6 +271,8 @@ do_authenticated(Authctxt *authctxt) if (!no_port_forwarding_flag && options.allow_tcp_forwarding) channel_permit_all_opens(); + auth_debug_send(); + if (compat20) do_authenticated2(authctxt); else diff --git a/sshd.c b/sshd.c index 0c3c04e4e..bc0d2753f 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.373 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.374 2010/03/07 11:57:13 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1939,6 +1939,7 @@ main(int ac, char **av) /* prepare buffer to collect messages to display to user after login */ buffer_init(&loginmsg); + auth_debug_reset(); if (use_privsep) if (privsep_preauth(authctxt) == 1) -- cgit v1.2.3 From b3bc331e09c7b3617579a53980ca59feb99a8dd2 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 8 Mar 2010 09:03:33 +1100 Subject: - (djm) OpenBSD CVS Sync - djm@cvs.openbsd.org 2010/03/07 22:01:32 [version.h] openssh-5.4 --- ChangeLog | 6 ++++++ version.h | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9afd093eb..0b26749a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20100307 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/03/07 22:01:32 + [version.h] + openssh-5.4 + 20100307 - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that it gets the passwd struct from the LAM that knows about the user which is diff --git a/version.h b/version.h index 721ebdea0..c604c753c 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.56 2009/06/30 14:54:40 markus Exp $ */ +/* $OpenBSD: version.h,v 1.57 2010/03/07 22:01:32 djm Exp $ */ -#define SSH_VERSION "OpenSSH_5.3" +#define SSH_VERSION "OpenSSH_5.4" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE -- cgit v1.2.3 From 3e1ee491f3fa4fa7e44a998799e251a3b08e66d2 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 8 Mar 2010 09:24:11 +1100 Subject: - djm@cvs.openbsd.org 2010/03/07 22:16:01 [ssh-keygen.c] make internal strptime string match strftime format; suggested by vinschen AT redhat.com and markus@ --- ChangeLog | 4 ++++ ssh-keygen.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b26749a1..707be2dd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 20100307 - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/03/07 22:16:01 + [ssh-keygen.c] + make internal strptime string match strftime format; + suggested by vinschen AT redhat.com and markus@ - djm@cvs.openbsd.org 2010/03/07 22:01:32 [version.h] openssh-5.4 diff --git a/ssh-keygen.c b/ssh-keygen.c index fc7ca4b0c..dd662c907 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.183 2010/03/04 23:27:25 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.184 2010/03/07 22:16:01 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1254,12 +1254,12 @@ parse_absolute_time(const char *s) */ switch (strlen(s)) { case 8: - fmt = "%Y/%m/%d"; - snprintf(buf, sizeof(buf), "%.4s/%.2s/%.2s", s, s + 4, s + 6); + fmt = "%Y-%m-%d"; + snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); break; case 14: - fmt = "%Y/%m/%d %H:%M:%S"; - snprintf(buf, sizeof(buf), "%.4s/%.2s/%.2s %.2s:%.2s:%.2s", + fmt = "%Y-%m-%dT%H:%M:%S"; + snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", s, s + 4, s + 6, s + 8, s + 10, s + 12); break; default: -- cgit v1.2.3 From 6bf31786cfa4518f2c81088ddaa7c34de0b532bf Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 8 Mar 2010 09:41:02 +1100 Subject: - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] crank version numbers --- ChangeLog | 3 +++ README | 4 ++-- contrib/caldera/openssh.spec | 6 +++--- contrib/redhat/openssh.spec | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 707be2dd6..ee1c3417f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,9 @@ - djm@cvs.openbsd.org 2010/03/07 22:01:32 [version.h] openssh-5.4 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + crank version numbers + 20100307 - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that diff --git a/README b/README index 16666518a..0ecb670b6 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-5.3 for the release notes. +See http://www.openssh.com/txt/release-5.4 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html @@ -62,4 +62,4 @@ References - [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 [7] http://www.openssh.com/faq.html -$Id: README,v 1.71 2009/10/02 01:49:03 djm Exp $ +$Id: README,v 1.72 2010/03/07 22:41:02 djm Exp $ diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec index e6c030c0d..7c291a0eb 100644 --- a/contrib/caldera/openssh.spec +++ b/contrib/caldera/openssh.spec @@ -17,11 +17,11 @@ #old cvs stuff. please update before use. may be deprecated. %define use_stable 1 %if %{use_stable} - %define version 5.3p1 + %define version 5.4p1 %define cvs %{nil} %define release 1 %else - %define version 5.3p1 + %define version 5.4p1 %define cvs cvs20050315 %define release 0r1 %endif @@ -360,4 +360,4 @@ fi * Mon Jan 01 1998 ... Template Version: 1.31 -$Id: openssh.spec,v 1.68 2010/02/24 07:21:46 djm Exp $ +$Id: openssh.spec,v 1.69 2010/03/07 22:41:03 djm Exp $ diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 4bec90078..de24f1c5d 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 5.3p1 +%define ver 5.4p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID -- cgit v1.2.3 From 958678726c398457036d63c715494e53bd84c5b9 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 8 Mar 2010 09:50:17 +1100 Subject: - (djm) Release OpenSSH-5.4p1 --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee1c3417f..9731af7c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,7 +9,7 @@ openssh-5.4 - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] crank version numbers - + - (djm) Release OpenSSH-5.4p1 20100307 - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that -- cgit v1.2.3 From 081c976e1cac3a1588f484c89f2f48f7a554d1e5 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 8 Mar 2010 11:30:00 +1100 Subject: - djm@cvs.openbsd.org 2010/03/08 00:28:55 [ssh-keygen.1] document permit-agent-forwarding certificate constraint; patch from stevesk@ --- ChangeLog | 4 ++++ ssh-keygen.1 | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9731af7c0..d6e4a4a25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,10 @@ [ssh-keygen.c] make internal strptime string match strftime format; suggested by vinschen AT redhat.com and markus@ + - djm@cvs.openbsd.org 2010/03/08 00:28:55 + [ssh-keygen.1] + document permit-agent-forwarding certificate constraint; patch from + stevesk@ - djm@cvs.openbsd.org 2010/03/07 22:01:32 [version.h] openssh-5.4 diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 069d87649..6557f9336 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.87 2010/03/04 22:52:40 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.88 2010/03/08 00:28:55 djm Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: March 4 2010 $ +.Dd $Mdocdate: March 8 2010 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -329,6 +329,10 @@ This is useful for clearing the default set of permissions so permissions may be added individually. .It Ic permit-x11-forwarding Allows X11 forwarding. +.It Ic permit-agent-forwarding +Allows +.Xr ssh-agent 1 +forwarding. .It Ic permit-port-forwarding Allows port forwarding. .It Ic permit-pty -- cgit v1.2.3 -- cgit v1.2.3