From list at eworm.de Wed Jul 2 17:18:50 2014 From: list at eworm.de (Christian Hesse) Date: Wed, 2 Jul 2014 09:18:50 +0200 Subject: [PATCH 1/1] fix inclusion of util.h Message-ID: <1404285530-5372-1-git-send-email-list@eworm.de> From: Christian Hesse --- sshkey.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sshkey.c b/sshkey.c index 24023d0..0c9032b 100644 --- a/sshkey.c +++ b/sshkey.c @@ -39,7 +39,9 @@ #include #include #include -#include +#ifdef HAVE_UTIL_H +# include +#endif #include "ssh2.h" #include "ssherr.h" -- 2.0.1 From sachin3072004 at gmail.com Fri Jul 4 09:22:07 2014 From: sachin3072004 at gmail.com (Sachin Gupta) Date: Thu, 3 Jul 2014 16:22:07 -0700 Subject: SFTP fails at connection Message-ID: Hello, I have recently installed openssh6.5 on my Centos box. And I can do ssh to my centos box. But SFTP fails at connection. I get following messages when I try to run sshd in debug mode. debug1: subsystem: exec() /usr/libexec/openssh/sftp-server Starting session: subsystem 'sftp' for op from 192.168.1.101 port 53994 debug1: server_input_channel_req: channel 0 request eow at openssh.com reply 0 debug1: Received SIGCHLD. debug1: session_by_pid: pid 25173 debug1: session_exit_message: session 0 channel 0 pid 25173 debug1: session_exit_message: release channel 0 Received disconnect from 192.168.1.101: 11: disconnected by user debug1: do_cleanup debug1: do_cleanup debug1: PAM: cleanup As suggested in FAQ's I tried following command too. ssh root at 10.64.17.115 /usr/bin/true bash: /usr/bin/true: No such file or directory Can you please guide me why SFTP connection is failing ? Thanks Sachin From djm at mindrot.org Fri Jul 4 09:42:37 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 4 Jul 2014 09:42:37 +1000 (EST) Subject: SFTP fails at connection In-Reply-To: References: Message-ID: On Thu, 3 Jul 2014, Sachin Gupta wrote: > Hello, > > I have recently installed openssh6.5 on my Centos box. > And I can do ssh to my centos box. But SFTP fails at connection. > I get following messages when I try to run sshd in debug mode. > > debug1: subsystem: exec() /usr/libexec/openssh/sftp-server > Starting session: subsystem 'sftp' for op from 192.168.1.101 port 53994 > debug1: server_input_channel_req: channel 0 request eow at openssh.com reply 0 > debug1: Received SIGCHLD. > debug1: session_by_pid: pid 25173 > debug1: session_exit_message: session 0 channel 0 pid 25173 > debug1: session_exit_message: release channel 0 > Received disconnect from 192.168.1.101: 11: disconnected by user > debug1: do_cleanup > debug1: do_cleanup > debug1: PAM: cleanup > > > As suggested in FAQ's I tried following command too. > > ssh root at 10.64.17.115 /usr/bin/true > bash: /usr/bin/true: No such file or directory > > Can you please guide me why SFTP connection is failing ? What does: ssh root at 10.64.17.115 /bin/true produce? Also: ssh root at 10.64.17.115 /usr/libexec/openssh/sftp-server -d From sachin3072004 at gmail.com Fri Jul 4 10:07:15 2014 From: sachin3072004 at gmail.com (Sachin Gupta) Date: Thu, 3 Jul 2014 17:07:15 -0700 Subject: SFTP fails at connection In-Reply-To: References: Message-ID: Thanks for your prompt response. 'ssh root at 10.64.17.115 /bin/true' does not produce any output. 'ssh root at 10.64.17.115 /usr/libexec/openssh/sftp-server' hangs there. But it has started the sftp-server process on 10.64.17.115. Thanks Sachin On Thu, Jul 3, 2014 at 4:42 PM, Damien Miller wrote: > On Thu, 3 Jul 2014, Sachin Gupta wrote: > > > Hello, > > > > I have recently installed openssh6.5 on my Centos box. > > And I can do ssh to my centos box. But SFTP fails at connection. > > I get following messages when I try to run sshd in debug mode. > > > > debug1: subsystem: exec() /usr/libexec/openssh/sftp-server > > Starting session: subsystem 'sftp' for op from 192.168.1.101 port 53994 > > debug1: server_input_channel_req: channel 0 request eow at openssh.com > reply 0 > > debug1: Received SIGCHLD. > > debug1: session_by_pid: pid 25173 > > debug1: session_exit_message: session 0 channel 0 pid 25173 > > debug1: session_exit_message: release channel 0 > > Received disconnect from 192.168.1.101: 11: disconnected by user > > debug1: do_cleanup > > debug1: do_cleanup > > debug1: PAM: cleanup > > > > > > As suggested in FAQ's I tried following command too. > > > > ssh root at 10.64.17.115 /usr/bin/true > > bash: /usr/bin/true: No such file or directory > > > > Can you please guide me why SFTP connection is failing ? > > What does: > > ssh root at 10.64.17.115 /bin/true > > produce? > > Also: > > ssh root at 10.64.17.115 /usr/libexec/openssh/sftp-server > > -d > From djm at mindrot.org Fri Jul 4 10:10:14 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 4 Jul 2014 10:10:14 +1000 (EST) Subject: SFTP fails at connection In-Reply-To: References: Message-ID: On Thu, 3 Jul 2014, Sachin Gupta wrote: > Thanks for your prompt response. > > 'ssh root at 10.64.17.115 /bin/true' does not produce any output. > > 'ssh root at 10.64.17.115 /usr/libexec/openssh/sftp-server' hangs there. But it > has started the sftp-server process on 10.64.17.115. that sounds fine. What does sftp -vvv root at 10.64.17.115 do? -d From sachin3072004 at gmail.com Fri Jul 4 14:37:32 2014 From: sachin3072004 at gmail.com (Sachin Gupta) Date: Thu, 3 Jul 2014 21:37:32 -0700 Subject: SFTP fails at connection In-Reply-To: References: Message-ID: I tried 'ssh sachinmaster at 10.64.17.115 /usr/libexec/openssh/sftp-server' And I got following output. Identity added: /Users/sachingupta/.ssh/id_dsa (/Users/sachingupta/.ssh/id_dsa) Password: No user found for uid 500 Any help will be highly appreciated. Thanks Sachin On Thu, Jul 3, 2014 at 5:44 PM, Damien Miller wrote: > On Thu, 3 Jul 2014, Sachin Gupta wrote: > > > dhcp-1-101:~ sachingupta$ sftp -vvv root at 10.64.17.115 > > So, sftp seems to be running when you invoke it explicitly but failing > when you run it as a subsystem > > If you are on the target host, does > > sftp -D /usr/libexec/openssh/sftp-server > > result in a working sftp session? > > I'd recommend turning up the logging from sftp-server too in your > sshd_config: > > Subsystem sftp /usr/libexec/openssh/sftp-server -l debug3 -f daemon > > And check your /var/log/daemon (or similar) for clues. > > -d > From djm at mindrot.org Fri Jul 4 14:59:55 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 4 Jul 2014 14:59:55 +1000 (EST) Subject: SFTP fails at connection In-Reply-To: References: Message-ID: On Thu, 3 Jul 2014, Sachin Gupta wrote: > I tried 'ssh sachinmaster at 10.64.17.115 /usr/libexec/openssh/sftp-server' > > And I got following output. > Identity added: /Users/sachingupta/.ssh/id_dsa > (/Users/sachingupta/.ssh/id_dsa) > Password: > No user found for uid 500 Your password file / NSS / PAM configuration is broken From list at eworm.de Fri Jul 4 18:44:27 2014 From: list at eworm.de (Christian Hesse) Date: Fri, 4 Jul 2014 10:44:27 +0200 Subject: multiplex.sh fails in make tests Message-ID: <20140704104427.542e3a5e@leda.localdomain> Hello everybody, running make tests on latest openssh-portable git master (V_6_6_P1-114-g72e6b5c) fails: [...] run test multiplex.sh ... test connection multiplexing: envpass test connection multiplexing: transfer test connection multiplexing: status 0 test connection multiplexing: status 1 test connection multiplexing: status 4 test connection multiplexing: status 5 test connection multiplexing: status 44 test connection multiplexing: cmd check test connection multiplexing: cmd forward local test connection multiplexing: cmd forward remote remote forward port still listening test connection multiplexing: cmd exit test connection multiplexing: cmd stop failed connection multiplexing Makefile:168: recipe for target 't-exec' failed make[1]: *** [t-exec] Error 1 Let me know if you need any more details. -- main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH" "CX:;",b;for(a/* Chris get my mail address: */=0;b=c[a++];) putchar(b-1/(/* gcc -o sig sig.c && ./sig */b/42*2-3)*42);} -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From nkadel at gmail.com Fri Jul 4 20:39:58 2014 From: nkadel at gmail.com (Nico Kadel-Garcia) Date: Fri, 4 Jul 2014 06:39:58 -0400 Subject: SFTP fails at connection In-Reply-To: References: Message-ID: On Thu, Jul 3, 2014 at 7:22 PM, Sachin Gupta wrote: > Hello, > > I have recently installed openssh6.5 on my Centos box. > And I can do ssh to my centos box. But SFTP fails at connection. > I get following messages when I try to run sshd in debug mode. How did you build it? Did you make an RPM, or did you compile from scratch and install it locally, possibly leaving in place the CentOS provided RPM to create confusion and overlapping components? And which CentOS release? Did you use OpenSSH 6,5, or OpenSSH 6.5p1 which has portability patches? The OpenSSH 6.6p1 tarball has a decent working .spec file for RHEL inside it, I do recommend that you use it. From djm at mindrot.org Sat Jul 5 12:34:33 2014 From: djm at mindrot.org (Damien Miller) Date: Sat, 5 Jul 2014 12:34:33 +1000 (EST) Subject: multiplex.sh fails in make tests In-Reply-To: <20140704104427.542e3a5e@leda.localdomain> References: <20140704104427.542e3a5e@leda.localdomain> Message-ID: On Fri, 4 Jul 2014, Christian Hesse wrote: > Hello everybody, > > running make tests on latest openssh-portable git master > (V_6_6_P1-114-g72e6b5c) fails: Yes, I've been trying to figure that out myself. I think this is the fix: diff --git channels.c channels.c index eb63325..a858ac2 100644 --- channels.c +++ channels.c @@ -3073,7 +3073,8 @@ channel_request_rforward_cancel(const char *host, u_short port) return -1; for (i = 0; i < num_permitted_opens; i++) { - if (open_listen_match(&permitted_opens[i], host, port, 0)) + if (open_listen_match(&permitted_opens[i], + channel_rfwd_bind_host(host), port, 1)) break; } if (i >= num_permitted_opens) { From list at eworm.de Sun Jul 6 21:36:56 2014 From: list at eworm.de (Christian Hesse) Date: Sun, 6 Jul 2014 13:36:56 +0200 Subject: multiplex.sh fails in make tests In-Reply-To: References: <20140704104427.542e3a5e@leda.localdomain> Message-ID: <20140706133656.5ec4c70b@leda.localdomain> Damien Miller on Sat, 2014/07/05 12:34: > On Fri, 4 Jul 2014, Christian Hesse wrote: > > > Hello everybody, > > > > running make tests on latest openssh-portable git master > > (V_6_6_P1-114-g72e6b5c) fails: > > Yes, I've been trying to figure that out myself. I think this is the fix: Works for me. Thanks! -- main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH" "CX:;",b;for(a/* Chris get my mail address: */=0;b=c[a++];) putchar(b-1/(/* gcc -o sig sig.c && ./sig */b/42*2-3)*42);} -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From djm at mindrot.org Mon Jul 7 08:17:06 2014 From: djm at mindrot.org (Damien Miller) Date: Mon, 7 Jul 2014 08:17:06 +1000 (EST) Subject: multiplex.sh fails in make tests In-Reply-To: <20140706133656.5ec4c70b@leda.localdomain> References: <20140704104427.542e3a5e@leda.localdomain> <20140706133656.5ec4c70b@leda.localdomain> Message-ID: On Sun, 6 Jul 2014, Christian Hesse wrote: > Damien Miller on Sat, 2014/07/05 12:34: > > On Fri, 4 Jul 2014, Christian Hesse wrote: > > > > > Hello everybody, > > > > > > running make tests on latest openssh-portable git master > > > (V_6_6_P1-114-g72e6b5c) fails: > > > > Yes, I've been trying to figure that out myself. I think this is the fix: > > Works for me. Thanks! I ended up committing something a bit different after some feedback from Markus. -d From helwigd at collax.com Tue Jul 8 01:41:22 2014 From: helwigd at collax.com (David Helwig) Date: Mon, 07 Jul 2014 17:41:22 +0200 Subject: Patch to Prevent client from not opening channel Message-ID: <53BABFA2.405@collax.com> Hi there, i had the problem that it wasn't possible to prevent the client from not opening a channel. This is necessary for me because i have written a custom shell which is doing some cleanup work after the connection is closed, which is not possible in case the shell isn't started at all. I have found some people with the same Problem on the internet, so i patched in a channelgracetime. I have asked on the openssh irc why there isn't such a feature and nobody had a real answer. If you know some reason why this is evil, and generally bad, please let me know. Also as far as i'm concerned i haven't broken anything but if you see something really wrong please tell me. Greetings David Helwig -------------- next part -------------- A non-text attachment was scrubbed... Name: 002-initialize-channel-alarm-handler.patch Type: text/x-patch Size: 1372 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 003-channel-alarm.patch Type: text/x-patch Size: 555 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 004-channel-initialize-option.patch Type: text/x-patch Size: 2524 bytes Desc: not available URL: From valentin.lab at kalysto.org Wed Jul 9 17:14:36 2014 From: valentin.lab at kalysto.org (Valentin LAB) Date: Wed, 09 Jul 2014 09:14:36 +0200 Subject: Keeping atomicity of write() through ssh Message-ID: <53BCEBDC.2010103@kalysto.org> Hi, I'm sorry if this is plain dumb or was already asked, but I couldn't find any reference to this. This is about ssh acting as a real terminal. Do some of you know pipe viewer, or 'pv' ? http://www.ivarch.com/programs/pv.shtml This clever little bit of code tries to write on your terminal some stats about data going through some pipes. But there's a nasty limitation when going through ssh related to the atomicity of write() lost when going through ssh: Often you have to use multiple PipeView, and each of them have to print stats on the same line and this works with some ANSI escape code. It relies heavily on the fact that even if each PipeView are in separate processes, the write() command is garanteed to be atomic so the string sent to the fd contains the ANSI chars to relocate to the correct line, print the stats, and go back to starting position. Atomicity is important because you don't want the string being cut by other messages before its fully sent to the terminal. However, if PipeView works fine on local host, it'll break when used through ssh, and I strongly suspect ssh to break atomicity of write() on the fd. More on stdout/stderr atomicity and buffering: http://www.pixelbeat.org/programming/stdio_buffering/ So 2 questions: - Can you confirm that ssh breaks atomicity of write on stderr/stdout ? - Has this issue any chances to be fixed one day ? - Related to the last question: would you accept any patches to fix that ? My main concern is to know if there are practical important reason why the atomicity was broken, or if the current ssh current code architecture won't allow patching easily this. Thanks for your answers. -- Valentin LAB From peter at stuge.se Wed Jul 9 18:36:44 2014 From: peter at stuge.se (Peter Stuge) Date: Wed, 9 Jul 2014 10:36:44 +0200 Subject: Keeping atomicity of write() through ssh In-Reply-To: <53BCEBDC.2010103@kalysto.org> References: <53BCEBDC.2010103@kalysto.org> Message-ID: <20140709083644.11257.qmail@stuge.se> Valentin LAB wrote: > even if each PipeView are in separate processes, the write() command > is garanteed to be atomic That's not at all true in the general case. Quoting my man 2 write: DESCRIPTION write() writes up to count bytes from the buffer pointed buf to the file referred to by the file descriptor fd. The number of bytes written may be less than count if, for example, there is insufficient space on the underlying physical medium, or the RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)), or the call was interrupted by a signal handler after having written less than count bytes. (See also pipe(7).) So relying on write() to always write either all bytes or none is, in the general case, a classical and oft-repeated application bug. Now, some file descriptor types do indeed have atomic write() behavior, but that is heavily dependent on the particular kernel driver, and unless an application ensures that a particular fd is indeed handled by a known-to-behave-that-way kernel driver, then relying on write() to be atomic is plain wrong. > Atomicity is important because you don't want the string being cut > by other messages before its fully sent to the terminal. It's possible that tty devices provide atomic write() behavior on some systems, but since they are character devices and not block devices I would actually be surprised if that is the case. > However, if PipeView works fine on local host, it'll break when used > through ssh, and I strongly suspect ssh to break atomicity of write() > on the fd. Please think again. ssh doesn't handle write() system calls - your kernel does. //Peter From scott_n at xypro.com Sat Jul 12 05:21:54 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Fri, 11 Jul 2014 19:21:54 +0000 Subject: Cross compiling? Message-ID: Any hints on how to run configure for a cross compilation? --- Scott Neugroschl From scott_n at xypro.com Sat Jul 12 07:19:08 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Fri, 11 Jul 2014 21:19:08 +0000 Subject: OpenSSH 6.6p1 configure script error Message-ID: In the configure script, when it checks to see if _res is an extern, there are two problems: 1. There is no ac_WHATEVER variable to control it and override it. 2. Because the extern reference to _res is unused, the linker on some systems may elide it, causing an erroneous definition of HAS__RES_EXTERN The test should be coded as follows: /* ... confdefs.h */ #include #if HAVE_SYS_TYPES_H # include #endif #include #include #include extern struct __res_state _res; int main () { struct __res_state *volatile p = &_res; /* force resolution of _res */ return 0; } --- Scott Neugroschl | XYPRO Technology Corporation 4100 Guardian Street | Suite 100 |Simi Valley, CA 93063 | Phone 805 583-2874|Fax 805 583-0124 | From hanno at hboeck.de Sat Jul 12 17:54:04 2014 From: hanno at hboeck.de (Hanno =?UTF-8?B?QsO2Y2s=?=) Date: Sat, 12 Jul 2014 09:54:04 +0200 Subject: openssh portable and libressl portable cause recursion between arc4random and RAND_bytes Message-ID: <20140712095404.0bc051d3@pc> Hi, Yesterday I tried to replace the system openssl in a gentoo system with libressl. With openssh an interesting issue popped up: * RAND_bytes in libressl calls arc4random * arc4random is a compat function both in openssh and libressl * arc4random from openssh uses RAND_bytes So what's happening is a recursion. arc4random wants to use RAND_bytes and RAND_bytes wants to use arc4random. The result is a segfault. OpenSSH is the latest 6.6.1. A quick and working solution was to replace the openssh-arc4random with the one shipped by libressl. One small change is needed: the libressl-arc4random.c doesn't have the arc4random_stir()-function, I copied that back from the openssh-arc4random.c. Works so far, see attached patch. An alternative would be to check for the availability of arc4random in libcrypto and use that if available. cu, -- Hanno B?ck http://hboeck.de/ mail/jabber: hanno at hboeck.de GPG: BBB51E42 -------------- next part -------------- A non-text attachment was scrubbed... Name: openssh-arc4random.diff.gz Type: application/gzip Size: 3055 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From djm at mindrot.org Mon Jul 14 09:39:28 2014 From: djm at mindrot.org (Damien Miller) Date: Mon, 14 Jul 2014 09:39:28 +1000 (EST) Subject: openssh portable and libressl portable cause recursion between arc4random and RAND_bytes In-Reply-To: <20140712095404.0bc051d3@pc> References: <20140712095404.0bc051d3@pc> Message-ID: On Sat, 12 Jul 2014, Hanno B?ck wrote: > Hi, > > Yesterday I tried to replace the system openssl in a gentoo system with > libressl. > > With openssh an interesting issue popped up: > * RAND_bytes in libressl calls arc4random > * arc4random is a compat function both in openssh and libressl > * arc4random from openssh uses RAND_bytes Right, I think we should just delay the checks for arc4random. I'd like to sync arc4random.c, but that's a separate issue. Can you tell me if this works for you? Index: configure.ac =================================================================== RCS file: /var/cvs/openssh/configure.ac,v retrieving revision 1.577 diff -u -p -r1.577 configure.ac --- configure.ac 3 Jul 2014 01:54:19 -0000 1.577 +++ configure.ac 13 Jul 2014 23:34:33 -0000 @@ -1575,10 +1575,6 @@ AC_CHECK_FUNCS([ \ Blowfish_expandstate \ Blowfish_expand0state \ Blowfish_stream2word \ - arc4random \ - arc4random_buf \ - arc4random_stir \ - arc4random_uniform \ asprintf \ b64_ntop \ __b64_ntop \ @@ -2639,6 +2635,13 @@ fi AC_SUBST([TEST_SSH_ECC]) AC_SUBST([COMMENT_OUT_ECC]) + +AC_CHECK_FUNCS([ \ + arc4random \ + arc4random_buf \ + arc4random_stir \ + arc4random_uniform \ +]) saved_LIBS="$LIBS" AC_CHECK_LIB([iaf], [ia_openinfo], [ From hanno at hboeck.de Mon Jul 14 20:48:04 2014 From: hanno at hboeck.de (Hanno =?UTF-8?B?QsO2Y2s=?=) Date: Mon, 14 Jul 2014 12:48:04 +0200 Subject: openssh portable and libressl portable cause recursion between arc4random and RAND_bytes In-Reply-To: References: <20140712095404.0bc051d3@pc> Message-ID: <20140714124804.6dd45079@pc> On Mon, 14 Jul 2014 09:39:28 +1000 (EST) Damien Miller wrote: > Right, I think we should just delay the checks for arc4random. I'd > like to sync arc4random.c, but that's a separate issue. > > Can you tell me if this works for you? Your patch seems to work so far. No segfaults. -- Hanno B?ck http://hboeck.de/ mail/jabber: hanno at hboeck.de GPG: BBB51E42 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From plautrba at redhat.com Wed Jul 16 01:00:01 2014 From: plautrba at redhat.com (Petr Lautrbach) Date: Tue, 15 Jul 2014 17:00:01 +0200 Subject: missing HAVE_EVP_RIPEMD160 breaks ssh client Message-ID: <53C541F1.8050104@redhat.com> Hello, I've updated sources but forgot to recreate configure so I've ended without #define HAVE_EVP_RIPEMD160 1 and ssh client ended with: OpenSSH_6.7p1, OpenSSL 1.0.1h-fips 5 Jun 2014 debug1: Reading configuration data ssh.config main: mux digest failed The problem was that ssh_digest_by_alg() couldn't verify alg with an index bigger than 1 since the line with SSH_DIGEST_RIPEMD160 wasn't compiled in and all indexes in the ssh_digest digests array was lowered by one. /* NB. Indexed directly by algorithm number */ const struct ssh_digest digests[] = { { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, #ifdef HAVE_EVP_RIPEMD160 /* XXX replace with local if missing */ { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 }, #endif { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, ... Would it be worth to use enum instead of defined constants for the digest type? --- a/digest.h +++ b/digest.h @@ -22,13 +22,17 @@ #define SSH_DIGEST_MAX_LENGTH 64 /* Digest algorithms */ -#define SSH_DIGEST_MD5 0 -#define SSH_DIGEST_RIPEMD160 1 -#define SSH_DIGEST_SHA1 2 -#define SSH_DIGEST_SHA256 3 -#define SSH_DIGEST_SHA384 4 -#define SSH_DIGEST_SHA512 5 -#define SSH_DIGEST_MAX 6 +enum ssh_digest_type { + SSH_DIGEST_MD5, +#ifdef HAVE_EVP_RIPEMD160 /* XXX replace with local if missing */ + SSH_DIGEST_RIPEMD160, +#endif + SSH_DIGEST_SHA1, + SSH_DIGEST_SHA256, + SSH_DIGEST_SHA384, + SSH_DIGEST_SHA512, + SSH_DIGEST_MAX +}; struct sshbuf; struct ssh_digest_ctx; Regards, Petr -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From plautrba at redhat.com Wed Jul 16 01:21:01 2014 From: plautrba at redhat.com (Petr Lautrbach) Date: Tue, 15 Jul 2014 17:21:01 +0200 Subject: missing HAVE_EVP_RIPEMD160 breaks ssh client In-Reply-To: <53C541F1.8050104@redhat.com> References: <53C541F1.8050104@redhat.com> Message-ID: <53C546DD.2090502@redhat.com> On 07/15/2014 05:00 PM, Petr Lautrbach wrote: > Hello, > > --- a/digest.h > +++ b/digest.h > @@ -22,13 +22,17 @@ > #define SSH_DIGEST_MAX_LENGTH 64 > > /* Digest algorithms */ > -#define SSH_DIGEST_MD5 0 > -#define SSH_DIGEST_RIPEMD160 1 > -#define SSH_DIGEST_SHA1 2 > -#define SSH_DIGEST_SHA256 3 > -#define SSH_DIGEST_SHA384 4 > -#define SSH_DIGEST_SHA512 5 > -#define SSH_DIGEST_MAX 6 > +enum ssh_digest_type { > + SSH_DIGEST_MD5, > +#ifdef HAVE_EVP_RIPEMD160 /* XXX replace with local if missing */ > + SSH_DIGEST_RIPEMD160, > +#endif > + SSH_DIGEST_SHA1, > + SSH_DIGEST_SHA256, > + SSH_DIGEST_SHA384, > + SSH_DIGEST_SHA512, > + SSH_DIGEST_MAX > +}; > Hmm, it would break the implementation in digest-libc.c so probably not the right fix. Petr -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From scott_n at xypro.com Wed Jul 16 07:52:33 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Tue, 15 Jul 2014 21:52:33 +0000 Subject: GSSAPI Message-ID: If I am trying to build OpenSSH 6.6 with Kerberos GSSAPI support, do I still need to get Simon Wilkinson's patches? --- Scott Neugroschl | XYPRO Technology Corporation 4100 Guardian Street | Suite 100 |Simi Valley, CA 93063 | Phone 805 583-2874|Fax 805 583-0124 | From djm at mindrot.org Wed Jul 16 09:09:17 2014 From: djm at mindrot.org (Damien Miller) Date: Wed, 16 Jul 2014 09:09:17 +1000 (EST) Subject: GSSAPI In-Reply-To: References: Message-ID: On Tue, 15 Jul 2014, Scott Neugroschl wrote: > If I am trying to build OpenSSH 6.6 with Kerberos GSSAPI support, do I > still need to get Simon Wilkinson's patches? If you want GSSAPI key exchange, yes. If you just want GSSAPI auth and token forwarding then no. AFAIK Simon is no longer maintaining the patches, but here's a version that at least applies and builds against 6.6p1. -d diff --git a/ChangeLog.gssapi b/ChangeLog.gssapi new file mode 100644 index 0000000..f117a33 --- /dev/null +++ b/ChangeLog.gssapi @@ -0,0 +1,113 @@ +20110101 + - Finally update for OpenSSH 5.6p1 + - Add GSSAPIServerIdentity option from Jim Basney + +20100308 + - [ Makefile.in, key.c, key.h ] + Updates for OpenSSH 5.4p1 + - [ servconf.c ] + Include GSSAPI options in the sshd -T configuration dump, and flag + some older configuration options as being unsupported. Thanks to Colin + Watson. + - + +20100124 + - [ sshconnect2.c ] + Adapt to deal with additional element in Authmethod structure. Thanks to + Colin Watson + +20090615 + - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c + sshd.c ] + Fix issues identified by Greg Hudson following a code review + Check return value of gss_indicate_mechs + Protect GSSAPI calls in monitor, so they can only be used if enabled + Check return values of bignum functions in key exchange + Use BN_clear_free to clear other side's DH value + Make ssh_gssapi_id_kex more robust + Only configure kex table pointers if GSSAPI is enabled + Don't leak mechanism list, or gss mechanism list + Cast data.length before printing + If serverkey isn't provided, use an empty string, rather than NULL + +20090201 + - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h + ssh_config.5 sshconnet2.c ] + Add support for the GSSAPIClientIdentity option, which allows the user + to specify which GSSAPI identity to use to contact a given server + +20080404 + - [ gss-serv.c ] + Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow + been omitted from a previous version of this patch. Reported by Borislav + Stoichkov + +20070317 + - [ gss-serv-krb5.c ] + Remove C99ism, where new_ccname was being declared in the middle of a + function + +20061220 + - [ servconf.c ] + Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and + documented, behaviour. Reported by Dan Watson. + +20060910 + - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c + ssh-gss.h ] + add support for gss-group14-sha1 key exchange mechanisms + - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ] + Add GSSAPIStrictAcceptorCheck option to allow the disabling of + acceptor principal checking on multi-homed machines. + + - [ sshd_config ssh_config ] + Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample + configuration files + - [ kexgss.c kegsss.c sshconnect2.c sshd.c ] + Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf() + Limit length of error messages displayed by client + +20060909 + - [ gss-genr.c gss-serv.c ] + move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server + only, where they belong + + +20060829 + - [ gss-serv-krb5.c ] + Fix CCAPI credentials cache name when creating KRB5CCNAME environment + variable + +20060828 + - [ gss-genr.c ] + Avoid Heimdal context freeing problem + + +20060818 + - [ gss-genr.c ssh-gss.h sshconnect2.c ] + Make sure that SPENGO is disabled + + +20060421 + - [ gssgenr.c, sshconnect2.c ] + a few type changes (signed versus unsigned, int versus size_t) to + fix compiler errors/warnings + (from jbasney AT ncsa.uiuc.edu) + - [ kexgssc.c, sshconnect2.c ] + fix uninitialized variable warnings + (from jbasney AT ncsa.uiuc.edu) + - [ gssgenr.c ] + pass oid to gss_display_status (helpful when using GSSAPI mechglue) + (from jbasney AT ncsa.uiuc.edu) + + - [ gss-serv-krb5.c ] + #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H + (from jbasney AT ncsa.uiuc.edu) + + - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c + add client-side GssapiKeyExchange option + (from jbasney AT ncsa.uiuc.edu) + - [ sshconnect2.c ] + add support for GssapiTrustDns option for gssapi-with-mic + (from jbasney AT ncsa.uiuc.edu) + diff --git a/Makefile.in b/Makefile.in index 28a8ec4..ee1d2c3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -72,6 +72,7 @@ LIBSSH_OBJS=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-ecdsa.o ssh-rsa.o dh.o \ kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ + kexgssc.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o krl.o smult_curve25519_ref.o \ kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ @@ -91,7 +92,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ kexc25519s.o auth-krb5.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o \ diff --git a/auth-krb5.c b/auth-krb5.c index 6c62bdf..69a1a53 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -182,8 +182,13 @@ auth_krb5_password(Authctxt *authctxt, const char *password) len = strlen(authctxt->krb5_ticket_file) + 6; authctxt->krb5_ccname = xmalloc(len); +#ifdef USE_CCAPI + snprintf(authctxt->krb5_ccname, len, "API:%s", + authctxt->krb5_ticket_file); +#else snprintf(authctxt->krb5_ccname, len, "FILE:%s", authctxt->krb5_ticket_file); +#endif #ifdef USE_PAM if (options.use_pam) @@ -240,15 +245,22 @@ krb5_cleanup_proc(Authctxt *authctxt) #ifndef HEIMDAL krb5_error_code ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { - int tmpfd, ret, oerrno; + int ret, oerrno; char ccname[40]; mode_t old_umask; +#ifdef USE_CCAPI + char cctemplate[] = "API:krb5cc_%d"; +#else + char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX"; + int tmpfd; +#endif ret = snprintf(ccname, sizeof(ccname), - "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); + cctemplate, geteuid()); if (ret < 0 || (size_t)ret >= sizeof(ccname)) return ENOMEM; +#ifndef USE_CCAPI old_umask = umask(0177); tmpfd = mkstemp(ccname + strlen("FILE:")); oerrno = errno; @@ -265,6 +277,7 @@ ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { return oerrno; } close(tmpfd); +#endif return (krb5_cc_resolve(ctx, ccname, ccache)); } diff --git a/auth2-gss.c b/auth2-gss.c index c28a705..3ff2d72 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ /* $OpenBSD: auth2-gss.c,v 1.21 2014/02/26 20:28:44 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); static void input_gssapi_errtok(int, u_int32_t, void *); +/* + * The 'gssapi_keyex' userauth mechanism. + */ +static int +userauth_gsskeyex(Authctxt *authctxt) +{ + int authenticated = 0; + Buffer b; + gss_buffer_desc mic, gssbuf; + u_int len; + + mic.value = packet_get_string(&len); + mic.length = len; + + packet_check_eom(); + + ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, + "gssapi-keyex"); + + gssbuf.value = buffer_ptr(&b); + gssbuf.length = buffer_len(&b); + + /* gss_kex_context is NULL with privsep, so we can't check it here */ + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, + &gssbuf, &mic)))) + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, + authctxt->pw)); + + buffer_free(&b); + free(mic.value); + + return (authenticated); +} + /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) @@ -235,7 +269,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) packet_check_eom(); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, + authctxt->pw)); authctxt->postponed = 0; dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); @@ -270,7 +305,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) gssbuf.length = buffer_len(&b); if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + authenticated = + PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); else logit("GSSAPI MIC check failed"); @@ -285,6 +321,12 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); } +Authmethod method_gsskeyex = { + "gssapi-keyex", + userauth_gsskeyex, + &options.gss_authentication +}; + Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, diff --git a/auth2.c b/auth2.c index a5490c0..fbe3e1b 100644 --- a/auth2.c +++ b/auth2.c @@ -69,6 +69,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI +extern Authmethod method_gsskeyex; extern Authmethod method_gssapi; #endif @@ -76,6 +77,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI + &method_gsskeyex, &method_gssapi, #endif &method_passwd, diff --git a/clientloop.c b/clientloop.c index 59ad3a2..6d8cd7d 100644 --- a/clientloop.c +++ b/clientloop.c @@ -111,6 +111,10 @@ #include "msg.h" #include "roaming.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* import options */ extern Options options; @@ -1608,6 +1612,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Do channel operations unless rekeying in progress. */ if (!rekeying) { channel_after_select(readset, writeset); + +#ifdef GSSAPI + if (options.gss_renewal_rekey && + ssh_gssapi_credentials_updated(NULL)) { + debug("credentials updated - forcing rekey"); + need_rekeying = 1; + } +#endif + if (need_rekeying || packet_need_rekeying()) { debug("need rekeying"); xxx_kex->done = 0; diff --git a/configure.ac b/configure.ac index 7c6ce08..d235fb0 100644 --- a/configure.ac +++ b/configure.ac @@ -584,6 +584,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) + AC_MSG_CHECKING([if we have the Security Authorization Session API]) + AC_TRY_COMPILE([#include ], + [SessionCreate(0, 0);], + [ac_cv_use_security_session_api="yes" + AC_DEFINE([USE_SECURITY_SESSION_API], [1], + [platform has the Security Authorization Session API]) + LIBS="$LIBS -framework Security" + AC_MSG_RESULT([yes])], + [ac_cv_use_security_session_api="no" + AC_MSG_RESULT([no])]) + AC_MSG_CHECKING([if we have an in-memory credentials cache]) + AC_TRY_COMPILE( + [#include ], + [cc_context_t c; + (void) cc_initialize (&c, 0, NULL, NULL);], + [AC_DEFINE([USE_CCAPI], [1], + [platform uses an in-memory credentials cache]) + LIBS="$LIBS -framework Security" + AC_MSG_RESULT([yes]) + if test "x$ac_cv_use_security_session_api" = "xno"; then + AC_MSG_ERROR([*** Need a security framework to use the credentials cache API ***]) + fi], + [AC_MSG_RESULT([no])] + ) m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff --git a/gss-genr.c b/gss-genr.c index b39281b..1e569ad 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,7 +1,7 @@ /* $OpenBSD: gss-genr.c,v 1.22 2013/11/08 00:39:15 djm Exp $ */ /* - * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,12 +39,167 @@ #include "buffer.h" #include "log.h" #include "ssh2.h" +#include "cipher.h" +#include "key.h" +#include "kex.h" +#include #include "ssh-gss.h" extern u_char *session_id2; extern u_int session_id2_len; +typedef struct { + char *encoded; + gss_OID oid; +} ssh_gss_kex_mapping; + +/* + * XXX - It would be nice to find a more elegant way of handling the + * XXX passing of the key exchange context to the userauth routines + */ + +Gssctxt *gss_kex_context = NULL; + +static ssh_gss_kex_mapping *gss_enc2oid = NULL; + +int +ssh_gssapi_oid_table_ok(void) { + return (gss_enc2oid != NULL); +} + +/* + * Return a list of the gss-group1-sha1 mechanisms supported by this program + * + * We test mechanisms to ensure that we can use them, to avoid starting + * a key exchange with a bad mechanism + */ + +char * +ssh_gssapi_client_mechanisms(const char *host, const char *client) { + gss_OID_set gss_supported; + OM_uint32 min_status; + + if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) + return NULL; + + return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, + host, client)); +} + +char * +ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, + const char *host, const char *client) { + Buffer buf; + size_t i; + int oidpos, enclen; + char *mechs, *encoded; + u_char digest[EVP_MAX_MD_SIZE]; + char deroid[2]; + const EVP_MD *evp_md = EVP_md5(); + EVP_MD_CTX md; + + if (gss_enc2oid != NULL) { + for (i = 0; gss_enc2oid[i].encoded != NULL; i++) + free(gss_enc2oid[i].encoded); + free(gss_enc2oid); + } + + gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) * + (gss_supported->count + 1)); + + buffer_init(&buf); + + oidpos = 0; + for (i = 0; i < gss_supported->count; i++) { + if (gss_supported->elements[i].length < 128 && + (*check)(NULL, &(gss_supported->elements[i]), host, client)) { + + deroid[0] = SSH_GSS_OIDTYPE; + deroid[1] = gss_supported->elements[i].length; + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, deroid, 2); + EVP_DigestUpdate(&md, + gss_supported->elements[i].elements, + gss_supported->elements[i].length); + EVP_DigestFinal(&md, digest, NULL); + + encoded = xmalloc(EVP_MD_size(evp_md) * 2); + enclen = __b64_ntop(digest, EVP_MD_size(evp_md), + encoded, EVP_MD_size(evp_md) * 2); + + if (oidpos != 0) + buffer_put_char(&buf, ','); + + buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, + sizeof(KEX_GSS_GEX_SHA1_ID) - 1); + buffer_append(&buf, encoded, enclen); + buffer_put_char(&buf, ','); + buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, + sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); + buffer_append(&buf, encoded, enclen); + buffer_put_char(&buf, ','); + buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, + sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); + buffer_append(&buf, encoded, enclen); + + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); + gss_enc2oid[oidpos].encoded = encoded; + oidpos++; + } + } + gss_enc2oid[oidpos].oid = NULL; + gss_enc2oid[oidpos].encoded = NULL; + + buffer_put_char(&buf, '\0'); + + mechs = xmalloc(buffer_len(&buf)); + buffer_get(&buf, mechs, buffer_len(&buf)); + buffer_free(&buf); + + if (strlen(mechs) == 0) { + free(mechs); + mechs = NULL; + } + + return (mechs); +} + +gss_OID +ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { + int i = 0; + + switch (kex_type) { + case KEX_GSS_GRP1_SHA1: + if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID)) + return GSS_C_NO_OID; + name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; + break; + case KEX_GSS_GRP14_SHA1: + if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID)) + return GSS_C_NO_OID; + name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; + break; + case KEX_GSS_GEX_SHA1: + if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) + return GSS_C_NO_OID; + name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; + break; + default: + return GSS_C_NO_OID; + } + + while (gss_enc2oid[i].encoded != NULL && + strcmp(name, gss_enc2oid[i].encoded) != 0) + i++; + + if (gss_enc2oid[i].oid != NULL && ctx != NULL) + ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid); + + return gss_enc2oid[i].oid; +} + /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) @@ -197,7 +352,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, } ctx->major = gss_init_sec_context(&ctx->minor, - GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, + ctx->client_creds, &ctx->context, ctx->name, ctx->oid, GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); @@ -227,8 +382,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) } OM_uint32 +ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) +{ + gss_buffer_desc gssbuf; + gss_name_t gssname; + OM_uint32 status; + gss_OID_set oidset; + + gssbuf.value = (void *) name; + gssbuf.length = strlen(gssbuf.value); + + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); + + ctx->major = gss_import_name(&ctx->minor, &gssbuf, + GSS_C_NT_USER_NAME, &gssname); + + if (!ctx->major) + ctx->major = gss_acquire_cred(&ctx->minor, + gssname, 0, oidset, GSS_C_INITIATE, + &ctx->client_creds, NULL, NULL); + + gss_release_name(&status, &gssname); + gss_release_oid_set(&status, &oidset); + + if (ctx->major) + ssh_gssapi_error(ctx); + + return(ctx->major); +} + +OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) { + if (ctx == NULL) + return -1; + if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); @@ -236,6 +425,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) return (ctx->major); } +/* Priviledged when used by server */ +OM_uint32 +ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +{ + if (ctx == NULL) + return -1; + + ctx->major = gss_verify_mic(&ctx->minor, ctx->context, + gssbuf, gssmic, NULL); + + return (ctx->major); +} + void ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, const char *context) @@ -249,11 +451,16 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, } int -ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, + const char *client) { gss_buffer_desc token = GSS_C_EMPTY_BUFFER; OM_uint32 major, minor; gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"}; + Gssctxt *intctx = NULL; + + if (ctx == NULL) + ctx = &intctx; /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && @@ -263,6 +470,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); + + if (!GSS_ERROR(major) && client) + major = ssh_gssapi_client_identity(*ctx, client); + if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); @@ -272,10 +483,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) GSS_C_NO_BUFFER); } - if (GSS_ERROR(major)) + if (GSS_ERROR(major) || intctx != NULL) ssh_gssapi_delete_ctx(ctx); return (!GSS_ERROR(major)); } +int +ssh_gssapi_credentials_updated(Gssctxt *ctxt) { + static gss_name_t saved_name = GSS_C_NO_NAME; + static OM_uint32 saved_lifetime = 0; + static gss_OID saved_mech = GSS_C_NO_OID; + static gss_name_t name; + static OM_uint32 last_call = 0; + OM_uint32 lifetime, now, major, minor; + int equal; + + now = time(NULL); + + if (ctxt) { + debug("Rekey has happened - updating saved versions"); + + if (saved_name != GSS_C_NO_NAME) + gss_release_name(&minor, &saved_name); + + major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, + &saved_name, &saved_lifetime, NULL, NULL); + + if (!GSS_ERROR(major)) { + saved_mech = ctxt->oid; + saved_lifetime+= now; + } else { + /* Handle the error */ + } + return 0; + } + + if (now - last_call < 10) + return 0; + + last_call = now; + + if (saved_mech == GSS_C_NO_OID) + return 0; + + major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, + &name, &lifetime, NULL, NULL); + if (major == GSS_S_CREDENTIALS_EXPIRED) + return 0; + else if (GSS_ERROR(major)) + return 0; + + major = gss_compare_name(&minor, saved_name, name, &equal); + gss_release_name(&minor, &name); + if (GSS_ERROR(major)) + return 0; + + if (equal && (saved_lifetime < lifetime + now - 10)) + return 1; + + return 0; +} + #endif /* GSSAPI */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c index 759fa10..e678a27 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv-krb5.c,v 1.8 2013/07/20 01:55:13 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -120,8 +120,8 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; - int len; const char *errmsg; + const char *new_ccname; if (client->creds == NULL) { debug("No credentials stored"); @@ -180,11 +180,16 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) return; } - client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); + new_ccname = krb5_cc_get_name(krb_context, ccache); + client->store.envvar = "KRB5CCNAME"; - len = strlen(client->store.filename) + 6; - client->store.envval = xmalloc(len); - snprintf(client->store.envval, len, "FILE:%s", client->store.filename); +#ifdef USE_CCAPI + xasprintf(&client->store.envval, "API:%s", new_ccname); + client->store.filename = NULL; +#else + xasprintf(&client->store.envval, "FILE:%s", new_ccname); + client->store.filename = xstrdup(new_ccname); +#endif #ifdef USE_PAM if (options.use_pam) @@ -196,6 +201,71 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) return; } +int +ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, + ssh_gssapi_client *client) +{ + krb5_ccache ccache = NULL; + krb5_principal principal = NULL; + char *name = NULL; + krb5_error_code problem; + OM_uint32 maj_status, min_status; + + if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { + logit("krb5_cc_resolve(): %.100s", + krb5_get_err_text(krb_context, problem)); + return 0; + } + + /* Find out who the principal in this cache is */ + if ((problem = krb5_cc_get_principal(krb_context, ccache, + &principal))) { + logit("krb5_cc_get_principal(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_cc_close(krb_context, ccache); + return 0; + } + + if ((problem = krb5_unparse_name(krb_context, principal, &name))) { + logit("krb5_unparse_name(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_free_principal(krb_context, principal); + krb5_cc_close(krb_context, ccache); + return 0; + } + + + if (strcmp(name,client->exportedname.value)!=0) { + debug("Name in local credentials cache differs. Not storing"); + krb5_free_principal(krb_context, principal); + krb5_cc_close(krb_context, ccache); + krb5_free_unparsed_name(krb_context, name); + return 0; + } + krb5_free_unparsed_name(krb_context, name); + + /* Name matches, so lets get on with it! */ + + if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { + logit("krb5_cc_initialize(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_free_principal(krb_context, principal); + krb5_cc_close(krb_context, ccache); + return 0; + } + + krb5_free_principal(krb_context, principal); + + if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, + ccache))) { + logit("gss_krb5_copy_ccache() failed. Sorry!"); + krb5_cc_close(krb_context, ccache); + return 0; + } + + return 1; +} + ssh_gssapi_mech gssapi_kerberos_mech = { "toWM5Slw5Ew8Mqkay+al2g==", "Kerberos", @@ -203,7 +273,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { NULL, &ssh_gssapi_krb5_userok, NULL, - &ssh_gssapi_krb5_storecreds + &ssh_gssapi_krb5_storecreds, + &ssh_gssapi_krb5_updatecreds }; #endif /* KRB5 */ diff --git a/gss-serv.c b/gss-serv.c index e61b37b..0639049 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,15 +45,21 @@ #include "channels.h" #include "session.h" #include "misc.h" +#include "servconf.h" +#include "uidswap.h" #include "ssh-gss.h" +#include "monitor_wrap.h" + +extern ServerOptions options; static ssh_gssapi_client gssapi_client = { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, - GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; + GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, NULL, + {NULL, NULL, NULL, NULL, NULL}, 0, 0}; ssh_gssapi_mech gssapi_null_mech = - { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; + { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; @@ -100,25 +106,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) char lname[MAXHOSTNAMELEN]; gss_OID_set oidset; - gss_create_empty_oid_set(&status, &oidset); - gss_add_oid_set_member(&status, ctx->oid, &oidset); + if (options.gss_strict_acceptor) { + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); - if (gethostname(lname, MAXHOSTNAMELEN)) { - gss_release_oid_set(&status, &oidset); - return (-1); - } + if (gethostname(lname, MAXHOSTNAMELEN)) { + gss_release_oid_set(&status, &oidset); + return (-1); + } + + if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { + gss_release_oid_set(&status, &oidset); + return (ctx->major); + } + + if ((ctx->major = gss_acquire_cred(&ctx->minor, + ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, + NULL, NULL))) + ssh_gssapi_error(ctx); - if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { gss_release_oid_set(&status, &oidset); return (ctx->major); + } else { + ctx->name = GSS_C_NO_NAME; + ctx->creds = GSS_C_NO_CREDENTIAL; } - - if ((ctx->major = gss_acquire_cred(&ctx->minor, - ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) - ssh_gssapi_error(ctx); - - gss_release_oid_set(&status, &oidset); - return (ctx->major); + return GSS_S_COMPLETE; } /* Privileged */ @@ -133,6 +146,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) } /* Unprivileged */ +char * +ssh_gssapi_server_mechanisms(void) +{ + if (supported_oids == NULL) + ssh_gssapi_prepare_supported_oids(); + return (ssh_gssapi_kex_mechs(supported_oids, + &ssh_gssapi_server_check_mech, NULL, NULL)); +} + +/* Unprivileged */ +int +ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, + const char *dummy) { + Gssctxt *ctx = NULL; + int res; + + res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); + ssh_gssapi_delete_ctx(&ctx); + + return (res); +} + +/* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) { @@ -142,7 +178,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); - gss_indicate_mechs(&min_status, &supported); + + if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) + return; while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, @@ -268,8 +306,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; + int equal = 0; + gss_name_t new_name = GSS_C_NO_NAME; + gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; + + if (options.gss_store_rekey && client->used && ctx->client_creds) { + if (client->mech->oid.length != ctx->oid->length || + (memcmp(client->mech->oid.elements, + ctx->oid->elements, ctx->oid->length) !=0)) { + debug("Rekeyed credentials have different mechanism"); + return GSS_S_COMPLETE; + } + + if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, + ctx->client_creds, ctx->oid, &new_name, + NULL, NULL, NULL))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } - gss_buffer_desc ename; + ctx->major = gss_compare_name(&ctx->minor, client->name, + new_name, &equal); + + if (GSS_ERROR(ctx->major)) { + ssh_gssapi_error(ctx); + return (ctx->major); + } + + if (!equal) { + debug("Rekeyed credentials have different name"); + return GSS_S_COMPLETE; + } + + debug("Marking rekeyed credentials for export"); + + gss_release_name(&ctx->minor, &client->name); + gss_release_cred(&ctx->minor, &client->creds); + client->name = new_name; + client->creds = ctx->client_creds; + ctx->client_creds = GSS_C_NO_CREDENTIAL; + client->updated = 1; + return GSS_S_COMPLETE; + } client->mech = NULL; @@ -284,6 +362,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) if (client->mech == NULL) return GSS_S_FAILURE; + if (ctx->client_creds && + (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, + ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } + if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); @@ -301,6 +386,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) return (ctx->major); } + gss_release_buffer(&ctx->minor, &ename); + /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; @@ -348,7 +435,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) /* Privileged */ int -ssh_gssapi_userok(char *user) +ssh_gssapi_userok(char *user, struct passwd *pw) { OM_uint32 lmin; @@ -358,9 +445,11 @@ ssh_gssapi_userok(char *user) return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) - if ((*gssapi_client.mech->userok)(&gssapi_client, user)) + if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { + gssapi_client.used = 1; + gssapi_client.store.owner = pw; return 1; - else { + } else { /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); @@ -374,14 +463,90 @@ ssh_gssapi_userok(char *user) return (0); } -/* Privileged */ -OM_uint32 -ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +/* These bits are only used for rekeying. The unpriviledged child is running + * as the user, the monitor is root. + * + * In the child, we want to : + * *) Ask the monitor to store our credentials into the store we specify + * *) If it succeeds, maybe do a PAM update + */ + +/* Stuff for PAM */ + +#ifdef USE_PAM +static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { - ctx->major = gss_verify_mic(&ctx->minor, ctx->context, - gssbuf, gssmic, NULL); + return (PAM_CONV_ERR); +} +#endif - return (ctx->major); +void +ssh_gssapi_rekey_creds(void) { + int ok; + int ret; +#ifdef USE_PAM + pam_handle_t *pamh = NULL; + struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; + char *envstr; +#endif + + if (gssapi_client.store.filename == NULL && + gssapi_client.store.envval == NULL && + gssapi_client.store.envvar == NULL) + return; + + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); + + if (!ok) + return; + + debug("Rekeyed credentials stored successfully"); + + /* Actually managing to play with the ssh pam stack from here will + * be next to impossible. In any case, we may want different options + * for rekeying. So, use our own :) + */ +#ifdef USE_PAM + if (!use_privsep) { + debug("Not even going to try and do PAM with privsep disabled"); + return; + } + + ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name, + &pamconv, &pamh); + if (ret) + return; + + xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, + gssapi_client.store.envval); + + ret = pam_putenv(pamh, envstr); + if (!ret) + pam_setcred(pamh, PAM_REINITIALIZE_CRED); + pam_end(pamh, PAM_SUCCESS); +#endif +} + +int +ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { + int ok = 0; + + /* Check we've got credentials to store */ + if (!gssapi_client.updated) + return 0; + + gssapi_client.updated = 0; + + temporarily_use_uid(gssapi_client.store.owner); + if (gssapi_client.mech && gssapi_client.mech->updatecreds) + ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); + else + debug("No update function for this mechanism"); + + restore_uid(); + + return ok; } #endif diff --git a/kex.c b/kex.c index 74e2b86..d114ee3 100644 --- a/kex.c +++ b/kex.c @@ -51,6 +51,10 @@ #include "roaming.h" #include "digest.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) # define evp_ssh_sha256 EVP_sha256 @@ -92,6 +96,14 @@ static const struct kexalg kexalgs[] = { #endif { NULL, -1, -1, -1}, }; +static const struct kexalg kexalg_prefixes[] = { +#ifdef GSSAPI + { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, +#endif + { NULL, -1, -1, -1 }, +}; char * kex_alg_list(char sep) @@ -120,6 +132,10 @@ kex_alg_by_name(const char *name) if (strcmp(k->name, name) == 0) return k; } + for (k = kexalg_prefixes; k->name != NULL; k++) { + if (strncmp(k->name, name, strlen(k->name)) == 0) + return k; + } return NULL; } diff --git a/kex.h b/kex.h index c85680e..ea698c4 100644 --- a/kex.h +++ b/kex.h @@ -76,6 +76,9 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, KEX_C25519_SHA256, + KEX_GSS_GRP1_SHA1, + KEX_GSS_GRP14_SHA1, + KEX_GSS_GEX_SHA1, KEX_MAX }; @@ -135,6 +138,12 @@ struct Kex { int flags; int hash_alg; int ec_nid; +#ifdef GSSAPI + int gss_deleg_creds; + int gss_trust_dns; + char *gss_host; + char *gss_client; +#endif char *client_version_string; char *server_version_string; int (*verify_host_key)(Key *); @@ -167,6 +176,11 @@ void kexecdh_server(Kex *); void kexc25519_client(Kex *); void kexc25519_server(Kex *); +#ifdef GSSAPI +void kexgss_client(Kex *); +void kexgss_server(Kex *); +#endif + void kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); diff --git a/kexgssc.c b/kexgssc.c new file mode 100644 index 0000000..92a31c5 --- /dev/null +++ b/kexgssc.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. 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" + +#ifdef GSSAPI + +#include "includes.h" + +#include +#include + +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "ssh2.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" + +#include "ssh-gss.h" + +void +kexgss_client(Kex *kex) { + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; + Gssctxt *ctxt; + OM_uint32 maj_status, min_status, ret_flags; + u_int klen, kout, slen = 0, hashlen, strlen; + DH *dh; + BIGNUM *dh_server_pub = NULL; + BIGNUM *shared_secret = NULL; + BIGNUM *p = NULL; + BIGNUM *g = NULL; + u_char *kbuf, *hash; + u_char *serverhostkey = NULL; + u_char *empty = ""; + char *msg; + int type = 0; + int first = 1; + int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; + + /* Initialise our GSSAPI world */ + ssh_gssapi_build_ctx(&ctxt); + if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) + == GSS_C_NO_OID) + fatal("Couldn't identify host exchange"); + + if (ssh_gssapi_import_name(ctxt, kex->gss_host)) + fatal("Couldn't import hostname"); + + if (kex->gss_client && + ssh_gssapi_client_identity(ctxt, kex->gss_client)) + fatal("Couldn't acquire client credentials"); + + switch (kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_GSS_GRP14_SHA1: + dh = dh_new_group14(); + break; + case KEX_GSS_GEX_SHA1: + debug("Doing group exchange\n"); + nbits = dh_estimate(kex->we_need * 8); + packet_start(SSH2_MSG_KEXGSS_GROUPREQ); + packet_put_int(min); + packet_put_int(nbits); + packet_put_int(max); + + packet_send(); + + packet_read_expect(SSH2_MSG_KEXGSS_GROUP); + + if ((p = BN_new()) == NULL) + fatal("BN_new() failed"); + packet_get_bignum2(p); + if ((g = BN_new()) == NULL) + fatal("BN_new() failed"); + packet_get_bignum2(g); + packet_check_eom(); + + if (BN_num_bits(p) < min || BN_num_bits(p) > max) + fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", + min, BN_num_bits(p), max); + + dh = dh_new_group(g, p); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + + /* Step 1 - e is dh->pub_key */ + dh_gen_key(dh, kex->we_need * 8); + + /* This is f, we initialise it now to make life easier */ + dh_server_pub = BN_new(); + if (dh_server_pub == NULL) + fatal("dh_server_pub == NULL"); + + token_ptr = GSS_C_NO_BUFFER; + + do { + debug("Calling gss_init_sec_context"); + + maj_status = ssh_gssapi_init_ctx(ctxt, + kex->gss_deleg_creds, token_ptr, &send_tok, + &ret_flags); + + if (GSS_ERROR(maj_status)) { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_KEXGSS_CONTINUE); + packet_put_string(send_tok.value, + send_tok.length); + } + fatal("gss_init_context failed"); + } + + /* If we've got an old receive buffer get rid of it */ + if (token_ptr != GSS_C_NO_BUFFER) + free(recv_tok.value); + + if (maj_status == GSS_S_COMPLETE) { + /* If mutual state flag is not true, kex fails */ + if (!(ret_flags & GSS_C_MUTUAL_FLAG)) + fatal("Mutual authentication failed"); + + /* If integ avail flag is not true kex fails */ + if (!(ret_flags & GSS_C_INTEG_FLAG)) + fatal("Integrity check failed"); + } + + /* + * If we have data to send, then the last message that we + * received cannot have been a 'complete'. + */ + if (send_tok.length != 0) { + if (first) { + packet_start(SSH2_MSG_KEXGSS_INIT); + packet_put_string(send_tok.value, + send_tok.length); + packet_put_bignum2(dh->pub_key); + first = 0; + } else { + packet_start(SSH2_MSG_KEXGSS_CONTINUE); + packet_put_string(send_tok.value, + send_tok.length); + } + packet_send(); + gss_release_buffer(&min_status, &send_tok); + + /* If we've sent them data, they should reply */ + do { + type = packet_read(); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { + debug("Received KEXGSS_HOSTKEY"); + if (serverhostkey) + fatal("Server host key received more than once"); + serverhostkey = + packet_get_string(&slen); + } + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); + + switch (type) { + case SSH2_MSG_KEXGSS_CONTINUE: + debug("Received GSSAPI_CONTINUE"); + if (maj_status == GSS_S_COMPLETE) + fatal("GSSAPI Continue received from server when complete"); + recv_tok.value = packet_get_string(&strlen); + recv_tok.length = strlen; + break; + case SSH2_MSG_KEXGSS_COMPLETE: + debug("Received GSSAPI_COMPLETE"); + packet_get_bignum2(dh_server_pub); + msg_tok.value = packet_get_string(&strlen); + msg_tok.length = strlen; + + /* Is there a token included? */ + if (packet_get_char()) { + recv_tok.value= + packet_get_string(&strlen); + recv_tok.length = strlen; + /* If we're already complete - protocol error */ + if (maj_status == GSS_S_COMPLETE) + packet_disconnect("Protocol error: received token when complete"); + } else { + /* No token included */ + if (maj_status != GSS_S_COMPLETE) + packet_disconnect("Protocol error: did not receive final token"); + } + break; + case SSH2_MSG_KEXGSS_ERROR: + debug("Received Error"); + maj_status = packet_get_int(); + min_status = packet_get_int(); + msg = packet_get_string(NULL); + (void) packet_get_string_ptr(NULL); + fatal("GSSAPI Error: \n%.400s",msg); + default: + packet_disconnect("Protocol error: didn't expect packet type %d", + type); + } + token_ptr = &recv_tok; + } else { + /* No data, and not complete */ + if (maj_status != GSS_S_COMPLETE) + fatal("Not complete, and no token output"); + } + } while (maj_status & GSS_S_CONTINUE_NEEDED); + + /* + * We _must_ have received a COMPLETE message in reply from the + * server, which will have set dh_server_pub and msg_tok + */ + + if (type != SSH2_MSG_KEXGSS_COMPLETE) + fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); + + /* Check f in range [1, p-1] */ + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + /* compute K=f^x mod p */ + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); + if (kout < 0) + fatal("DH_compute_key: failed"); + + shared_secret = BN_new(); + if (shared_secret == NULL) + fatal("kexgss_client: BN_new failed"); + + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexdh_client: BN_bin2bn failed"); + + memset(kbuf, 0, klen); + free(kbuf); + + switch (kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: + kex_dh_hash( kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + dh->pub_key, /* e */ + dh_server_pub, /* f */ + shared_secret, /* K */ + &hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: + kexgex_hash( + kex->hash_alg, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + (serverhostkey ? serverhostkey : empty), slen, + min, nbits, max, + dh->p, dh->g, + dh->pub_key, + dh_server_pub, + shared_secret, + &hash, &hashlen + ); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + + gssbuf.value = hash; + gssbuf.length = hashlen; + + /* Verify that the hash matches the MIC we just got. */ + if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) + packet_disconnect("Hash's MIC didn't verify"); + + free(msg_tok.value); + + DH_free(dh); + free(serverhostkey); + BN_clear_free(dh_server_pub); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + if (kex->gss_deleg_creds) + ssh_gssapi_credentials_updated(ctxt); + + if (gss_kex_context == NULL) + gss_kex_context = ctxt; + else + ssh_gssapi_delete_ctx(&ctxt); + + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} + +#endif /* GSSAPI */ diff --git a/kexgsss.c b/kexgsss.c new file mode 100644 index 0000000..8095259 --- /dev/null +++ b/kexgsss.c @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. 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" + +#ifdef GSSAPI + +#include + +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "ssh2.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh-gss.h" +#include "monitor_wrap.h" +#include "servconf.h" + +extern ServerOptions options; + +void +kexgss_server(Kex *kex) +{ + OM_uint32 maj_status, min_status; + + /* + * Some GSSAPI implementations use the input value of ret_flags (an + * output variable) as a means of triggering mechanism specific + * features. Initializing it to zero avoids inadvertently + * activating this non-standard behaviour. + */ + + OM_uint32 ret_flags = 0; + gss_buffer_desc gssbuf, recv_tok, msg_tok; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + Gssctxt *ctxt = NULL; + u_int slen, klen, kout, hashlen; + u_char *kbuf, *hash; + DH *dh; + int min = -1, max = -1, nbits = -1; + BIGNUM *shared_secret = NULL; + BIGNUM *dh_client_pub = NULL; + int type = 0; + gss_OID oid; + char *mechs; + + /* Initialise GSSAPI */ + + /* If we're rekeying, privsep means that some of the private structures + * in the GSSAPI code are no longer available. This kludges them back + * into life + */ + if (!ssh_gssapi_oid_table_ok()) { + mechs = ssh_gssapi_server_mechanisms(); + free(mechs); + } + + debug2("%s: Identifying %s", __func__, kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + + debug2("%s: Acquiring credentials", __func__); + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); + + switch (kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_GSS_GRP14_SHA1: + dh = dh_new_group14(); + break; + case KEX_GSS_GEX_SHA1: + debug("Doing group exchange"); + packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); + min = packet_get_int(); + nbits = packet_get_int(); + max = packet_get_int(); + min = MAX(DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); + packet_check_eom(); + if (max < min || nbits < min || max < nbits) + fatal("GSS_GEX, bad parameters: %d !< %d !< %d", + min, nbits, max); + dh = PRIVSEP(choose_dh(min, nbits, max)); + if (dh == NULL) + packet_disconnect("Protocol error: no matching group found"); + + packet_start(SSH2_MSG_KEXGSS_GROUP); + packet_put_bignum2(dh->p); + packet_put_bignum2(dh->g); + packet_send(); + + packet_write_wait(); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + + dh_gen_key(dh, kex->we_need * 8); + + do { + debug("Wait SSH2_MSG_GSSAPI_INIT"); + type = packet_read(); + switch(type) { + case SSH2_MSG_KEXGSS_INIT: + if (dh_client_pub != NULL) + fatal("Received KEXGSS_INIT after initialising"); + recv_tok.value = packet_get_string(&slen); + recv_tok.length = slen; + + if ((dh_client_pub = BN_new()) == NULL) + fatal("dh_client_pub == NULL"); + + packet_get_bignum2(dh_client_pub); + + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ + break; + case SSH2_MSG_KEXGSS_CONTINUE: + recv_tok.value = packet_get_string(&slen); + recv_tok.length = slen; + break; + default: + packet_disconnect( + "Protocol error: didn't expect packet type %d", + type); + } + + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, + &send_tok, &ret_flags)); + + free(recv_tok.value); + + if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) + fatal("Zero length token output when incomplete"); + + if (dh_client_pub == NULL) + fatal("No client public key"); + + if (maj_status & GSS_S_CONTINUE_NEEDED) { + debug("Sending GSSAPI_CONTINUE"); + packet_start(SSH2_MSG_KEXGSS_CONTINUE); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&min_status, &send_tok); + } + } while (maj_status & GSS_S_CONTINUE_NEEDED); + + if (GSS_ERROR(maj_status)) { + if (send_tok.length > 0) { + packet_start(SSH2_MSG_KEXGSS_CONTINUE); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + } + fatal("accept_ctx died"); + } + + if (!(ret_flags & GSS_C_MUTUAL_FLAG)) + fatal("Mutual Authentication flag wasn't set"); + + if (!(ret_flags & GSS_C_INTEG_FLAG)) + fatal("Integrity flag wasn't set"); + + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); + if (kout < 0) + fatal("DH_compute_key: failed"); + + shared_secret = BN_new(); + if (shared_secret == NULL) + fatal("kexgss_server: BN_new failed"); + + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexgss_server: BN_bin2bn failed"); + + memset(kbuf, 0, klen); + free(kbuf); + + switch (kex->kex_type) { + case KEX_GSS_GRP1_SHA1: + case KEX_GSS_GRP14_SHA1: + kex_dh_hash( + kex->client_version_string, kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + NULL, 0, /* Change this if we start sending host keys */ + dh_client_pub, dh->pub_key, shared_secret, + &hash, &hashlen + ); + break; + case KEX_GSS_GEX_SHA1: + kexgex_hash( + kex->hash_alg, + kex->client_version_string, kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + NULL, 0, + min, nbits, max, + dh->p, dh->g, + dh_client_pub, + dh->pub_key, + shared_secret, + &hash, &hashlen + ); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + + BN_clear_free(dh_client_pub); + + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + gssbuf.value = hash; + gssbuf.length = hashlen; + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) + fatal("Couldn't get MIC"); + + packet_start(SSH2_MSG_KEXGSS_COMPLETE); + packet_put_bignum2(dh->pub_key); + packet_put_string(msg_tok.value,msg_tok.length); + + if (send_tok.length != 0) { + packet_put_char(1); /* true */ + packet_put_string(send_tok.value, send_tok.length); + } else { + packet_put_char(0); /* false */ + } + packet_send(); + + gss_release_buffer(&min_status, &send_tok); + gss_release_buffer(&min_status, &msg_tok); + + if (gss_kex_context == NULL) + gss_kex_context = ctxt; + else + ssh_gssapi_delete_ctx(&ctxt); + + DH_free(dh); + + kex_derive_keys_bn(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); + + /* If this was a rekey, then save out any delegated credentials we + * just exchanged. */ + if (options.gss_store_rekey) + ssh_gssapi_rekey_creds(); +} +#endif /* GSSAPI */ diff --git a/key.c b/key.c index 168e1b7..3d640e7 100644 --- a/key.c +++ b/key.c @@ -985,6 +985,7 @@ static const struct keytype keytypes[] = { KEY_DSA_CERT_V00, 0, 1 }, { "ssh-ed25519-cert-v01 at openssh.com", "ED25519-CERT", KEY_ED25519_CERT, 0, 1 }, + { "null", "null", KEY_NULL, 0, 0 }, { NULL, NULL, -1, -1, 0 } }; @@ -1063,7 +1064,7 @@ key_alg_list(int certs_only, int plain_only) const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { - if (kt->name == NULL) + if (kt->name == NULL || kt->type == KEY_NULL) continue; if ((certs_only && !kt->cert) || (plain_only && kt->cert)) continue; diff --git a/key.h b/key.h index d8ad13d..c8aeba2 100644 --- a/key.h +++ b/key.h @@ -46,6 +46,7 @@ enum types { KEY_ED25519_CERT, KEY_RSA_CERT_V00, KEY_DSA_CERT_V00, + KEY_NULL, KEY_UNSPEC }; enum fp_type { diff --git a/monitor.c b/monitor.c index 531c4f9..2918814 100644 --- a/monitor.c +++ b/monitor.c @@ -175,6 +175,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *); int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); +int mm_answer_gss_sign(int, Buffer *); +int mm_answer_gss_updatecreds(int, Buffer *); #endif #ifdef SSH_AUDIT_EVENTS @@ -247,11 +249,18 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, + {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, #endif {0, 0, NULL} }; struct mon_table mon_dispatch_postauth20[] = { +#ifdef GSSAPI + {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, + {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, + {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, + {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, +#endif {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, {MONITOR_REQ_SIGN, 0, mm_answer_sign}, {MONITOR_REQ_PTY, 0, mm_answer_pty}, @@ -360,6 +369,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); +#ifdef GSSAPI + /* and for the GSSAPI key exchange */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); +#endif } else { mon_dispatch = mon_dispatch_proto15; @@ -465,6 +478,10 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); +#ifdef GSSAPI + /* and for the GSSAPI key exchange */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); +#endif } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1834,6 +1851,13 @@ mm_get_kex(Buffer *m) kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; kex->kex[KEX_C25519_SHA256] = kexc25519_server; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; + } +#endif kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); @@ -2041,6 +2065,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) OM_uint32 major; u_int len; + if (!options.gss_authentication && !options.gss_keyex) + fatal("In GSSAPI monitor when GSSAPI is disabled"); + goid.elements = buffer_get_string(m, &len); goid.length = len; @@ -2068,6 +2095,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) OM_uint32 flags = 0; /* GSI needs this */ u_int len; + if (!options.gss_authentication && !options.gss_keyex) + fatal("In GSSAPI monitor when GSSAPI is disabled"); + in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); @@ -2085,6 +2115,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1); } return (0); } @@ -2096,6 +2127,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) OM_uint32 ret; u_int len; + if (!options.gss_authentication && !options.gss_keyex) + fatal("In GSSAPI monitor when GSSAPI is disabled"); + gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); @@ -2122,7 +2156,11 @@ mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + if (!options.gss_authentication && !options.gss_keyex) + fatal("In GSSAPI monitor when GSSAPI is disabled"); + + authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw); buffer_clear(m); buffer_put_int(m, authenticated); @@ -2135,5 +2173,73 @@ mm_answer_gss_userok(int sock, Buffer *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } + +int +mm_answer_gss_sign(int socket, Buffer *m) +{ + gss_buffer_desc data; + gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; + OM_uint32 major, minor; + u_int len; + + if (!options.gss_authentication && !options.gss_keyex) + fatal("In GSSAPI monitor when GSSAPI is disabled"); + + data.value = buffer_get_string(m, &len); + data.length = len; + if (data.length != 20) + fatal("%s: data length incorrect: %d", __func__, + (int) data.length); + + /* Save the session ID on the first time around */ + if (session_id2_len == 0) { + session_id2_len = data.length; + session_id2 = xmalloc(session_id2_len); + memcpy(session_id2, data.value, session_id2_len); + } + major = ssh_gssapi_sign(gsscontext, &data, &hash); + + free(data.value); + + buffer_clear(m); + buffer_put_int(m, major); + buffer_put_string(m, hash.value, hash.length); + + mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); + + gss_release_buffer(&minor, &hash); + + /* Turn on getpwnam permissions */ + monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); + + /* And credential updating, for when rekeying */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); + + return (0); +} + +int +mm_answer_gss_updatecreds(int socket, Buffer *m) { + ssh_gssapi_ccache store; + int ok; + + store.filename = buffer_get_string(m, NULL); + store.envvar = buffer_get_string(m, NULL); + store.envval = buffer_get_string(m, NULL); + + ok = ssh_gssapi_update_creds(&store); + + free(store.filename); + free(store.envvar); + free(store.envval); + + buffer_clear(m); + buffer_put_int(m, ok); + + mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); + + return(0); +} + #endif /* GSSAPI */ diff --git a/monitor.h b/monitor.h index 5bc41b5..7f32b0c 100644 --- a/monitor.h +++ b/monitor.h @@ -65,6 +65,9 @@ enum monitor_reqtype { MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, + MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, + MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, + }; struct mm_master; diff --git a/monitor_wrap.c b/monitor_wrap.c index 1a47e41..60b987d 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1271,7 +1271,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int -mm_ssh_gssapi_userok(char *user) +mm_ssh_gssapi_userok(char *user, struct passwd *pw) { Buffer m; int authenticated = 0; @@ -1288,5 +1288,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } + +OM_uint32 +mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) +{ + Buffer m; + OM_uint32 major; + u_int len; + + buffer_init(&m); + buffer_put_string(&m, data->value, data->length); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m); + + major = buffer_get_int(&m); + hash->value = buffer_get_string(&m, &len); + hash->length = len; + + buffer_free(&m); + + return(major); +} + +int +mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) +{ + Buffer m; + int ok; + + buffer_init(&m); + + buffer_put_cstring(&m, store->filename ? store->filename : ""); + buffer_put_cstring(&m, store->envvar ? store->envvar : ""); + buffer_put_cstring(&m, store->envval ? store->envval : ""); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m); + + ok = buffer_get_int(&m); + + buffer_free(&m); + + return (ok); +} + #endif /* GSSAPI */ diff --git a/monitor_wrap.h b/monitor_wrap.h index 18c2501..a4e9d24 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -58,8 +58,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); -int mm_ssh_gssapi_userok(char *user); +int mm_ssh_gssapi_userok(char *user, struct passwd *); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); +OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); +int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif #ifdef USE_PAM diff --git a/readconf.c b/readconf.c index dc884c9..7613ff2 100644 --- a/readconf.c +++ b/readconf.c @@ -141,6 +141,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, + oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, + oGssServerIdentity, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, @@ -183,10 +185,19 @@ static struct { { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, + { "gssapikeyexchange", oGssKeyEx }, { "gssapidelegatecredentials", oGssDelegateCreds }, + { "gssapitrustdns", oGssTrustDns }, + { "gssapiclientidentity", oGssClientIdentity }, + { "gssapiserveridentity", oGssServerIdentity }, + { "gssapirenewalforcesrekey", oGssRenewalRekey }, #else { "gssapiauthentication", oUnsupported }, + { "gssapikeyexchange", oUnsupported }, { "gssapidelegatecredentials", oUnsupported }, + { "gssapitrustdns", oUnsupported }, + { "gssapiclientidentity", oUnsupported }, + { "gssapirenewalforcesrekey", oUnsupported }, #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, @@ -841,10 +852,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; + case oGssKeyEx: + intptr = &options->gss_keyex; + goto parse_flag; + case oGssDelegateCreds: intptr = &options->gss_deleg_creds; goto parse_flag; + case oGssTrustDns: + intptr = &options->gss_trust_dns; + goto parse_flag; + + case oGssClientIdentity: + charptr = &options->gss_client_identity; + goto parse_string; + + case oGssServerIdentity: + charptr = &options->gss_server_identity; + goto parse_string; + + case oGssRenewalRekey: + intptr = &options->gss_renewal_rekey; + goto parse_flag; + case oBatchMode: intptr = &options->batch_mode; goto parse_flag; @@ -1497,7 +1528,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; + options->gss_keyex = -1; options->gss_deleg_creds = -1; + options->gss_trust_dns = -1; + options->gss_renewal_rekey = -1; + options->gss_client_identity = NULL; + options->gss_server_identity = NULL; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; @@ -1616,8 +1652,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; + if (options->gss_keyex == -1) + options->gss_keyex = 0; if (options->gss_deleg_creds == -1) options->gss_deleg_creds = 0; + if (options->gss_trust_dns == -1) + options->gss_trust_dns = 0; + if (options->gss_renewal_rekey == -1) + options->gss_renewal_rekey = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) diff --git a/readconf.h b/readconf.h index 75e3f8f..5cc97f0 100644 --- a/readconf.h +++ b/readconf.h @@ -54,7 +54,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ + int gss_keyex; /* Try GSS key exchange */ int gss_deleg_creds; /* Delegate GSS credentials */ + int gss_trust_dns; /* Trust DNS for GSS canonicalization */ + int gss_renewal_rekey; /* Credential renewal forces rekey */ + char *gss_client_identity; /* Principal to initiate GSSAPI with */ + char *gss_server_identity; /* GSSAPI target principal */ int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c index 7ba65d5..0083cf8 100644 --- a/servconf.c +++ b/servconf.c @@ -108,7 +108,10 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; + options->gss_keyex = -1; options->gss_cleanup_creds = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; @@ -244,8 +247,14 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; + if (options->gss_keyex == -1) + options->gss_keyex = 0; if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; + if (options->gss_strict_acceptor == -1) + options->gss_strict_acceptor = 1; + if (options->gss_store_rekey == -1) + options->gss_store_rekey = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -340,7 +349,9 @@ typedef enum { sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssStoreRekey, + sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, @@ -407,10 +418,20 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, + { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, #endif + { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, + { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, @@ -1086,10 +1107,22 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; + case sGssKeyEx: + intptr = &options->gss_keyex; + goto parse_flag; + case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; + case sGssStrictAcceptor: + intptr = &options->gss_strict_acceptor; + goto parse_flag; + + case sGssStoreRekey: + intptr = &options->gss_store_rekey; + goto parse_flag; + case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; @@ -1995,7 +2028,10 @@ dump_config(ServerOptions *o) #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); + dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h index 752d1c5..c922eb5 100644 --- a/servconf.h +++ b/servconf.h @@ -112,7 +112,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ + int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ + int gss_store_rekey; int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/ssh-gss.h b/ssh-gss.h index a99d7f0..914701b 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -1,6 +1,6 @@ /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -61,10 +61,22 @@ #define SSH_GSS_OIDTYPE 0x06 +#define SSH2_MSG_KEXGSS_INIT 30 +#define SSH2_MSG_KEXGSS_CONTINUE 31 +#define SSH2_MSG_KEXGSS_COMPLETE 32 +#define SSH2_MSG_KEXGSS_HOSTKEY 33 +#define SSH2_MSG_KEXGSS_ERROR 34 +#define SSH2_MSG_KEXGSS_GROUPREQ 40 +#define SSH2_MSG_KEXGSS_GROUP 41 +#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" +#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" +#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" + typedef struct { char *filename; char *envvar; char *envval; + struct passwd *owner; void *data; } ssh_gssapi_ccache; @@ -72,8 +84,11 @@ typedef struct { gss_buffer_desc displayname; gss_buffer_desc exportedname; gss_cred_id_t creds; + gss_name_t name; struct ssh_gssapi_mech_struct *mech; ssh_gssapi_ccache store; + int used; + int updated; } ssh_gssapi_client; typedef struct ssh_gssapi_mech_struct { @@ -84,6 +99,7 @@ typedef struct ssh_gssapi_mech_struct { int (*userok) (ssh_gssapi_client *, char *); int (*localname) (ssh_gssapi_client *, char **); void (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); } ssh_gssapi_mech; typedef struct { @@ -94,10 +110,11 @@ typedef struct { gss_OID oid; /* client */ gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ - gss_cred_id_t client_creds; /* server */ + gss_cred_id_t client_creds; /* both */ } Gssctxt; extern ssh_gssapi_mech *supported_mechs[]; +extern Gssctxt *gss_kex_context; int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); @@ -119,16 +136,32 @@ void ssh_gssapi_build_ctx(Gssctxt **); void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); -int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); +int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); +OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); +int ssh_gssapi_credentials_updated(Gssctxt *); /* In the server */ +typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, + const char *); +char *ssh_gssapi_client_mechanisms(const char *, const char *); +char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, + const char *); +gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); +int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, + const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); -int ssh_gssapi_userok(char *name); +int ssh_gssapi_userok(char *name, struct passwd *); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_do_child(char ***, u_int *); void ssh_gssapi_cleanup_creds(void); void ssh_gssapi_storecreds(void); +char *ssh_gssapi_server_mechanisms(void); +int ssh_gssapi_oid_table_ok(void); + +int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); +void ssh_gssapi_rekey_creds(void); + #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ diff --git a/ssh_config b/ssh_config index 03a228f..228e5ab 100644 --- a/ssh_config +++ b/ssh_config @@ -26,6 +26,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no # GSSAPIDelegateCredentials no +# GSSAPIKeyExchange no +# GSSAPITrustDNS no # BatchMode no # CheckHostIP yes # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 index b580392..e7accd6 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -682,11 +682,43 @@ Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . Note that this option applies to protocol version 2 only. +.It Cm GSSAPIKeyExchange +Specifies whether key exchange based on GSSAPI may be used. When using +GSSAPI key exchange the server need not have a host key. +The default is +.Dq no . +Note that this option applies to protocol version 2 only. +.It Cm GSSAPIClientIdentity +If set, specifies the GSSAPI client identity that ssh should use when +connecting to the server. The default is unset, which means that the default +identity will be used. +.It Cm GSSAPIServerIdentity +If set, specifies the GSSAPI server identity that ssh should expect when +connecting to the server. The default is unset, which means that the +expected GSSAPI server identity will be determined from the target +hostname. .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is .Dq no . -Note that this option applies to protocol version 2 only. +Note that this option applies to protocol version 2 connections using GSSAPI. +.It Cm GSSAPIRenewalForcesRekey +If set to +.Dq yes +then renewal of the client's GSSAPI credentials will force the rekeying of the +ssh connection. With a compatible server, this can delegate the renewed +credentials to a session on the server. +The default is +.Dq no . +.It Cm GSSAPITrustDns +Set to +.Dq yes to indicate that the DNS is trusted to securely canonicalize +the name of the host being connected to. If +.Dq no, the hostname entered on the +command line will be passed untouched to the GSSAPI library. +The default is +.Dq no . +This option only applies to protocol version 2 connections using GSSAPI. .It Cm HashKnownHosts Indicates that .Xr ssh 1 diff --git a/sshconnect2.c b/sshconnect2.c index 7f4ff41..66cb035 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -158,9 +158,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) { Kex *kex; +#ifdef GSSAPI + char *orig = NULL, *gss = NULL; + char *gss_host = NULL; +#endif + xxx_host = host; xxx_hostaddr = hostaddr; +#ifdef GSSAPI + if (options.gss_keyex) { + /* Add the GSSAPI mechanisms currently supported on this + * client to the key exchange algorithm proposal */ + orig = myproposal[PROPOSAL_KEX_ALGS]; + + if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(1); + else + gss_host = host; + + gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); + if (gss) { + debug("Offering GSSAPI proposal: %s", gss); + xasprintf(&myproposal[PROPOSAL_KEX_ALGS], + "%s,%s", gss, orig); + } + } +#endif + if (options.ciphers == (char *)-1) { logit("No valid ciphers for protocol version 2 given, using defaults."); options.ciphers = NULL; @@ -196,6 +221,17 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) if (options.kex_algorithms != NULL) myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; +#ifdef GSSAPI + /* If we've got GSSAPI algorithms, then we also support the + * 'null' hostkey, as a last resort */ + if (options.gss_keyex && gss) { + orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; + xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], + "%s,null", orig); + free(gss); + } +#endif + if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits((u_int32_t)options.rekey_limit, (time_t)options.rekey_interval); @@ -208,10 +244,30 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; kex->kex[KEX_ECDH_SHA2] = kexecdh_client; kex->kex[KEX_C25519_SHA256] = kexc25519_client; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; + } +#endif kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->gss_deleg_creds = options.gss_deleg_creds; + kex->gss_trust_dns = options.gss_trust_dns; + kex->gss_client = options.gss_client_identity; + if (options.gss_server_identity) { + kex->gss_host = options.gss_server_identity; + } else { + kex->gss_host = gss_host; + } + } +#endif + xxx_kex = kex; dispatch_run(DISPATCH_BLOCK, &kex->done, kex); @@ -301,6 +357,7 @@ void input_gssapi_token(int type, u_int32_t, void *); void input_gssapi_hash(int type, u_int32_t, void *); void input_gssapi_error(int, u_int32_t, void *); void input_gssapi_errtok(int, u_int32_t, void *); +int userauth_gsskeyex(Authctxt *authctxt); #endif void userauth(Authctxt *, char *); @@ -316,6 +373,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI + {"gssapi-keyex", + userauth_gsskeyex, + NULL, + &options.gss_authentication, + NULL}, {"gssapi-with-mic", userauth_gssapi, NULL, @@ -612,19 +674,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; + const char *gss_host; + + if (options.gss_server_identity) + gss_host = options.gss_server_identity; + else if (options.gss_trust_dns) + gss_host = get_canonical_hostname(1); + else + gss_host = authctxt->host; /* Try one GSSAPI method at a time, rather than sending them all at * once. */ if (gss_supported == NULL) - gss_indicate_mechs(&min, &gss_supported); + if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) { + gss_supported = NULL; + return 0; + } /* Check to see if the mechanism is usable before we offer it */ while (mech < gss_supported->count && !ok) { /* My DER encoding requires length<128 */ if (gss_supported->elements[mech].length < 128 && ssh_gssapi_check_mechanism(&gssctxt, - &gss_supported->elements[mech], authctxt->host)) { + &gss_supported->elements[mech], gss_host, + options.gss_client_identity)) { ok = 1; /* Mechanism works */ } else { mech++; @@ -721,8 +795,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; - int oidlen; - char *oidv; + u_int oidlen; + u_char *oidv; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); @@ -831,6 +905,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) free(msg); free(lang); } + +int +userauth_gsskeyex(Authctxt *authctxt) +{ + Buffer b; + gss_buffer_desc gssbuf; + gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; + OM_uint32 ms; + + static int attempt = 0; + if (attempt++ >= 1) + return (0); + + if (gss_kex_context == NULL) { + debug("No valid Key exchange context"); + return (0); + } + + ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, + "gssapi-keyex"); + + gssbuf.value = buffer_ptr(&b); + gssbuf.length = buffer_len(&b); + + if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { + buffer_free(&b); + return (0); + } + + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_string(mic.value, mic.length); + packet_send(); + + buffer_free(&b); + gss_release_buffer(&ms, &mic); + + return (1); +} + #endif /* GSSAPI */ int diff --git a/sshd.c b/sshd.c index 7523de9..34ebaa3 100644 --- a/sshd.c +++ b/sshd.c @@ -122,6 +122,10 @@ #include "ssh-sandbox.h" #include "version.h" +#ifdef USE_SECURITY_SESSION_API +#include +#endif + #ifdef LIBWRAP #include #include @@ -620,7 +624,7 @@ privsep_preauth_child(void) #ifdef GSSAPI /* Cache supported mechanism OIDs for later use */ - if (options.gss_authentication) + if (options.gss_authentication || options.gss_keyex) ssh_gssapi_prepare_supported_oids(); #endif @@ -1728,10 +1732,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } +#ifndef GSSAPI + /* The GSSAPI key exchange can run without a host key */ if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { logit("Disabling protocol version 2. Could not load host key"); options.protocol &= ~SSH_PROTO_2; } +#endif if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); @@ -2058,6 +2065,60 @@ main(int ac, char **av) remote_ip, remote_port, get_local_ipaddr(sock_in), get_local_port()); +#ifdef USE_SECURITY_SESSION_API + /* + * Create a new security session for use by the new user login if + * the current session is the root session or we are not launched + * by inetd (eg: debugging mode or server mode). We do not + * necessarily need to create a session if we are launched from + * inetd because Panther xinetd will create a session for us. + * + * The only case where this logic will fail is if there is an + * inetd running in a non-root session which is not creating + * new sessions for us. Then all the users will end up in the + * same session (bad). + * + * When the client exits, the session will be destroyed for us + * automatically. + * + * We must create the session before any credentials are stored + * (including AFS pags, which happens a few lines below). + */ + { + OSStatus err = 0; + SecuritySessionId sid = 0; + SessionAttributeBits sattrs = 0; + + err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); + if (err) + error("SessionGetInfo() failed with error %.8X", + (unsigned) err); + else + debug("Current Session ID is %.8X / Session Attributes are %.8X", + (unsigned) sid, (unsigned) sattrs); + + if (inetd_flag && !(sattrs & sessionIsRoot)) + debug("Running in inetd mode in a non-root session... " + "assuming inetd created the session for us."); + else { + debug("Creating new security session..."); + err = SessionCreate(0, sessionHasTTY | sessionIsRemote); + if (err) + error("SessionCreate() failed with error %.8X", + (unsigned) err); + + err = SessionGetInfo(callerSecuritySession, &sid, + &sattrs); + if (err) + error("SessionGetInfo() failed with error %.8X", + (unsigned) err); + else + debug("New Session ID is %.8X / Session Attributes are %.8X", + (unsigned) sid, (unsigned) sattrs); + } + } +#endif + /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is @@ -2469,6 +2530,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); +#ifdef GSSAPI + { + char *orig; + char *gss = NULL; + char *newstr = NULL; + orig = myproposal[PROPOSAL_KEX_ALGS]; + + /* + * If we don't have a host key, then there's no point advertising + * the other key exchange algorithms + */ + + if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) + orig = NULL; + + if (options.gss_keyex) + gss = ssh_gssapi_server_mechanisms(); + else + gss = NULL; + + if (gss && orig) + xasprintf(&newstr, "%s,%s", gss, orig); + else if (gss) + newstr = gss; + else if (orig) + newstr = orig; + + /* + * If we've got GSSAPI mechanisms, then we've got the 'null' host + * key alg, but we can't tell people about it unless its the only + * host key algorithm we support + */ + if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; + + if (newstr) + myproposal[PROPOSAL_KEX_ALGS] = newstr; + else + fatal("No supported key exchange algorithms"); + } +#endif + /* start key exchange */ kex = kex_setup(myproposal); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; @@ -2477,6 +2580,13 @@ do_ssh2_kex(void) kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; kex->kex[KEX_C25519_SHA256] = kexc25519_server; +#ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; + } +#endif kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; diff --git a/sshd_config b/sshd_config index e9045bc..d9b8594 100644 --- a/sshd_config +++ b/sshd_config @@ -84,6 +84,8 @@ AuthorizedKeysFile .ssh/authorized_keys # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes +#GSSAPIStrictAcceptorCheck yes +#GSSAPIKeyExchange no # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --git a/sshd_config.5 b/sshd_config.5 index ce71efe..ceed88a 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -493,12 +493,40 @@ Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . Note that this option applies to protocol version 2 only. +.It Cm GSSAPIKeyExchange +Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange +doesn't rely on ssh keys to verify host identity. +The default is +.Dq no . +Note that this option applies to protocol version 2 only. .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. The default is .Dq yes . Note that this option applies to protocol version 2 only. +.It Cm GSSAPIStrictAcceptorCheck +Determines whether to be strict about the identity of the GSSAPI acceptor +a client authenticates against. If +.Dq yes +then the client must authenticate against the +.Pa host +service on the current hostname. If +.Dq no +then the client may authenticate against any service key stored in the +machine's default store. This facility is provided to assist with operation +on multi homed machines. +The default is +.Dq yes . +Note that this option applies only to protocol version 2 GSSAPI connections, +and setting it to +.Dq no +may only work with recent Kerberos GSSAPI libraries. +.It Cm GSSAPIStoreCredentialsOnRekey +Controls whether the user's GSSAPI credentials should be updated following a +successful connection rekeying. This option can be used to accepted renewed +or updated credentials from a compatible client. The default is +.Dq no . .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed From djm at mindrot.org Wed Jul 16 09:18:02 2014 From: djm at mindrot.org (Damien Miller) Date: Wed, 16 Jul 2014 09:18:02 +1000 (EST) Subject: missing HAVE_EVP_RIPEMD160 breaks ssh client In-Reply-To: <53C541F1.8050104@redhat.com> References: <53C541F1.8050104@redhat.com> Message-ID: On Tue, 15 Jul 2014, Petr Lautrbach wrote: > Hello, > > I've updated sources but forgot to recreate configure so I've ended without > #define HAVE_EVP_RIPEMD160 1 > > and ssh client ended with: > > OpenSSH_6.7p1, OpenSSL 1.0.1h-fips 5 Jun 2014 > debug1: Reading configuration data ssh.config > main: mux digest failed > > The problem was that ssh_digest_by_alg() couldn't verify alg with an index bigger than 1 since > the line with SSH_DIGEST_RIPEMD160 wasn't compiled in and all indexes in the ssh_digest digests array > was lowered by one. > > /* NB. Indexed directly by algorithm number */ > const struct ssh_digest digests[] = { > { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, > #ifdef HAVE_EVP_RIPEMD160 /* XXX replace with local if missing */ > { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 }, > #endif > { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, > ... Try this: Index: digest-openssl.c =================================================================== RCS file: /var/cvs/openssh/digest-openssl.c,v retrieving revision 1.5 diff -u -p -r1.5 digest-openssl.c --- digest-openssl.c 3 Jul 2014 11:23:25 -0000 1.5 +++ digest-openssl.c 15 Jul 2014 23:16:30 -0000 @@ -30,6 +30,15 @@ #include "digest.h" #include "ssherr.h" +#ifndef HAVE_EVP_RIPEMD160 +# define EVP_ripemd160 NULL +#endif /* HAVE_EVP_RIPEMD160 */ +#ifndef HAVE_EVP_SHA256 +# define EVP_sha256 NULL +# define EVP_sha384 NULL +# define EVP_sha512 NULL +#endif /* HAVE_EVP_SHA256 */ + struct ssh_digest_ctx { int alg; EVP_MD_CTX mdctx; @@ -45,15 +54,11 @@ struct ssh_digest { /* NB. Indexed directly by algorithm number */ const struct ssh_digest digests[] = { { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, -#ifdef HAVE_EVP_RIPEMD160 /* XXX replace with local if missing */ { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 }, -#endif { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, -#ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, -#endif { -1, NULL, 0, NULL }, }; @@ -63,6 +68,8 @@ ssh_digest_by_alg(int alg) if (alg < 0 || alg >= SSH_DIGEST_MAX) return NULL; if (digests[alg].id != alg) /* sanity */ + return NULL; + if (digests[alg].mdfunc == NULL) return NULL; return &(digests[alg]); } From coy.hile at coyhile.com Wed Jul 16 19:05:26 2014 From: coy.hile at coyhile.com (Coy Hile) Date: Wed, 16 Jul 2014 05:05:26 -0400 Subject: GSSAPI In-Reply-To: References: Message-ID: On Jul 15, 2014, at 5:52 PM, Scott Neugroschl wrote: > If I am trying to build OpenSSH 6.6 with Kerberos GSSAPI support, do I still need to get Simon Wilkinson's patches? > If you want GSSAPI KeyExchange, then yes. Personally it baffles me that those particular laches haven?t been accepted upstream, but I?m sure djm has what he considers good reasons. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2251 bytes Desc: not available URL: From plautrba at redhat.com Wed Jul 16 23:05:53 2014 From: plautrba at redhat.com (Petr Lautrbach) Date: Wed, 16 Jul 2014 15:05:53 +0200 Subject: missing HAVE_EVP_RIPEMD160 breaks ssh client In-Reply-To: References: <53C541F1.8050104@redhat.com> Message-ID: <20140716130551.GA31693@hulk.local> On Wed, Jul 16, 2014 at 09:18:02AM +1000, Damien Miller wrote: > On Tue, 15 Jul 2014, Petr Lautrbach wrote: > > > Hello, > > > > I've updated sources but forgot to recreate configure so I've ended without > > #define HAVE_EVP_RIPEMD160 1 > > > > and ssh client ended with: > > > > OpenSSH_6.7p1, OpenSSL 1.0.1h-fips 5 Jun 2014 > > debug1: Reading configuration data ssh.config > > main: mux digest failed > > > > The problem was that ssh_digest_by_alg() couldn't verify alg with an index bigger than 1 since > > the line with SSH_DIGEST_RIPEMD160 wasn't compiled in and all indexes in the ssh_digest digests array > > was lowered by one. > > > > /* NB. Indexed directly by algorithm number */ > > const struct ssh_digest digests[] = { > > { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, > > #ifdef HAVE_EVP_RIPEMD160 /* XXX replace with local if missing */ > > { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 }, > > #endif > > { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, > > ... > > Try this: It works, thanks. Petr > Index: digest-openssl.c > =================================================================== > RCS file: /var/cvs/openssh/digest-openssl.c,v > retrieving revision 1.5 > diff -u -p -r1.5 digest-openssl.c > --- digest-openssl.c 3 Jul 2014 11:23:25 -0000 1.5 > +++ digest-openssl.c 15 Jul 2014 23:16:30 -0000 > @@ -30,6 +30,15 @@ > #include "digest.h" > #include "ssherr.h" > > +#ifndef HAVE_EVP_RIPEMD160 > +# define EVP_ripemd160 NULL > +#endif /* HAVE_EVP_RIPEMD160 */ > +#ifndef HAVE_EVP_SHA256 > +# define EVP_sha256 NULL > +# define EVP_sha384 NULL > +# define EVP_sha512 NULL > +#endif /* HAVE_EVP_SHA256 */ > + > struct ssh_digest_ctx { > int alg; > EVP_MD_CTX mdctx; > @@ -45,15 +54,11 @@ struct ssh_digest { > /* NB. Indexed directly by algorithm number */ > const struct ssh_digest digests[] = { > { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, > -#ifdef HAVE_EVP_RIPEMD160 /* XXX replace with local if missing */ > { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 }, > -#endif > { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, > -#ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */ > { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, > { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, > { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, > -#endif > { -1, NULL, 0, NULL }, > }; > > @@ -63,6 +68,8 @@ ssh_digest_by_alg(int alg) > if (alg < 0 || alg >= SSH_DIGEST_MAX) > return NULL; > if (digests[alg].id != alg) /* sanity */ > + return NULL; > + if (digests[alg].mdfunc == NULL) > return NULL; > return &(digests[alg]); > } From openssh at stormcloud9.net Wed Jul 16 23:11:01 2014 From: openssh at stormcloud9.net (Patrick Hemmer) Date: Wed, 16 Jul 2014 09:11:01 -0400 Subject: Usefulness of randomart for user keys? Message-ID: <53C679E5.6020304@stormcloud9.net> When using `ssh-keygen` to generate a user key, the default output includes a randomart image. I'm trying to figure out what the usefulness of this image is for user keys. For host keys, the benefit is easily explained, as it makes it easier for a human to ensure the remote host's key has not changed. But for user keys I do not see a use. I know that ssh-keygen is used to generate both host and user keys, so my original thought was that it was because the utility didn't know whether it was a user key or a host key being generated. But then you have the `-A` option which generates the host keys. When you use this option, the randomart image doesn't show up. So the utility is not showing randomart images for host keys where the usefulness is obvious, and it is showing it for user keys where the usefulness is not apparent. Can anyone explain this behavior, and what benefit randomart has for a user key? Thanks -Patrick From plautrba at redhat.com Thu Jul 17 00:04:04 2014 From: plautrba at redhat.com (Petr Lautrbach) Date: Wed, 16 Jul 2014 16:04:04 +0200 Subject: ssh - Connection closed by UNKNOWN Message-ID: <20140716140401.GB31693@hulk.local> Hi, ssh clients shows "closed by UNKNOWN" message when a socket is closed by a remote side while ssh is waiting for user's password: $ ssh user at localhost user at localhost's password: Connection closed by UNKNOWN When the packet_read_seqnr() calls get_remote_ipaddr(), a connection's socket is already closed and there's not been any other call of this function yet so canonical_host_ip from canohost.c is still NULL and the function returns "UNKNOWN". I think that it could be workarounded by calling get_remote_ipaddr() right after packet_set_connection(), e.g. using another debug message, see bellow, or there could be set_remote_ipaddr() in canonhost.c for that. --- a/sshconnect.c +++ b/sshconnect.c @@ -62,6 +62,7 @@ #include "monitor_fdpass.h" #include "ssh2.h" #include "version.h" +#include "canohost.h" char *client_version_string = NULL; char *server_version_string = NULL; @@ -171,6 +172,8 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, /* Set the connection file descriptors. */ packet_set_connection(sock, sock); + debug("Connected to %.200s [%.100s] port %d.", + host, get_remote_ipaddr(), get_remote_port()); return 0; } @@ -493,6 +496,8 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop /* Set the connection. */ packet_set_connection(sock, sock); + debug("Connected to %.200s [%.100s] port %d.", + host, get_remote_ipaddr(), get_remote_port()); return 0; } From tange at gnu.org Wed Jul 16 20:24:44 2014 From: tange at gnu.org (Ole Tange) Date: Wed, 16 Jul 2014 12:24:44 +0200 Subject: Allow for passing Ctrl-C and don't mix stderr with stdout Message-ID: I have been losing my mind over this problem, so any ideas are welcome. When running non-interactive jobs on remote machines, I want output to stderr and to stdout to remain separate in two streams just as if they were run locally. I also want jobs running remotely to die when I press Ctrl-C just as if they were run locally. At first glance these do not seem to be mutual exclusive, but when you get further into the details it seems they more or less are. "ssh example.com ls no_such_file" will print "ls: no_such_file: No such file or directory" on stderr. "ssh -tt example.com sleep 1000" will run sleep on the remote machine. Pressing Ctrl-C will kill sleep. But: "ssh -tt example.com ls no_such_file" will print "ls: no_such_file: No such file or directory" on STDOUT. "ssh example.com sleep 1000" will run sleep on the remote machine. Pressing Ctrl-C will NOT kill sleep. So 'ssh -tt' will do the right thing for Ctrl-C, but the wrong thing for stderr, and 'ssh' will do the right thing for stderr but the wrong thing for Ctrl-C. I have asked on StackExchange: http://unix.stackexchange.com/questions/134139/stderr-over-ssh-t and the solution there: * works for: suse, debian, mandriva, scosysv, ubuntu, unixware, redhat, raspberrypi. * does not kill remote job for: tru64, hurd, miros, freebsd, openbsd, netbsd, qnx, dragonfly * blocks for: solaris, centos(sometimes works), openindiana, irix, aix, hpux Is there a way where I can avoid mixing stderr with stdout and have remote jobs killed when I press Ctrl-C (as 'ssh -tt' does)? Background GNU Parallel uses 'ssh -tt' to propagate Ctrl+C. This makes it possible to kill remotely running jobs. But data sent to STDERR should continue to go to STDERR at the receiving end. /Ole From scott_n at xypro.com Thu Jul 17 05:03:46 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Wed, 16 Jul 2014 19:03:46 +0000 Subject: GSSAPI In-Reply-To: References: Message-ID: On Tue, 15 Jul 2014, Damien wrote: > On Tue, 15 Jul 2014, Scott Neugroschl wrote: >> If I am trying to build OpenSSH 6.6 with Kerberos GSSAPI support, do I >>still need to get Simon Wilkinson's patches? >If you want GSSAPI key exchange, yes. If you just want GSSAPI auth and >token forwarding then no. >AFAIK Simon is no longer maintaining the patches, but here's a version >that at least applies and builds against 6.6p1. [ diff --git changes redacted] > [patch redacted] Thanks again for the list. Forgive my total ignorance, but is there a way that I can use that text as input to patch? I'm not really familiar with patch, and what it's expecting. ScottN From keisial at gmail.com Thu Jul 17 08:33:25 2014 From: keisial at gmail.com (=?ISO-8859-1?Q?=C1ngel_Gonz=E1lez?=) Date: Thu, 17 Jul 2014 00:33:25 +0200 Subject: GSSAPI In-Reply-To: References: Message-ID: <53C6FDB5.7030607@gmail.com> On 16/07/14 21:03, Scott Neugroschl wrote: > Thanks again for the list. Forgive my total ignorance, but is there a way > that I can use that text as input to patch? I'm not really familiar with > patch, and what it's expecting. > > ScottN Extract the tarball for openssh-6.6p1, cd into that folder and run patch without arguments, providing the patch as input. You can simply paste everything from "diff --git" until the end of the mail (excluding the mailing list footer), press Ctrl+D to send an EOF on the terminal. From scott_n at xypro.com Thu Jul 17 08:49:19 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Wed, 16 Jul 2014 22:49:19 +0000 Subject: GSSAPI In-Reply-To: <53C6FDB5.7030607@gmail.com> References: <53C6FDB5.7030607@gmail.com> Message-ID: Got it. Thanks, Angel. You can ignore my previous email. ScottN -----Original Message----- From: ?ngel Gonz?lez [mailto:keisial at gmail.com] Sent: Wednesday, July 16, 2014 3:33 PM To: Scott Neugroschl Cc: OpenSSH Unix Dev Mailing List (openssh-unix-dev at mindrot.org) Subject: Re: GSSAPI On 16/07/14 21:03, Scott Neugroschl wrote: > Thanks again for the list. Forgive my total ignorance, but is there a way > that I can use that text as input to patch? I'm not really familiar with > patch, and what it's expecting. > > ScottN Extract the tarball for openssh-6.6p1, cd into that folder and run patch without arguments, providing the patch as input. You can simply paste everything from "diff --git" until the end of the mail (excluding the mailing list footer), press Ctrl+D to send an EOF on the terminal. From ronf at timeheart.net Thu Jul 17 15:17:49 2014 From: ronf at timeheart.net (Ron Frederick) Date: Wed, 16 Jul 2014 22:17:49 -0700 Subject: Allow for passing Ctrl-C and don't mix stderr with stdout In-Reply-To: References: Message-ID: On Jul 16, 2014, at 3:24 AM, Ole Tange wrote: > I have been losing my mind over this problem, so any ideas are welcome. > > When running non-interactive jobs on remote machines, I want output to > stderr and to stdout to remain separate in two streams just as if they > were run locally. I also want jobs running remotely to die when I > press Ctrl-C just as if they were run locally. With OpenSSH, you can only get separate stdout and stderr streams if you don?t allocate a pseudo-tty when you open up the SSH session. If you allocate a tty, the remote program can still have separate stdout and stderr, but whichever of those is directed to the pseudo-tty will be output by the local ssh client on stdout and nothing with go to the local stderr. Running with ?-tt? forces a pseudo-tty allocation and that will lose the stdout/stderr independence for the reasons explained in the stackexchange.com response related to having only a single pseudo-tty fd to read the output from. If you want separate stdout & stderr, you need to find a different way to trigger the interrupt signal. The SSH protocol provides a way for a client to send signals to the remote system without relying on a pseudo-tty, but I don?t think OpenSSH implements this feature yet (on either the client or server side). With it, it might be possible to add a ?~? SSH escape sequence which you could use instead of the Ctrl-C, similar to the way ?~B? sends a break request or ?~R? trigger key renegotiation. Without it, though, I can?t think of an easy way to accomplish what you are asking. -- Ron Frederick ronf at timeheart.net From plautrba at redhat.com Thu Jul 17 16:24:09 2014 From: plautrba at redhat.com (Petr Lautrbach) Date: Thu, 17 Jul 2014 08:24:09 +0200 Subject: ssh - Connection closed by UNKNOWN In-Reply-To: <20140716140401.GB31693@hulk.local> References: <20140716140401.GB31693@hulk.local> Message-ID: <20140717062407.GB18138@hulk.local> On Wed, Jul 16, 2014 at 04:04:04PM +0200, Petr Lautrbach wrote: > or there could be set_remote_ipaddr() in canonhost.c for that. > --- a/canohost.c +++ b/canohost.c @@ -321,6 +321,21 @@ clear_cached_addr(void) cached_port = -1; } +void set_remote_ipaddr(void) { + if (canonical_host_ip != NULL) + free(canonical_host_ip); + + if (packet_connection_is_on_socket()) { + canonical_host_ip = + get_peer_ipaddr(packet_get_connection_in()); + if (canonical_host_ip == NULL) + cleanup_exit(255); + } else { + /* If not on socket, return UNKNOWN. */ + canonical_host_ip = xstrdup("UNKNOWN"); + } +} + /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. @@ -330,17 +345,9 @@ const char * get_remote_ipaddr(void) { /* Check whether we have cached the ipaddr. */ - if (canonical_host_ip == NULL) { - if (packet_connection_is_on_socket()) { - canonical_host_ip = - get_peer_ipaddr(packet_get_connection_in()); - if (canonical_host_ip == NULL) - cleanup_exit(255); - } else { - /* If not on socket, return UNKNOWN. */ - canonical_host_ip = xstrdup("UNKNOWN"); - } - } + if (canonical_host_ip == NULL) + set_remote_ipaddr(); + return canonical_host_ip; } diff --git a/canohost.h b/canohost.h index 4c8636f..4079953 100644 --- a/canohost.h +++ b/canohost.h @@ -13,6 +13,7 @@ */ const char *get_canonical_hostname(int); +void set_remote_ipaddr(void); const char *get_remote_ipaddr(void); const char *get_remote_name_or_ip(u_int, int); diff --git a/sshconnect.c b/sshconnect.c index 799c8d0..08886ac 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -62,6 +62,7 @@ #include "monitor_fdpass.h" #include "ssh2.h" #include "version.h" +#include "canohost.h" char *client_version_string = NULL; char *server_version_string = NULL; @@ -171,6 +172,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, /* Set the connection file descriptors. */ packet_set_connection(sock, sock); + set_remote_ipaddr(); return 0; } @@ -493,6 +495,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, /* Set the connection. */ packet_set_connection(sock, sock); + set_remote_ipaddr(); return 0; } From plautrba at redhat.com Fri Jul 18 00:04:16 2014 From: plautrba at redhat.com (Petr Lautrbach) Date: Thu, 17 Jul 2014 16:04:16 +0200 Subject: OpenSSH banner doesnot display multibyte characters like korean In-Reply-To: References: Message-ID: <53C7D7E0.40602@redhat.com> On 10/05/2012 02:39 AM, Darren Tucker wrote: > On Tue, Sep 25, 2012 at 9:12 PM, balu chandra wrote: >> I also found little information inthe changelog on why strnvis() was >> introduced in input_userauth_banner. Is it added to address any >> security vulnerability. > > I believe the intent was to prevent a malicious server from sending a > banner containing a terminal answerback command sequence. I'm not > aware of any UTF-8 aware equivalent of strnvis, though (if someone > knows of one we'll look at using it). > I've asked my colleagues for help with [1] and it comes to that the case you describe might not be an issue at all. The banner is sent after a server is authenticated to a client and a client can always suppress printing a banner using -q option if he doesn't trust it. And what would stop a malicious server from sending a terminal answerback command sequence during a session instead in preauth phase? Is there any relevant discussion related to this problem from past with more specific information? [1] https://bugzilla.mindrot.org/show_bug.cgi?id=2058 Petr -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From deengert at gmail.com Fri Jul 18 00:21:18 2014 From: deengert at gmail.com (Douglas E Engert) Date: Thu, 17 Jul 2014 09:21:18 -0500 Subject: GSSAPI In-Reply-To: References: <53C6FDB5.7030607@gmail.com> Message-ID: <53C7DBDE.1030706@gmail.com> On 7/16/2014 5:49 PM, Scott Neugroschl wrote: > Got it. Thanks, Angel. You can ignore my previous email. All the Debian versions are built with the patch which can be found in: http://ftp.de.debian.org/debian/pool/main/o/openssh/openssh_6.6p1-6.debian.tar.xz It looks like Simon is still maintaining the patch as it includes in the comments: From: Simon Wilkinson Date: Sun, 9 Feb 2014 16:09:48 +0000 Subject: GSSAPI key exchange support The ChangeLog implies it has not changed from the version you already have. I too am personally baffled why OpenSSH does not include the patch. > ScottN > > > -----Original Message----- > From: ?ngel Gonz?lez [mailto:keisial at gmail.com] > Sent: Wednesday, July 16, 2014 3:33 PM > To: Scott Neugroschl > Cc: OpenSSH Unix Dev Mailing List (openssh-unix-dev at mindrot.org) > Subject: Re: GSSAPI > > On 16/07/14 21:03, Scott Neugroschl wrote: >> Thanks again for the list. Forgive my total ignorance, but is there a way >> that I can use that text as input to patch? I'm not really familiar with >> patch, and what it's expecting. >> >> ScottN > Extract the tarball for openssh-6.6p1, cd into that folder and run patch without arguments, providing the patch as input. You can simply paste everything from "diff --git" until the end of the mail (excluding the mailing list footer), press Ctrl+D to send an EOF on the terminal. > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > -- Douglas E. Engert From djm at mindrot.org Fri Jul 18 09:59:21 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 18 Jul 2014 09:59:21 +1000 (EST) Subject: GSSAPI In-Reply-To: <53C7DBDE.1030706@gmail.com> References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> Message-ID: On Thu, 17 Jul 2014, Douglas E Engert wrote: > I too am personally baffled why OpenSSH does not include the patch. We don't trust the attack surface the Kerberos/GSSAPI provides. -d From djm at mindrot.org Fri Jul 18 10:01:21 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 18 Jul 2014 10:01:21 +1000 (EST) Subject: ssh - Connection closed by UNKNOWN In-Reply-To: <20140717062407.GB18138@hulk.local> References: <20140716140401.GB31693@hulk.local> <20140717062407.GB18138@hulk.local> Message-ID: Could you make a bug at https://bugzilla.mindrot.org and attach your patch there? This ensures that it won't get lost. -d On Thu, 17 Jul 2014, Petr Lautrbach wrote: > On Wed, Jul 16, 2014 at 04:04:04PM +0200, Petr Lautrbach wrote: > > or there could be set_remote_ipaddr() in canonhost.c for that. > > > > > --- a/canohost.c > +++ b/canohost.c > @@ -321,6 +321,21 @@ clear_cached_addr(void) > cached_port = -1; > } > > +void set_remote_ipaddr(void) { > + if (canonical_host_ip != NULL) > + free(canonical_host_ip); > + > + if (packet_connection_is_on_socket()) { > + canonical_host_ip = > + get_peer_ipaddr(packet_get_connection_in()); > + if (canonical_host_ip == NULL) > + cleanup_exit(255); > + } else { > + /* If not on socket, return UNKNOWN. */ > + canonical_host_ip = xstrdup("UNKNOWN"); > + } > +} > + > /* > * Returns the IP-address of the remote host as a string. The returned > * string must not be freed. > @@ -330,17 +345,9 @@ const char * > get_remote_ipaddr(void) > { > /* Check whether we have cached the ipaddr. */ > - if (canonical_host_ip == NULL) { > - if (packet_connection_is_on_socket()) { > - canonical_host_ip = > - get_peer_ipaddr(packet_get_connection_in()); > - if (canonical_host_ip == NULL) > - cleanup_exit(255); > - } else { > - /* If not on socket, return UNKNOWN. */ > - canonical_host_ip = xstrdup("UNKNOWN"); > - } > - } > + if (canonical_host_ip == NULL) > + set_remote_ipaddr(); > + > return canonical_host_ip; > } > > diff --git a/canohost.h b/canohost.h > index 4c8636f..4079953 100644 > --- a/canohost.h > +++ b/canohost.h > @@ -13,6 +13,7 @@ > */ > > const char *get_canonical_hostname(int); > +void set_remote_ipaddr(void); > const char *get_remote_ipaddr(void); > const char *get_remote_name_or_ip(u_int, int); > > diff --git a/sshconnect.c b/sshconnect.c > index 799c8d0..08886ac 100644 > --- a/sshconnect.c > +++ b/sshconnect.c > @@ -62,6 +62,7 @@ > #include "monitor_fdpass.h" > #include "ssh2.h" > #include "version.h" > +#include "canohost.h" > > char *client_version_string = NULL; > char *server_version_string = NULL; > @@ -171,6 +172,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, > > /* Set the connection file descriptors. */ > packet_set_connection(sock, sock); > + set_remote_ipaddr(); > > return 0; > } > @@ -493,6 +495,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, > > /* Set the connection. */ > packet_set_connection(sock, sock); > + set_remote_ipaddr(); > > return 0; > } > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > From coy.hile at coyhile.com Fri Jul 18 11:01:47 2014 From: coy.hile at coyhile.com (Coy Hile) Date: Thu, 17 Jul 2014 21:01:47 -0400 Subject: GSSAPI In-Reply-To: References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> Message-ID: <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> On Jul 17, 2014, at 7:59 PM, Damien Miller wrote: > On Thu, 17 Jul 2014, Douglas E Engert wrote: > >> I too am personally baffled why OpenSSH does not include the patch. > > We don't trust the attack surface the Kerberos/GSSAPI provides. What?s your justification for that? I don?t see a larger attack surface in a kerberized environment compared to the wild west. In fact, I see a lesser attack surface in a purely kerberized environment (unless the host happens to be on the border) because you know everyone connecting has either already been authenticated by the KDC or will promptly get dropped on the floor. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2251 bytes Desc: not available URL: From nkadel at gmail.com Fri Jul 18 11:33:17 2014 From: nkadel at gmail.com (Nico Kadel-Garcia) Date: Thu, 17 Jul 2014 21:33:17 -0400 Subject: GSSAPI In-Reply-To: <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> Message-ID: On Thu, Jul 17, 2014 at 9:01 PM, Coy Hile wrote: > > On Jul 17, 2014, at 7:59 PM, Damien Miller wrote: > >> On Thu, 17 Jul 2014, Douglas E Engert wrote: >> >>> I too am personally baffled why OpenSSH does not include the patch. >> >> We don't trust the attack surface the Kerberos/GSSAPI provides. > > What?s your justification for that? I don?t see a larger attack surface in a kerberized environment compared to the wild west. In fact, I see a lesser attack surface in a purely kerberized environment (unless the host happens to be on the border) because you know everyone connecting has either already been authenticated by the KDC or will promptly get dropped on the floor. Especially compared to the "oh, let me just leave my SSH private keys without passphrases so I don't have to unlock them" practice that is the commonplace in every environment I've dealt with since 1996, when I first tried to compile ssh-1. This is re-inforced by the default acceptance of ssh-keygen of passphrase keys, and *every environment* I've ever audited has at least 20% passphrase free SSH private keys. Often it approaches 90%. The technology of OpenSSH is pretty robust, but the commonplace practices are often utterly, utterly horrid. Educating user communities is too often seen as "not on task", and "not part of the priorities", especially because it's often the CTO and architects at a company who are most likely to ignore basic security practices as a matter of policy. The Kerberos tokens are a tremendous win over this, for robust single-sign-on, for the ability to invalidate or reject keys at a central access point, and for their ease of integration with SSL and other technologies. From kop at meme.com Fri Jul 18 12:21:03 2014 From: kop at meme.com (Karl O. Pinc) Date: Thu, 17 Jul 2014 21:21:03 -0500 Subject: GSSAPI In-Reply-To: (from nkadel@gmail.com on Thu Jul 17 20:33:17 2014) References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> Message-ID: <1405650063.3375.1@slate> On 07/17/2014 08:33:17 PM, Nico Kadel-Garcia wrote: > On Thu, Jul 17, 2014 at 9:01 PM, Coy Hile > wrote: > > > > On Jul 17, 2014, at 7:59 PM, Damien Miller wrote: > > > >> On Thu, 17 Jul 2014, Douglas E Engert wrote: > >> > >>> I too am personally baffled why OpenSSH does not include the > patch. > >> > >> We don't trust the attack surface the Kerberos/GSSAPI provides. > > > > What?s your justification for that? I don?t see a larger attack > surface in a kerberized environment compared to the wild west. > Especially compared to the "oh, let me just leave my SSH private keys > without passphrases so I don't have to unlock them" practice that is > the commonplace in every environment I've dealt with since 1996, when > I first tried to compile ssh-1. This is re-inforced by the default > acceptance of ssh-keygen of passphrase keys, and *every environment* > I've ever audited has at least 20% passphrase free SSH private keys. > Often it approaches 90%. The technology of OpenSSH is pretty robust, > but the commonplace practices are often utterly, utterly horrid. > Educating user communities is too often seen as "not on task", and > "not part of the priorities", especially because it's often the CTO > and architects at a company who are most likely to ignore basic > security practices as a matter of policy. > > The Kerberos tokens are a tremendous win over this, for robust > single-sign-on, for the ability to invalidate or reject keys at a > central access point, and for their ease of integration with SSL and > other technologies. FWIW, an alternative approach with similar benefits is to use hardware tokens such as yubikeys. This has some advantages when it comes to the social aspects involved in fixing poor security practices. The hardware cost is low enough that the risk/reward ratio can be good, especially as -- as noted above -- dealing with people is often the hardest part. Karl Free Software: "You don't pay back, you pay forward." -- Robert A. Heinlein From ronf at timeheart.net Fri Jul 18 13:11:16 2014 From: ronf at timeheart.net (Ron Frederick) Date: Thu, 17 Jul 2014 20:11:16 -0700 Subject: OpenSSH banner doesnot display multibyte characters like korean In-Reply-To: <53C7D7E0.40602@redhat.com> References: <53C7D7E0.40602@redhat.com> Message-ID: On Jul 17, 2014, at 7:04 AM, Petr Lautrbach wrote: > On 10/05/2012 02:39 AM, Darren Tucker wrote: >> On Tue, Sep 25, 2012 at 9:12 PM, balu chandra wrote: >>> I also found little information inthe changelog on why strnvis() was >>> introduced in input_userauth_banner. Is it added to address any >>> security vulnerability. >> >> I believe the intent was to prevent a malicious server from sending a >> banner containing a terminal answerback command sequence. I'm not >> aware of any UTF-8 aware equivalent of strnvis, though (if someone >> knows of one we'll look at using it). >> > > I've asked my colleagues for help with [1] and it comes to that the case you describe might > not be an issue at all. > > The banner is sent after a server is authenticated to a client and a client can always suppress > printing a banner using -q option if he doesn't trust it. > > And what would stop a malicious server from sending a terminal answerback command sequence > during a session instead in preauth phase? > > Is there any relevant discussion related to this problem from past with more specific information? I can?t speak to the history of when this got added to OpenSSH, but the SSH RFCs do specifically discuss this point. In particular in section 5.4 about the auth banner, RFC 4252 says: If the 'message' string is displayed, control character filtering, discussed in [SSH-ARCH], SHOULD be used to avoid attacks by sending terminal control characters. It defines the banner text as follows, though: string message in ISO-10646 UTF-8 encoding [RFC3629] So, any control character filtering should not be stripping out printable Unicode characters if they are properly encoded as UTF-8. SSH-ARCH here refers to RFC 4251, which covers this topic in section 9.2, Control Character Filtering: 9.2. Control Character Filtering When displaying text to a user, such as error or debug messages, the client software SHOULD replace any control characters (except tab, carriage return, and newline) with safe sequences to avoid attacks by sending terminal control characters. Looking at the OpenSSH sources, the strnvis() function is definitely not UTF-8 aware, so this is technically a violation of the spec. -- Ron Frederick ronf at timeheart.net From mfriedl at gmail.com Fri Jul 18 14:20:17 2014 From: mfriedl at gmail.com (Markus Friedl) Date: Fri, 18 Jul 2014 06:20:17 +0200 Subject: GSSAPI In-Reply-To: <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> Message-ID: <8FA6E06E-F76F-4EAA-97FF-178E143BFAAE@gmail.com> > Am 18.07.2014 um 03:01 schrieb Coy Hile : > > What?s your justification for that? The amount of extra code involved. -m From plautrba at redhat.com Fri Jul 18 14:36:54 2014 From: plautrba at redhat.com (Petr Lautrbach) Date: Fri, 18 Jul 2014 06:36:54 +0200 Subject: ssh - Connection closed by UNKNOWN In-Reply-To: References: <20140716140401.GB31693@hulk.local> <20140717062407.GB18138@hulk.local> Message-ID: <20140718043652.GA17149@hulk.w.lan> On Fri, Jul 18, 2014 at 10:01:21AM +1000, Damien Miller wrote: > Could you make a bug at https://bugzilla.mindrot.org and attach your patch > there? This ensures that it won't get lost. > Sure - https://bugzilla.mindrot.org/show_bug.cgi?id=2257 > > On Thu, 17 Jul 2014, Petr Lautrbach wrote: > > > On Wed, Jul 16, 2014 at 04:04:04PM +0200, Petr Lautrbach wrote: > > > or there could be set_remote_ipaddr() in canonhost.c for that. > > > > > > > > > --- a/canohost.c > > +++ b/canohost.c > > @@ -321,6 +321,21 @@ clear_cached_addr(void) > > cached_port = -1; > > } > > > > +void set_remote_ipaddr(void) { > > + if (canonical_host_ip != NULL) > > + free(canonical_host_ip); > > + > > + if (packet_connection_is_on_socket()) { > > + canonical_host_ip = > > + get_peer_ipaddr(packet_get_connection_in()); > > + if (canonical_host_ip == NULL) > > + cleanup_exit(255); > > + } else { > > + /* If not on socket, return UNKNOWN. */ > > + canonical_host_ip = xstrdup("UNKNOWN"); > > + } > > +} > > + > > /* > > * Returns the IP-address of the remote host as a string. The returned > > * string must not be freed. > > @@ -330,17 +345,9 @@ const char * > > get_remote_ipaddr(void) > > { > > /* Check whether we have cached the ipaddr. */ > > - if (canonical_host_ip == NULL) { > > - if (packet_connection_is_on_socket()) { > > - canonical_host_ip = > > - get_peer_ipaddr(packet_get_connection_in()); > > - if (canonical_host_ip == NULL) > > - cleanup_exit(255); > > - } else { > > - /* If not on socket, return UNKNOWN. */ > > - canonical_host_ip = xstrdup("UNKNOWN"); > > - } > > - } > > + if (canonical_host_ip == NULL) > > + set_remote_ipaddr(); > > + > > return canonical_host_ip; > > } > > > > diff --git a/canohost.h b/canohost.h > > index 4c8636f..4079953 100644 > > --- a/canohost.h > > +++ b/canohost.h > > @@ -13,6 +13,7 @@ > > */ > > > > const char *get_canonical_hostname(int); > > +void set_remote_ipaddr(void); > > const char *get_remote_ipaddr(void); > > const char *get_remote_name_or_ip(u_int, int); > > > > diff --git a/sshconnect.c b/sshconnect.c > > index 799c8d0..08886ac 100644 > > --- a/sshconnect.c > > +++ b/sshconnect.c > > @@ -62,6 +62,7 @@ > > #include "monitor_fdpass.h" > > #include "ssh2.h" > > #include "version.h" > > +#include "canohost.h" > > > > char *client_version_string = NULL; > > char *server_version_string = NULL; > > @@ -171,6 +172,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, > > > > /* Set the connection file descriptors. */ > > packet_set_connection(sock, sock); > > + set_remote_ipaddr(); > > > > return 0; > > } > > @@ -493,6 +495,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, > > > > /* Set the connection. */ > > packet_set_connection(sock, sock); > > + set_remote_ipaddr(); > > > > return 0; > > } > > _______________________________________________ > > openssh-unix-dev mailing list > > openssh-unix-dev at mindrot.org > > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > > From nkadel at gmail.com Fri Jul 18 20:11:35 2014 From: nkadel at gmail.com (Nico Kadel-Garcia) Date: Fri, 18 Jul 2014 06:11:35 -0400 Subject: GSSAPI In-Reply-To: <1405650063.3375.1@slate> References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> <1405650063.3375.1@slate> Message-ID: On Thu, Jul 17, 2014 at 10:21 PM, Karl O. Pinc wrote: > On 07/17/2014 08:33:17 PM, Nico Kadel-Garcia wrote: >> On Thu, Jul 17, 2014 at 9:01 PM, Coy Hile >> wrote: >> > >> > On Jul 17, 2014, at 7:59 PM, Damien Miller wrote: >> > >> >> On Thu, 17 Jul 2014, Douglas E Engert wrote: >> >> >> >>> I too am personally baffled why OpenSSH does not include the >> patch. >> >> >> >> We don't trust the attack surface the Kerberos/GSSAPI provides. >> > >> > What?s your justification for that? I don?t see a larger attack >> surface in a kerberized environment compared to the wild west. > >> Especially compared to the "oh, let me just leave my SSH private keys >> without passphrases so I don't have to unlock them" practice that is >> the commonplace in every environment I've dealt with since 1996, when >> I first tried to compile ssh-1. This is re-inforced by the default >> acceptance of ssh-keygen of passphrase keys, and *every environment* >> I've ever audited has at least 20% passphrase free SSH private keys. >> Often it approaches 90%. The technology of OpenSSH is pretty robust, >> but the commonplace practices are often utterly, utterly horrid. >> Educating user communities is too often seen as "not on task", and >> "not part of the priorities", especially because it's often the CTO >> and architects at a company who are most likely to ignore basic >> security practices as a matter of policy. >> >> The Kerberos tokens are a tremendous win over this, for robust >> single-sign-on, for the ability to invalidate or reject keys at a >> central access point, and for their ease of integration with SSL and >> other technologies. > > FWIW, an alternative approach with similar benefits is to > use hardware tokens such as yubikeys. This has some > advantages when it comes to the social aspects involved in > fixing poor security practices. The hardware cost is low enough > that the risk/reward ratio can be good, especially as -- as > noted above -- dealing with people is often the hardest part. Those are different patches!!!! And I wish hardware tokens worked out well. I've had to manage up to 20 distinct environments, simultaneously, each with their own credentials system. Tokens would have become unwieldy, especially in today's tablet based computing where the computer itself is so light and small. I realize this is the devel mailing list, and most of us would know this, but perhaps a few newer UNIX or Linux admins don't realize how ubituitious Kerberos based authentication has become, especially in environments that use Active Directory, or modern Samba. Linux or UNIX environments can activate just the Kerberos part and use local account management and reduce the setup costs for Kerberos ticket handling profoundly, far more stably and reliably than using AD for account management. So it's very useful indeed for complex environments that are already running AD. I was a happy camper when GSSAPI was enabled in Putty: it turned one of my complex and awkward environments into a genuine SSO, or "Single Sign-On" environment. From simonxwilkinson at gmail.com Fri Jul 18 20:28:22 2014 From: simonxwilkinson at gmail.com (Simon Wilkinson) Date: Fri, 18 Jul 2014 11:28:22 +0100 Subject: GSSAPI In-Reply-To: <8FA6E06E-F76F-4EAA-97FF-178E143BFAAE@gmail.com> References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> <8FA6E06E-F76F-4EAA-97FF-178E143BFAAE@gmail.com> Message-ID: <951DB6AA-2CFA-46BE-815F-DBBD48EA61EC@gmail.com> On 18 Jul 2014, at 05:20, Markus Friedl wrote: > >> Am 18.07.2014 um 03:01 schrieb Coy Hile : >> >> What?s your justification for that? > > The amount of extra code involved. I?m not actually convinced that the attack surface is radically different between userauth and key exchange. In both the GSSAPI calls are being performed in the privileged monitor, and the GSSAPI calls that are used are pretty much identical. Cheers, Simon From kop at meme.com Fri Jul 18 23:15:08 2014 From: kop at meme.com (Karl O. Pinc) Date: Fri, 18 Jul 2014 08:15:08 -0500 Subject: GSSAPI In-Reply-To: (from nkadel@gmail.com on Fri Jul 18 05:11:35 2014) References: <53C6FDB5.7030607@gmail.com> <53C7DBDE.1030706@gmail.com> <1B1ABC20-6742-4970-BBAD-5C309574DAB1@coyhile.com> <1405650063.3375.1@slate> Message-ID: <1405689308.25001.0@slate> On 07/18/2014 05:11:35 AM, Nico Kadel-Garcia wrote: > On Thu, Jul 17, 2014 at 10:21 PM, Karl O. Pinc wrote: > > On 07/17/2014 08:33:17 PM, Nico Kadel-Garcia wrote: > >> The Kerberos tokens are a tremendous win over this, for robust > >> single-sign-on, for the ability to invalidate or reject keys at a > >> central access point, and for their ease of integration with SSL > and > >> other technologies. > > > > FWIW, an alternative approach with similar benefits is to > > use hardware tokens such as yubikeys. This has some > > advantages when it comes to the social aspects involved in > > fixing poor security practices. The hardware cost is low enough > > that the risk/reward ratio can be good, especially as -- as > > noted above -- dealing with people is often the hardest part. > > Those are different patches!!!! Sorry, I forgot yubikey support was not integrated. I usually get it for free either via PAM or OpenBSD. Karl Free Software: "You don't pay back, you pay forward." -- Robert A. Heinlein From jim at jimkeener.com Sat Jul 19 09:17:09 2014 From: jim at jimkeener.com (James Keener) Date: Fri, 18 Jul 2014 19:17:09 -0400 Subject: Read-only on /dev/tty causes ssh-add to show passwords when typed and ssh'ing to new hosts to fail Message-ID: <53C9AAF5.80901@jimkeener.com> When permissions on /dev/tty are crw------- and owner root:root, ssh-add will echo passwords to the terminal (sudo does not) and ssh fails with a "Host key verification failed." error. ssh -v -v -v provided a "debug1: read_passphrase: can't open /dev/tty: Permission denied" which is how I figured out that /dev/tty had weird permission issues. I would have expected that error print without need the -v option and ssh-add to fail so that my password would not show (or use another method, if possible). This happens with binaries compiled from source from openssh-6.6p1 obtained from http://openbsd.mirrors.pair.com/OpenSSH/portable/openssh-6.6p1.tar.gz Thank you, Jim Keener -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 884 bytes Desc: OpenPGP digital signature URL: From djm at mindrot.org Sun Jul 20 20:01:42 2014 From: djm at mindrot.org (Damien Miller) Date: Sun, 20 Jul 2014 20:01:42 +1000 (EST) Subject: Read-only on /dev/tty causes ssh-add to show passwords when typed and ssh'ing to new hosts to fail In-Reply-To: <53C9AAF5.80901@jimkeener.com> References: <53C9AAF5.80901@jimkeener.com> Message-ID: On Fri, 18 Jul 2014, James Keener wrote: > When permissions on /dev/tty are crw------- and owner root:root, ssh-add > will echo passwords to the terminal (sudo does not) and ssh fails with a > "Host key verification failed." error. I would expect that ssh can't successfully issue termios calls to turn off tty echo when /dev/tty isn't writable to the user. sudo will work because it is setuid root. There isn't much ssh can do with bad permissions on /dev/tty. -d From jim at jimkeener.com Sun Jul 20 21:51:25 2014 From: jim at jimkeener.com (James Keener) Date: Sun, 20 Jul 2014 07:51:25 -0400 Subject: Read-only on /dev/tty causes ssh-add to show passwords when typed and ssh'ing to new hosts to fail In-Reply-To: References: <53C9AAF5.80901@jimkeener.com> Message-ID: <0d15a509-4fd7-41e6-8e56-3ff5614c4f91@email.android.com> Lookin into it more I believe that readpassphrase falls back to stdin when /dev/tty isn't accessible. I wonder if ssh-add could be more proactive by checking /dev/tty and the presence of $DISPLAY to provide a warning or abort with an error before calling readpassphrase. I didn't think ssh-add could fix a bad configuration :) The issue is that I know there are many use cases for ssh-add (many of which i don't know) and being able to accommodate them all may be difficult. Jim -- Sent from my Android device with K-9 Mail. Please excuse my brevity. From gert at greenie.muc.de Mon Jul 21 06:58:26 2014 From: gert at greenie.muc.de (Gert Doering) Date: Sun, 20 Jul 2014 22:58:26 +0200 Subject: Read-only on /dev/tty causes ssh-add to show passwords when typed and ssh'ing to new hosts to fail In-Reply-To: References: <53C9AAF5.80901@jimkeener.com> Message-ID: <20140720205826.GF1118@greenie.muc.de> Hi, On Sun, Jul 20, 2014 at 08:01:42PM +1000, Damien Miller wrote: > There isn't much ssh can do with bad permissions on /dev/tty. Well - you could issue an error message and die. Termios operation on stdin(-connected-to-a-tty) do not need /dev/tty, so there must be some explicit open() somewhere - and if that fails, do not go on. Without having checked the code, it might be some sort of corner case ("if this fails we do not have a controlling tty, so use stdin instead and do not try to turn off echo instead!" - not differenciating between the error for "no controlling tty" and "broken permissions"). gert -- USENET is *not* the non-clickable part of WWW! //www.muc.de/~gert/ Gert Doering - Munich, Germany gert at greenie.muc.de fax: +49-89-35655025 gert at net.informatik.tu-muenchen.de From djm at mindrot.org Mon Jul 21 09:49:10 2014 From: djm at mindrot.org (Damien Miller) Date: Mon, 21 Jul 2014 09:49:10 +1000 (EST) Subject: Read-only on /dev/tty causes ssh-add to show passwords when typed and ssh'ing to new hosts to fail In-Reply-To: <20140720205826.GF1118@greenie.muc.de> References: <53C9AAF5.80901@jimkeener.com> <20140720205826.GF1118@greenie.muc.de> Message-ID: On Sun, 20 Jul 2014, Gert Doering wrote: > Hi, > > On Sun, Jul 20, 2014 at 08:01:42PM +1000, Damien Miller wrote: > > There isn't much ssh can do with bad permissions on /dev/tty. > > Well - you could issue an error message and die. > > Termios operation on stdin(-connected-to-a-tty) do not need /dev/tty, so we can't depend on stdin as tty. Otherwise "ssh foo < /somefile" wouldn't work. > there must be some explicit open() somewhere - and if that fails, do not > go on. Without having checked the code, it might be some sort of corner > case ("if this fails we do not have a controlling tty, so use stdin instead > and do not try to turn off echo instead!" - not differenciating between > the error for "no controlling tty" and "broken permissions"). that sounds like a whole lot of special cases to deal with someone who has broken their /dev From gert at greenie.muc.de Mon Jul 21 17:10:12 2014 From: gert at greenie.muc.de (Gert Doering) Date: Mon, 21 Jul 2014 09:10:12 +0200 Subject: Read-only on /dev/tty causes ssh-add to show passwords when typed and ssh'ing to new hosts to fail In-Reply-To: References: <53C9AAF5.80901@jimkeener.com> <20140720205826.GF1118@greenie.muc.de> Message-ID: <20140721071012.GH1118@greenie.muc.de> Hi, On Mon, Jul 21, 2014 at 09:49:10AM +1000, Damien Miller wrote: > > On Sun, Jul 20, 2014 at 08:01:42PM +1000, Damien Miller wrote: > > > There isn't much ssh can do with bad permissions on /dev/tty. > > > > Well - you could issue an error message and die. > > > > Termios operation on stdin(-connected-to-a-tty) do not need /dev/tty, so > > we can't depend on stdin as tty. Otherwise "ssh foo < /somefile" wouldn't > work. Understood. I think we're slightly misunderstanding each other - I was only explaining why the success or failure of termios operations is (generally) independent from the permissions of /dev/tty. > > there must be some explicit open() somewhere - and if that fails, do not > > go on. Without having checked the code, it might be some sort of corner > > case ("if this fails we do not have a controlling tty, so use stdin instead > > and do not try to turn off echo instead!" - not differenciating between > > the error for "no controlling tty" and "broken permissions"). > > that sounds like a whole lot of special cases to deal with someone who > has broken their /dev Well, you already *have* that special case - "if /dev/tty isn't working, assume we do not have a controlling tty and use stdin". The question is whether you can (and want to) distinguish "I have no controlling tty" from "/dev/tty is messed up -> print error and die". gert -- USENET is *not* the non-clickable part of WWW! //www.muc.de/~gert/ Gert Doering - Munich, Germany gert at greenie.muc.de fax: +49-89-35655025 gert at net.informatik.tu-muenchen.de From asn at cryptomilk.org Mon Jul 21 21:16:27 2014 From: asn at cryptomilk.org (Andreas Schneider) Date: Mon, 21 Jul 2014 13:16:27 +0200 Subject: GSSAPI In-Reply-To: References: Message-ID: <3162583.seGC0hIEk4@magrathea> On Tuesday 15 July 2014 21:52:33 Scott Neugroschl wrote: > If I am trying to build OpenSSH 6.6 with Kerberos GSSAPI support, do I still > need to get Simon Wilkinson's patches? As the FreeIPA project has support for managing SSH Keys they have a maintained patchset for GSSAPI support. You can take a look here: http://pkgs.fedoraproject.org/cgit/openssh.git/tree/ -- andreas -- Andreas Schneider GPG-ID: CC014E3D www.cryptomilk.org asn at cryptomilk.org From list at eworm.de Thu Jul 24 19:32:26 2014 From: list at eworm.de (Christian Hesse) Date: Thu, 24 Jul 2014 11:32:26 +0200 Subject: [PATCH 1/1] fix regress/multiplex.sh Message-ID: <1406194346-15232-1-git-send-email-list@eworm.de> From: Christian Hesse commit 04f4824 removed the wrong line, so fix this --- regress/multiplex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regress/multiplex.sh b/regress/multiplex.sh index fc32d13..693211b 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh @@ -165,8 +165,8 @@ echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \ || fail "connect to remote forwarded path failed" ${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \ || fail "cancel remote forward failed" -N=$(echo "" | $NC -U $OBJ/unix-1.fwd 2>&1 | wc -l) N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) +test ${N} -eq 0 || fail "remote forward path still listening" rm -f $OBJ/unix-1.fwd verbose "test $tid: cmd exit" -- 2.0.2 From list at eworm.de Thu Jul 24 19:49:01 2014 From: list at eworm.de (Christian Hesse) Date: Thu, 24 Jul 2014 11:49:01 +0200 Subject: GNU netcat in make tests Message-ID: <20140724114901.3bdd0d11@leda.localdomain> Hello everybody, regression tests do use `nc -U` since commit 0e4e955 to test for Unix domain socket forwarding. This fails on systems that have GNU netcat installed as that does not support Unix domain sockets. In fact it does not understand the `-U` option at all. What way to go there? -- main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH" "CX:;",b;for(a/* Chris get my mail address: */=0;b=c[a++];) putchar(b-1/(/* gcc -o sig sig.c && ./sig */b/42*2-3)*42);} -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From djm at mindrot.org Thu Jul 24 19:54:37 2014 From: djm at mindrot.org (Damien Miller) Date: Thu, 24 Jul 2014 19:54:37 +1000 (EST) Subject: GNU netcat in make tests In-Reply-To: <20140724114901.3bdd0d11@leda.localdomain> References: <20140724114901.3bdd0d11@leda.localdomain> Message-ID: On Thu, 24 Jul 2014, Christian Hesse wrote: > Hello everybody, > > regression tests do use `nc -U` since commit 0e4e955 to test for Unix domain > socket forwarding. This fails on systems that have GNU netcat installed as > that does not support Unix domain sockets. In fact it does not understand the > `-U` option at all. What way to go there? Despatch some time-travelling robot assassins to ensure that GNU netcat was never created? In the meantime, maybe we could avoid the use of GNU netcat althother by using a ssh-agent's socket in the tests... -d From nkadel at gmail.com Thu Jul 24 21:56:57 2014 From: nkadel at gmail.com (Nico Kadel-Garcia) Date: Thu, 24 Jul 2014 07:56:57 -0400 Subject: GNU netcat in make tests In-Reply-To: References: <20140724114901.3bdd0d11@leda.localdomain> Message-ID: On Thu, Jul 24, 2014 at 5:54 AM, Damien Miller wrote: > On Thu, 24 Jul 2014, Christian Hesse wrote: > >> Hello everybody, >> >> regression tests do use `nc -U` since commit 0e4e955 to test for Unix domain >> socket forwarding. This fails on systems that have GNU netcat installed as >> that does not support Unix domain sockets. In fact it does not understand the >> `-U` option at all. What way to go there? > > Despatch some time-travelling robot assassins to ensure that GNU > netcat was never created? > > In the meantime, maybe we could avoid the use of GNU netcat althother > by using a ssh-agent's socket in the tests... Or submit a patch. Looks like the original GNU version is at netcat.sourceforge.net. Is the '-U' option added by BSD, to the original 1.10 release by Hobbit, or left out by the GNU version? From igor at mir2.org Thu Jul 24 23:31:54 2014 From: igor at mir2.org (Igor Bukanov) Date: Thu, 24 Jul 2014 15:31:54 +0200 Subject: ssh-agent and socket permission check Message-ID: I would like to run ssh-agent under a different account to make sure that its memory holding private keys is not readable. However, this is not directly possible as ssh-agent.c explicitly rejects connections to the agent socket from a different user [1]. Would it be possible to have an option to relax the check so the connections is allowed as long as it comes from a process belonging to agent's process group? [1] - https://github.com/openssh/openssh-portable/blob/master/ssh-agent.c#L934 From djm at mindrot.org Fri Jul 25 08:09:28 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 25 Jul 2014 08:09:28 +1000 (EST) Subject: ssh-agent and socket permission check In-Reply-To: References: Message-ID: On Thu, 24 Jul 2014, Igor Bukanov wrote: > I would like to run ssh-agent under a different account to make sure that > its memory holding private keys is not readable. It shouldn't be anyway. We ship it setgid by default and also use prctl() on Linux to prevent ptrace() From djm at mindrot.org Fri Jul 25 09:02:19 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 25 Jul 2014 09:02:19 +1000 (EST) Subject: GNU netcat in make tests In-Reply-To: References: <20140724114901.3bdd0d11@leda.localdomain> Message-ID: On Thu, 24 Jul 2014, Damien Miller wrote: > In the meantime, maybe we could avoid the use of GNU netcat althother > by using a ssh-agent's socket in the tests... I got halfway through implementing this before realising that it is insufficient - we need to tests UNIX domain socket to TCP forwarding and ssh-add/agent can't do this. From igor at mir2.org Fri Jul 25 09:24:02 2014 From: igor at mir2.org (Igor Bukanov) Date: Fri, 25 Jul 2014 01:24:02 +0200 Subject: ssh-agent and socket permission check In-Reply-To: References: Message-ID: On 25 July 2014 00:09, Damien Miller wrote: > > It shouldn't be anyway. We ship it setgid by default and also use prctl() > on Linux to prevent ptrace() > So with that setup on Linux it is not possible for an ordinary account to read memory of ssh-agent barring a kernel bug? In any case, as in my case everything runs in a container with no setuid/setguid binaries available, that would not help. From djm at mindrot.org Fri Jul 25 09:31:44 2014 From: djm at mindrot.org (Damien Miller) Date: Fri, 25 Jul 2014 09:31:44 +1000 (EST) Subject: ssh-agent and socket permission check In-Reply-To: References: Message-ID: On Fri, 25 Jul 2014, Igor Bukanov wrote: > On 25 July 2014 00:09, Damien Miller wrote: > > > It shouldn't be anyway. We ship it setgid by default and also use > > prctl() > > on Linux to prevent ptrace() > > So with that setup on Linux it is not possible for an ordinary account to > read memory of ssh-agent barring a kernel bug? In any case, as in my case > everything runs in a container with no setuid/setguid binaries available, > that would not help. If you are on Linux then prctl will still prevent ptrace, even without setgid. So yeah, your attacker will need root or a kernel bug. You can try it yourself: "gdb -p $SSH_AGENT_PID /usr/bin/ssh-agent" -d From list at eworm.de Fri Jul 25 16:28:24 2014 From: list at eworm.de (Christian Hesse) Date: Fri, 25 Jul 2014 08:28:24 +0200 Subject: GNU netcat in make tests In-Reply-To: References: <20140724114901.3bdd0d11@leda.localdomain> Message-ID: <20140725082824.02c7c70e@leda.localdomain> Damien Miller on Fri, 2014/07/25 09:02: > On Thu, 24 Jul 2014, Damien Miller wrote: > > > In the meantime, maybe we could avoid the use of GNU netcat althother > > by using a ssh-agent's socket in the tests... > > I got halfway through implementing this before realising that it is > insufficient - we need to tests UNIX domain socket to TCP forwarding > and ssh-add/agent can't do this. Perhaps we should rely on OpenBSD netcat and skip tests if GNU netcat is found. Something like this? From 9e3fb5105317a4d64ea3d7285f86fa66af623761 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 25 Jul 2014 08:26:17 +0200 Subject: [PATCH 1/1] skip multiplex.sh if nc does not support UNIX domain sockets --- regress/multiplex.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/regress/multiplex.sh b/regress/multiplex.sh index 693211b..45480eb 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh @@ -6,7 +6,10 @@ CTL=/tmp/openssh.regress.ctl-sock.$$ tid="connection multiplexing" if have_prog nc ; then - if nc -h 2>&1 | grep -- -N >/dev/null; then + if nc -h 2>&1 | grep -- -U >/dev/null; then + echo "skipped (netcat does not support UNIX domain sockets)" + exit 0 + else if nc -h 2>&1 | grep -- -N >/dev/null; then NC="nc -N"; else NC="nc" -- main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH" "CX:;",b;for(a/* Chris get my mail address: */=0;b=c[a++];) putchar(b-1/(/* gcc -o sig sig.c && ./sig */b/42*2-3)*42);} -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From dtucker at zip.com.au Fri Jul 25 16:28:35 2014 From: dtucker at zip.com.au (Darren Tucker) Date: Fri, 25 Jul 2014 02:28:35 -0400 Subject: ssh-agent and socket permission check In-Reply-To: References: Message-ID: On 24 Jul 2014 19:32, "Damien Miller" wrote: > > On Fri, 25 Jul 2014, Igor Bukanov wrote: > > > On 25 July 2014 00:09, Damien Miller wrote: > > > > > It shouldn't be anyway. We ship it setgid by default and also use > > > prctl() > > > on Linux to prevent ptrace() > > > > So with that setup on Linux it is not possible for an ordinary account to > > read memory of ssh-agent barring a kernel bug? In any case, as in my case > > everything runs in a container with no setuid/setguid binaries available, > > that would not help. > > If you are on Linux then prctl will still prevent ptrace, even without > setgid. Yeah but from memory ssh-agent will also call getpeereid() on the connecting socket, which will prevent other uids in the same group from making use of the key without exposing it to copying. From list at eworm.de Fri Jul 25 17:14:50 2014 From: list at eworm.de (Christian Hesse) Date: Fri, 25 Jul 2014 09:14:50 +0200 Subject: corrupted copy in regress/multiplex.sh Message-ID: <20140725091450.7a537255@leda.localdomain> Hello everybody, after installing openbsd-netcat some tests in multiplex.sh do still fail for me. Sadly this happens when trying to build a package only, everything works just fine if I try to debug this. Any ideas? Logfile failed-regress.log is attached. [...] run test multiplex.sh ... test connection multiplexing: envpass test connection multiplexing: transfer test connection multiplexing: forward cmp: EOF on openssh/regress/copy ssh: corrupted copy of openssh/regress/data cmp: EOF on openssh/regress/copy ssh: corrupted copy of openssh/regress/data test connection multiplexing: status 0 test connection multiplexing: status 1 test connection multiplexing: status 4 test connection multiplexing: status 5 test connection multiplexing: status 44 test connection multiplexing: cmd check test connection multiplexing: cmd forward local (TCP) test connection multiplexing: cmd forward remote (TCP) test connection multiplexing: cmd forward local (UNIX) test connection multiplexing: cmd forward remote (UNIX) test connection multiplexing: cmd exit test connection multiplexing: cmd stop failed connection multiplexing Makefile:168: recipe for target 't-exec' failed -- main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH" "CX:;",b;for(a/* Chris get my mail address: */=0;b=c[a++];) putchar(b-1/(/* gcc -o sig sig.c && ./sig */b/42*2-3)*42);} -------------- next part -------------- A non-text attachment was scrubbed... Name: failed-regress.log Type: text/x-log Size: 9577 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From alex at alex.org.uk Fri Jul 25 17:38:31 2014 From: alex at alex.org.uk (Alex Bligh) Date: Fri, 25 Jul 2014 08:38:31 +0100 Subject: GNU netcat in make tests In-Reply-To: <20140725082824.02c7c70e@leda.localdomain> References: <20140724114901.3bdd0d11@leda.localdomain> <20140725082824.02c7c70e@leda.localdomain> Message-ID: <24C93A73-8858-444A-BBB0-35EF44ACAD48@alex.org.uk> On 25 Jul 2014, at 07:28, Christian Hesse wrote: > Damien Miller on Fri, 2014/07/25 09:02: >> On Thu, 24 Jul 2014, Damien Miller wrote: >> >>> In the meantime, maybe we could avoid the use of GNU netcat althother >>> by using a ssh-agent's socket in the tests... >> >> I got halfway through implementing this before realising that it is >> insufficient - we need to tests UNIX domain socket to TCP forwarding >> and ssh-add/agent can't do this. > > Perhaps we should rely on OpenBSD netcat and skip tests if GNU netcat is > found. Perhaps use socat instead? The correct netcat/socat could be detected in configure. -- Alex Bligh -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 842 bytes Desc: Message signed with OpenPGP using GPGMail URL: From igor at mir2.org Fri Jul 25 18:21:42 2014 From: igor at mir2.org (Igor Bukanov) Date: Fri, 25 Jul 2014 10:21:42 +0200 Subject: ssh-agent and socket permission check In-Reply-To: References: Message-ID: On 25 July 2014 08:28, Darren Tucker wrote: > > If you are on Linux then prctl will still prevent ptrace, even without > > setgid. > > Yeah but from memory ssh-agent will also call getpeereid() on the > connecting socket, which will prevent other uids in the same group from > making use of the key without exposing it to copying. > Yes, this a very good point. If I want to avoid a password on the key, then the check [1] indeed makes it impossible to use the agent without exposing the key even if the agent memory itself is not accessible. So an option to relax the check to permit access from any process that belongs to the agent group is still useful even if on Linux access to the agent memory is restricted indeed. Note that currently I workaround that check using socat unix socket redirection and rely on socket access restriction enforced in Linux, but it would be nice to avoid that with a relaxed check in the agent itself. [1] - https://github.com/openssh/openssh-portable/blob/master/ssh-agent.c#L934 From vinschen at redhat.com Fri Jul 25 18:33:57 2014 From: vinschen at redhat.com (Corinna Vinschen) Date: Fri, 25 Jul 2014 10:33:57 +0200 Subject: GNU netcat in make tests In-Reply-To: <20140725082824.02c7c70e@leda.localdomain> References: <20140724114901.3bdd0d11@leda.localdomain> <20140725082824.02c7c70e@leda.localdomain> Message-ID: <20140725083357.GA8876@calimero.vinschen.de> On Jul 25 08:28, Christian Hesse wrote: > Damien Miller on Fri, 2014/07/25 09:02: > > On Thu, 24 Jul 2014, Damien Miller wrote: > > > > > In the meantime, maybe we could avoid the use of GNU netcat althother > > > by using a ssh-agent's socket in the tests... > > > > I got halfway through implementing this before realising that it is > > insufficient - we need to tests UNIX domain socket to TCP forwarding > > and ssh-add/agent can't do this. > > Perhaps we should rely on OpenBSD netcat and skip tests if GNU netcat is > found. Something like this? > > From 9e3fb5105317a4d64ea3d7285f86fa66af623761 Mon Sep 17 00:00:00 2001 > From: Christian Hesse > Date: Fri, 25 Jul 2014 08:26:17 +0200 > Subject: [PATCH 1/1] skip multiplex.sh if nc does not support UNIX domain > sockets > > --- > regress/multiplex.sh | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/regress/multiplex.sh b/regress/multiplex.sh > index 693211b..45480eb 100644 > --- a/regress/multiplex.sh > +++ b/regress/multiplex.sh > @@ -6,7 +6,10 @@ CTL=/tmp/openssh.regress.ctl-sock.$$ > tid="connection multiplexing" > > if have_prog nc ; then > - if nc -h 2>&1 | grep -- -N >/dev/null; then > + if nc -h 2>&1 | grep -- -U >/dev/null; then > + echo "skipped (netcat does not support UNIX domain sockets)" > + exit 0 > + else if nc -h 2>&1 | grep -- -N >/dev/null; then > NC="nc -N"; That would skip all netcat's which implement -U. Like OpenBSD netcat as used on Cygwin, or the ncat tool from http://nmap.org/ as used on Fedora, both of which provide -U for AF_UNIX sockets. That was not really what you want, right? Corinna -- Corinna Vinschen Cygwin Maintainer Red Hat -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From mail at eworm.de Fri Jul 25 18:46:36 2014 From: mail at eworm.de (Christian Hesse) Date: Fri, 25 Jul 2014 10:46:36 +0200 Subject: GNU netcat in make tests In-Reply-To: <20140725083357.GA8876@calimero.vinschen.de> References: <20140724114901.3bdd0d11@leda.localdomain> <20140725082824.02c7c70e@leda.localdomain> <20140725083357.GA8876@calimero.vinschen.de> Message-ID: <20140725104636.28a4984e@leda.localdomain> Corinna Vinschen on Fri, 2014/07/25 10:33: > On Jul 25 08:28, Christian Hesse wrote: > > Damien Miller on Fri, 2014/07/25 09:02: > > > On Thu, 24 Jul 2014, Damien Miller wrote: > > > > > > > In the meantime, maybe we could avoid the use of GNU netcat althother > > > > by using a ssh-agent's socket in the tests... > > > > > > I got halfway through implementing this before realising that it is > > > insufficient - we need to tests UNIX domain socket to TCP forwarding > > > and ssh-add/agent can't do this. > > > > Perhaps we should rely on OpenBSD netcat and skip tests if GNU netcat is > > found. Something like this? > > > > [...] > > That would skip all netcat's which implement -U. Like OpenBSD netcat as > used on Cygwin, or the ncat tool from http://nmap.org/ as used on > Fedora, both of which provide -U for AF_UNIX sockets. > > That was not really what you want, right? Uh, forgot a negation. My bad, sorry. From 9e3fb5105317a4d64ea3d7285f86fa66af623761 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 25 Jul 2014 08:26:17 +0200 Subject: [PATCH 1/1] skip multiplex.sh if nc does not support UNIX domain sockets --- regress/multiplex.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/regress/multiplex.sh b/regress/multiplex.sh index 693211b..45480eb 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh @@ -6,7 +6,10 @@ CTL=/tmp/openssh.regress.ctl-sock.$$ tid="connection multiplexing" if have_prog nc ; then - if nc -h 2>&1 | grep -- -N >/dev/null; then + if ! nc -h 2>&1 | grep -- -U >/dev/null; then + echo "skipped (netcat does not support UNIX domain sockets)" + exit 0 + else if nc -h 2>&1 | grep -- -N >/dev/null; then NC="nc -N"; else NC="nc" -- Schoene Gruesse Chris O< ascii ribbon campaign stop html mail - www.asciiribbon.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From nkadel at gmail.com Fri Jul 25 19:52:41 2014 From: nkadel at gmail.com (Nico Kadel-Garcia) Date: Fri, 25 Jul 2014 05:52:41 -0400 Subject: GNU netcat in make tests In-Reply-To: <20140725083357.GA8876@calimero.vinschen.de> References: <20140724114901.3bdd0d11@leda.localdomain> <20140725082824.02c7c70e@leda.localdomain> <20140725083357.GA8876@calimero.vinschen.de> Message-ID: On Fri, Jul 25, 2014 at 4:33 AM, Corinna Vinschen wrote: > That would skip all netcat's which implement -U. Like OpenBSD netcat as > used on Cygwin, or the ncat tool from http://nmap.org/ as used on > Fedora, both of which provide -U for AF_UNIX sockets. > > That was not really what you want, right? It's also available in the "nmap-ncat" version of netcat on RHEL 7, which was published quite recently. From svenkieske at gmail.com Fri Jul 25 19:45:04 2014 From: svenkieske at gmail.com (Sven Kieske) Date: Fri, 25 Jul 2014 11:45:04 +0200 Subject: improving passphrase protected private keys Message-ID: <53D22720.3000904@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, I got a proposal for a slight different default private key encryption protocol. Here is my understanding what ssh-keygen currently does. According to this article: http://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html when you create a new key with a passphrase to protect it, ssh-keygen uses a hard-coded openssl call to do this: It encrypts the private key with AES-128 in CBC mode, and generates the encryption key the following way: 1. "Append the first 8 bytes of the IV to the passphrase, without a separator (serves as a salt)." 2. "Take the MD5 hash of the resulting string (once)." So my proposal is, to alter this by using PKCS 8 as defined in RFC 5208 as is described in the above article. This currently works already by converting your key manually: openssl pkcs8 -topk8 -v2 des3 \ -in test_rsa_key.old -passin 'pass:super secret passphrase' \ -out test_rsa_key -passout 'pass:super secret passphrase' I didn't find any contradicting documentation or stuff inside the SSH RFCs why this is not the default yet. I know this is just a little hardening and just covers cases where your encrypted private key gets stolen and is harder to bruteforce due to the use of PBKDF2 instead of MD5. What do you think about this? Is there some error in my information which prevents this from being the default way ssh keys are generated? Does this not work on all supported plattforms? Please keep me CC'ed in your answers as I'm not subscribed to the list. kind regards Sven Kieske PS: Thanks for this awesome free software and your work! -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (MingW32) iQGcBAEBAgAGBQJT0icgAAoJEAq0kGAWDrql8vAL/2XS8mhAy5Z1acQBVVA/pLd3 5bLecQQCMEJL8l0zsYSV/6YHBUj7TI0DJleN0qh4OJG+rmK+XIOz4CnnjxY/p/tg dgwy/XSXEqhoVqWajSP6Q+fiYsydAxqyTa7UXIuGtzyWyqldK6x0n5ThTeNqX/LV Qt1kLhIsD+w+0AmNN+ERI1uP72/Y1YhLluIC91lA+OrcL0RRkptXN6Vjo2WYR2e9 Edbk55N8J4Dli7YdycSs0fRykad3zjPqH/KxwOopil7+tis1dJTJIBawZaCWs0nq 7OJzF3bs+7smN5342KscO6hpSZ5igOQH2MkS3SXi8D6E5hX9KODupBtu8eZ7qvdN 4qtYno1EMaVJZUCRALmrqAxtVnkGGvDdzNC3dPGEXPgXq4QTHll9aMbWN4R3rOuC FzMCK97u3DA2ss7+6nY7A1gRSedMPisLGn4fsCYmYn+nVBFKK9s4NXzrGocPgpsA koNhXZCG2B0554NBNincT4gyO++fPQtUtLqKge/msw== =lUo9 -----END PGP SIGNATURE----- From svenkieske at gmail.com Fri Jul 25 21:08:25 2014 From: svenkieske at gmail.com (Sven Kieske) Date: Fri, 25 Jul 2014 13:08:25 +0200 Subject: improving passphrase protected private keys In-Reply-To: <53D22720.3000904@gmail.com> References: <53D22720.3000904@gmail.com> Message-ID: <53D23AA9.5060504@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hum, no I'm a little bit concerned that my request is actually not needed? At least this is what I found in the source, but I'm not that familiar with it: /* openssh private key file format */ #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" #define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" #define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1) #define MARK_END_LEN (sizeof(MARK_END) - 1) #define KDFNAME "bcrypt" #define AUTH_MAGIC "openssh-key-v1" #define SALT_LEN 16 #define DEFAULT_CIPHERNAME "aes256-cbc" #define DEFAULT_ROUNDS 16 from: https://github.com/openssh/openssh-portable/blob/948a1774a79a85f9deba6d74db95f402dee32c69/sshkey.c So it seems you actually use bcrypt as default? Is this already in a released version available? And if yes, since which version? Sorry for creating this noise. kind regards Sven -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (MingW32) iQGcBAEBAgAGBQJT0jqoAAoJEAq0kGAWDrqlK00L/jN78/qf0xhEIo5YHjfLEk3x YJViqOJYQqN+3IkIB6ZqeDTfQyShGLbRVCXnG4u3BMG+YhlmQkO96q3zNv6dYWh2 62R3mEz99vRlPr7WScjbZzLiWCd5yi8nxiEcMomDxD+qhYZ1P3/NcWQZFVxO2Ztf IygA6Z10dHVcQGHupAG8Ng6jMlCjos7rgz0gvghpuU7fbtQtUa/nhqhZwrq6jTBm zbDTB2InD0I/tCx6mN01tq7VBcZSN7VPqnOy1s90uSFp7eHNnhfh5WZ+y+9C6/wg oagBm/JNXn4GIVsiSyh48sNAsCGKCYfA3B/wJIiaYeKc2qDukXsfXExMssqt0WMZ Sqt+bYopTW6AGsHqmhhaTPKgGOPWR6m+W6vUkXrL/Y5jsjOHxZYRidAyOPpRNGFv EB9LWrmfxF1uy6cONyyO661jVqeirE5YgtCtMtVT0qFV0QCygc80HUGWAyWNe33v 66uHd4kQEic0jY+2UFFK89n2gXFc63adtn2rdlhDCw== =4kU7 -----END PGP SIGNATURE----- From dtucker at zip.com.au Sat Jul 26 00:59:01 2014 From: dtucker at zip.com.au (Darren Tucker) Date: Fri, 25 Jul 2014 10:59:01 -0400 Subject: GNU netcat in make tests In-Reply-To: <20140725083357.GA8876@calimero.vinschen.de> References: <20140724114901.3bdd0d11@leda.localdomain> <20140725082824.02c7c70e@leda.localdomain> <20140725083357.GA8876@calimero.vinschen.de> Message-ID: On Fri, Jul 25, 2014 at 4:33 AM, Corinna Vinschen wrote: > > [...] or the ncat tool from http://nmap.org/ as used on > Fedora, both of which provide -U for AF_UNIX sockets. > ncat has a different problem: it doesn't handle FD closures properly. Grab yourself a decent-sized (a MB or two) data file and try this (this is on Fedora 20): $ ncat -l 127.0.0.1 1234 testcopy This will transfer the full file then hang indefinitely waiting for stdin to close: ^C $ ls -l testdata testcopy -rw-r--r-- 1 dtucker dtucker 5485744 Jul 26 00:45 testcopy -rwxr-xr-x 1 dtucker dtucker 5485744 Jul 26 00:43 testdata If you try to work around this by redirecting stdin to /dev/null it'll exit after one pass through the copy loop even though the TCP stream it's writing hasn't been completely written: $ ncat -l 127.0.0.1 1234 testcopy References: <53D22720.3000904@gmail.com> <53D23AA9.5060504@gmail.com> Message-ID: On Fri, Jul 25, 2014 at 7:08 AM, Sven Kieske wrote: [...] > > So it seems you actually use bcrypt as default? > Is this already in a released version available? > And if yes, since which version? > Yes, 6.5. See http://www.openssh.com/txt/release-6.5 -- Darren Tucker (dtucker at zip.com.au) GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 Good judgement comes with experience. Unfortunately, the experience usually comes from bad judgement. From singh.ravipratap88 at gmail.com Sat Jul 26 05:54:40 2014 From: singh.ravipratap88 at gmail.com (RAVI PRATAP Singh) Date: Sat, 26 Jul 2014 01:24:40 +0530 Subject: Does openssh supports multi-channeling ? Message-ID: Hi All, In openssh, do we support multi-channeling? Rather than opening a new TCP socket for each SSH connection, all the SSH connections are multiplexed into one TCP connection. If so, from which version , do openssh supports it? Thanks Ravi Pratap From imorgan at nas.nasa.gov Sat Jul 26 06:17:12 2014 From: imorgan at nas.nasa.gov (Iain Morgan) Date: Fri, 25 Jul 2014 13:17:12 -0700 Subject: Does openssh supports multi-channeling ? In-Reply-To: References: Message-ID: <20140725201712.GA4734@linux124.nas.nasa.gov> On Sat, Jul 26, 2014 at 01:24:40 +0530, RAVI PRATAP Singh wrote: > Hi All, > > In openssh, do we support multi-channeling? > Rather than opening a new TCP socket for each SSH connection, all the SSH > connections are multiplexed into one TCP connection. > > If so, from which version , do openssh supports it? > > Thanks Yes, since 4.4, if I recall correctly. See ControlMaster and ControlPath in ssh_config(5). -- Iain Morgan From bert.wesarg at googlemail.com Sat Jul 26 06:22:50 2014 From: bert.wesarg at googlemail.com (Bert Wesarg) Date: Fri, 25 Jul 2014 22:22:50 +0200 Subject: Does openssh supports multi-channeling ? In-Reply-To: References: Message-ID: Hi, it looks like this had its 10th anniversary last month: djm at cvs.openbsd.org 2004/06/13 15:03:02 [channels.c channels.h clientloop.c clientloop.h includes.h readconf.c] [readconf.h scp.1 sftp.1 ssh.1 ssh.c ssh_config.5] implement session multiplexing in the client (the server has supported this since 2.0); ok markus@ Bert On Fri, Jul 25, 2014 at 9:54 PM, RAVI PRATAP Singh wrote: > Hi All, > > In openssh, do we support multi-channeling? > Rather than opening a new TCP socket for each SSH connection, all the SSH > connections are multiplexed into one TCP connection. > > If so, from which version , do openssh supports it? > > Thanks > Ravi Pratap > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From bert.wesarg at googlemail.com Sat Jul 26 06:28:53 2014 From: bert.wesarg at googlemail.com (Bert Wesarg) Date: Fri, 25 Jul 2014 22:28:53 +0200 Subject: Does openssh supports multi-channeling ? In-Reply-To: <20140725201712.GA4734@linux124.nas.nasa.gov> References: <20140725201712.GA4734@linux124.nas.nasa.gov> Message-ID: On Fri, Jul 25, 2014 at 10:17 PM, Iain Morgan wrote: > On Sat, Jul 26, 2014 at 01:24:40 +0530, RAVI PRATAP Singh wrote: >> Hi All, >> >> In openssh, do we support multi-channeling? >> Rather than opening a new TCP socket for each SSH connection, all the SSH >> connections are multiplexed into one TCP connection. >> >> If so, from which version , do openssh supports it? >> >> Thanks > > Yes, since 4.4, if I recall correctly. See ControlMaster and > ControlPath in ssh_config(5). It was 3.9: http://www.openssh.com/txt/release-3.9 From sshuserga at gmail.com Mon Jul 28 01:58:52 2014 From: sshuserga at gmail.com (sshuser GA) Date: Sun, 27 Jul 2014 21:28:52 +0530 Subject: Query Message-ID: Hello, I recently upgraded to openssh 6.6 version and I am finding public authentication doesn't seem to work. I see the openssh application exits with the error, fatal: key_free: bad key type 1515870810 After I created one more user, it throws the below error and exits. fatal: restore_uid: temporarily use_uid not effective I was able to successfully authenticate using 5.x openssh version. Kindly let me know, if this is a problem with 6.6 version? Regards Opensshuser From nkadel at gmail.com Mon Jul 28 21:09:57 2014 From: nkadel at gmail.com (Nico Kadel-Garcia) Date: Mon, 28 Jul 2014 07:09:57 -0400 Subject: Query In-Reply-To: References: Message-ID: On Sun, Jul 27, 2014 at 11:58 AM, sshuser GA wrote: > Hello, > > I recently upgraded to openssh 6.6 version and I am finding public > authentication doesn't seem to work. I'm not sure this is so much 'openssh-unix-dev' content yet, but I won't try to trim the thread. Start with your basic configuration. If you're not on a stable OpenBSD operating system, you're not on the reference development environment, and may need to use openssh 6.6p1 to get the portability patches. And if you're not familiar enough with debugging powerful software to start out with your own analysis, why are you starting your education with one of the most critical pieces of system software? > I see the openssh application exits with the error, > > fatal: key_free: bad key type 1515870810 > > After I created one more user, it throws the below error and exits. > > fatal: restore_uid: temporarily use_uid not effective > > I was able to successfully authenticate using 5.x openssh version. > Kindly let me know, if this is a problem with 6.6 version? Ghods only know. Did you build openssh 5.x by hand and test that? Or did you grab binaries from your operating system's upstream provider? Wherever possible, when building testing new software, I urge you to work from your upstream provider's reference configuration. It's more likely to correctly follow your upstream conventions, set permissions correctly, and resolve dependencies correctly. I went through that a *lot* of that when local developers would try to stuff their own, personally compiled OpenSSH into working Linux systems with reference OpenSSH distributins. Hilarity would ensue as the OS provided package and the locally built one would overwrite each other or cause weird, weird library dependency confusion, especially when people would "look it up on Google" and start editing the "/etc/ld.so.conf" or manipulating LD_LIBRARY_PATH in /etc/rc and just cause endless confusion. So, start from the beginning. Which OpenSSH bundle or tarball did you use, what OS, and is there still another OpenSSH binary in place? > Regards > Opensshuser > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From scott_n at xypro.com Tue Jul 29 02:19:54 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Mon, 28 Jul 2014 16:19:54 +0000 Subject: Cross Compile Message-ID: For 6.6p1, is there a way to run configure for a cross-compiler? --- Scott Neugroschl | XYPRO Technology Corporation 4100 Guardian Street | Suite 100 |Simi Valley, CA 93063 | Phone 805 583-2874|Fax 805 583-0124 | From peter at stuge.se Tue Jul 29 10:27:39 2014 From: peter at stuge.se (Peter Stuge) Date: Tue, 29 Jul 2014 02:27:39 +0200 Subject: Cross Compile In-Reply-To: References: Message-ID: <20140729002739.6277.qmail@stuge.se> Scott Neugroschl wrote: > For 6.6p1, is there a way to run configure for a cross-compiler? It works the same way as with every other configure script for every other package from every version of autoconf, namely with --host. //Peter From sachin3072004 at gmail.com Tue Jul 29 11:06:46 2014 From: sachin3072004 at gmail.com (Sachin Gupta) Date: Mon, 28 Jul 2014 18:06:46 -0700 Subject: sftp-server log messages Message-ID: Hello, Where does sftp-server logs its messages ? I am using centos 5.2. I used the following command in my sshd_config. Subsystem sftp /usr/libexec/openssh/sftp-server -l DEBUG3 -f DAEMON But I do not see any log messages in /var/log/messages. Thanks Sachin From scott_n at xypro.com Wed Jul 30 01:04:51 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Tue, 29 Jul 2014 15:04:51 +0000 Subject: Cross Compile In-Reply-To: <20140729002739.6277.qmail@stuge.se> References: <20140729002739.6277.qmail@stuge.se> Message-ID: OK. Didn't see a --host option when I ran configure --help -----Original Message----- From: openssh-unix-dev [mailto:openssh-unix-dev-bounces+scott_n=xypro.com at mindrot.org] On Behalf Of Peter Stuge Sent: Monday, July 28, 2014 5:28 PM To: openssh-unix-dev at mindrot.org Subject: Re: Cross Compile Scott Neugroschl wrote: > For 6.6p1, is there a way to run configure for a cross-compiler? It works the same way as with every other configure script for every other package from every version of autoconf, namely with --host. //Peter _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev at mindrot.org https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From dtucker at zip.com.au Wed Jul 30 01:29:15 2014 From: dtucker at zip.com.au (Darren Tucker) Date: Tue, 29 Jul 2014 11:29:15 -0400 Subject: Cross Compile In-Reply-To: References: <20140729002739.6277.qmail@stuge.se> Message-ID: On Tue, Jul 29, 2014 at 11:04 AM, Scott Neugroschl wrote: > OK. Didn't see a --host option when I ran configure --help Looks like it's there. $ cd openssh-6.6p1 $ ./configure --help | grep -- --host --host=HOST cross-compile to build programs to run on HOST [BUILD] -- Darren Tucker (dtucker at zip.com.au) GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 Good judgement comes with experience. Unfortunately, the experience usually comes from bad judgement. From sven at timegate.de Wed Jul 30 02:14:05 2014 From: sven at timegate.de (Sven Hoexter) Date: Tue, 29 Jul 2014 18:14:05 +0200 Subject: Match directive and negations Message-ID: <20140729161404.GA3134@garkbit.lan> Hi, I tried to setup some special cases with the help of the "Match" directive in sshd_config and stumbled over how negations in the pattern matching work. What I tried first was Match User !root, Group !mygroup which to my momentary surprise did not work. After carefully re-reading the manpage, and some try and error I've understood that the logic is based on set theory and I tried to essentially exclude user/groups from an empty set, which of course has no result and thus can not match anything. So a Match User *,!root, Group *,!mygroup worked for my case. I guess it's intentional that there is no kind of default filling of the set you match on, so I would propose a patch to the ssh_config.5 manpage to make it a bit more obvious. Sven -------------- next part -------------- A non-text attachment was scrubbed... Name: ssh_config.5_negations.diff Type: text/x-diff Size: 726 bytes Desc: not available URL: From scott_n at xypro.com Wed Jul 30 04:43:02 2014 From: scott_n at xypro.com (Scott Neugroschl) Date: Tue, 29 Jul 2014 18:43:02 +0000 Subject: Cross Compile In-Reply-To: References: <20140729002739.6277.qmail@stuge.se> Message-ID: Yeah, I just missed it. Old eyes.... you know how it goes :) -----Original Message----- From: dtucker at dtucker.net [mailto:dtucker at dtucker.net] On Behalf Of Darren Tucker Sent: Tuesday, July 29, 2014 8:29 AM To: Scott Neugroschl Cc: Peter Stuge; openssh-unix-dev at mindrot.org Subject: Re: Cross Compile On Tue, Jul 29, 2014 at 11:04 AM, Scott Neugroschl wrote: > OK. Didn't see a --host option when I ran configure --help Looks like it's there. $ cd openssh-6.6p1 $ ./configure --help | grep -- --host --host=HOST cross-compile to build programs to run on HOST [BUILD] -- Darren Tucker (dtucker at zip.com.au) GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 Good judgement comes with experience. Unfortunately, the experience usually comes from bad judgement. From keisial at gmail.com Wed Jul 30 05:27:20 2014 From: keisial at gmail.com (=?ISO-8859-1?Q?=C1ngel_Gonz=E1lez?=) Date: Tue, 29 Jul 2014 21:27:20 +0200 Subject: Match directive and negations In-Reply-To: <20140729161404.GA3134@garkbit.lan> References: <20140729161404.GA3134@garkbit.lan> Message-ID: <53D7F598.6090205@gmail.com> Sven Hoexter wrote: > I guess it's intentional that there is no kind of default > filling of the set you match on, so I would propose a patch > to the ssh_config.5 manpage to make it a bit more obvious. > > Sven I think that would also deserve a runtime warning. From keisial at gmail.com Wed Jul 30 05:40:16 2014 From: keisial at gmail.com (=?ISO-8859-1?Q?=C1ngel_Gonz=E1lez?=) Date: Tue, 29 Jul 2014 21:40:16 +0200 Subject: Cross Compile In-Reply-To: References: <20140729002739.6277.qmail@stuge.se> Message-ID: <53D7F8A0.7020800@gmail.com> Scott Neugroschl wrote: > Yeah, I just missed it. Old eyes.... you know how it goes :) No problem. I wish all issues were so easy to solve :) From keisial at gmail.com Wed Jul 30 05:39:02 2014 From: keisial at gmail.com (=?ISO-8859-1?Q?=C1ngel_Gonz=E1lez?=) Date: Tue, 29 Jul 2014 21:39:02 +0200 Subject: sftp-server log messages In-Reply-To: References: Message-ID: <53D7F856.80602@gmail.com> On 29/07/14 03:06, Sachin Gupta wrote: > Hello, > > Where does sftp-server logs its messages ? > I am using centos 5.2. Which openssh version is used there? > I used the following command in my sshd_config. > > Subsystem sftp /usr/libexec/openssh/sftp-server -l DEBUG3 -f DAEMON > > But I do not see any log messages in /var/log/messages. > > Thanks > Sachin Are you using ChrootDirectory? In that case, is there a /dev/log inside the chroot? Regards From keisial at gmail.com Wed Jul 30 05:51:17 2014 From: keisial at gmail.com (=?ISO-8859-1?Q?=C1ngel_Gonz=E1lez?=) Date: Tue, 29 Jul 2014 21:51:17 +0200 Subject: Read-only on /dev/tty causes ssh-add to show passwords when typed and ssh'ing to new hosts to fail In-Reply-To: <20140721071012.GH1118@greenie.muc.de> References: <53C9AAF5.80901@jimkeener.com> <20140720205826.GF1118@greenie.muc.de> <20140721071012.GH1118@greenie.muc.de> Message-ID: <53D7FB35.8070009@gmail.com> On 21/07/14 09:10, Gert Doering wrote: > Well, you already *have* that special case - "if /dev/tty isn't working, > assume we do not have a controlling tty and use stdin". The question is > whether you can (and want to) distinguish "I have no controlling tty" > from "/dev/tty is messed up -> print error and die". > > gert Well, if you consider ssh-add should fail in that case, you can simply do this: > diff --git a/ssh-add.c b/ssh-add.c > index 3421452..977b3f1 100644 > --- a/ssh-add.c > +++ b/ssh-add.c > @@ -213,7 +213,7 @@ add_file(AuthenticationConnection *ac, const char > *filename, int key_only) > snprintf(msg, sizeof msg, "Enter passphrase for %.200s: ", > comment); > for (;;) { > - pass = read_passphrase(msg, RP_ALLOW_STDIN); > + pass = read_passphrase(msg, 0); > if (strcmp(pass, "") == 0) { > clear_pass(); > free(comment); From terrafrost at gmail.com Thu Jul 31 06:37:25 2014 From: terrafrost at gmail.com (Terra Frost) Date: Wed, 30 Jul 2014 15:37:25 -0500 Subject: checking for "dh_gen_key: group too small" errors Message-ID: On Ubuntu 12.04 / OpenSSH_5.9p1 Debian-5ubuntu1 trying to initiate a connection with hmac-sha2-512 and diffie-hellman-group1-sha1 results in OpenSSH killing the connection after the SSH_MSG_KEXINIT packet is sent. The OpenSSH error logs state the following: debug2: mac_setup: found hmac-sha2-512 [preauth] debug1: kex: server->client arcfour256 hmac-sha2-512 none [preauth] dh_gen_key: group too small: 1024 (2*need 1024) [preauth] debug1: do_cleanup [preauth] This behavior, I believe, is in error as the shared secret produced by the diffie-hellman key exchange is essentially extended to the appropriate length by successive hashes that are concatenated together per RFC4253#section-7.2 Also, it works fine in Ubuntu 14.04 / OpenSSH_6.6p1 Ubuntu-2ubuntu1. My question is... for what versions of OpenSSH an issue? I'd like to hide hmac-sha2-512 from the list of supported MAC's the client sends over for all the affected SSH servers (ie. similar to how PuTTY handles SSH server bugs with http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter4.html#config-ssh-bugs). To do so, however, I need to know what I need to look for in the identification strings. ie. if this issue was present on all versions of OpenSSH prior to 6.5 I could just look for any identification string for which substr(identification-string, 8, 3) < '6.5'. If the issue is present in any server who's identification string ends with Debian-5ubuntu1 I could make a similar check for that. I just need to know what I should be checking for. Is there perchance a link that'd discuss this in more detail? From list at eworm.de Thu Jul 31 17:19:35 2014 From: list at eworm.de (Christian Hesse) Date: Thu, 31 Jul 2014 09:19:35 +0200 Subject: corrupted copy in regress/multiplex.sh In-Reply-To: <20140725091450.7a537255@leda.localdomain> References: <20140725091450.7a537255@leda.localdomain> Message-ID: <20140731091935.39219cf1@leda.localdomain> Christian Hesse on Fri, 2014/07/25 09:14: > Hello everybody, > > after installing openbsd-netcat some tests in multiplex.sh do still fail for > me. Sadly this happens when trying to build a package only, everything works > just fine if I try to debug this. Any ideas? Logfile failed-regress.log is > attached. Looks like the copy is truncated for any reason... In some really rare cases the tests succeed. (Though I have never seen both to succeed at the same time.) Still no clue what really is the culprit. -- main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH" "CX:;",b;for(a/* Chris get my mail address: */=0;b=c[a++];) putchar(b-1/(/* gcc -o sig sig.c && ./sig */b/42*2-3)*42);} -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From peter at stuge.se Thu Jul 31 18:38:47 2014 From: peter at stuge.se (Peter Stuge) Date: Thu, 31 Jul 2014 10:38:47 +0200 Subject: corrupted copy in regress/multiplex.sh In-Reply-To: <20140731091935.39219cf1@leda.localdomain> References: <20140725091450.7a537255@leda.localdomain> <20140731091935.39219cf1@leda.localdomain> Message-ID: <20140731083847.25075.qmail@stuge.se> Christian Hesse wrote: > > after installing openbsd-netcat some tests in multiplex.sh do still fail for > > me. Sadly this happens when trying to build a package only, everything works > > just fine if I try to debug this. Any ideas? Logfile failed-regress.log is > > attached. > > Looks like the copy is truncated for any reason... In some really rare cases > the tests succeed. (Though I have never seen both to succeed at the same > time.) Still no clue what really is the culprit. Maybe a pipe is line buffered? //Peter -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 190 bytes Desc: not available URL: