From candland at xmission.com Wed Nov 3 02:21:18 2010 From: candland at xmission.com (Rob C) Date: Tue, 2 Nov 2010 09:21:18 -0600 Subject: SFTP subsystem and umask Message-ID: <20101102152118.GA29504@shell.xmission.com> Hello, I have noticed that the -u parameter to the sftp-server or internal-sftp subsystem is not working correctly. For openssh-5.6p1 I believe that the problem lies in this code, starting at line 1414 in sftp-server.c: ---------------------------------------------------------- case 'u': mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); if (errmsg != NULL) fatal("Invalid umask \"%s\": %s", optarg, errmsg); (void)umask(mask); break; ---------------------------------------------------------- I think that adherence to strtonum() in this instance causes unexpected results due to "mask" being set to decimal/base 10. For example, say you had the following in sshd_config: Subsystem sftp /usr/local/libexec/sftp-server -u 022 Then say you upload a file with permissions of 777 via sftp -p, you would expect the uploaded file to end up with permission of 755, right? In this case you get a file with permissions of 751 or -rwxr-x--x. Why? I believe it is because decimal 22 == octal 026. Further compounding the problem is that sftp-server doggedly insists upon accepting permissions from the sftp client before it applies umask. To test, set the following in your sshd_config: Subsystem sftp /your/path/to/sftp-server -u 18 Then kill -HUP sshd and create a file on the client with permissions of 777. Upload the file via sftp -p and observe permissions of the file created by sftp-server. I ended up with a file with permissions of 755. I think it's because decimal 18 == octal 022..... Is the solution to use strtol() or strtoul()? You would end up having to trust the user to use sane values in sshd_config, or trust that a user will run sftp-server with sane parameters. I tested using RHEL4 and Ubuntu 10.04. Best regards, Rob Candland From mduft at gentoo.org Wed Nov 3 02:48:26 2010 From: mduft at gentoo.org (Markus Duft) Date: Tue, 02 Nov 2010 16:48:26 +0100 Subject: Interix Port In-Reply-To: <4CC7EEA9.20202@gentoo.org> References: <4CC7EEA9.20202@gentoo.org> Message-ID: <4CD032CA.6080301@gentoo.org> On 10/27/2010 11:19 AM, Markus Duft wrote: > Hi! > > Thanks for the suggestions. Attached is another version of the patch > for the second review round ;) ping. no comments on this? any chance to get this into the vcs? markus > > I tried to - as much as possible - use the same preprocessor syntax, > and - again, as much as possible - use the log infrastructure. however > the big fat INTERIX_PWD_WARNING must be written on stderr directly, as > even with error(), it won't appear if the _server_ is not at least in > verbose mode (one -v), which is not what i want. anything i missed there? > > the rest is pretty much the same, but without buffer overflow, with > added configure check for res_query - and thus a feature flag, etc ;) > > (BTW: now subscribed to the list, so i should be able to reply on future > mails - sorry for breaking the thread ... ) > > Regards, and thanks, > Markus > > > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From djm at mindrot.org Wed Nov 3 12:53:05 2010 From: djm at mindrot.org (Damien Miller) Date: Wed, 3 Nov 2010 12:53:05 +1100 (EST) Subject: SFTP subsystem and umask In-Reply-To: <20101102152118.GA29504@shell.xmission.com> References: <20101102152118.GA29504@shell.xmission.com> Message-ID: On Tue, 2 Nov 2010, Rob C wrote: > Hello, > > I have noticed that the -u parameter to the sftp-server or > internal-sftp subsystem is not working correctly. For openssh-5.6p1 I > believe that the problem lies in this code, starting at line 1414 in > sftp-server.c: > > ---------------------------------------------------------- > case 'u': > mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); > if (errmsg != NULL) > fatal("Invalid umask \"%s\": %s", > optarg, errmsg); > (void)umask(mask); > break; > ---------------------------------------------------------- Yep, that is completely broken. Please try this patch: Index: sftp-server.c =================================================================== RCS file: /cvs/src/usr.bin/ssh/sftp-server.c,v retrieving revision 1.91 diff -u -p -r1.91 sftp-server.c --- sftp-server.c 13 Jan 2010 01:40:16 -0000 1.91 +++ sftp-server.c 3 Nov 2010 01:52:50 -0000 @@ -1349,8 +1349,7 @@ sftp_server_main(int argc, char **argv, ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; char *cp, buf[4*4096]; - const char *errmsg; - mode_t mask; + long mask; extern char *optarg; extern char *__progname; @@ -1383,11 +1382,12 @@ sftp_server_main(int argc, char **argv, error("Invalid log facility \"%s\"", optarg); break; case 'u': - mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); - if (errmsg != NULL) - fatal("Invalid umask \"%s\": %s", - optarg, errmsg); - (void)umask(mask); + errno = 0; + mask = strtol(optarg, &cp, 8); + if (mask < 0 || mask > 0777 || *cp != '\0' || + cp == optarg || (mask == 0 && errno != 0)) + fatal("Invalid umask \"%s\"", optarg); + (void)umask((mode_t)mask); break; case 'h': default: From djm at mindrot.org Wed Nov 3 12:53:55 2010 From: djm at mindrot.org (Damien Miller) Date: Wed, 3 Nov 2010 12:53:55 +1100 (EST) Subject: Interix Port In-Reply-To: <4CD032CA.6080301@gentoo.org> References: <4CC7EEA9.20202@gentoo.org> <4CD032CA.6080301@gentoo.org> Message-ID: On Tue, 2 Nov 2010, Markus Duft wrote: > On 10/27/2010 11:19 AM, Markus Duft wrote: > > Hi! > > > > Thanks for the suggestions. Attached is another version of the patch > > for the second review round ;) > > ping. no comments on this? any chance to get this into the vcs? if you haven't already, please submit the patch as a bug on https://bugzilla.mindrot.org/ > > > > I tried to - as much as possible - use the same preprocessor syntax, > > and - again, as much as possible - use the log infrastructure. however > > the big fat INTERIX_PWD_WARNING must be written on stderr directly, as > > even with error(), it won't appear if the _server_ is not at least in > > verbose mode (one -v), which is not what i want. anything i missed there? > > > > the rest is pretty much the same, but without buffer overflow, with > > added configure check for res_query - and thus a feature flag, etc ;) > > > > (BTW: now subscribed to the list, so i should be able to reply on future > > mails - sorry for breaking the thread ... ) > > > > Regards, and thanks, > > Markus > > > > > > > > _______________________________________________ > > openssh-unix-dev mailing list > > openssh-unix-dev at mindrot.org > > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > From mduft at gentoo.org Wed Nov 3 18:04:23 2010 From: mduft at gentoo.org (Markus Duft) Date: Wed, 03 Nov 2010 08:04:23 +0100 Subject: Interix Port In-Reply-To: References: <4CC7EEA9.20202@gentoo.org> <4CD032CA.6080301@gentoo.org> Message-ID: <4CD10977.3040405@gentoo.org> On 11/03/2010 02:53 AM, Damien Miller wrote: > On Tue, 2 Nov 2010, Markus Duft wrote: > >> On 10/27/2010 11:19 AM, Markus Duft wrote: >>> Hi! >>> >>> Thanks for the suggestions. Attached is another version of the patch >>> for the second review round ;) >> >> ping. no comments on this? any chance to get this into the vcs? > > if you haven't already, please submit the patch as a bug on > https://bugzilla.mindrot.org/ ok, thanks - i will do so. markus > >>> >>> I tried to - as much as possible - use the same preprocessor syntax, >>> and - again, as much as possible - use the log infrastructure. however >>> the big fat INTERIX_PWD_WARNING must be written on stderr directly, as >>> even with error(), it won't appear if the _server_ is not at least in >>> verbose mode (one -v), which is not what i want. anything i missed there? >>> >>> the rest is pretty much the same, but without buffer overflow, with >>> added configure check for res_query - and thus a feature flag, etc ;) >>> >>> (BTW: now subscribed to the list, so i should be able to reply on future >>> mails - sorry for breaking the thread ... ) >>> >>> Regards, and thanks, >>> Markus >>> >>> >>> >>> _______________________________________________ >>> openssh-unix-dev mailing list >>> openssh-unix-dev at mindrot.org >>> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev >> >> _______________________________________________ >> openssh-unix-dev mailing list >> openssh-unix-dev at mindrot.org >> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev >> > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From paul.bradley.listmail at gmail.com Thu Nov 4 02:55:24 2010 From: paul.bradley.listmail at gmail.com (Paul Bradley) Date: Wed, 3 Nov 2010 15:55:24 +0000 Subject: x509 cert chain In-Reply-To: <4CCD4BC4.1060004@roumenpetrov.info> References: <58F774BBB3E7499A8810D3169F5D7D9F@d8400> <4CCD4BC4.1060004@roumenpetrov.info> Message-ID: Thankyou all for the information. I will hold off for a week or two before making a decision, as although I have only a few client machines and servers here (it's just a home network) I am actually thinking of using Samba4 to put in a pseudo active directory domain to manage my windows client machines using group policy. If I do that, I will need LDAP and a Kerberos box so if getting openssh to work with x509 certs means patching it (on all the servers, each time I update) it may be easier to just centralise it and authenticate to the Kerberos with x509 then do kerberos authentication to the ssh servers. Thanks anyway, and I won't rule out just doing it on each box individually using Roumen's patches, but I suspect I might go with the kerberos solution. All the best and thanks again for the help. Paul On 10/31/10, Roumen Petrov wrote: > Plau, > > Hostbased authentication require SSL Server in "Netscape Cert Type" for > the server certificate. > Otherwise user could update AllowedCertPurpose as default is sslserver. > > Please check for EnableSSHKeysign in user configuration. > > Roumen > > > Erwin Himawan wrote: >> I was able to patch openssh using Roumen Petrovs' >> I was able to perform x509 mutual authentication between the client >> and daemon. >> I was also able to perform CRL verfication/ >> However, My CA has oly one leve; I.e. RootCA issues certificate to >> openssh daemon and openSSH client. >> Due to time constraint, I have not tried multi-level CA like yours. I >> am still interested to try multi-level CA. >> >> So, If you want, send me your daemon config file, client config file, >> and client's known host and daeom's knowhost files. >> I can take a look into your config file and help you troubleshoot. >> >> Erwin >> >> -------------------------------------------------- >> From: "Paul Bradley" >> Sent: Saturday, October 30, 2010 4:15 AM >> To: >> Subject: Re: x509 cert chain >> >>> Sorry for the followup - I forgot something: >>> >>> I'd also like to know how I get an x509 certificate into the server >>> for it >>> to use as it's host key, so both the host and users can verify each >>> other >>> using the same CA. >>> >>> thanks >>> >>> Paul >>> >>> >>> On Sat, Oct 30, 2010 at 10:11 AM, Paul Bradley < >>> paul.bradley.listmail at gmail.com> wrote: >>> >>>> >>>> Hi, >>>> >>>> I am trying to set up OpenSSH with x509 certs and I'm getting >>>> nowhere. I've >>>> been at this on and off for days and doing all the googling I can >>>> but I'm >>>> still not making progress so any help would be very much appreciated. I >>>> believe the latest OpenSSH builds support x509 certificates - I'm >>>> running >>>> 5.5 on Ubuntu 10.04. >>>> >>>> What I want to do is have users on Windows boxes using PuttySC or >>>> similar >>>> (suggestions welcome) log in without needing to enter a >>>> username/password, >>>> using an x509 certificate stored on a smartcard / token. >>>> >>>> The user identities already exist (x509 certs + private keys) and >>>> there is >>>> a multi-level CA structure. It's a simple one though: ROOT CA -> >>>> POLICY >>>> CA -> ISSUING CA -> USER CERTIFICATE >>>> >>>> How do I configure OpenSSH to allow logins from users who have >>>> certificates >>>> signed by the trusted issuing CA at the end of the chain above. >>>> Presumably >>>> the server needs the whole CA chain and I've tried cat'ing the .pem >>>> files >>>> for the CA certificates together and copying the result to a file >>>> that I've >>>> pointed to with CACertificateFile in sshd_config. >>>> >>>> In the authorized_keys I've got: >>>> x509v3-sign-rsa subject= >>>> /C=COUNTRY/ST=STATE/O=ORGANIZATION/OU=OU/CN=CN ie. >>>> the DN of the ROOT CA certificate - should this instead be the >>>> issuing CA? >>>> >>>> Generally any pointers would be very helpful, I've found Roumen Petrovs >>>> patches and read some of his stuff but I find it a bit difficult to >>>> follow >>>> and in any case I'm not sure how relevant his implementation is to the >>>> mainline openssh 5.4/5.5 x509. >>>> >>>> Thanks >>>> >>>> Paul >>>> >>>> >>> _______________________________________________ >>> openssh-unix-dev mailing list >>> openssh-unix-dev at mindrot.org >>> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev >> >> _______________________________________________ >> openssh-unix-dev mailing list >> openssh-unix-dev at mindrot.org >> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > > > -- > Get X.509 certificates support in OpenSSH: > http://roumenpetrov.info/openssh/ > > From peter at stuge.se Thu Nov 4 22:52:16 2010 From: peter at stuge.se (Peter Stuge) Date: Thu, 4 Nov 2010 12:52:16 +0100 Subject: x509 cert chain In-Reply-To: References: <58F774BBB3E7499A8810D3169F5D7D9F@d8400> <4CCD4BC4.1060004@roumenpetrov.info> Message-ID: <20101104115216.14013.qmail@stuge.se> Paul Bradley wrote: > if getting openssh to work with x509 certs means patching it (on > all the servers, each time I update) Suggest using a distribution on your servers that can take care of this for you. //Peter From djm at mindrot.org Fri Nov 5 09:19:18 2010 From: djm at mindrot.org (Damien Miller) Date: Fri, 5 Nov 2010 09:19:18 +1100 (EST) Subject: x509 cert chain In-Reply-To: References: <20101030112740.22570.qmail@stuge.se> Message-ID: On Sun, 31 Oct 2010, Damien Miller wrote: > On Sat, 30 Oct 2010, Peter Stuge wrote: > > > Paul Bradley wrote: > > > I believe the latest OpenSSH builds support x509 certificates > > > > Not at all. OpenSSH uses it's own certificate format. > > > > > > > I've found Roumen Petrovs patches and read some of his stuff but I > > > find it a bit difficult to follow and in any case I'm not sure how > > > relevant his implementation is to the mainline openssh 5.4/5.5 > > > x509. > > > > There is no x509 in OpenSSH mainline. You need the patches if that is > > what you want. > > Yes, Roumen Petrov has maintained some for quite a few years: > > http://www.roumenpetrov.info/openssh/ Also, FWIW I will probably try to implement some basic chaining in OpenSSH certs at some point too. -d From candland at xmission.com Fri Nov 5 10:43:48 2010 From: candland at xmission.com (Rob C) Date: Thu, 4 Nov 2010 17:43:48 -0600 Subject: Explicit file permissions for sftp-server Message-ID: <20101104234348.GA17793@shell.xmission.com> Hello again, Even with umask working (thanks very much!) I have found that I require more control over file permissions with sftp-server/internal-sftp. Please see the attached patch. It adds yet another option to sftp-server (-m) that will force file permissions. I have a been running a patched version of 5.6p1 under RHEL4 in production with no problems. Please consider including this change or something similar in the next release. Please note that the attached patch is a diff from cvs version 1.92 of sftp-server.c Best regards and thanks again, Rob Candland -- -------------- next part -------------- A non-text attachment was scrubbed... Name: openssh-forcefileperm.patch Type: text/x-diff Size: 2632 bytes Desc: not available URL: From dtucker at zip.com.au Fri Nov 5 15:15:33 2010 From: dtucker at zip.com.au (Darren Tucker) Date: Fri, 5 Nov 2010 15:15:33 +1100 Subject: test request: SCO with setluid() (i686-pc-sco3.2v5.0.7, possibly others) Message-ID: <20101105041533.GA23811@gate.dtucker.net> Hi all. I am cleaning up (I hope) one of the nastier pieces of code in openssh: do_setusercontext which is/was a twisty maze of platform-specific nested ifdefs. I made a series of changes[1] where I moved each platform-specific piece into a portable-only file platform.c, which does not need to be kept in sync with OpenBSD. The changes did not (I hope!) change the semantics, but there's one change I'd like to make that doesn't fit into the new scheme: the code that calls setluid. The code in question dates back to at least 2001 and I suspect its current location is mere historical accident. Based on some cvs archaeology and looking at the survey[2] data, I believe this only affects SCO platforms, possibly limited to *-pc-sco3.2v*. If anyone is still in possesion of such a beast, could you please try the patch below (against today's snapshot or newer) and see if it still behaves as expected? Thanks. [1] http://anoncvs.mindrot.org/index.cgi/openssh/session.c?r1=1.398&r2=1.408 [2] plug: have you sent survey info for your platform? if not, try "make survey"! Index: platform.c =================================================================== RCS file: /var/cvs/openssh/platform.c,v retrieving revision 1.14 diff -u -p -r1.14 platform.c --- platform.c 5 Nov 2010 03:47:01 -0000 1.14 +++ platform.c 5 Nov 2010 04:08:42 -0000 @@ -109,6 +109,14 @@ platform_setusercontext(struct passwd *p } } # endif /* USE_PAM */ + +#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) + if (getuid() == 0 || geteuid() == 0) { + /* Sets login uid for accounting */ + if (getluid() == -1 && setluid(pw->pw_uid) == -1) + error("setluid: %s", strerror(errno)); + } +#endif } /* Index: session.c =================================================================== RCS file: /var/cvs/openssh/session.c,v retrieving revision 1.408 diff -u -p -r1.408 session.c --- session.c 5 Nov 2010 03:47:01 -0000 1.408 +++ session.c 5 Nov 2010 04:08:42 -0000 @@ -1479,12 +1479,6 @@ do_setusercontext(struct passwd *pw) exit(1); } #else -# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID) - /* Sets login uid for accounting */ - if (getluid() == -1 && setluid(pw->pw_uid) == -1) - error("setluid: %s", strerror(errno)); -# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */ - if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); if (setgid(pw->pw_gid) < 0) { -- 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 jmknoble at pobox.com Fri Nov 5 16:27:28 2010 From: jmknoble at pobox.com (Jim Knoble) Date: Thu, 4 Nov 2010 22:27:28 -0700 Subject: Explicit file permissions for sftp-server Message-ID: Recommend filing patch in OpenSSH Bugzilla (https://bugzilla.mindrot.org/ ) so it doesn't get lost. -- jim knoble | jmknoble at pobox.com On Nov 4, 2010, at 16:43, Rob C wrote: > Hello again, > > Even with umask working (thanks very much!) I have found that I > require > more control over file permissions with sftp-server/internal-sftp. > > Please see the attached patch. It adds yet another option to > sftp-server (-m) that will force file permissions. > > I have a been running a patched version of 5.6p1 under RHEL4 in > production with no problems. Please consider including this change or > something similar in the next release. > > Please note that the attached patch is a diff from cvs version 1.92 of > sftp-server.c > > Best regards and thanks again, > > Rob Candland > > -- > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From gert at greenie.muc.de Fri Nov 5 20:46:03 2010 From: gert at greenie.muc.de (Gert Doering) Date: Fri, 5 Nov 2010 10:46:03 +0100 Subject: test request: SCO with setluid() (i686-pc-sco3.2v5.0.7, possibly others) In-Reply-To: <20101105041533.GA23811@gate.dtucker.net> References: <20101105041533.GA23811@gate.dtucker.net> Message-ID: <20101105094603.GH10703@greenie.muc.de> Hi, On Fri, Nov 05, 2010 at 03:15:33PM +1100, Darren Tucker wrote: > The changes did not (I hope!) change the semantics, but there's one > change I'd like to make that doesn't fit into the new scheme: the code > that calls setluid. The code in question dates back to at least 2001 and > I suspect its current location is mere historical accident. Based on > some cvs archaeology and looking at the survey[2] data, I believe this > only affects SCO platforms, possibly limited to *-pc-sco3.2v*. I can try building on a SCO OSR 3.0 (sco3.2v4.2) or SCO OSE 5 (sco3.2v5) system. Will investigate this weekend. 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 candland at xmission.com Fri Nov 5 06:31:59 2010 From: candland at xmission.com (Rob C) Date: Thu, 4 Nov 2010 13:31:59 -0600 Subject: SFTP subsystem and explicit file permissions Message-ID: <20101104193159.GA5611@shell.xmission.com> Hello again, Now that umask is working (thanks very much!) I have found that I would like to see more control over sftp-server/internal-sftp file permissions. Given that previous patches (sftp file control comes to mind) were produced indicates there are other users that would also like more control over file permissions. My solution was to add yet another option to sftp-server/internal-sftp that forces file permissions, so something like the following in sshd_config: Match Group sftponly ChrootDirectory /home/chroot-%u ForceCommand internal-sftp -m 660 Or even globally: Subsystem sftp /usr/local/libexec/sftp-server -m 600 Please see the attached patch. I have only been able to test the changes on RHEL4 and Ubuntu 10.04. I have been running a patched version of 5.6p1 in production on RHEL4 and haven't had any problems. Note that the attached patch was produced against the 1.92 version of sftp-server.c. Best regards, Rob Candland -- -------------- next part -------------- A non-text attachment was scrubbed... Name: openssh-forcefileperm.patch Type: text/x-diff Size: 2632 bytes Desc: not available URL: From ynonrapoport at gmail.com Tue Nov 9 01:45:33 2010 From: ynonrapoport at gmail.com (ynon repoport) Date: Mon, 8 Nov 2010 16:45:33 +0200 Subject: openssh question Message-ID: The denyUsers / AllowUsers option in openSSH does not satisfy our needs. We want to supply our own software to allow/deny sessions based on time of day. I do not know if PAM can do this, but in any case we can not use PAM. ? Did someone do such a change in openSSH code From jlpicard15 at hotmail.com Tue Nov 9 09:51:05 2010 From: jlpicard15 at hotmail.com (JL Picard) Date: Mon, 8 Nov 2010 17:51:05 -0500 Subject: How to explicitly define the default setting for ProxyCommand for a particular host Message-ID: I would like to create an ssh_config file with two basic groups of settings: A default "Host *" settings group with: Proxycommand=/my/helper/binary %h %p And another specific "Host specialServer" settings group with ProxyCommand= or ProxyCommand='' And yes, my current ssh_config file is setup in the correct order with the "Host *" declaration last. Host specialServer ProxyCommand=XXXXXXX Host * Proxycommand=/my/helper/binary %h %p I would like to know what I should put in for XXXXXXX, so that server=specialServer just directly SSH's without any proxy command From dtucker at zip.com.au Tue Nov 9 11:39:52 2010 From: dtucker at zip.com.au (Darren Tucker) Date: Tue, 09 Nov 2010 11:39:52 +1100 Subject: How to explicitly define the default setting for ProxyCommand for a particular host In-Reply-To: References: Message-ID: <4CD89858.1050405@zip.com.au> On 9/11/10 9:51 AM, JL Picard wrote: [...] > I would like to know what I should put in for XXXXXXX, so that > server=specialServer just directly SSH's without any proxy command "ProxyCommand none", which was introduced in v3.6. From ssh_config(5): ProxyCommand [...] Setting the command to ``none'' disables this option entirely. -- 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 dtucker at zip.com.au Tue Nov 9 11:49:20 2010 From: dtucker at zip.com.au (Darren Tucker) Date: Tue, 09 Nov 2010 11:49:20 +1100 Subject: openssh question In-Reply-To: References: Message-ID: <4CD89A90.2070509@zip.com.au> On 9/11/10 1:45 AM, ynon repoport wrote: > The denyUsers / AllowUsers option in openSSH does not satisfy our > needs. > > We want to supply our own software to allow/deny sessions based on > time of day. > > I do not know if PAM can do this, but in any case we can not use > PAM. A PAM module could do this (eg LinuxPAM's pam_time). > ? Did someone do such a change in openSSH code You could potentially add code to Match to invoke an external program, but it would have to be done very carefully to avoid introducing a security problem. Can you describe the system some more? There might be a simple solution (eg you could swap sshd_config files and SIGHUP sshd from a cron job). -- 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 tim at multitalents.net Tue Nov 9 12:51:36 2010 From: tim at multitalents.net (Tim Rice) Date: Mon, 8 Nov 2010 17:51:36 -0800 (PST) Subject: test request: SCO with setluid() (i686-pc-sco3.2v5.0.7, possibly others) In-Reply-To: <20101105041533.GA23811@gate.dtucker.net> References: <20101105041533.GA23811@gate.dtucker.net> Message-ID: On Fri, 5 Nov 2010, Darren Tucker wrote: > The changes did not (I hope!) change the semantics, but there's one > change I'd like to make that doesn't fit into the new scheme: the code > that calls setluid. The code in question dates back to at least 2001 and > I suspect its current location is mere historical accident. Based on Well, in do_setusercontext() does look apropriate to me. > some cvs archaeology and looking at the survey[2] data, I believe this > only affects SCO platforms, possibly limited to *-pc-sco3.2v*. And *-*-sysv5SCO_SV* > If anyone is still in possesion of such a beast, could you please try > the patch below (against today's snapshot or newer) and see if it still > behaves as expected? The patch looks good. I'll build and run on a couple of machines here and let you know. -- Tim Rice Multitalents (707) 887-1469 tim at multitalents.net From tim at multitalents.net Tue Nov 9 17:16:02 2010 From: tim at multitalents.net (Tim Rice) Date: Mon, 8 Nov 2010 22:16:02 -0800 (PST) Subject: test request: SCO with setluid() (i686-pc-sco3.2v5.0.7, possibly others) In-Reply-To: References: <20101105041533.GA23811@gate.dtucker.net> Message-ID: On Mon, 8 Nov 2010, Tim Rice wrote: > > If anyone is still in possesion of such a beast, could you please try > > the patch below (against today's snapshot or newer) and see if it still > > behaves as expected? > > The patch looks good. I'll build and run on a couple of machines here > and let you know. ok tim. -- Tim Rice Multitalents (707) 887-1469 tim at multitalents.net From jlpicard15 at hotmail.com Thu Nov 11 10:25:46 2010 From: jlpicard15 at hotmail.com (JL Picard) Date: Wed, 10 Nov 2010 18:25:46 -0500 Subject: Exit Codes on Reverse Tunnel bug? Message-ID: I ran the following command to create a reverse tunnel from another server back to my local host ssh -4xnT -o PreferredAuthentications=publickey -o ConnectTimeout=10 -o BatchMode=yes -f \ -o ExitOnForwardFailure=yes -N -R myTargetHost:2525:myLocalHost:25 myUser at myTargetHost and on machine=myTargetHost, the port 2525 was already being utilized, so it gave me this error and exited: ? ?? Error: remote port forwarding failed for listen port 2525 However, when I got the exit code it returned a zero (Successful exit code) When I try to attach to a localhost port that is being utilized using the (-L) option, ssh exits with a 255 exit code.? So at very least it appears to be inconsistent behavior between the two tunneling methods. The version I am using is:? OpenSSH_5.4p1 Platform is Solaris 10 Sparc on both machines (and before anyone asks, I am not using Sun/Oracle's version of SSH, I am using the version at www.opencsw.org) Thanks in advance for any response you can provide. From djm at mindrot.org Thu Nov 11 21:07:09 2010 From: djm at mindrot.org (Damien Miller) Date: Thu, 11 Nov 2010 21:07:09 +1100 (EST) Subject: Exit Codes on Reverse Tunnel bug? In-Reply-To: References: Message-ID: Could you try 5.6p1? I think I fixed this bug in August. On Wed, 10 Nov 2010, JL Picard wrote: > > I ran the following command to create a reverse tunnel from another server back to my local host > ssh -4xnT -o PreferredAuthentications=publickey -o ConnectTimeout=10 -o BatchMode=yes -f \ > -o ExitOnForwardFailure=yes -N -R myTargetHost:2525:myLocalHost:25 myUser at myTargetHost > > and on machine=myTargetHost, the port 2525 was already being utilized, so it gave me this error and exited: > Error: remote port forwarding failed for listen port 2525 > > However, when I got the exit code it returned a zero (Successful exit code) > > > When I try to attach to a localhost port that is being utilized using the (-L) option, ssh exits with a 255 exit code. > > So at very least it appears to be inconsistent behavior between the two tunneling methods. > > The version I am using is: OpenSSH_5.4p1 > Platform is Solaris 10 Sparc on both machines (and before anyone asks, I am not using Sun/Oracle's version of SSH, I am using the version at www.opencsw.org) > > Thanks in advance for any response you can provide. > > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > From kevin.gurney at oracle.com Fri Nov 12 04:06:51 2010 From: kevin.gurney at oracle.com (kevin gurney) Date: Thu, 11 Nov 2010 09:06:51 -0800 Subject: Why the limitation on Windows environnment introduced in OpenSSH 4.0? Message-ID: <4CDC22AB.90503@oracle.com> Hello all, First off, thanks for all of your hard work on OpenSSH! I recently updated our SSH infrastructure from OpenSSH 3.8.1p1 to Cygwin 1.7 (which includes OpenSSH 5.4p1) and noticed that when running commands via ssh on my Windows machines I no longer have access to the full set of Windows environment variables. Digging through source, I see that this change was introduced in v4.0 (the "fetch_windows_environment()" function in openbsd-compat/bsd-cygwin_util.c). Can anyone shed light on why this was thought to be a "bug" needing fixing? And, more importantly, is there a way to work around this? Our build system relies on having access to the full set of Windows environment variables such as those created by software package installations. Having a very restricted Windows environment is causing us a ton of grief. The only workable solution we have found is to use a ~/.ssh/environment file on each of our Windows build machines. Not my preferred solution however. Thanks, Kevin Gurney -- Oracle Kevin Gurney Phone: +1 925 6943893 Green Oracle Oracle is committed to developing practices and products that help protect the environment From peter at stuge.se Fri Nov 12 05:44:24 2010 From: peter at stuge.se (Peter Stuge) Date: Thu, 11 Nov 2010 19:44:24 +0100 Subject: Why the limitation on Windows environnment introduced in OpenSSH 4.0? In-Reply-To: <4CDC22AB.90503@oracle.com> References: <4CDC22AB.90503@oracle.com> Message-ID: <20101111184424.2980.qmail@stuge.se> kevin gurney wrote: > Digging through source, I see that this change was introduced in v4.0 > (the "fetch_windows_environment()" function in > openbsd-compat/bsd-cygwin_util.c). > > Can anyone shed light on why this was thought to be a "bug" needing > fixing? What does the commit message for the change say? Look up which revision of that file introduced the change. //Peter From kevin.gurney at oracle.com Fri Nov 12 05:51:02 2010 From: kevin.gurney at oracle.com (kevin gurney) Date: Thu, 11 Nov 2010 10:51:02 -0800 Subject: Why the limitation on Windows environnment introduced in OpenSSH 4.0? In-Reply-To: <20101111184424.2980.qmail@stuge.se> References: <4CDC22AB.90503@oracle.com> <20101111184424.2980.qmail@stuge.se> Message-ID: <4CDC3B16.2070201@oracle.com> Here's the complete description of *Bug 915* - [PATCH] Only copy basic Windows environment: So far, the whole environment is copied over to child processes started from sshd when running under Cygwin. The attached patch restricts this to the basic environment created for all processes. (https://bugzilla.mindrot.org/show_bug.cgi?id=915) Corinna Vinschen was the author of the bug report. Are you reading this list, Corinna? Kevin On 11/11/2010 10:44 AM, Peter Stuge wrote: > kevin gurney wrote: > >> Digging through source, I see that this change was introduced in v4.0 >> (the "fetch_windows_environment()" function in >> openbsd-compat/bsd-cygwin_util.c). >> >> Can anyone shed light on why this was thought to be a "bug" needing >> fixing? >> > > What does the commit message for the change say? Look up which > revision of that file introduced the change. > > > //Peter > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > -- Oracle Kevin Gurney Phone: +1 925 6943893 Green Oracle Oracle is committed to developing practices and products that help protect the environment From peter at stuge.se Fri Nov 12 06:03:21 2010 From: peter at stuge.se (Peter Stuge) Date: Thu, 11 Nov 2010 20:03:21 +0100 Subject: Why the limitation on Windows environnment introduced in OpenSSH 4.0? In-Reply-To: <4CDC3B16.2070201@oracle.com> References: <4CDC22AB.90503@oracle.com> <20101111184424.2980.qmail@stuge.se> <4CDC3B16.2070201@oracle.com> Message-ID: <20101111190321.5920.qmail@stuge.se> kevin gurney wrote: > Here's the complete description of *Bug 915* > - [PATCH] Only copy > basic Windows environment: > > So far, the whole environment is copied over to child processes > started from sshd when running under Cygwin. The attached patch > restricts this to the basic environment created for all processes. Ok. CVS doesn't have more information: $ cvs log -N -r1.13 openbsd-compat/bsd-cygwin_util.c RCS file: /cvs/openssh/openbsd-compat/bsd-cygwin_util.c,v Working file: openbsd-compat/bsd-cygwin_util.c head: 1.22 branch: locks: strict access list: keyword substitution: kv total revisions: 23; selected revisions: 1 description: ---------------------------- revision 1.13 date: 2004/08/30 10:42:08; author: dtucker; state: Exp; lines: +52 -2 branches: 1.13.4; - (dtucker) [session.c openbsd-compat/bsd-cygwin_util.{c,h}] Bug #915: only copy required environment variables on Cygwin. Patch from vinschen at redhat.com, ok djm@ ============================================================================= //Peter From vinschen at redhat.com Sat Nov 13 20:46:05 2010 From: vinschen at redhat.com (Corinna Vinschen) Date: Sat, 13 Nov 2010 10:46:05 +0100 Subject: Why the limitation on Windows environnment introduced in OpenSSH 4.0? In-Reply-To: <4CDC3B16.2070201@oracle.com> References: <4CDC22AB.90503@oracle.com> <20101111184424.2980.qmail@stuge.se> <4CDC3B16.2070201@oracle.com> Message-ID: <20101113094605.GC18309@calimero.vinschen.de> On Nov 11 10:51, kevin gurney wrote: > Here's the complete description of *Bug 915* > - [PATCH] Only > copy basic Windows environment: > > So far, the whole environment is copied over to child processes > started from sshd when running under Cygwin. The attached patch > restricts this to the basic environment created for all processes. > > (https://bugzilla.mindrot.org/show_bug.cgi?id=915) > > > Corinna Vinschen was the author of the bug report. Are you reading > this list, Corinna? At that time the patch was requested by Damien for security reasons, AFAIR. Cygwin was the only platform which propagated the environment of the privileged user running sshd to the process spawned for the user just logging in. [...time passes...] I just found the related thread in the ML archive: http://marc.info/?l=openssh-unix-dev&m=109232852213455&w=2 If you need more environment, it has to be created within your user session, as on other systems(*). Corinna (*) For instance, fill ~/.ssh/environment. Or use ~/.ssh/rc to run a script which fills the environment with values from the registry. Or add a script to /etc/profile.d. There are a lot of methods available, some of which have been discussed on the Cygwin ML already. Check the archives. -- Corinna Vinschen Cygwin Project Co-Leader Red Hat From horsley1953 at gmail.com Tue Nov 16 04:23:39 2010 From: horsley1953 at gmail.com (Tom Horsley) Date: Mon, 15 Nov 2010 12:23:39 -0500 Subject: X forwarding uses up some resource? Message-ID: <20101115122339.10c039a7@tomh> After many weeks of running tests on different systems, all started from inside the same X session and using ssh -X forwarding to make the display accessible from the systems running the tests, X forwarding just sorta stops working. The remote machines still get a localhost:N DISPLAY variable established, but trying to actually run an X client results in connection errors. Does this sound familiar to anyone? Is there some resource that could be "used up" on the host machine if some of the test sessions terminate abnormally so that eventually there isn't any left to make forwarding work? It isn't the X session itself that has problems. If I talk to it directly without using X forwarding, it works fine. It is just the X forwarded connections that stop. Rebooting the host system makes everything work fine again for a few weeks, then the X forwarded connections stop working again. Details: Host system is fedora 13 x86_64 running openssh-server-5.4p1-3.fc13.x86_64. The X display the tests are run from is a VNC server. From rapier at psc.edu Sat Nov 20 07:27:34 2010 From: rapier at psc.edu (rapier) Date: Fri, 19 Nov 2010 15:27:34 -0500 Subject: File Offsets for SCP (patch) Message-ID: <4CE6DDB6.8070908@psc.edu> I don't know if anyone would be interested in this but I'm including a patch to allow for offsets when transferring files with SCP. It's pretty simple and assumes the user knows what they are doing (for example, if transferring with a wild card the offset would apply to all files). -A is the number of bytes offset from the beginning of the files. -Z is the number of bytes inset from the end of the file. We may be using this when transferring very large files (100GB+) over multiple parallel TCP streams by instantiating multiple SSH connections by means of a management application. Any comments, questions, or suggestions are welcome. --- ../canonical-openssh5.6/scp.c 2010-07-01 23:37:33.000000000 -0400 +++ scp.c 2010-11-19 17:17:26.000000000 -0500 @@ -302,6 +302,7 @@ struct passwd *pwd; uid_t userid; int errs, remin, remout; int pflag, iamremote, iamrecursive, targetshouldbedirectory; +double fd_offset, fd_inset; #define CMDNEEDS 64 char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ @@ -324,6 +325,9 @@ main(int argc, char **argv) extern char *optarg; extern int optind; + fd_inset = 0; + fd_offset = 0; + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -344,7 +348,7 @@ main(int argc, char **argv) addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:A:Z:")) != -1) switch (ch) { /* User-visible flags. */ case '1': @@ -407,6 +411,16 @@ main(int argc, char **argv) setmode(0, O_BINARY); #endif break; + case 'A': + fd_offset = strtod(optarg, &endp); + if (fd_offset < 0 || *endp != '\0') + usage(); + break; + case 'Z': + fd_inset = strtod(optarg, &endp); + if (fd_inset < 0 || *endp != '\0') + usage(); + break; default: usage(); } @@ -680,6 +694,16 @@ syserr: run_err("%s: %s", name, strerr run_err("%s: %s", name, "Negative file size"); goto next; } + if (fd_offset > stb.st_size) { + run_err("Offset greater than file size"); + goto next; + } + if (fd_inset > stb.st_size) { + run_err("Inset greater than file size"); + goto next; + } + lseek (fd, fd_offset, SEEK_SET); + stb.st_size -= (fd_offset + fd_inset); unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: From alex at alex.org.uk Sat Nov 20 20:00:45 2010 From: alex at alex.org.uk (Alex Bligh) Date: Sat, 20 Nov 2010 09:00:45 +0000 Subject: File Offsets for SCP (patch) In-Reply-To: <4CE6DDB6.8070908@psc.edu> References: <4CE6DDB6.8070908@psc.edu> Message-ID: --On 19 November 2010 15:27:34 -0500 rapier wrote: > I don't know if anyone would be interested in this but I'm including a > patch to allow for offsets when transferring files with SCP. Out of interest, why was something like ssh foo.example.com dd [dd options] file - | dd [dd options] - file not sufficient? -- Alex Bligh From maniac.nl at gmail.com Mon Nov 22 10:49:10 2010 From: maniac.nl at gmail.com (Mark Janssen) Date: Mon, 22 Nov 2010 00:49:10 +0100 Subject: File Offsets for SCP (patch) In-Reply-To: References: <4CE6DDB6.8070908@psc.edu> Message-ID: On Sat, Nov 20, 2010 at 10:00 AM, Alex Bligh wrote: > > Out of interest, why was something like > ?ssh foo.example.com dd [dd options] file - ?| dd [dd options] - file > > not sufficient? Or rsync ? -- Mark Janssen? --? maniac(at)maniac.nl? --? pgp: 0x357D2178 |?? ,''`.? | Unix / Linux Open-Source and Internet Consultant? ? ? ? ?? |? : :' :? | Maniac.nl Sig-IO.nl MarkJanssen.nl NerdNet.nl Snow.nl? ? ? |? `. `'?? | Skype: markmjanssen ICQ: 129696007 irc: FooBar on undernet |? ? `-? ? | From bert.wesarg at googlemail.com Mon Nov 22 18:52:54 2010 From: bert.wesarg at googlemail.com (Bert Wesarg) Date: Mon, 22 Nov 2010 08:52:54 +0100 Subject: File Offsets for SCP (patch) In-Reply-To: <4CE6DDB6.8070908@psc.edu> References: <4CE6DDB6.8070908@psc.edu> Message-ID: On Fri, Nov 19, 2010 at 21:27, rapier wrote: > I don't know if anyone would be interested in this but I'm including a patch > to allow for offsets when transferring files with SCP. > > It's pretty simple and assumes the user knows what they are doing (for > example, if transferring with a wild card the offset would apply to all > files). -A is the number of bytes offset from the beginning of the files. -Z > is the number of bytes inset from the end of the file. > > We may be using this when transferring very large files (100GB+) over > multiple parallel TCP streams by instantiating multiple SSH connections by > means of a management application. > > Any comments, questions, or suggestions are welcome. > > > --- ../canonical-openssh5.6/scp.c ? ? ? 2010-07-01 23:37:33.000000000 -0400 > +++ scp.c ? ? ? 2010-11-19 17:17:26.000000000 -0500 > @@ -302,6 +302,7 @@ struct passwd *pwd; > ?uid_t userid; > ?int errs, remin, remout; > ?int pflag, iamremote, iamrecursive, targetshouldbedirectory; > +double fd_offset, fd_inset; > > ?#define ? ? ? ?CMDNEEDS ? ? ? ?64 > ?char cmd[CMDNEEDS]; ? ? ? ? ? ?/* must hold "rcp -r -p -d\0" */ > @@ -324,6 +325,9 @@ main(int argc, char **argv) > ? ? ? ?extern char *optarg; > ? ? ? ?extern int optind; > > + ? ? ? fd_inset = 0; > + ? ? ? fd_offset = 0; > + > ? ? ? ?/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ > ? ? ? ?sanitise_stdfd(); > > @@ -344,7 +348,7 @@ main(int argc, char **argv) > ? ? ? ?addargs(&args, "-oClearAllForwardings yes"); > > ? ? ? ?fflag = tflag = 0; > - ? ? ? while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != > -1) > + ? ? ? while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:A:Z:")) > != -1) > ? ? ? ? ? ? ? ?switch (ch) { > ? ? ? ? ? ? ? ?/* User-visible flags. */ > ? ? ? ? ? ? ? ?case '1': > @@ -407,6 +411,16 @@ main(int argc, char **argv) > ? ? ? ? ? ? ? ? ? ? ? ?setmode(0, O_BINARY); > ?#endif > ? ? ? ? ? ? ? ? ? ? ? ?break; > + ? ? ? ? ? ? ? case 'A': > + ? ? ? ? ? ? ? ? ? ? ? fd_offset = strtod(optarg, &endp); > + ? ? ? ? ? ? ? ? ? ? ? if (fd_offset < 0 || *endp != '\0') > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?usage(); > + ? ? ? ? ? ? ? ? ? ? ? break; > + ? ? ? ? ? ? ? case 'Z': > + ? ? ? ? ? ? ? ? ? ? ? fd_inset = strtod(optarg, &endp); > + ? ? ? ? ? ? ? ? ? ? ? if (fd_inset < 0 || *endp != '\0') > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?usage(); > + ? ? ? ? ? ? ? ? ? ? ? break; > ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ?usage(); > ? ? ? ? ? ? ? ?} > @@ -680,6 +694,16 @@ syserr: ? ? ? ? ? ? ? ? ? ?run_err("%s: %s", name, > strerr > ? ? ? ? ? ? ? ? ? ? ? ?run_err("%s: %s", name, "Negative file size"); > ? ? ? ? ? ? ? ? ? ? ? ?goto next; > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? if (fd_offset > stb.st_size) { > + ? ? ? ? ? ? ? ? ? ? ? run_err("Offset greater than file size"); > + ? ? ? ? ? ? ? ? ? ? ? goto next; > + ? ? ? ? ? ? ? } > + ? ? ? ? ? ? ? if (fd_inset > stb.st_size) { > + ? ? ? ? ? ? ? ? ? ? ? run_err("Inset greater than file size"); > + ? ? ? ? ? ? ? ? ? ? ? goto next; > + ? ? ? ? ? ? ? } > + ? ? ? ? ? ? ? lseek (fd, fd_offset, SEEK_SET); > + ? ? ? ? ? ? ? stb.st_size -= (fd_offset + fd_inset); What happen if you set fd_offset == fd_inset == stb.st_size? Bert > ? ? ? ? ? ? ? ?unset_nonblock(fd); > ? ? ? ? ? ? ? ?switch (stb.st_mode & S_IFMT) { > ? ? ? ? ? ? ? ?case S_IFREG: > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > From aris at 0xbadc0de.be Mon Nov 22 19:02:50 2010 From: aris at 0xbadc0de.be (Aris Adamantiadis) Date: Mon, 22 Nov 2010 09:02:50 +0100 Subject: File Offsets for SCP (patch) In-Reply-To: <4CE6DDB6.8070908@psc.edu> References: <4CE6DDB6.8070908@psc.edu> Message-ID: <4CEA23AA.4050900@0xbadc0de.be> Le 19/11/10 21:27, rapier a ?crit : > > We may be using this when transferring very large files (100GB+) over > multiple parallel TCP streams by instantiating multiple SSH connections > by means of a management application. Hi Rapier, Seems to me like a use case for a sftp-based transfert. hacking SCP, that has a known record of being undocumented, is a recipe for problems. There are multiple SSH libraries to choose from, for such an application I suggest libssh :). My two cents, Kr, Aris From rapier at psc.edu Tue Nov 23 05:49:34 2010 From: rapier at psc.edu (rapier) Date: Mon, 22 Nov 2010 13:49:34 -0500 Subject: File Offsets for SCP (patch) In-Reply-To: References: <4CE6DDB6.8070908@psc.edu> Message-ID: <4CEABB3E.6090008@psc.edu> It's really a user interface issue. We're trying to minimize the complexity so we don't have to keep explaining to our users how to do things. While we have some really smart users they're more familiar with climate modeling than dd. Eventually we hope to use this with a manager application to chunk TB+ size files so we can more them in parallel (possibly dmover). We we have get close to 1Gb speeds transcontinental now with SSH we run into the slow start issue. By parallelizing the transfer even if we hit congestion we don't spend as much time in slow start in aggregate. In that case using dd may make more sense over all. However, for right now if we have a user that drops the connection 90% of the way through a 2 day file transfer this ends up being a useful tool for them (which what happened last last week). Really, though it's just something we found useful which I thought to share. Alex Bligh wrote: > > > --On 19 November 2010 15:27:34 -0500 rapier wrote: > >> I don't know if anyone would be interested in this but I'm including a >> patch to allow for offsets when transferring files with SCP. > > Out of interest, why was something like > ssh foo.example.com dd [dd options] file - | dd [dd options] - file > > not sufficient? > From rapier at psc.edu Tue Nov 23 06:11:11 2010 From: rapier at psc.edu (rapier) Date: Mon, 22 Nov 2010 14:11:11 -0500 Subject: File Offsets for SCP (patch) In-Reply-To: References: <4CE6DDB6.8070908@psc.edu> Message-ID: <4CEAC04F.4070608@psc.edu> Rsync is a great solution for some needs but it's not always effective in our situations. The biggest issue, sadly enough, tends to be the experience level of the user. Since we don't generally have remote access to their machines we need something that's as simple as possible. This, to me at least, seemed to be an easier solution in as far as this user was concerned. Mark Janssen wrote: > On Sat, Nov 20, 2010 at 10:00 AM, Alex Bligh wrote: > >> Out of interest, why was something like >> ssh foo.example.com dd [dd options] file - | dd [dd options] - file >> >> not sufficient? > > Or rsync ? > From rapier at psc.edu Tue Nov 23 07:03:05 2010 From: rapier at psc.edu (rapier) Date: Mon, 22 Nov 2010 15:03:05 -0500 Subject: File Offsets for SCP (patch) In-Reply-To: References: <4CE6DDB6.8070908@psc.edu> Message-ID: <4CEACC79.3080407@psc.edu> Good question. I just tested this out. If you set either A or Z to the file size then it creates a zero byte file on the remote end. Which is exactly what you'd expect. If you set either A or Z greater than the file size then you get an error 'Offset greater than file size'. If the combination of A and Z are greater than the file size you get a protocol error 'scp: protocol error: size not delimited'. So I need to add some math in there. Bert Wesarg wrote: > On Fri, Nov 19, 2010 at 21:27, rapier wrote: >> I don't know if anyone would be interested in this but I'm including a patch >> to allow for offsets when transferring files with SCP. >> >> It's pretty simple and assumes the user knows what they are doing (for >> example, if transferring with a wild card the offset would apply to all >> files). -A is the number of bytes offset from the beginning of the files. -Z >> is the number of bytes inset from the end of the file. >> >> We may be using this when transferring very large files (100GB+) over >> multiple parallel TCP streams by instantiating multiple SSH connections by >> means of a management application. >> >> Any comments, questions, or suggestions are welcome. >> >> >> --- ../canonical-openssh5.6/scp.c 2010-07-01 23:37:33.000000000 -0400 >> +++ scp.c 2010-11-19 17:17:26.000000000 -0500 >> @@ -302,6 +302,7 @@ struct passwd *pwd; >> uid_t userid; >> int errs, remin, remout; >> int pflag, iamremote, iamrecursive, targetshouldbedirectory; >> +double fd_offset, fd_inset; >> >> #define CMDNEEDS 64 >> char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ >> @@ -324,6 +325,9 @@ main(int argc, char **argv) >> extern char *optarg; >> extern int optind; >> >> + fd_inset = 0; >> + fd_offset = 0; >> + >> /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ >> sanitise_stdfd(); >> >> @@ -344,7 +348,7 @@ main(int argc, char **argv) >> addargs(&args, "-oClearAllForwardings yes"); >> >> fflag = tflag = 0; >> - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != >> -1) >> + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:A:Z:")) >> != -1) >> switch (ch) { >> /* User-visible flags. */ >> case '1': >> @@ -407,6 +411,16 @@ main(int argc, char **argv) >> setmode(0, O_BINARY); >> #endif >> break; >> + case 'A': >> + fd_offset = strtod(optarg, &endp); >> + if (fd_offset < 0 || *endp != '\0') >> + usage(); >> + break; >> + case 'Z': >> + fd_inset = strtod(optarg, &endp); >> + if (fd_inset < 0 || *endp != '\0') >> + usage(); >> + break; >> default: >> usage(); >> } >> @@ -680,6 +694,16 @@ syserr: run_err("%s: %s", name, >> strerr >> run_err("%s: %s", name, "Negative file size"); >> goto next; >> } >> + if (fd_offset > stb.st_size) { >> + run_err("Offset greater than file size"); >> + goto next; >> + } >> + if (fd_inset > stb.st_size) { >> + run_err("Inset greater than file size"); >> + goto next; >> + } >> + lseek (fd, fd_offset, SEEK_SET); >> + stb.st_size -= (fd_offset + fd_inset); > > What happen if you set fd_offset == fd_inset == stb.st_size? > > Bert > >> unset_nonblock(fd); >> switch (stb.st_mode & S_IFMT) { >> case S_IFREG: >> _______________________________________________ >> openssh-unix-dev mailing list >> openssh-unix-dev at mindrot.org >> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev >> > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From rapier at psc.edu Tue Nov 23 05:42:19 2010 From: rapier at psc.edu (rapier) Date: Mon, 22 Nov 2010 13:42:19 -0500 Subject: File Offsets for SCP (patch) In-Reply-To: <4CEA23AA.4050900@0xbadc0de.be> References: <4CE6DDB6.8070908@psc.edu> <4CEA23AA.4050900@0xbadc0de.be> Message-ID: <4CEAB98B.8010406@psc.edu> In our environment SFTP has it's own problems. The big issues is the inclusion of a 3rd layer of flow control on top of both TCP and SSH. While we've gotten around the SSH flow control issue by developing HPN-SSH those enhancement don't move up the stack. I suppose I could p[atch SFTP to do that at some point, but the users we support generally don't use SFTP. SCP is somewhat more conducive to the scripts they write. Admittedly, in the best of all worlds they'd use GridFTP (or even kftp) but the underlying infrastructure to support GridFTP can be... shall we say... an obstacle for some user organizations we're supporting. Chris Aris Adamantiadis wrote: > Le 19/11/10 21:27, rapier a ?crit : > >> We may be using this when transferring very large files (100GB+) over >> multiple parallel TCP streams by instantiating multiple SSH connections >> by means of a management application. > > Hi Rapier, > > Seems to me like a use case for a sftp-based transfert. hacking SCP, > that has a known record of being undocumented, is a recipe for problems. > There are multiple SSH libraries to choose from, for such an application > I suggest libssh :). > > My two cents, > > Kr, > > Aris > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev From rapier at psc.edu Tue Nov 23 09:46:50 2010 From: rapier at psc.edu (rapier) Date: Mon, 22 Nov 2010 17:46:50 -0500 Subject: File Offsets for SCP (patch revised) In-Reply-To: <4CEACC79.3080407@psc.edu> References: <4CE6DDB6.8070908@psc.edu> <4CEACC79.3080407@psc.edu> Message-ID: <4CEAF2DA.9080507@psc.edu> Just a follow up patch. You now just specify the byte length you want to transfer and a little more error checking. Again, don't know if this would be useful to anyone but I thought I'd share just in case. Also, just to make sure this is clear, this only works on the source side. --- ../canonical-openssh5.6/scp.c 2010-07-01 23:37:33.000000000 -0400 +++ ./scp.c 2010-11-22 19:48:46.000000000 -0500 @@ -302,6 +302,8 @@ struct passwd *pwd; uid_t userid; int errs, remin, remout; int pflag, iamremote, iamrecursive, targetshouldbedirectory; +// user requested file offset and amount of data to xfer +double fd_offset, fd_length; #define CMDNEEDS 64 char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ @@ -324,6 +326,9 @@ main(int argc, char **argv) extern char *optarg; extern int optind; + fd_length = 0; + fd_offset = 0; + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -344,7 +349,7 @@ main(int argc, char **argv) addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:A:L:")) != -1) switch (ch) { /* User-visible flags. */ case '1': @@ -407,6 +412,16 @@ main(int argc, char **argv) setmode(0, O_BINARY); #endif break; + case 'A': + fd_offset = strtod(optarg, &endp); + if (fd_offset < 0 || *endp != '\0') + usage(); + break; + case 'L': + fd_length = strtod(optarg, &endp); + if (fd_length < 0 || *endp != '\0') + usage(); + break; default: usage(); } @@ -680,6 +695,34 @@ syserr: run_err("%s: %s", name, strerr run_err("%s: %s", name, "Negative file size"); goto next; } + + // if the offset is greater than the file size + // we can't do this + if (fd_offset > stb.st_size) { + run_err("Offset greater than file size"); + goto next; + } + + // if the offset plus the requested length are greater + // than the file size then we have to quit + if (fd_length + fd_offset > stb.st_size) { + run_err("Length greater than file size"); + goto next; + } + + // if the user only has an offset then we reduce + // the file size by the offset. if they have a length + // then we use stb.st_size and the length + // to determine the actual stopping point + if (fd_length != 0) { + stb.st_size -= (stb.st_size - fd_length); + } else { + stb.st_size -= fd_offset; + } + + // seek to the position as requested by user + lseek (fd, fd_offset, SEEK_SET); + unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: From joachim at joachimschipper.nl Sun Nov 28 00:35:43 2010 From: joachim at joachimschipper.nl (Joachim Schipper) Date: Sat, 27 Nov 2010 14:35:43 +0100 Subject: [patch] Make passphrase-protected SSHv1 keys work again Message-ID: <20101127133542.GA6155@polymnia.joachimschipper.nl> ssh-add on OpenBSD current (with malloc -S enabled) crashes ("chunk is already free") when loading my password-protected SSHv1 key (used only for testing). "ssh-add ~/.ssh/identity" also fails to format the prompt properly ("Enter passphrase for :"). The issue is as follows: Starting at ssh-add.c:158 in add_file(ac, filename = "~/.ssh/identity"), we call key_load_private(filename = "~/.ssh/identity", passphrase = "", commentp = &comment) key_parse_private_type(blob = , KEY_RSA1, passphrase = "", commentp = &comment) key_parse_private_rsa1(blob, passphrase = "", commentp = &comment). In key_parse_private_rsa1, at authfile.c:423-424, we execute if (commentp) *commentp = buffer_get_string(blob, NULL); However, the empty passphrase is not correct (recall that my ~/.ssh/identity file has a passphrase), we fail to load the key and "goto fail" at authfile.c:455?, and execute fail: if (commentp) xfree(*commentp); so when key_parse_private_rsa1 returns NULL (and key_parse_private_type and key_load_private return the same value), commentp points into deallocated space. Unfortunately, since commentp != NULL, add_file assumes that it is valid, uses it and calls xfree at ssh-add.c:462. Also note that *commentp as allocated at authfile.c:687 leaks. The patch below reverts a small part of authfile.c r1.86 ("Refactor internals of private key loading and saving to work on memory buffers rather than directly on files."), and solves this issue. Joachim Index: authfile.c =================================================================== RCS file: /usr/cvs/src/src/usr.bin/ssh/authfile.c,v retrieving revision 1.86 diff -u -p -r1.86 authfile.c --- authfile.c 21 Nov 2010 10:57:07 -0000 1.86 +++ authfile.c 27 Nov 2010 13:28:27 -0000 @@ -695,7 +695,7 @@ key_load_private(const char *filename, c } else { key_free(pub); prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase, - commentp); + NULL); } buffer_free(&buffer); return prv; From rhammond at databit7.com Sun Nov 28 13:20:45 2010 From: rhammond at databit7.com (Robin David Hammond) Date: Sun, 28 Nov 2010 02:20:45 +0000 Subject: Forwarding Remote Ports. Message-ID: <4CF1BC7D.80205@databit7.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I was setting up sshd on a netbsd box to allow cygwin users to auto-ssh in, and be rsync'ed. I wanted to secure the install such that a compromised or stolen cygwin client could not be used to attack the sshd server. Setting shell to /usr/bin/false and using -N client side were helpful. I disabled portforwarding for the client sshkey, and enabled some local port forwarding for my webserver (backupPC has a decent CGI for the tech literate users). Works great, thanks to all who made that possible! I wanted to allow the rsync connection to be initiated from a box attached to the sshd host, this would mean using ssh -R client-side. With TCPforwarding on in sshd_config the client can forward any remote (server) port. If, however, TCPforwarding is off in sshd_config even if I use permitopen in authorized_keys I cannot forward any remote ports. I was wondering if having remote ports be allowed through permitopen was a good idea, then concluded that ambiguity between forwarded local and forwarded remote ports was dangerous. Its not like we NEVER renumber networks.... I decided to implement this behaviour using a permitremote=HOST:PORT (unless anyone has a better suggestion) expect a patch when I get a Round Tuit. - -- _ ASCII ribbon campaign ( ) | Robin-David Hammond %KB3IEN against HTML e-mail X | CCNA / \ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQIcBAEBAgAGBQJM8bx9AAoJELbrs44SuiR0r24P/juiwhLEdSvkdXTUoWmDG5Cc A9V17fcsryyDq68aRyjSwgesaTX2ne2WRF22If30bvaFoXLpU3nMHAmGh9U5sFNi Bn5Y6b782C7YZCWKOqFwgZimLmns7hsoARe41nmd6G3cJM2eWIapRd1o3mDAp3/N SuwIAj+zo36XfVA5UQoauGRDmck1m+SpqGFFx7WbZBAYQ4c8hQxNGxa2nZByMhG4 /pVsgKZ1vZ9a1qwITbQMw/A4J3XqS2D0BjbTKAD9pEr70PKBTcVz3SE8MIc3EDtJ ZthlaZ0QvMW4WFGBeEqhAIlNq1WrIUvrfGzruoG2CvWpIUw58T3FLBjgSdNzY/As 5cfrAbsHyE2BYyNKNMmRIpG/gNFKrTxHnE7G+IPV16cyi1xwBsAok2JnANY1ctP8 gUlr/QeMeL35ySJzy/S/AlKHaXGaaB79PK80X3Oa/KYwxxnpq3QvpUDm1SwufEZx /d+KMlgOtil1ajEXAVAz1YyocRfSIXzPErn2E2OIwlnWAE4JYQsyS08ElGNr4Q/+ a1hp8Sa9WXoSkHugR1zQkwrqYKjPQaWkwd5hpuXN8eI3wjhQJDYdfc5oaXlXpv7x eip9BZET/Wf2s76P9eensQFDkoVooocks4RuyBz6sPSS9kjNthTWRiYAeVs8VH42 G2oedhvuaF4D5McbmUp0 =FmHV -----END PGP SIGNATURE----- -------------- next part -------------- A non-text attachment was scrubbed... Name: rhammond.vcf Type: text/x-vcard Size: 234 bytes Desc: not available URL: From jandres at gmx.net Sun Nov 28 22:33:12 2010 From: jandres at gmx.net (Jan Andres) Date: Sun, 28 Nov 2010 12:33:12 +0100 Subject: [PATCH] Use canonical hostname for DNS SSHFP lookup Message-ID: <20101128113312.GC854@pitr.home.jan> In the current implementation, ssh always uses the hostname supplied by the user directly for the SSHFP DNS record lookup. This causes problems when using the domain search path, e.g. I have "search example.com" in my resolv.conf and then do a "ssh host", I will connect to host.example.com, but ssh will query the DNS for an SSHFP record of "host.", not "host.example.com.". The patch below attempts to fix this issue by having getaddrinfo() return the canonical host name from the lookup, and passes this on so it can be used in the SSHFP record query. As a side-effect, the patch will completely suppress the SSHFP lookup if establishing an SSH1 connection, as RSA1 keys cannot be stored in SSHFP records anyway. The getaddrinfo() implementation in openbsd-compat/fake-rfc2553.c is also updated to support the AI_CANONNAME flag. I don't use OpenBSD, so the patch was prepared against the latest snapshot of the portable OpenSSH version. Sorry if this causes any inconvenience. Regards, Jan diff -ur openssh/dns.c openssh-sshfp/dns.c --- openssh/dns.c 2010-08-31 14:41:14.000000000 +0200 +++ openssh-sshfp/dns.c 2010-11-27 23:36:30.775455403 +0100 @@ -173,7 +173,7 @@ */ int verify_host_key_dns(const char *hostname, struct sockaddr *address, - Key *hostkey, int *flags) + Key *hostkey, int *flags, const char *canohost) { u_int counter; int result; @@ -200,7 +200,7 @@ return -1; } - result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, + result = getrrsetbyname(canohost, DNS_RDATACLASS_IN, DNS_RDATATYPE_SSHFP, 0, &fingerprints); if (result) { verbose("DNS lookup error: %s", dns_result_totext(result)); diff -ur openssh/dns.h openssh-sshfp/dns.h --- openssh/dns.h 2010-02-26 21:55:05.000000000 +0100 +++ openssh-sshfp/dns.h 2010-11-28 10:34:56.536431386 +0100 @@ -46,7 +46,8 @@ #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 -int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); +int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *, + const char *); int export_dns_rr(const char *, Key *, FILE *, int); #endif /* DNS_H */ diff -ur openssh/openbsd-compat/fake-rfc2553.c openssh-sshfp/openbsd-compat/fake-rfc2553.c --- openssh/openbsd-compat/fake-rfc2553.c 2008-07-14 13:37:37.000000000 +0200 +++ openssh-sshfp/openbsd-compat/fake-rfc2553.c 2010-11-28 12:01:24.574267973 +0100 @@ -121,15 +121,23 @@ #ifndef HAVE_GETADDRINFO static struct -addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) +addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints, + const char *canonname) { struct addrinfo *ai; + int len = sizeof(*ai) + sizeof(struct sockaddr_in); + int canonlen = 0; - ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); + if (canonname != NULL) { + canonlen = strlen (canonname); + len += canonlen + 1; + } + + ai = malloc(len); if (ai == NULL) return (NULL); - memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); + memset(ai, '\0', len); ai->ai_addr = (struct sockaddr *)(ai + 1); /* XXX -- ssh doesn't use sa_len */ @@ -138,6 +146,11 @@ ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + if (canonname != NULL) { + ai->ai_canonname = ((char *)ai->ai_addr) + sizeof(struct sockaddr_in); + strlcpy(ai->ai_canonname, canonname, canonlen + 1); + } /* XXX: the following is not generally correct, but does what we want */ if (hints->ai_socktype) @@ -182,21 +195,24 @@ addr = htonl(0x00000000); if (hostname && inet_aton(hostname, &in) != 0) addr = in.s_addr; - *res = malloc_ai(port, addr, hints); + *res = malloc_ai(port, addr, hints, NULL); if (*res == NULL) return (EAI_MEMORY); return (0); } if (!hostname) { - *res = malloc_ai(port, htonl(0x7f000001), hints); + *res = malloc_ai(port, htonl(0x7f000001), hints, NULL); if (*res == NULL) return (EAI_MEMORY); return (0); } if (inet_aton(hostname, &in)) { - *res = malloc_ai(port, in.s_addr, hints); + const char *canonname = NULL; + if (hints && hints->ai_flags & AI_CANONNAME) + canonname = hostname; + *res = malloc_ai(port, in.s_addr, hints, canonname); if (*res == NULL) return (EAI_MEMORY); return (0); @@ -213,8 +229,12 @@ cur = prev = *res = NULL; for (i = 0; hp->h_addr_list[i]; i++) { struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; + const char *canonname = NULL; + + if (!prev && hints && hints->ai_flags & AI_CANONNAME) + canonname = hp->h_name; - cur = malloc_ai(port, in->s_addr, hints); + cur = malloc_ai(port, in->s_addr, hints, canonname); if (cur == NULL) { if (*res != NULL) freeaddrinfo(*res); diff -ur openssh/roaming_client.c openssh-sshfp/roaming_client.c --- openssh/roaming_client.c 2010-01-26 02:53:06.000000000 +0100 +++ openssh-sshfp/roaming_client.c 2010-11-28 09:49:06.626052834 +0100 @@ -263,7 +263,7 @@ if (ssh_connect(host, &hostaddr, options.port, options.address_family, 1, &timeout_ms, options.tcp_keep_alive, options.use_privileged_port, - options.proxy_command) == 0 && roaming_resume() == 0) { + options.proxy_command, NULL) == 0 && roaming_resume() == 0) { packet_restore_state(); reenter_guard = 0; fprintf(stderr, "[connection resumed]\n"); diff -ur openssh/ssh.c openssh-sshfp/ssh.c --- openssh/ssh.c 2010-11-20 05:19:38.000000000 +0100 +++ openssh-sshfp/ssh.c 2010-11-27 23:43:12.843314405 +0100 @@ -229,6 +229,7 @@ extern char *optarg; struct servent *sp; Forward fwd; + char *canohost; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -760,7 +761,7 @@ #else original_effective_uid == 0 && options.use_privileged_port, #endif - options.proxy_command) != 0) + options.proxy_command, &canohost) != 0) exit(255); if (timeout_ms > 0) @@ -880,7 +881,7 @@ /* Log into the remote system. Never returns if the login fails. */ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, - pw, timeout_ms); + pw, timeout_ms, canohost); if (packet_connection_is_on_socket()) { verbose("Authenticated to %s ([%s]:%d).", host, @@ -889,6 +890,8 @@ verbose("Authenticated to %s (via proxy).", host); } + xfree (canohost); + /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { for (i = 0; i < sensitive_data.nkeys; i++) { diff -ur openssh/sshconnect1.c openssh-sshfp/sshconnect1.c --- openssh/sshconnect1.c 2006-11-07 13:14:42.000000000 +0100 +++ openssh-sshfp/sshconnect1.c 2010-11-27 23:57:11.267747490 +0100 @@ -535,7 +535,7 @@ debug("Received server public key (%d bits) and host key (%d bits).", BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); - if (verify_host_key(host, hostaddr, host_key) == -1) + if (verify_host_key(host, hostaddr, host_key, NULL) == -1) fatal("Host key verification failed."); client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; diff -ur openssh/sshconnect2.c openssh-sshfp/sshconnect2.c --- openssh/sshconnect2.c 2010-09-24 14:11:14.000000000 +0200 +++ openssh-sshfp/sshconnect2.c 2010-11-27 23:38:36.154046251 +0100 @@ -90,24 +90,26 @@ char *xxx_host; struct sockaddr *xxx_hostaddr; +const char *xxx_canohost; Kex *xxx_kex = NULL; static int verify_host_key_callback(Key *hostkey) { - if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) + if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, xxx_canohost) == -1) fatal("Host key verification failed."); return 0; } void -ssh_kex2(char *host, struct sockaddr *hostaddr) +ssh_kex2(char *host, struct sockaddr *hostaddr, const char *canohost) { Kex *kex; xxx_host = host; xxx_hostaddr = hostaddr; + xxx_canohost = canohost; if (options.ciphers == (char *)-1) { logit("No valid ciphers for protocol version 2 given, using defaults."); diff -ur openssh/sshconnect.c openssh-sshfp/sshconnect.c --- openssh/sshconnect.c 2010-11-28 12:04:32.127050308 +0100 +++ openssh-sshfp/sshconnect.c 2010-11-28 10:32:12.357225689 +0100 @@ -335,7 +335,8 @@ int ssh_connect(const char *host, struct sockaddr_storage * hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, - int want_keepalive, int needpriv, const char *proxy_command) + int want_keepalive, int needpriv, const char *proxy_command, + char **canohost) { int gaierr; int on = 1; @@ -352,6 +353,8 @@ /* No proxy command. */ memset(&hints, 0, sizeof(hints)); + if (canohost != NULL) + hints.ai_flags = AI_CANONNAME; hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%u", port); @@ -359,6 +362,9 @@ fatal("%s: Could not resolve hostname %.100s: %s", __progname, host, ssh_gai_strerror(gaierr)); + if (canohost != NULL) + *canohost = xstrdup (aitop->ai_canonname); + for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ @@ -1061,14 +1067,16 @@ /* returns 0 if key verifies or -1 if key does NOT verify */ int -verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) +verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *canohost) { struct stat st; int flags = 0; /* XXX certs are not yet supported for DNS */ if (!key_is_cert(host_key) && options.verify_host_key_dns && - verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { + canohost != NULL && + verify_host_key_dns(host, hostaddr, host_key, &flags, canohost) == 0) { if (flags & DNS_VERIFY_FOUND) { @@ -1108,7 +1116,8 @@ */ void ssh_login(Sensitive *sensitive, const char *orighost, - struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms) + struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms, + const char *canohost) { char *host, *cp; char *server_user, *local_user; @@ -1131,7 +1140,7 @@ /* key exchange */ /* authenticate user */ if (compat20) { - ssh_kex2(host, hostaddr); + ssh_kex2(host, hostaddr, canohost); ssh_userauth2(local_user, server_user, host, sensitive); } else { ssh_kex(host, hostaddr); diff -ur openssh/sshconnect.h openssh-sshfp/sshconnect.h --- openssh/sshconnect.h 2010-10-07 13:07:33.000000000 +0200 +++ openssh-sshfp/sshconnect.h 2010-11-28 10:34:37.941783851 +0100 @@ -33,18 +33,19 @@ int ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, - int *, int, int, const char *); + int *, int, int, const char *, char **); void ssh_kill_proxy_command(void); void -ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int); +ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int, + const char *); void ssh_exchange_identification(int); -int verify_host_key(char *, struct sockaddr *, Key *); +int verify_host_key(char *, struct sockaddr *, Key *, const char *); void ssh_kex(char *, struct sockaddr *); -void ssh_kex2(char *, struct sockaddr *); +void ssh_kex2(char *, struct sockaddr *, const char *); void ssh_userauth1(const char *, const char *, char *, Sensitive *); void ssh_userauth2(const char *, const char *, char *, Sensitive *); -- Jan Andres From dan at doxpara.com Sun Nov 28 22:37:56 2010 From: dan at doxpara.com (Dan Kaminsky) Date: Sun, 28 Nov 2010 03:37:56 -0800 Subject: [PATCH] Use canonical hostname for DNS SSHFP lookup In-Reply-To: <20101128113312.GC854@pitr.home.jan> References: <20101128113312.GC854@pitr.home.jan> Message-ID: Presumably, a CNAME will be returned as the canonical name, meaning you're asking the network what name to expect. That's generally quite verboten. However, if we presume that SSHFP is wildly insecure anyway without DNSSEC, then this might be OK, because end-to-end DNSSEC will prevent a malicious CNAME from being accepted. On Sun, Nov 28, 2010 at 3:33 AM, Jan Andres wrote: > In the current implementation, ssh always uses the hostname supplied by > the user directly for the SSHFP DNS record lookup. This causes problems > when using the domain search path, e.g. I have "search example.com" in my > resolv.conf and then do a "ssh host", I will connect to host.example.com, > but ssh will query the DNS for an SSHFP record of "host.", not > "host.example.com.". > > The patch below attempts to fix this issue by having getaddrinfo() > return the canonical host name from the lookup, and passes this on so it > can be used in the SSHFP record query. > > As a side-effect, the patch will completely suppress the SSHFP lookup if > establishing an SSH1 connection, as RSA1 keys cannot be stored in SSHFP > records anyway. > > The getaddrinfo() implementation in openbsd-compat/fake-rfc2553.c is > also updated to support the AI_CANONNAME flag. > > I don't use OpenBSD, so the patch was prepared against the latest > snapshot of the portable OpenSSH version. Sorry if this causes any > inconvenience. > > Regards, > Jan > > > diff -ur openssh/dns.c openssh-sshfp/dns.c > --- openssh/dns.c ? ? ? 2010-08-31 14:41:14.000000000 +0200 > +++ openssh-sshfp/dns.c 2010-11-27 23:36:30.775455403 +0100 > @@ -173,7 +173,7 @@ > ?*/ > ?int > ?verify_host_key_dns(const char *hostname, struct sockaddr *address, > - ? ?Key *hostkey, int *flags) > + ? ?Key *hostkey, int *flags, const char *canohost) > ?{ > ? ? ? ?u_int counter; > ? ? ? ?int result; > @@ -200,7 +200,7 @@ > ? ? ? ? ? ? ? ?return -1; > ? ? ? ?} > > - ? ? ? result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, > + ? ? ? result = getrrsetbyname(canohost, DNS_RDATACLASS_IN, > ? ? ? ? ? ?DNS_RDATATYPE_SSHFP, 0, &fingerprints); > ? ? ? ?if (result) { > ? ? ? ? ? ? ? ?verbose("DNS lookup error: %s", dns_result_totext(result)); > diff -ur openssh/dns.h openssh-sshfp/dns.h > --- openssh/dns.h ? ? ? 2010-02-26 21:55:05.000000000 +0100 > +++ openssh-sshfp/dns.h 2010-11-28 10:34:56.536431386 +0100 > @@ -46,7 +46,8 @@ > ?#define DNS_VERIFY_MATCH ? ? ? 0x00000002 > ?#define DNS_VERIFY_SECURE ? ? ?0x00000004 > > -int ? ?verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); > +int ? ?verify_host_key_dns(const char *, struct sockaddr *, Key *, int *, > + ? ?const char *); > ?int ? ?export_dns_rr(const char *, Key *, FILE *, int); > > ?#endif /* DNS_H */ > diff -ur openssh/openbsd-compat/fake-rfc2553.c openssh-sshfp/openbsd-compat/fake-rfc2553.c > --- openssh/openbsd-compat/fake-rfc2553.c ? ? ? 2008-07-14 13:37:37.000000000 +0200 > +++ openssh-sshfp/openbsd-compat/fake-rfc2553.c 2010-11-28 12:01:24.574267973 +0100 > @@ -121,15 +121,23 @@ > > ?#ifndef HAVE_GETADDRINFO > ?static struct > -addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) > +addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints, > + ? ?const char *canonname) > ?{ > ? ? ? ?struct addrinfo *ai; > + ? ? ? int len = sizeof(*ai) + sizeof(struct sockaddr_in); > + ? ? ? int canonlen = 0; > > - ? ? ? ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); > + ? ? ? if (canonname != NULL) { > + ? ? ? ? ? ? ? canonlen = strlen (canonname); > + ? ? ? ? ? ? ? len += canonlen + 1; > + ? ? ? } > + > + ? ? ? ai = malloc(len); > ? ? ? ?if (ai == NULL) > ? ? ? ? ? ? ? ?return (NULL); > > - ? ? ? memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); > + ? ? ? memset(ai, '\0', len); > > ? ? ? ?ai->ai_addr = (struct sockaddr *)(ai + 1); > ? ? ? ?/* XXX -- ssh doesn't use sa_len */ > @@ -138,6 +146,11 @@ > > ? ? ? ?((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; > ? ? ? ?((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; > + > + ? ? ? if (canonname != NULL) { > + ? ? ? ? ? ? ? ai->ai_canonname = ((char *)ai->ai_addr) + sizeof(struct sockaddr_in); > + ? ? ? ? ? ? ? strlcpy(ai->ai_canonname, canonname, canonlen + 1); > + ? ? ? } > > ? ? ? ?/* XXX: the following is not generally correct, but does what we want */ > ? ? ? ?if (hints->ai_socktype) > @@ -182,21 +195,24 @@ > ? ? ? ? ? ? ? ?addr = htonl(0x00000000); > ? ? ? ? ? ? ? ?if (hostname && inet_aton(hostname, &in) != 0) > ? ? ? ? ? ? ? ? ? ? ? ?addr = in.s_addr; > - ? ? ? ? ? ? ? *res = malloc_ai(port, addr, hints); > + ? ? ? ? ? ? ? *res = malloc_ai(port, addr, hints, NULL); > ? ? ? ? ? ? ? ?if (*res == NULL) > ? ? ? ? ? ? ? ? ? ? ? ?return (EAI_MEMORY); > ? ? ? ? ? ? ? ?return (0); > ? ? ? ?} > > ? ? ? ?if (!hostname) { > - ? ? ? ? ? ? ? *res = malloc_ai(port, htonl(0x7f000001), hints); > + ? ? ? ? ? ? ? *res = malloc_ai(port, htonl(0x7f000001), hints, NULL); > ? ? ? ? ? ? ? ?if (*res == NULL) > ? ? ? ? ? ? ? ? ? ? ? ?return (EAI_MEMORY); > ? ? ? ? ? ? ? ?return (0); > ? ? ? ?} > > ? ? ? ?if (inet_aton(hostname, &in)) { > - ? ? ? ? ? ? ? *res = malloc_ai(port, in.s_addr, hints); > + ? ? ? ? ? ? ? const char *canonname = NULL; > + ? ? ? ? ? ? ? if (hints && hints->ai_flags & AI_CANONNAME) > + ? ? ? ? ? ? ? ? ? ? ? canonname = hostname; > + ? ? ? ? ? ? ? *res = malloc_ai(port, in.s_addr, hints, canonname); > ? ? ? ? ? ? ? ?if (*res == NULL) > ? ? ? ? ? ? ? ? ? ? ? ?return (EAI_MEMORY); > ? ? ? ? ? ? ? ?return (0); > @@ -213,8 +229,12 @@ > ? ? ? ? ? ? ? ?cur = prev = *res = NULL; > ? ? ? ? ? ? ? ?for (i = 0; hp->h_addr_list[i]; i++) { > ? ? ? ? ? ? ? ? ? ? ? ?struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; > + ? ? ? ? ? ? ? ? ? ? ? const char *canonname = NULL; > + > + ? ? ? ? ? ? ? ? ? ? ? if (!prev && hints && hints->ai_flags & AI_CANONNAME) > + ? ? ? ? ? ? ? ? ? ? ? ? ? canonname = hp->h_name; > > - ? ? ? ? ? ? ? ? ? ? ? cur = malloc_ai(port, in->s_addr, hints); > + ? ? ? ? ? ? ? ? ? ? ? cur = malloc_ai(port, in->s_addr, hints, canonname); > ? ? ? ? ? ? ? ? ? ? ? ?if (cur == NULL) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (*res != NULL) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?freeaddrinfo(*res); > diff -ur openssh/roaming_client.c openssh-sshfp/roaming_client.c > --- openssh/roaming_client.c ? ?2010-01-26 02:53:06.000000000 +0100 > +++ openssh-sshfp/roaming_client.c ? ? ?2010-11-28 09:49:06.626052834 +0100 > @@ -263,7 +263,7 @@ > ? ? ? ? ? ? ? ?if (ssh_connect(host, &hostaddr, options.port, > ? ? ? ? ? ? ? ? ? ?options.address_family, 1, &timeout_ms, > ? ? ? ? ? ? ? ? ? ?options.tcp_keep_alive, options.use_privileged_port, > - ? ? ? ? ? ? ? ? ? options.proxy_command) == 0 && roaming_resume() == 0) { > + ? ? ? ? ? ? ? ? ? options.proxy_command, NULL) == 0 && roaming_resume() == 0) { > ? ? ? ? ? ? ? ? ? ? ? ?packet_restore_state(); > ? ? ? ? ? ? ? ? ? ? ? ?reenter_guard = 0; > ? ? ? ? ? ? ? ? ? ? ? ?fprintf(stderr, "[connection resumed]\n"); > diff -ur openssh/ssh.c openssh-sshfp/ssh.c > --- openssh/ssh.c ? ? ? 2010-11-20 05:19:38.000000000 +0100 > +++ openssh-sshfp/ssh.c 2010-11-27 23:43:12.843314405 +0100 > @@ -229,6 +229,7 @@ > ? ? ? ?extern char *optarg; > ? ? ? ?struct servent *sp; > ? ? ? ?Forward fwd; > + ? ? ? char *canohost; > > ? ? ? ?/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ > ? ? ? ?sanitise_stdfd(); > @@ -760,7 +761,7 @@ > ?#else > ? ? ? ? ? ?original_effective_uid == 0 && options.use_privileged_port, > ?#endif > - ? ? ? ? ? options.proxy_command) != 0) > + ? ? ? ? ? options.proxy_command, &canohost) != 0) > ? ? ? ? ? ? ? ?exit(255); > > ? ? ? ?if (timeout_ms > 0) > @@ -880,7 +881,7 @@ > > ? ? ? ?/* Log into the remote system. ?Never returns if the login fails. */ > ? ? ? ?ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, > - ? ? ? ? ? pw, timeout_ms); > + ? ? ? ? ? pw, timeout_ms, canohost); > > ? ? ? ?if (packet_connection_is_on_socket()) { > ? ? ? ? ? ? ? ?verbose("Authenticated to %s ([%s]:%d).", host, > @@ -889,6 +890,8 @@ > ? ? ? ? ? ? ? ?verbose("Authenticated to %s (via proxy).", host); > ? ? ? ?} > > + ? ? ? xfree (canohost); > + > ? ? ? ?/* We no longer need the private host keys. ?Clear them now. */ > ? ? ? ?if (sensitive_data.nkeys != 0) { > ? ? ? ? ? ? ? ?for (i = 0; i < sensitive_data.nkeys; i++) { > diff -ur openssh/sshconnect1.c openssh-sshfp/sshconnect1.c > --- openssh/sshconnect1.c ? ? ? 2006-11-07 13:14:42.000000000 +0100 > +++ openssh-sshfp/sshconnect1.c 2010-11-27 23:57:11.267747490 +0100 > @@ -535,7 +535,7 @@ > ? ? ? ?debug("Received server public key (%d bits) and host key (%d bits).", > ? ? ? ? ? ?BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); > > - ? ? ? if (verify_host_key(host, hostaddr, host_key) == -1) > + ? ? ? if (verify_host_key(host, hostaddr, host_key, NULL) == -1) > ? ? ? ? ? ? ? ?fatal("Host key verification failed."); > > ? ? ? ?client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; > diff -ur openssh/sshconnect2.c openssh-sshfp/sshconnect2.c > --- openssh/sshconnect2.c ? ? ? 2010-09-24 14:11:14.000000000 +0200 > +++ openssh-sshfp/sshconnect2.c 2010-11-27 23:38:36.154046251 +0100 > @@ -90,24 +90,26 @@ > > ?char *xxx_host; > ?struct sockaddr *xxx_hostaddr; > +const char *xxx_canohost; > > ?Kex *xxx_kex = NULL; > > ?static int > ?verify_host_key_callback(Key *hostkey) > ?{ > - ? ? ? if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) > + ? ? ? if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, xxx_canohost) == -1) > ? ? ? ? ? ? ? ?fatal("Host key verification failed."); > ? ? ? ?return 0; > ?} > > ?void > -ssh_kex2(char *host, struct sockaddr *hostaddr) > +ssh_kex2(char *host, struct sockaddr *hostaddr, const char *canohost) > ?{ > ? ? ? ?Kex *kex; > > ? ? ? ?xxx_host = host; > ? ? ? ?xxx_hostaddr = hostaddr; > + ? ? ? xxx_canohost = canohost; > > ? ? ? ?if (options.ciphers == (char *)-1) { > ? ? ? ? ? ? ? ?logit("No valid ciphers for protocol version 2 given, using defaults."); > diff -ur openssh/sshconnect.c openssh-sshfp/sshconnect.c > --- openssh/sshconnect.c ? ? ? ?2010-11-28 12:04:32.127050308 +0100 > +++ openssh-sshfp/sshconnect.c ?2010-11-28 10:32:12.357225689 +0100 > @@ -335,7 +335,8 @@ > ?int > ?ssh_connect(const char *host, struct sockaddr_storage * hostaddr, > ? ? u_short port, int family, int connection_attempts, int *timeout_ms, > - ? ?int want_keepalive, int needpriv, const char *proxy_command) > + ? ?int want_keepalive, int needpriv, const char *proxy_command, > + ? ?char **canohost) > ?{ > ? ? ? ?int gaierr; > ? ? ? ?int on = 1; > @@ -352,6 +353,8 @@ > ? ? ? ?/* No proxy command. */ > > ? ? ? ?memset(&hints, 0, sizeof(hints)); > + ? ? ? if (canohost != NULL) > + ? ? ? ? ? ? ? hints.ai_flags = AI_CANONNAME; > ? ? ? ?hints.ai_family = family; > ? ? ? ?hints.ai_socktype = SOCK_STREAM; > ? ? ? ?snprintf(strport, sizeof strport, "%u", port); > @@ -359,6 +362,9 @@ > ? ? ? ? ? ? ? ?fatal("%s: Could not resolve hostname %.100s: %s", __progname, > ? ? ? ? ? ? ? ? ? ?host, ssh_gai_strerror(gaierr)); > > + ? ? ? if (canohost != NULL) > + ? ? ? ? ? ? ? *canohost = xstrdup (aitop->ai_canonname); > + > ? ? ? ?for (attempt = 0; attempt < connection_attempts; attempt++) { > ? ? ? ? ? ? ? ?if (attempt > 0) { > ? ? ? ? ? ? ? ? ? ? ? ?/* Sleep a moment before retrying. */ > @@ -1061,14 +1067,16 @@ > > ?/* returns 0 if key verifies or -1 if key does NOT verify */ > ?int > -verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) > +verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, > + ? ?const char *canohost) > ?{ > ? ? ? ?struct stat st; > ? ? ? ?int flags = 0; > > ? ? ? ?/* XXX certs are not yet supported for DNS */ > ? ? ? ?if (!key_is_cert(host_key) && options.verify_host_key_dns && > - ? ? ? ? ? verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { > + ? ? ? ? ? canohost != NULL && > + ? ? ? ? ? verify_host_key_dns(host, hostaddr, host_key, &flags, canohost) == 0) { > > ? ? ? ? ? ? ? ?if (flags & DNS_VERIFY_FOUND) { > > @@ -1108,7 +1116,8 @@ > ?*/ > ?void > ?ssh_login(Sensitive *sensitive, const char *orighost, > - ? ?struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms) > + ? ?struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms, > + ? ?const char *canohost) > ?{ > ? ? ? ?char *host, *cp; > ? ? ? ?char *server_user, *local_user; > @@ -1131,7 +1140,7 @@ > ? ? ? ?/* key exchange */ > ? ? ? ?/* authenticate user */ > ? ? ? ?if (compat20) { > - ? ? ? ? ? ? ? ssh_kex2(host, hostaddr); > + ? ? ? ? ? ? ? ssh_kex2(host, hostaddr, canohost); > ? ? ? ? ? ? ? ?ssh_userauth2(local_user, server_user, host, sensitive); > ? ? ? ?} else { > ? ? ? ? ? ? ? ?ssh_kex(host, hostaddr); > diff -ur openssh/sshconnect.h openssh-sshfp/sshconnect.h > --- openssh/sshconnect.h ? ? ? ?2010-10-07 13:07:33.000000000 +0200 > +++ openssh-sshfp/sshconnect.h ?2010-11-28 10:34:37.941783851 +0100 > @@ -33,18 +33,19 @@ > > ?int > ?ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, > - ? ?int *, int, int, const char *); > + ? ?int *, int, int, const char *, char **); > ?void ? ?ssh_kill_proxy_command(void); > > ?void > -ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int); > +ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int, > + ? ?const char *); > > ?void ? ?ssh_exchange_identification(int); > > -int ? ? verify_host_key(char *, struct sockaddr *, Key *); > +int ? ? verify_host_key(char *, struct sockaddr *, Key *, const char *); > > ?void ? ?ssh_kex(char *, struct sockaddr *); > -void ? ?ssh_kex2(char *, struct sockaddr *); > +void ? ?ssh_kex2(char *, struct sockaddr *, const char *); > > ?void ? ?ssh_userauth1(const char *, const char *, char *, Sensitive *); > ?void ? ?ssh_userauth2(const char *, const char *, char *, Sensitive *); > > -- > Jan Andres > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > From jandres at gmx.net Sun Nov 28 23:26:14 2010 From: jandres at gmx.net (Jan Andres) Date: Sun, 28 Nov 2010 13:26:14 +0100 Subject: [PATCH] Use canonical hostname for DNS SSHFP lookup In-Reply-To: References: <20101128113312.GC854@pitr.home.jan> Message-ID: <20101128122614.GE854@pitr.home.jan> On Sun, Nov 28, 2010 at 03:37:56AM -0800, Dan Kaminsky wrote: > Presumably, a CNAME will be returned as the canonical name, meaning > you're asking the network what name to expect. That's generally quite > verboten. However, if we presume that SSHFP is wildly insecure anyway > without DNSSEC, then this might be OK, because end-to-end DNSSEC will > prevent a malicious CNAME from being accepted. Agreed. While ssh will request DNSSEC for the SSHFP record, and will only trust the key if DNSSEC is established, we do not know whether the same is true for the address lookup yielding the canonical name. Plus, there seems to be no portable way to get this information out of getaddrinfo(). To get around this, I might suggest the following approach: - Instead of directly using the canonical name from getaddrinfo(), search for the SSHFP record using the normal domain search path. - Only if DNSSEC is established for the SSHFP lookup, AND it yields the same canonical name as the address lookup did, trust the fingerprint obtained from DNS. Would this be an acceptable approach? Regards, Jan -- Jan Andres From dan at doxpara.com Mon Nov 29 02:32:56 2010 From: dan at doxpara.com (Dan Kaminsky) Date: Sun, 28 Nov 2010 07:32:56 -0800 Subject: [PATCH] Use canonical hostname for DNS SSHFP lookup In-Reply-To: <20101128122614.GE854@pitr.home.jan> References: <20101128113312.GC854@pitr.home.jan> <20101128122614.GE854@pitr.home.jan> Message-ID: On Sun, Nov 28, 2010 at 4:26 AM, Jan Andres wrote: > On Sun, Nov 28, 2010 at 03:37:56AM -0800, Dan Kaminsky wrote: >> Presumably, a CNAME will be returned as the canonical name, meaning >> you're asking the network what name to expect. ?That's generally quite >> verboten. ?However, if we presume that SSHFP is wildly insecure anyway >> without DNSSEC, then this might be OK, because end-to-end DNSSEC will >> prevent a malicious CNAME from being accepted. > > Agreed. While ssh will request DNSSEC for the SSHFP record, and will only > trust the key if DNSSEC is established, we do not know whether the same > is true for the address lookup yielding the canonical name. Plus, there > seems to be no portable way to get this information out of getaddrinfo(). > > To get around this, I might suggest the following approach: > > - Instead of directly using the canonical name from getaddrinfo(), > ?search for the SSHFP record using the normal domain search path. > > - Only if DNSSEC is established for the SSHFP lookup, AND it yields the > ?same canonical name as the address lookup did, trust the fingerprint > ?obtained from DNS. > > Would this be an acceptable approach? Possibly. There's an *enormous* reckoning coming, as we figure out how to actually deliver DNSSEC guarantees end-to-end (no, the AD bit is not enough). I actually hadn't worked in the vagaries of search lists and devolution, into how DNSSEC will operate...there's more than a bit to figure out, before we can adequately answer what the correct semantics here are. From jandres at gmx.net Mon Nov 29 04:57:57 2010 From: jandres at gmx.net (Jan Andres) Date: Sun, 28 Nov 2010 18:57:57 +0100 Subject: [PATCH] Use canonical hostname for DNS SSHFP lookup In-Reply-To: <20101128122614.GE854@pitr.home.jan> References: <20101128113312.GC854@pitr.home.jan> <20101128122614.GE854@pitr.home.jan> Message-ID: <20101128175757.GF854@pitr.home.jan> Here is a patch for the second approach. This one required some butchering of the getrrsetbyname() code in order to - add an option to use res_search() instead of res_query() (i.e. use the search path from resolv.conf) - return the actual canonical name when confronted with CNAME/DNAME RRs (without this change, it would return the name of the CNAME as the canonical name). Regards, Jan diff -ur openssh/dns.c openssh-sshfp/dns.c --- openssh/dns.c 2010-08-31 14:41:14.000000000 +0200 +++ openssh-sshfp/dns.c 2010-11-28 18:45:41.594577525 +0100 @@ -173,7 +173,7 @@ */ int verify_host_key_dns(const char *hostname, struct sockaddr *address, - Key *hostkey, int *flags) + Key *hostkey, int *flags, const char *canohost) { u_int counter; int result; @@ -201,16 +201,25 @@ } result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, - DNS_RDATATYPE_SSHFP, 0, &fingerprints); + DNS_RDATATYPE_SSHFP, RRSET_SEARCH, &fingerprints); if (result) { verbose("DNS lookup error: %s", dns_result_totext(result)); return -1; } + debug3("canonical hostname of SSHFP RRset is %s", + fingerprints->rri_name); + if (fingerprints->rri_flags & RRSET_VALIDATED) { - *flags |= DNS_VERIFY_SECURE; - debug("found %d secure fingerprints in DNS", - fingerprints->rri_nrdatas); + if (strcasecmp(fingerprints->rri_name, canohost) == 0) { + *flags |= DNS_VERIFY_SECURE; + debug("found %d secure fingerprints in DNS", + fingerprints->rri_nrdatas); + } else { + debug("found %d insecure fingerprints in DNS, " + "not trusted due to host name mismatch", + fingerprints->rri_nrdatas); + } } else { debug("found %d insecure fingerprints in DNS", fingerprints->rri_nrdatas); diff -ur openssh/dns.h openssh-sshfp/dns.h --- openssh/dns.h 2010-02-26 21:55:05.000000000 +0100 +++ openssh-sshfp/dns.h 2010-11-28 10:34:56.536431386 +0100 @@ -46,7 +46,8 @@ #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 -int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); +int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *, + const char *); int export_dns_rr(const char *, Key *, FILE *, int); #endif /* DNS_H */ diff -ur openssh/openbsd-compat/fake-rfc2553.c openssh-sshfp/openbsd-compat/fake-rfc2553.c --- openssh/openbsd-compat/fake-rfc2553.c 2008-07-14 13:37:37.000000000 +0200 +++ openssh-sshfp/openbsd-compat/fake-rfc2553.c 2010-11-28 12:01:24.574267973 +0100 @@ -121,15 +121,23 @@ #ifndef HAVE_GETADDRINFO static struct -addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) +addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints, + const char *canonname) { struct addrinfo *ai; + int len = sizeof(*ai) + sizeof(struct sockaddr_in); + int canonlen = 0; - ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); + if (canonname != NULL) { + canonlen = strlen (canonname); + len += canonlen + 1; + } + + ai = malloc(len); if (ai == NULL) return (NULL); - memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); + memset(ai, '\0', len); ai->ai_addr = (struct sockaddr *)(ai + 1); /* XXX -- ssh doesn't use sa_len */ @@ -138,6 +146,11 @@ ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + if (canonname != NULL) { + ai->ai_canonname = ((char *)ai->ai_addr) + sizeof(struct sockaddr_in); + strlcpy(ai->ai_canonname, canonname, canonlen + 1); + } /* XXX: the following is not generally correct, but does what we want */ if (hints->ai_socktype) @@ -182,21 +195,24 @@ addr = htonl(0x00000000); if (hostname && inet_aton(hostname, &in) != 0) addr = in.s_addr; - *res = malloc_ai(port, addr, hints); + *res = malloc_ai(port, addr, hints, NULL); if (*res == NULL) return (EAI_MEMORY); return (0); } if (!hostname) { - *res = malloc_ai(port, htonl(0x7f000001), hints); + *res = malloc_ai(port, htonl(0x7f000001), hints, NULL); if (*res == NULL) return (EAI_MEMORY); return (0); } if (inet_aton(hostname, &in)) { - *res = malloc_ai(port, in.s_addr, hints); + const char *canonname = NULL; + if (hints && hints->ai_flags & AI_CANONNAME) + canonname = hostname; + *res = malloc_ai(port, in.s_addr, hints, canonname); if (*res == NULL) return (EAI_MEMORY); return (0); @@ -213,8 +229,12 @@ cur = prev = *res = NULL; for (i = 0; hp->h_addr_list[i]; i++) { struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; + const char *canonname = NULL; + + if (!prev && hints && hints->ai_flags & AI_CANONNAME) + canonname = hp->h_name; - cur = malloc_ai(port, in->s_addr, hints); + cur = malloc_ai(port, in->s_addr, hints, canonname); if (cur == NULL) { if (*res != NULL) freeaddrinfo(*res); diff -ur openssh/openbsd-compat/getrrsetbyname.c openssh-sshfp/openbsd-compat/getrrsetbyname.c --- openssh/openbsd-compat/getrrsetbyname.c 2009-07-13 03:38:23.000000000 +0200 +++ openssh-sshfp/openbsd-compat/getrrsetbyname.c 2010-11-28 18:49:13.886195349 +0100 @@ -209,8 +209,8 @@ goto fail; } - /* don't allow flags yet, unimplemented */ - if (flags) { + /* check for unsupported flags */ + if (flags & ~RRSET_SEARCH) { result = ERRSET_INVAL; goto fail; } @@ -232,8 +232,13 @@ #endif /* RES_USE_DNSEC */ /* make query */ - length = res_query(hostname, (signed int) rdclass, (signed int) rdtype, - answer, sizeof(answer)); + if (flags & RRSET_SEARCH) + length = res_search(hostname, (signed int) rdclass, + (signed int) rdtype, answer, sizeof(answer)); + else + length = res_query(hostname, (signed int) rdclass, + (signed int) rdtype, answer, sizeof(answer)); + if (length < 0) { switch(h_errno) { case HOST_NOT_FOUND: @@ -277,13 +282,6 @@ rrset->rri_flags |= RRSET_VALIDATED; #endif - /* copy name from answer section */ - rrset->rri_name = strdup(response->answer->name); - if (rrset->rri_name == NULL) { - result = ERRSET_NOMEMORY; - goto fail; - } - /* count answers */ rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, rrset->rri_rdtype); @@ -314,8 +312,17 @@ rdata = NULL; if (rr->class == rrset->rri_rdclass && - rr->type == rrset->rri_rdtype) + rr->type == rrset->rri_rdtype) { + /* extract canonical name from first data RR */ + if (index_ans == 0) { + rrset->rri_name = strdup(rr->name); + if (rrset->rri_name == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + } rdata = &rrset->rri_rdatas[index_ans++]; + } if (rr->class == rrset->rri_rdclass && rr->type == T_RRSIG) Only in openssh-sshfp/openbsd-compat: .getrrsetbyname.c.swp diff -ur openssh/openbsd-compat/getrrsetbyname.h openssh-sshfp/openbsd-compat/getrrsetbyname.h --- openssh/openbsd-compat/getrrsetbyname.h 2007-10-26 08:26:50.000000000 +0200 +++ openssh-sshfp/openbsd-compat/getrrsetbyname.h 2010-11-28 14:48:32.393987287 +0100 @@ -69,6 +69,13 @@ /* * Flags for getrrsetbyname() */ +#ifndef RRSET_SEARCH +# define RRSET_SEARCH 1 +#endif + +/* + * Flags for rrsetinfo.rri_flags + */ #ifndef RRSET_VALIDATED # define RRSET_VALIDATED 1 #endif diff -ur openssh/roaming_client.c openssh-sshfp/roaming_client.c --- openssh/roaming_client.c 2010-01-26 02:53:06.000000000 +0100 +++ openssh-sshfp/roaming_client.c 2010-11-28 09:49:06.626052834 +0100 @@ -263,7 +263,7 @@ if (ssh_connect(host, &hostaddr, options.port, options.address_family, 1, &timeout_ms, options.tcp_keep_alive, options.use_privileged_port, - options.proxy_command) == 0 && roaming_resume() == 0) { + options.proxy_command, NULL) == 0 && roaming_resume() == 0) { packet_restore_state(); reenter_guard = 0; fprintf(stderr, "[connection resumed]\n"); diff -ur openssh/ssh.c openssh-sshfp/ssh.c --- openssh/ssh.c 2010-11-20 05:19:38.000000000 +0100 +++ openssh-sshfp/ssh.c 2010-11-27 23:43:12.843314405 +0100 @@ -229,6 +229,7 @@ extern char *optarg; struct servent *sp; Forward fwd; + char *canohost; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -760,7 +761,7 @@ #else original_effective_uid == 0 && options.use_privileged_port, #endif - options.proxy_command) != 0) + options.proxy_command, &canohost) != 0) exit(255); if (timeout_ms > 0) @@ -880,7 +881,7 @@ /* Log into the remote system. Never returns if the login fails. */ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, - pw, timeout_ms); + pw, timeout_ms, canohost); if (packet_connection_is_on_socket()) { verbose("Authenticated to %s ([%s]:%d).", host, @@ -889,6 +890,8 @@ verbose("Authenticated to %s (via proxy).", host); } + xfree (canohost); + /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { for (i = 0; i < sensitive_data.nkeys; i++) { diff -ur openssh/sshconnect1.c openssh-sshfp/sshconnect1.c --- openssh/sshconnect1.c 2006-11-07 13:14:42.000000000 +0100 +++ openssh-sshfp/sshconnect1.c 2010-11-27 23:57:11.267747490 +0100 @@ -535,7 +535,7 @@ debug("Received server public key (%d bits) and host key (%d bits).", BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); - if (verify_host_key(host, hostaddr, host_key) == -1) + if (verify_host_key(host, hostaddr, host_key, NULL) == -1) fatal("Host key verification failed."); client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; diff -ur openssh/sshconnect2.c openssh-sshfp/sshconnect2.c --- openssh/sshconnect2.c 2010-09-24 14:11:14.000000000 +0200 +++ openssh-sshfp/sshconnect2.c 2010-11-27 23:38:36.154046251 +0100 @@ -90,24 +90,26 @@ char *xxx_host; struct sockaddr *xxx_hostaddr; +const char *xxx_canohost; Kex *xxx_kex = NULL; static int verify_host_key_callback(Key *hostkey) { - if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) + if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, xxx_canohost) == -1) fatal("Host key verification failed."); return 0; } void -ssh_kex2(char *host, struct sockaddr *hostaddr) +ssh_kex2(char *host, struct sockaddr *hostaddr, const char *canohost) { Kex *kex; xxx_host = host; xxx_hostaddr = hostaddr; + xxx_canohost = canohost; if (options.ciphers == (char *)-1) { logit("No valid ciphers for protocol version 2 given, using defaults."); diff -ur openssh/sshconnect.c openssh-sshfp/sshconnect.c --- openssh/sshconnect.c 2010-11-28 12:04:32.127050308 +0100 +++ openssh-sshfp/sshconnect.c 2010-11-28 10:32:12.357225689 +0100 @@ -335,7 +335,8 @@ int ssh_connect(const char *host, struct sockaddr_storage * hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, - int want_keepalive, int needpriv, const char *proxy_command) + int want_keepalive, int needpriv, const char *proxy_command, + char **canohost) { int gaierr; int on = 1; @@ -352,6 +353,8 @@ /* No proxy command. */ memset(&hints, 0, sizeof(hints)); + if (canohost != NULL) + hints.ai_flags = AI_CANONNAME; hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%u", port); @@ -359,6 +362,9 @@ fatal("%s: Could not resolve hostname %.100s: %s", __progname, host, ssh_gai_strerror(gaierr)); + if (canohost != NULL) + *canohost = xstrdup (aitop->ai_canonname); + for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ @@ -1061,14 +1067,16 @@ /* returns 0 if key verifies or -1 if key does NOT verify */ int -verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) +verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *canohost) { struct stat st; int flags = 0; /* XXX certs are not yet supported for DNS */ if (!key_is_cert(host_key) && options.verify_host_key_dns && - verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { + canohost != NULL && + verify_host_key_dns(host, hostaddr, host_key, &flags, canohost) == 0) { if (flags & DNS_VERIFY_FOUND) { @@ -1108,7 +1116,8 @@ */ void ssh_login(Sensitive *sensitive, const char *orighost, - struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms) + struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms, + const char *canohost) { char *host, *cp; char *server_user, *local_user; @@ -1131,7 +1140,7 @@ /* key exchange */ /* authenticate user */ if (compat20) { - ssh_kex2(host, hostaddr); + ssh_kex2(host, hostaddr, canohost); ssh_userauth2(local_user, server_user, host, sensitive); } else { ssh_kex(host, hostaddr); diff -ur openssh/sshconnect.h openssh-sshfp/sshconnect.h --- openssh/sshconnect.h 2010-10-07 13:07:33.000000000 +0200 +++ openssh-sshfp/sshconnect.h 2010-11-28 10:34:37.941783851 +0100 @@ -33,18 +33,19 @@ int ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, - int *, int, int, const char *); + int *, int, int, const char *, char **); void ssh_kill_proxy_command(void); void -ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int); +ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int, + const char *); void ssh_exchange_identification(int); -int verify_host_key(char *, struct sockaddr *, Key *); +int verify_host_key(char *, struct sockaddr *, Key *, const char *); void ssh_kex(char *, struct sockaddr *); -void ssh_kex2(char *, struct sockaddr *); +void ssh_kex2(char *, struct sockaddr *, const char *); void ssh_userauth1(const char *, const char *, char *, Sensitive *); void ssh_userauth2(const char *, const char *, char *, Sensitive *); -- Jan Andres From djm at mindrot.org Mon Nov 29 10:47:10 2010 From: djm at mindrot.org (Damien Miller) Date: Mon, 29 Nov 2010 10:47:10 +1100 (EST) Subject: [PATCH] Use canonical hostname for DNS SSHFP lookup In-Reply-To: <20101128113312.GC854@pitr.home.jan> References: <20101128113312.GC854@pitr.home.jan> Message-ID: On Sun, 28 Nov 2010, Jan Andres wrote: > In the current implementation, ssh always uses the hostname supplied by > the user directly for the SSHFP DNS record lookup. This causes problems > when using the domain search path, e.g. I have "search example.com" in my > resolv.conf and then do a "ssh host", I will connect to host.example.com, > but ssh will query the DNS for an SSHFP record of "host.", not > "host.example.com.". > > The patch below attempts to fix this issue by having getaddrinfo() > return the canonical host name from the lookup, and passes this on so it > can be used in the SSHFP record query. > > As a side-effect, the patch will completely suppress the SSHFP lookup if > establishing an SSH1 connection, as RSA1 keys cannot be stored in SSHFP > records anyway. > > The getaddrinfo() implementation in openbsd-compat/fake-rfc2553.c is > also updated to support the AI_CANONNAME flag. > > I don't use OpenBSD, so the patch was prepared against the latest > snapshot of the portable OpenSSH version. Sorry if this causes any > inconvenience. I looked at this a while ago and rejected this approach as trusting the DNS too much. See the thread "Re: Question about host certificates" on this list from mid-June this year. What we really (IMHO) need is better feedback from the local resolver as to how it transformed the name before external resolution. There is a hackish workaround for recent OpenSSH - in ~/.ssh/config you can do: Hostname *.* *:* :* Hostname %h Hostname * Hostname %h.your.domain.com -d