diff options
Diffstat (limited to 'crypto/openssh')
118 files changed, 5359 insertions, 2247 deletions
diff --git a/crypto/openssh/LICENCE b/crypto/openssh/LICENCE new file mode 100644 index 000000000000..e8ab01b9b74f --- /dev/null +++ b/crypto/openssh/LICENCE @@ -0,0 +1,136 @@ +This file is part of the ssh software. + +The licences which components of this software falls under are as +follows. First, we will summarize and say that that all components +are under a BSD licence, or a licence more free than that. + +OpenSSH contains no GPL code. + +1) + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + + [Tatu continues] + * However, I am not implying to give any licenses to any patents or + * copyrights held by third parties, and the software includes parts that + * are not under my direct control. As far as I know, all included + * source code is used in accordance with the relevant license agreements + * and can be used freely for any purpose (the GNU license being the most + * restrictive); see below for details. + + [However, none of that term is relevant at this point in time. All of + these restrictively licenced software components which he talks about + have been removed from OpenSSH, ie. + + - RSA is no longer included, found in the OpenSSL library + - IDEA is no longer included, it's use is depricated + - DES is now external, in the OpenSSL library + - GMP is no longer used, and instead we call BN code from OpenSSL + - Zlib is now external, in a library + - The make-ssh-known-hosts script is no longer included + - TSS has been removed + - MD5 is now external, in the OpenSSL library + - RC4 support has been removed + - Blowfish is now external, in the OpenSSL library + + [The licence continues] + + Note that any information and cryptographic algorithms used in this + software are publicly available on the Internet and at any major + bookstore, scientific library, and patent office worldwide. More + information can be found e.g. at "http://www.cs.hut.fi/crypto". + + The legal status of this program is some combination of all these + permissions and restrictions. Use only at your own responsibility. + You will be responsible for any legal consequences yourself; I am not + making any claims whether possessing or using this is legal or not in + your country, and I am not taking any responsibility on your behalf. + + + NO WARRANTY + + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS + TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, + REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING + OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED + TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY + YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + +2) + The 32-bit CRC implementation in crc32.c is due to Gary S. Brown. + Comments in the file indicate it may be used for any purpose without + restrictions: + + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + +3) + The 32-bit CRC compensation attack detector in deattack.c was + contributed by CORE SDI S.A. under a BSD-style license. See + http://www.core-sdi.com/english/ssh/ for details. + + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky <futo@core-sdi.com> + * <http://www.core-sdi.com> + +4) + Remaining components of the software are provided under a standard + 2-term BSD licence with the following names as copyright holders: + + Markus Friedl + Theo de Raadt + Niels Provos + Dug Song + Aaron Campbell + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/crypto/openssh/Makefile b/crypto/openssh/Makefile index 668900c3bdd6..299d3497cf27 100644 --- a/crypto/openssh/Makefile +++ b/crypto/openssh/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.5 1999/10/25 20:27:26 markus Exp $ +# $OpenBSD: Makefile,v 1.6 2000/08/31 21:52:23 markus Exp $ .include <bsd.own.mk> -SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp +SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server distribution: install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \ diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c index 668d4900e937..019eda813cf1 100644 --- a/crypto/openssh/atomicio.c +++ b/crypto/openssh/atomicio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Theo de Raadt + * Copyright (c) 1995,1999 Theo de Raadt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$Id: atomicio.c,v 1.3 2000/03/16 20:56:13 markus Exp $"); +RCSID("$OpenBSD: atomicio.c,v 1.5 2000/09/07 20:27:49 deraadt Exp $"); #include "xmalloc.h" #include "ssh.h" diff --git a/crypto/openssh/auth-krb4.c b/crypto/openssh/auth-krb4.c index a26842713aae..799cf261a70e 100644 --- a/crypto/openssh/auth-krb4.c +++ b/crypto/openssh/auth-krb4.c @@ -1,6 +1,25 @@ /* - * Dug Song <dugsong@UMICH.EDU> - * Kerberos v4 authentication and ticket-passing routines. + * Copyright (c) 1999 Dug Song. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" @@ -9,6 +28,8 @@ #include "ssh.h" #include "servconf.h" +RCSID("$OpenBSD: auth-krb4.c,v 1.18 2000/09/07 20:27:49 deraadt Exp $"); + #ifdef KRB4 char *ticket = NULL; @@ -80,11 +101,12 @@ auth_krb4_password(struct passwd * pw, const char *password) if (r == RD_AP_UNDEC) { /* * Probably didn't have a srvtab on - * localhost. Allow login. + * localhost. Disallow login. */ log("Kerberos V4 TGT for %s unverifiable, " "no srvtab installed? krb_rd_req: %s", pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; } else if (r != KSUCCESS) { log("Kerberos V4 %s ticket unverifiable: %s", KRB4_SERVICE_NAME, krb_err_txt[r]); @@ -92,12 +114,13 @@ auth_krb4_password(struct passwd * pw, const char *password) } } else if (r == KDC_PR_UNKNOWN) { /* - * Allow login if no rcmd service exists, but + * Disallow login if no rcmd service exists, and * log the error. */ log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " "not registered, or srvtab is wrong?", pw->pw_name, krb_err_txt[r], KRB4_SERVICE_NAME, phost); + goto kerberos_auth_failure; } else { /* * TGT is bad, forget it. Possibly spoofed! @@ -150,7 +173,7 @@ krb4_init(uid_t uid) if (lstat("/ticket", &st) != -1) tkt_root = "/ticket/"; #endif /* AFS */ - snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); + snprintf(ticket, MAXPATHLEN, "%s%u_%d", tkt_root, uid, getpid()); (void) krb_set_tkt_string(ticket); } /* Register ticket cleanup in case of fatal error. */ diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c new file mode 100644 index 000000000000..da6965266af3 --- /dev/null +++ b/crypto/openssh/auth-options.c @@ -0,0 +1,223 @@ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * RSA-based authentication. This code determines whether to admit a login + * based on RSA authentication. This file also contains functions to check + * validity of the host key. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-options.c,v 1.4 2000/09/07 21:13:36 markus Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "match.h" + +/* Flags set authorized_keys flags */ +int no_port_forwarding_flag = 0; +int no_agent_forwarding_flag = 0; +int no_x11_forwarding_flag = 0; +int no_pty_flag = 0; + +/* "command=" option. */ +char *forced_command = NULL; + +/* "environment=" options. */ +struct envstring *custom_environment = NULL; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int +auth_parse_options(struct passwd *pw, char *options, unsigned long linenum) +{ + const char *cp; + if (!options) + return 1; + while (*options && *options != ' ' && *options != '\t') { + cp = "no-port-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Port forwarding disabled."); + no_port_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-agent-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Agent forwarding disabled."); + no_agent_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-X11-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("X11 forwarding disabled."); + no_x11_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-pty"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Pty allocation disabled."); + no_pty_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "command=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + options += strlen(cp); + forced_command = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + forced_command[i++] = '"'; + continue; + } + forced_command[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + forced_command[i] = 0; + packet_send_debug("Forced command: %.900s", forced_command); + options++; + goto next_option; + } + cp = "environment=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + char *s; + struct envstring *new_envstring; + options += strlen(cp); + s = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + s[i++] = '"'; + continue; + } + s[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + s[i] = 0; + packet_send_debug("Adding to environment: %.900s", s); + debug("Adding to environment: %.900s", s); + options++; + new_envstring = xmalloc(sizeof(struct envstring)); + new_envstring->s = s; + new_envstring->next = custom_environment; + custom_environment = new_envstring; + goto next_option; + } + cp = "from=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int mname, mip; + char *patterns = xmalloc(strlen(options) + 1); + int i; + options += strlen(cp); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + patterns[i++] = '"'; + continue; + } + patterns[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + patterns[i] = 0; + options++; + /* + * Deny access if we get a negative + * match for the hostname or the ip + * or if we get not match at all + */ + mname = match_hostname(get_canonical_hostname(), + patterns, strlen(patterns)); + mip = match_hostname(get_remote_ipaddr(), + patterns, strlen(patterns)); + xfree(patterns); + if (mname == -1 || mip == -1 || + (mname != 1 && mip != 1)) { + log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).", + pw->pw_name, get_canonical_hostname(), + get_remote_ipaddr()); + packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", + get_canonical_hostname()); + /* key invalid for this host, reset flags */ + no_agent_forwarding_flag = 0; + no_port_forwarding_flag = 0; + no_pty_flag = 0; + no_x11_forwarding_flag = 0; + while (custom_environment) { + struct envstring *ce = custom_environment; + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + if (forced_command) { + xfree(forced_command); + forced_command = NULL; + } + /* deny access */ + return 0; + } + /* Host name matches. */ + goto next_option; + } +next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (!*options) + fatal("Bugs in auth-options.c option processing."); + if (*options == ' ' || *options == '\t') + break; /* End of options. */ + if (*options != ',') + goto bad_option; + options++; + /* Process the next option. */ + } + /* grant access */ + return 1; + +bad_option: + log("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + packet_send_debug("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + /* deny access */ + return 0; +} diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h new file mode 100644 index 000000000000..9044d98bea87 --- /dev/null +++ b/crypto/openssh/auth-options.h @@ -0,0 +1,25 @@ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +#ifndef AUTH_OPTIONS_H +#define AUTH_OPTIONS_H +/* Flags that may be set in authorized_keys options. */ +extern int no_port_forwarding_flag; +extern int no_agent_forwarding_flag; +extern int no_x11_forwarding_flag; +extern int no_pty_flag; +extern char *forced_command; +extern struct envstring *custom_environment; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int auth_parse_options(struct passwd *pw, char *options, unsigned long linenum); +#endif diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c index fea75d925bdf..c67ead7f9f4a 100644 --- a/crypto/openssh/auth-passwd.c +++ b/crypto/openssh/auth-passwd.c @@ -2,13 +2,64 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Sat Mar 18 05:11:38 1995 ylo * Password authentication. This file contains the functions to check whether * the password is valid for the user. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 1999 Dug Song. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: auth-passwd.c,v 1.15 2000/04/14 10:30:29 markus Exp $"); +RCSID("$OpenBSD: auth-passwd.c,v 1.17 2000/09/07 20:27:49 deraadt Exp $"); #include "packet.h" #include "ssh.h" diff --git a/crypto/openssh/auth-rh-rsa.c b/crypto/openssh/auth-rh-rsa.c index f251fb9cc3ef..072e385ab29e 100644 --- a/crypto/openssh/auth-rh-rsa.c +++ b/crypto/openssh/auth-rh-rsa.c @@ -1,21 +1,19 @@ /* - * - * auth-rh-rsa.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sun May 7 03:08:06 1995 ylo - * * Rhosts or /etc/hosts.equiv authentication combined with RSA host * authentication. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: auth-rh-rsa.c,v 1.13 2000/04/14 10:30:29 markus Exp $"); +RCSID("$OpenBSD: auth-rh-rsa.c,v 1.16 2000/09/07 21:13:36 markus Exp $"); #include "packet.h" #include "ssh.h" diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c index 3393b86661dd..901c8d1390e7 100644 --- a/crypto/openssh/auth-rhosts.c +++ b/crypto/openssh/auth-rhosts.c @@ -1,22 +1,20 @@ /* - * - * auth-rhosts.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Fri Mar 17 05:12:18 1995 ylo - * * Rhosts authentication. This file contains code to check whether to admit * the login based on rhosts authentication. This file also processes * /etc/hosts.equiv. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: auth-rhosts.c,v 1.13 2000/04/14 10:30:29 markus Exp $"); +RCSID("$OpenBSD: auth-rhosts.c,v 1.15 2000/09/07 20:27:49 deraadt Exp $"); #include "packet.h" #include "ssh.h" diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c index 78d28f0b8c87..8aefc8fadadd 100644 --- a/crypto/openssh/auth-rsa.c +++ b/crypto/openssh/auth-rsa.c @@ -1,22 +1,20 @@ /* - * - * auth-rsa.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Mon Mar 27 01:46:52 1995 ylo - * * RSA-based authentication. This code determines whether to admit a login * based on RSA authentication. This file also contains functions to check * validity of the host key. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: auth-rsa.c,v 1.23 2000/04/29 18:11:51 markus Exp $"); +RCSID("$OpenBSD: auth-rsa.c,v 1.29 2000/09/07 21:13:36 markus Exp $"); #include "rsa.h" #include "packet.h" @@ -26,18 +24,11 @@ RCSID("$Id: auth-rsa.c,v 1.23 2000/04/29 18:11:51 markus Exp $"); #include "uidswap.h" #include "match.h" #include "servconf.h" +#include "auth-options.h" #include <openssl/rsa.h> #include <openssl/md5.h> -/* Flags that may be set in authorized_keys options. */ -extern int no_port_forwarding_flag; -extern int no_agent_forwarding_flag; -extern int no_x11_forwarding_flag; -extern int no_pty_flag; -extern char *forced_command; -extern struct envstring *custom_environment; - /* * Session identifier that is used to bind key exchange and authentication * responses to a particular session. @@ -186,8 +177,8 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) } if (fail) { fclose(f); - log(buf); - packet_send_debug(buf); + log("%s",buf); + packet_send_debug("%s",buf); restore_uid(); return 0; } @@ -268,188 +259,10 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) * authenticated. Note that we have not yet processed the * options; this will be reset if the options cause the * authentication to be rejected. - */ - authenticated = 1; - - /* RSA part of authentication was accepted. Now process the options. */ - if (options) { - while (*options && *options != ' ' && *options != '\t') { - cp = "no-port-forwarding"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("Port forwarding disabled."); - no_port_forwarding_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "no-agent-forwarding"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("Agent forwarding disabled."); - no_agent_forwarding_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "no-X11-forwarding"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("X11 forwarding disabled."); - no_x11_forwarding_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "no-pty"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("Pty allocation disabled."); - no_pty_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "command=\""; - if (strncmp(options, cp, strlen(cp)) == 0) { - int i; - options += strlen(cp); - forced_command = xmalloc(strlen(options) + 1); - i = 0; - while (*options) { - if (*options == '"') - break; - if (*options == '\\' && options[1] == '"') { - options += 2; - forced_command[i++] = '"'; - continue; - } - forced_command[i++] = *options++; - } - if (!*options) { - debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - packet_send_debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - continue; - } - forced_command[i] = 0; - packet_send_debug("Forced command: %.900s", forced_command); - options++; - goto next_option; - } - cp = "environment=\""; - if (strncmp(options, cp, strlen(cp)) == 0) { - int i; - char *s; - struct envstring *new_envstring; - options += strlen(cp); - s = xmalloc(strlen(options) + 1); - i = 0; - while (*options) { - if (*options == '"') - break; - if (*options == '\\' && options[1] == '"') { - options += 2; - s[i++] = '"'; - continue; - } - s[i++] = *options++; - } - if (!*options) { - debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - packet_send_debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - continue; - } - s[i] = 0; - packet_send_debug("Adding to environment: %.900s", s); - debug("Adding to environment: %.900s", s); - options++; - new_envstring = xmalloc(sizeof(struct envstring)); - new_envstring->s = s; - new_envstring->next = custom_environment; - custom_environment = new_envstring; - goto next_option; - } - cp = "from=\""; - if (strncmp(options, cp, strlen(cp)) == 0) { - char *patterns = xmalloc(strlen(options) + 1); - int i; - options += strlen(cp); - i = 0; - while (*options) { - if (*options == '"') - break; - if (*options == '\\' && options[1] == '"') { - options += 2; - patterns[i++] = '"'; - continue; - } - patterns[i++] = *options++; - } - if (!*options) { - debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - packet_send_debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - continue; - } - patterns[i] = 0; - options++; - if (!match_hostname(get_canonical_hostname(), patterns, - strlen(patterns)) && - !match_hostname(get_remote_ipaddr(), patterns, - strlen(patterns))) { - log("RSA authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).", - pw->pw_name, get_canonical_hostname(), - get_remote_ipaddr()); - packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", - get_canonical_hostname()); - xfree(patterns); - /* key invalid for this host, reset flags */ - authenticated = 0; - no_agent_forwarding_flag = 0; - no_port_forwarding_flag = 0; - no_pty_flag = 0; - no_x11_forwarding_flag = 0; - while (custom_environment) { - struct envstring *ce = custom_environment; - custom_environment = ce->next; - xfree(ce->s); - xfree(ce); - } - if (forced_command) { - xfree(forced_command); - forced_command = NULL; - } - break; - } - xfree(patterns); - /* Host name matches. */ - goto next_option; - } - bad_option: - log("Bad options in %.100s file, line %lu: %.50s", - SSH_USER_PERMITTED_KEYS, linenum, options); - packet_send_debug("Bad options in %.100s file, line %lu: %.50s", - SSH_USER_PERMITTED_KEYS, linenum, options); - authenticated = 0; - break; - - next_option: - /* - * Skip the comma, and move to the next option - * (or break out if there are no more). - */ - if (!*options) - fatal("Bugs in auth-rsa.c option processing."); - if (*options == ' ' || *options == '\t') - break; /* End of options. */ - if (*options != ',') - goto bad_option; - options++; - /* Process the next option. */ - continue; - } - } - /* * Break out of the loop if authentication was successful; * otherwise continue searching. */ + authenticated = auth_parse_options(pw, options, linenum); if (authenticated) break; } diff --git a/crypto/openssh/auth-skey.c b/crypto/openssh/auth-skey.c index 5f3fe9ee1b96..81dd4c28af27 100644 --- a/crypto/openssh/auth-skey.c +++ b/crypto/openssh/auth-skey.c @@ -1,5 +1,29 @@ +/* + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include "includes.h" -RCSID("$Id: auth-skey.c,v 1.6 2000/04/14 10:30:29 markus Exp $"); +RCSID("$OpenBSD: auth-skey.c,v 1.8 2000/09/07 20:27:49 deraadt Exp $"); #include "ssh.h" #include "packet.h" diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index 20e9760c4281..2d4f6d041777 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -1,11 +1,39 @@ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $"); +RCSID("$OpenBSD: auth.c,v 1.10 2000/09/07 21:13:36 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -24,12 +52,9 @@ RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $"); #include "ssh2.h" #include "auth.h" #include "session.h" -#include "dispatch.h" - /* import */ extern ServerOptions options; -extern char *forced_command; /* * Check if the user is allowed to log in via ssh. If user is listed in diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h index 72126e0992d9..65bf7ae1012b 100644 --- a/crypto/openssh/auth.h +++ b/crypto/openssh/auth.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef AUTH_H #define AUTH_H @@ -7,7 +30,7 @@ void do_authentication2(void); struct passwd * auth_get_user(void); -int allowed_user(struct passwd * pw);; +int allowed_user(struct passwd * pw); #define AUTH_FAIL_MAX 6 #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c index 38114d8c06eb..59df9e30320c 100644 --- a/crypto/openssh/auth1.c +++ b/crypto/openssh/auth1.c @@ -1,10 +1,16 @@ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.2 2000/04/29 18:11:52 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.4 2000/09/07 20:27:49 deraadt Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -429,6 +435,7 @@ do_authentication() pwcopy.pw_passwd = xstrdup(pw->pw_passwd); pwcopy.pw_uid = pw->pw_uid; pwcopy.pw_gid = pw->pw_gid; + pwcopy.pw_class = xstrdup(pw->pw_class); pwcopy.pw_dir = xstrdup(pw->pw_dir); pwcopy.pw_shell = xstrdup(pw->pw_shell); pw = &pwcopy; diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c index 3f8c254080de..f2d742810af1 100644 --- a/crypto/openssh/auth2.c +++ b/crypto/openssh/auth2.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -26,8 +21,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.8 2000/05/08 17:42:24 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.14 2000/09/07 20:27:49 deraadt Exp $"); #include <openssl/dsa.h> #include <openssl/rsa.h> @@ -54,6 +50,7 @@ RCSID("$OpenBSD: auth2.c,v 1.8 2000/05/08 17:42:24 markus Exp $"); #include "dsa.h" #include "uidswap.h" +#include "auth-options.h" /* import */ extern ServerOptions options; @@ -69,7 +66,7 @@ void protocol_error(int type, int plen); /* auth */ int ssh2_auth_none(struct passwd *pw); int ssh2_auth_password(struct passwd *pw); -int ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen); +int ssh2_auth_pubkey(struct passwd *pw, char *service); /* helper */ struct passwd* auth_set_user(char *u, char *s); @@ -150,17 +147,14 @@ input_userauth_request(int type, int plen) { static void (*authlog) (const char *fmt,...) = verbose; static int attempt = 0; - unsigned int len, rlen; + unsigned int len; int authenticated = 0; - char *raw, *user, *service, *method, *authmsg = NULL; + char *user, *service, *method, *authmsg = NULL; struct passwd *pw; if (++attempt == AUTH_FAIL_MAX) packet_disconnect("too many failed userauth_requests"); - raw = packet_get_raw(&rlen); - if (plen != rlen) - fatal("plen != rlen"); user = packet_get_string(&len); service = packet_get_string(&len); method = packet_get_string(&len); @@ -174,7 +168,7 @@ input_userauth_request(int type, int plen) } else if (strcmp(method, "password") == 0) { authenticated = ssh2_auth_password(pw); } else if (strcmp(method, "publickey") == 0) { - authenticated = ssh2_auth_pubkey(pw, raw, rlen); + authenticated = ssh2_auth_pubkey(pw, service); } } if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) { @@ -252,7 +246,7 @@ ssh2_auth_password(struct passwd *pw) return authenticated; } int -ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen) +ssh2_auth_pubkey(struct passwd *pw, char *service) { Buffer b; Key *key; @@ -265,10 +259,6 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen) debug("pubkey auth disabled"); return 0; } - if (datafellows & SSH_BUG_PUBKEYAUTH) { - log("bug compatibility with ssh-2.0.13 pubkey not implemented"); - return 0; - } have_sig = packet_get_char(); pkalg = packet_get_string(&alen); if (strcmp(pkalg, KEX_DSS) != 0) { @@ -283,11 +273,22 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen) sig = packet_get_string(&slen); packet_done(); buffer_init(&b); - buffer_append(&b, session_id2, session_id2_len); + if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) { + buffer_put_string(&b, session_id2, session_id2_len); + } else { + buffer_append(&b, session_id2, session_id2_len); + } + /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - if (slen + 4 > rlen) - fatal("bad rlen/slen"); - buffer_append(&b, raw, rlen - slen - 4); + buffer_put_cstring(&b, pw->pw_name); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PUBKEYAUTH ? + "ssh-userauth" : + service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, have_sig); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, pkblob, blen); #ifdef DEBUG_DSS buffer_dump(&b); #endif @@ -355,6 +356,7 @@ auth_set_user(char *u, char *s) copy->pw_passwd = xstrdup(pw->pw_passwd); copy->pw_uid = pw->pw_uid; copy->pw_gid = pw->pw_gid; + copy->pw_class = xstrdup(pw->pw_class); copy->pw_dir = xstrdup(pw->pw_dir); copy->pw_shell = xstrdup(pw->pw_shell); authctxt->valid = 1; @@ -433,8 +435,8 @@ user_dsa_key_allowed(struct passwd *pw, Key *key) } } if (fail) { - log(buf); fclose(f); + log("%s",buf); restore_uid(); return 0; } @@ -443,17 +445,36 @@ user_dsa_key_allowed(struct passwd *pw, Key *key) found = key_new(KEY_DSA); while (fgets(line, sizeof(line), f)) { - char *cp; + char *cp, *options = NULL; linenum++; /* Skip leading whitespace, empty and comment lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; if (!*cp || *cp == '\n' || *cp == '#') continue; + bits = key_read(found, &cp); - if (bits == 0) - continue; - if (key_equal(found, key)) { + if (bits == 0) { + /* no key? check if there are options for this key */ + int quoted = 0; + options = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + /* Skip remaining whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + bits = key_read(found, &cp); + if (bits == 0) { + /* still no key? advance to next line*/ + continue; + } + } + if (key_equal(found, key) && + auth_parse_options(pw, options, linenum) == 1) { found_key = 1; debug("matching key found: file %s, line %ld", file, linenum); diff --git a/crypto/openssh/authfd.c b/crypto/openssh/authfd.c index 77d38e00dd37..958638560b00 100644 --- a/crypto/openssh/authfd.c +++ b/crypto/openssh/authfd.c @@ -1,30 +1,59 @@ /* - * - * authfd.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved + * Functions for connecting the local authentication agent. * - * Created: Wed Mar 29 01:30:28 1995 ylo + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". * - * Functions for connecting the local authentication agent. + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. All rights reserved. * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: authfd.c,v 1.19 2000/04/29 18:11:52 markus Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.27 2000/09/07 20:27:49 deraadt Exp $"); #include "ssh.h" #include "rsa.h" -#include "authfd.h" #include "buffer.h" #include "bufaux.h" #include "xmalloc.h" #include "getput.h" #include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <openssl/evp.h> +#include "key.h" +#include "authfd.h" +#include "kex.h" +#include "dsa.h" + +/* helper */ +int decode_reply(int type); /* Returns the number of the authentication fd, or -1 if there is none. */ @@ -32,7 +61,7 @@ int ssh_get_authentication_socket() { const char *authsocket; - int sock; + int sock, len; struct sockaddr_un sunaddr; authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); @@ -41,6 +70,7 @@ ssh_get_authentication_socket() sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); + sunaddr.sun_len = len = SUN_LEN(&sunaddr)+1; sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) @@ -51,13 +81,66 @@ ssh_get_authentication_socket() close(sock); return -1; } - if (connect(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { + if (connect(sock, (struct sockaddr *) & sunaddr, len) < 0) { close(sock); return -1; } return sock; } +int +ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply) +{ + int l, len; + char buf[1024]; + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(request); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(request), + buffer_len(request)) != buffer_len(request)) { + error("Error writing to authentication socket."); + return 0; + } + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + len = 4; + while (len > 0) { + l = read(auth->fd, buf + 4 - len, len); + if (l <= 0) { + error("Error reading response length from authentication socket."); + return 0; + } + len -= l; + } + + /* Extract the length, and check it for sanity. */ + len = GET_32BIT(buf); + if (len > 256 * 1024) + fatal("Authentication response too long: %d", len); + + /* Read the rest of the response in to the buffer. */ + buffer_clear(reply); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + l = read(auth->fd, buf, l); + if (l <= 0) { + error("Error reading response from authentication socket."); + return 0; + } + buffer_append(reply, (char *) buf, l); + len -= l; + } + return 1; +} + /* * Closes the agent socket if it should be closed (depends on how it was * obtained). The argument must have been returned by @@ -96,7 +179,6 @@ ssh_get_authentication_connection() auth = xmalloc(sizeof(*auth)); auth->fd = sock; - buffer_init(&auth->packet); buffer_init(&auth->identities); auth->howmany = 0; @@ -109,121 +191,108 @@ ssh_get_authentication_connection() */ void -ssh_close_authentication_connection(AuthenticationConnection *ac) +ssh_close_authentication_connection(AuthenticationConnection *auth) { - buffer_free(&ac->packet); - buffer_free(&ac->identities); - close(ac->fd); - xfree(ac); + buffer_free(&auth->identities); + close(auth->fd); + xfree(auth); } /* * Returns the first authentication identity held by the agent. - * Returns true if an identity is available, 0 otherwise. - * The caller must initialize the integers before the call, and free the - * comment after a successful call (before calling ssh_get_next_identity). */ -int -ssh_get_first_identity(AuthenticationConnection *auth, - BIGNUM *e, BIGNUM *n, char **comment) +Key * +ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version) { - unsigned char msg[8192]; - int len, l; + int type, code1 = 0, code2 = 0; + Buffer request; + + switch(version){ + case 1: + code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES; + code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER; + break; + case 2: + code1 = SSH2_AGENTC_REQUEST_IDENTITIES; + code2 = SSH2_AGENT_IDENTITIES_ANSWER; + break; + default: + return NULL; + } /* * Send a message to the agent requesting for a list of the * identities it can represent. */ - msg[0] = 0; - msg[1] = 0; - msg[2] = 0; - msg[3] = 1; - msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES; - if (atomicio(write, auth->fd, msg, 5) != 5) { - error("write auth->fd: %.100s", strerror(errno)); - return 0; - } - /* Read the length of the response. XXX implement timeouts here. */ - len = 4; - while (len > 0) { - l = read(auth->fd, msg + 4 - len, len); - if (l <= 0) { - error("read auth->fd: %.100s", strerror(errno)); - return 0; - } - len -= l; - } + buffer_init(&request); + buffer_put_char(&request, code1); - /* - * Extract the length, and check it for sanity. (We cannot trust - * authentication agents). - */ - len = GET_32BIT(msg); - if (len < 1 || len > 256 * 1024) - fatal("Authentication reply message too long: %d\n", len); - - /* Read the packet itself. */ buffer_clear(&auth->identities); - while (len > 0) { - l = len; - if (l > sizeof(msg)) - l = sizeof(msg); - l = read(auth->fd, msg, l); - if (l <= 0) - fatal("Incomplete authentication reply."); - buffer_append(&auth->identities, (char *) msg, l); - len -= l; + if (ssh_request_reply(auth, &request, &auth->identities) == 0) { + buffer_free(&request); + return NULL; } + buffer_free(&request); /* Get message type, and verify that we got a proper answer. */ - buffer_get(&auth->identities, (char *) msg, 1); - if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER) - fatal("Bad authentication reply message type: %d", msg[0]); + type = buffer_get_char(&auth->identities); + if (type == SSH_AGENT_FAILURE) { + return NULL; + } else if (type != code2) { + fatal("Bad authentication reply message type: %d", type); + } /* Get the number of entries in the response and check it for sanity. */ auth->howmany = buffer_get_int(&auth->identities); if (auth->howmany > 1024) - fatal("Too many identities in authentication reply: %d\n", auth->howmany); + fatal("Too many identities in authentication reply: %d\n", + auth->howmany); /* Return the first entry (if any). */ - return ssh_get_next_identity(auth, e, n, comment); + return ssh_get_next_identity(auth, comment, version); } -/* - * Returns the next authentication identity for the agent. Other functions - * can be called between this and ssh_get_first_identity or two calls of this - * function. This returns 0 if there are no more identities. The caller - * must free comment after a successful return. - */ - -int -ssh_get_next_identity(AuthenticationConnection *auth, - BIGNUM *e, BIGNUM *n, char **comment) +Key * +ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version) { unsigned int bits; + unsigned char *blob; + unsigned int blen; + Key *key = NULL; /* Return failure if no more entries. */ if (auth->howmany <= 0) - return 0; + return NULL; /* * Get the next entry from the packet. These will abort with a fatal * error if the packet is too short or contains corrupt data. */ - bits = buffer_get_int(&auth->identities); - buffer_get_bignum(&auth->identities, e); - buffer_get_bignum(&auth->identities, n); - *comment = buffer_get_string(&auth->identities, NULL); - - if (bits != BN_num_bits(n)) - log("Warning: identity keysize mismatch: actual %d, announced %u", - BN_num_bits(n), bits); - + switch(version){ + case 1: + key = key_new(KEY_RSA); + bits = buffer_get_int(&auth->identities); + buffer_get_bignum(&auth->identities, key->rsa->e); + buffer_get_bignum(&auth->identities, key->rsa->n); + *comment = buffer_get_string(&auth->identities, NULL); + if (bits != BN_num_bits(key->rsa->n)) + log("Warning: identity keysize mismatch: actual %d, announced %u", + BN_num_bits(key->rsa->n), bits); + break; + case 2: + blob = buffer_get_string(&auth->identities, &blen); + *comment = buffer_get_string(&auth->identities, NULL); + key = dsa_key_from_blob(blob, blen); + xfree(blob); + break; + default: + return NULL; + break; + } /* Decrement the number of remaining entries. */ auth->howmany--; - - return 1; + return key; } /* @@ -236,101 +305,124 @@ ssh_get_next_identity(AuthenticationConnection *auth, int ssh_decrypt_challenge(AuthenticationConnection *auth, - BIGNUM* e, BIGNUM *n, BIGNUM *challenge, - unsigned char session_id[16], - unsigned int response_type, - unsigned char response[16]) + Key* key, BIGNUM *challenge, + unsigned char session_id[16], + unsigned int response_type, + unsigned char response[16]) { Buffer buffer; - unsigned char buf[8192]; - int len, l, i; + int success = 0; + int i; + int type; - /* Response type 0 is no longer supported. */ - if (response_type == 0) - fatal("Compatibility with ssh protocol version 1.0 no longer supported."); - - /* Format a message to the agent. */ - buf[0] = SSH_AGENTC_RSA_CHALLENGE; + if (key->type != KEY_RSA) + return 0; + if (response_type == 0) { + log("Compatibility with ssh protocol version 1.0 no longer supported."); + return 0; + } buffer_init(&buffer); - buffer_append(&buffer, (char *) buf, 1); - buffer_put_int(&buffer, BN_num_bits(n)); - buffer_put_bignum(&buffer, e); - buffer_put_bignum(&buffer, n); + buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE); + buffer_put_int(&buffer, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&buffer, key->rsa->e); + buffer_put_bignum(&buffer, key->rsa->n); buffer_put_bignum(&buffer, challenge); buffer_append(&buffer, (char *) session_id, 16); buffer_put_int(&buffer, response_type); - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); -error_cleanup: + if (ssh_request_reply(auth, &buffer, &buffer) == 0) { buffer_free(&buffer); return 0; } - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - goto error_cleanup; - } - len -= l; + type = buffer_get_char(&buffer); + + if (type == SSH_AGENT_FAILURE) { + log("Agent admitted failure to authenticate using the key."); + } else if (type != SSH_AGENT_RSA_RESPONSE) { + fatal("Bad authentication response: %d", type); + } else { + success = 1; + /* + * Get the response from the packet. This will abort with a + * fatal error if the packet is corrupt. + */ + for (i = 0; i < 16; i++) + response[i] = buffer_get_char(&buffer); } + buffer_free(&buffer); + return success; +} - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Authentication response too long: %d", len); +/* ask agent to sign data, returns -1 on error, 0 on success */ +int +ssh_agent_sign(AuthenticationConnection *auth, + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen) +{ + Buffer msg; + unsigned char *blob; + unsigned int blen; + int type; + int ret = -1; - /* Read the rest of the response in tothe buffer. */ - buffer_clear(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - goto error_cleanup; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } + if (dsa_make_key_blob(key, &blob, &blen) == 0) + return -1; - /* Get the type of the packet. */ - buffer_get(&buffer, (char *) buf, 1); + buffer_init(&msg); + buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); + buffer_put_string(&msg, blob, blen); + buffer_put_string(&msg, data, datalen); + buffer_put_int(&msg, 0); /* flags, unused */ + xfree(blob); - /* Check for agent failure message. */ - if (buf[0] == SSH_AGENT_FAILURE) { - log("Agent admitted failure to authenticate using the key."); - goto error_cleanup; + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return -1; + } + type = buffer_get_char(&msg); + if (type == SSH_AGENT_FAILURE) { + log("Agent admitted failure to sign using the key."); + } else if (type != SSH2_AGENT_SIGN_RESPONSE) { + fatal("Bad authentication response: %d", type); + } else { + ret = 0; + *sigp = buffer_get_string(&msg, lenp); } - /* Now it must be an authentication response packet. */ - if (buf[0] != SSH_AGENT_RSA_RESPONSE) - fatal("Bad authentication response: %d", buf[0]); + buffer_free(&msg); + return ret; +} - /* - * Get the response from the packet. This will abort with a fatal - * error if the packet is corrupt. - */ - for (i = 0; i < 16; i++) - response[i] = buffer_get_char(&buffer); +/* Encode key for a message to the agent. */ - /* The buffer containing the packet is no longer needed. */ - buffer_free(&buffer); +void +ssh_encode_identity_rsa(Buffer *b, RSA *key, const char *comment) +{ + buffer_clear(b); + buffer_put_char(b, SSH_AGENTC_ADD_RSA_IDENTITY); + buffer_put_int(b, BN_num_bits(key->n)); + buffer_put_bignum(b, key->n); + buffer_put_bignum(b, key->e); + buffer_put_bignum(b, key->d); + /* To keep within the protocol: p < q for ssh. in SSL p > q */ + buffer_put_bignum(b, key->iqmp); /* ssh key->u */ + buffer_put_bignum(b, key->q); /* ssh key->p, SSL key->q */ + buffer_put_bignum(b, key->p); /* ssh key->q, SSL key->p */ + buffer_put_string(b, comment, strlen(comment)); +} - /* Correct answer. */ - return 1; +void +ssh_encode_identity_dsa(Buffer *b, DSA *key, const char *comment) +{ + buffer_clear(b); + buffer_put_char(b, SSH2_AGENTC_ADD_IDENTITY); + buffer_put_cstring(b, KEX_DSS); + buffer_put_bignum2(b, key->p); + buffer_put_bignum2(b, key->q); + buffer_put_bignum2(b, key->g); + buffer_put_bignum2(b, key->pub_key); + buffer_put_bignum2(b, key->priv_key); + buffer_put_string(b, comment, strlen(comment)); } /* @@ -339,86 +431,32 @@ error_cleanup: */ int -ssh_add_identity(AuthenticationConnection *auth, - RSA * key, const char *comment) +ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) { - Buffer buffer; - unsigned char buf[8192]; - int len, l, type; - - /* Format a message to the agent. */ - buffer_init(&buffer); - buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY); - buffer_put_int(&buffer, BN_num_bits(key->n)); - buffer_put_bignum(&buffer, key->n); - buffer_put_bignum(&buffer, key->e); - buffer_put_bignum(&buffer, key->d); - /* To keep within the protocol: p < q for ssh. in SSL p > q */ - buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */ - buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */ - buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */ - buffer_put_string(&buffer, comment, strlen(comment)); - - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); -error_cleanup: - buffer_free(&buffer); + Buffer msg; + int type; + + buffer_init(&msg); + + switch (key->type) { + case KEY_RSA: + ssh_encode_identity_rsa(&msg, key->rsa, comment); + break; + case KEY_DSA: + ssh_encode_identity_dsa(&msg, key->dsa, comment); + break; + default: + buffer_free(&msg); return 0; + break; } - /* Wait for response from the agent. First read the length of the - response packet. */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - goto error_cleanup; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Add identity response too long: %d", len); - - /* Read the rest of the response in tothe buffer. */ - buffer_clear(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - goto error_cleanup; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - type = buffer_get_char(&buffer); - switch (type) { - case SSH_AGENT_FAILURE: - buffer_free(&buffer); + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); return 0; - case SSH_AGENT_SUCCESS: - buffer_free(&buffer); - return 1; - default: - fatal("Bad response to add identity from authentication agent: %d", - type); } - /* NOTREACHED */ - return 0; + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); } /* @@ -427,81 +465,36 @@ error_cleanup: */ int -ssh_remove_identity(AuthenticationConnection *auth, RSA *key) +ssh_remove_identity(AuthenticationConnection *auth, Key *key) { - Buffer buffer; - unsigned char buf[8192]; - int len, l, type; - - /* Format a message to the agent. */ - buffer_init(&buffer); - buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY); - buffer_put_int(&buffer, BN_num_bits(key->n)); - buffer_put_bignum(&buffer, key->e); - buffer_put_bignum(&buffer, key->n); - - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); -error_cleanup: - buffer_free(&buffer); + Buffer msg; + int type; + unsigned char *blob; + unsigned int blen; + + buffer_init(&msg); + + if (key->type == KEY_RSA) { + buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY); + buffer_put_int(&msg, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&msg, key->rsa->e); + buffer_put_bignum(&msg, key->rsa->n); + } else if (key->type == KEY_DSA) { + dsa_make_key_blob(key, &blob, &blen); + buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); + buffer_put_string(&msg, blob, blen); + xfree(blob); + } else { + buffer_free(&msg); return 0; } - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - goto error_cleanup; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Remove identity response too long: %d", len); - - /* Read the rest of the response in tothe buffer. */ - buffer_clear(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - goto error_cleanup; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - type = buffer_get_char(&buffer); - switch (type) { - case SSH_AGENT_FAILURE: - buffer_free(&buffer); + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); return 0; - case SSH_AGENT_SUCCESS: - buffer_free(&buffer); - return 1; - default: - fatal("Bad response to remove identity from authentication agent: %d", - type); } - /* NOTREACHED */ - return 0; + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); } /* @@ -510,68 +503,37 @@ error_cleanup: */ int -ssh_remove_all_identities(AuthenticationConnection *auth) +ssh_remove_all_identities(AuthenticationConnection *auth, int version) { - Buffer buffer; - unsigned char buf[8192]; - int len, l, type; + Buffer msg; + int type; + int code = (version==1) ? + SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : + SSH2_AGENTC_REMOVE_ALL_IDENTITIES; - /* Get the length of the message, and format it in the buffer. */ - PUT_32BIT(buf, 1); - buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES; + buffer_init(&msg); + buffer_put_char(&msg, code); - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 5) != 5) { - error("Error writing to authentication socket."); + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); return 0; } - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - return 0; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Remove identity response too long: %d", len); - - /* Read the rest of the response into the buffer. */ - buffer_init(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - buffer_free(&buffer); - return 0; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} - /* Get the type of the packet. */ - type = buffer_get_char(&buffer); +int +decode_reply(int type) +{ switch (type) { case SSH_AGENT_FAILURE: - buffer_free(&buffer); + log("SSH_AGENT_FAILURE"); return 0; case SSH_AGENT_SUCCESS: - buffer_free(&buffer); return 1; default: - fatal("Bad response to remove identity from authentication agent: %d", - type); + fatal("Bad response from authentication agent: %d", type); } /* NOTREACHED */ return 0; diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h index fbeea2334dc8..b7a137d99d38 100644 --- a/crypto/openssh/authfd.h +++ b/crypto/openssh/authfd.h @@ -1,19 +1,17 @@ /* - * - * authfd.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Wed Mar 29 01:17:41 1995 ylo - * * Functions to interface with the SSH_AUTHENTICATION_FD socket. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: authfd.h,v 1.7 2000/04/14 10:30:30 markus Exp $"); */ +/* RCSID("$OpenBSD: authfd.h,v 1.11 2000/09/07 20:27:49 deraadt Exp $"); */ #ifndef AUTHFD_H #define AUTHFD_H @@ -31,12 +29,20 @@ #define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 #define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 +#define SSH2_AGENTC_REQUEST_IDENTITIES 11 +#define SSH2_AGENT_IDENTITIES_ANSWER 12 +#define SSH2_AGENTC_SIGN_REQUEST 13 +#define SSH2_AGENT_SIGN_RESPONSE 14 +#define SSH2_AGENTC_ADD_IDENTITY 17 +#define SSH2_AGENTC_REMOVE_IDENTITY 18 +#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 + typedef struct { int fd; - Buffer packet; Buffer identities; int howmany; } AuthenticationConnection; + /* Returns the number of the authentication fd, or -1 if there is none. */ int ssh_get_authentication_socket(); @@ -59,44 +65,48 @@ AuthenticationConnection *ssh_get_authentication_connection(); * Closes the connection to the authentication agent and frees any associated * memory. */ -void ssh_close_authentication_connection(AuthenticationConnection * ac); +void ssh_close_authentication_connection(AuthenticationConnection *auth); /* - * Returns the first authentication identity held by the agent. Returns true - * if an identity is available, 0 otherwise. The caller must initialize the - * integers before the call, and free the comment after a successful call - * (before calling ssh_get_next_identity). + * Returns the first authentication identity held by the agent or NULL if + * no identies are available. Caller must free comment and key. + * Note that you cannot mix calls with different versions. */ -int -ssh_get_first_identity(AuthenticationConnection * connection, - BIGNUM * e, BIGNUM * n, char **comment); +Key *ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version); /* * Returns the next authentication identity for the agent. Other functions * can be called between this and ssh_get_first_identity or two calls of this - * function. This returns 0 if there are no more identities. The caller - * must free comment after a successful return. + * function. This returns NULL if there are no more identities. The caller + * must free key and comment after a successful return. */ -int -ssh_get_next_identity(AuthenticationConnection * connection, - BIGNUM * e, BIGNUM * n, char **comment); +Key *ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version); -/* Requests the agent to decrypt the given challenge. Returns true if - the agent claims it was able to decrypt it. */ +/* + * Requests the agent to decrypt the given challenge. Returns true if the + * agent claims it was able to decrypt it. + */ int -ssh_decrypt_challenge(AuthenticationConnection * auth, - BIGNUM * e, BIGNUM * n, BIGNUM * challenge, +ssh_decrypt_challenge(AuthenticationConnection *auth, + Key *key, BIGNUM * challenge, unsigned char session_id[16], unsigned int response_type, unsigned char response[16]); +/* Requests the agent to sign data using key */ +int +ssh_agent_sign(AuthenticationConnection *auth, + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen); + /* * Adds an identity to the authentication server. This call is not meant to * be used by normal applications. This returns true if the identity was * successfully added. */ int -ssh_add_identity(AuthenticationConnection * connection, RSA * key, +ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment); /* @@ -104,16 +114,13 @@ ssh_add_identity(AuthenticationConnection * connection, RSA * key, * meant to be used by normal applications. This returns true if the * identity was successfully added. */ -int ssh_remove_identity(AuthenticationConnection * connection, RSA * key); +int ssh_remove_identity(AuthenticationConnection *auth, Key *key); /* * Removes all identities from the authentication agent. This call is not * meant to be used by normal applications. This returns true if the * operation was successful. */ -int ssh_remove_all_identities(AuthenticationConnection * connection); - -/* Closes the connection to the authentication agent. */ -void ssh_close_authentication(AuthenticationConnection * connection); +int ssh_remove_all_identities(AuthenticationConnection *auth, int version); #endif /* AUTHFD_H */ diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c index 92740c48a1c2..bd6fee05f523 100644 --- a/crypto/openssh/authfile.c +++ b/crypto/openssh/authfile.c @@ -1,21 +1,42 @@ /* - * - * authfile.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Mon Mar 27 03:52:05 1995 ylo - * * This file contains functions for reading and writing identity files, and * for reading the passphrase from the user. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: authfile.c,v 1.16 2000/04/26 21:28:32 markus Exp $"); +RCSID("$OpenBSD: authfile.c,v 1.19 2000/09/07 20:27:49 deraadt Exp $"); #include <openssl/bn.h> #include <openssl/dsa.h> @@ -262,6 +283,7 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) return 1; } +/* load public key from private-key file */ int load_public_key(const char *filename, Key * key, char **comment_return) { @@ -491,3 +513,57 @@ load_private_key(const char *filename, const char *passphrase, Key *key, close(fd); return ret; } + +int +do_load_public_key(const char *filename, Key *k, char **commentp) +{ + FILE *f; + unsigned int bits; + char line[1024]; + char *cp; + + f = fopen(filename, "r"); + if (f != NULL) { + while (fgets(line, sizeof(line), f)) { + line[sizeof(line)-1] = '\0'; + cp = line; + switch(*cp){ + case '#': + case '\n': + case '\0': + continue; + } + /* Skip leading whitespace. */ + for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) + ; + if (*cp) { + bits = key_read(k, &cp); + if (bits != 0) { + if (commentp) + *commentp=xstrdup(filename); + fclose(f); + return 1; + } + } + } + fclose(f); + } + return 0; +} + +/* load public key from pubkey file */ +int +try_load_public_key(const char *filename, Key *k, char **commentp) +{ + char pub[MAXPATHLEN]; + + if (do_load_public_key(filename, k, commentp) == 1) + return 1; + if (strlcpy(pub, filename, sizeof pub) >= MAXPATHLEN) + return 0; + if (strlcat(pub, ".pub", sizeof pub) >= MAXPATHLEN) + return 0; + if (do_load_public_key(pub, k, commentp) == 1) + return 1; + return 0; +} diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h index afec27d5433e..4283d9381c06 100644 --- a/crypto/openssh/authfile.h +++ b/crypto/openssh/authfile.h @@ -1,3 +1,15 @@ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ #ifndef AUTHFILE_H #define AUTHFILE_H @@ -18,9 +30,8 @@ save_private_key(const char *filename, const char *passphrase, * comment of the key is returned in comment_return if it is non-NULL; the * caller must free the value with xfree. */ -int -load_public_key(const char *filename, Key * pub, - char **comment_return); +int load_public_key(const char *filename, Key * pub, char **comment_return); +int try_load_public_key(const char *filename, Key * pub, char **comment_return); /* * Loads the private key from the file. Returns 0 if an error is encountered diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c index 922acc4e1146..a3f220f89ebe 100644 --- a/crypto/openssh/bufaux.c +++ b/crypto/openssh/bufaux.c @@ -1,23 +1,43 @@ /* - * - * bufaux.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Wed Mar 29 02:24:47 1995 ylo - * * Auxiliary functions for storing and retrieving various data types to/from * Buffers. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * * SSH2 packet format added by Markus Friedl + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: bufaux.c,v 1.11 2000/04/14 10:30:30 markus Exp $"); +RCSID("$OpenBSD: bufaux.c,v 1.13 2000/09/07 20:27:50 deraadt Exp $"); #include "ssh.h" #include <openssl/bn.h> diff --git a/crypto/openssh/bufaux.h b/crypto/openssh/bufaux.h index 8ba92f8b5925..4f53858f75b1 100644 --- a/crypto/openssh/bufaux.h +++ b/crypto/openssh/bufaux.h @@ -1,17 +1,16 @@ /* - * - * bufaux.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Wed Mar 29 02:18:23 1995 ylo - * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: bufaux.h,v 1.6 2000/04/14 10:30:30 markus Exp $"); */ +/* RCSID("$OpenBSD: bufaux.h,v 1.8 2000/09/07 20:27:50 deraadt Exp $"); */ #ifndef BUFAUX_H #define BUFAUX_H diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c index 4d8343322cdf..d993c8bcdef8 100644 --- a/crypto/openssh/buffer.c +++ b/crypto/openssh/buffer.c @@ -1,20 +1,18 @@ /* - * - * buffer.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sat Mar 18 04:15:33 1995 ylo - * * Functions for manipulating fifo buffers (that can grow if needed). * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: buffer.c,v 1.6 2000/04/14 10:30:30 markus Exp $"); +RCSID("$OpenBSD: buffer.c,v 1.8 2000/09/07 20:27:50 deraadt Exp $"); #include "xmalloc.h" #include "buffer.h" diff --git a/crypto/openssh/buffer.h b/crypto/openssh/buffer.h index be4fdc3cabd5..522036a41445 100644 --- a/crypto/openssh/buffer.h +++ b/crypto/openssh/buffer.h @@ -1,19 +1,17 @@ /* - * - * buffer.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sat Mar 18 04:12:25 1995 ylo - * * Code for manipulating FIFO buffers. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: buffer.h,v 1.4 2000/04/14 10:30:30 markus Exp $"); */ +/* RCSID("$OpenBSD: buffer.h,v 1.6 2000/09/07 20:27:50 deraadt Exp $"); */ #ifndef BUFFER_H #define BUFFER_H diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c index a73f8d0ecf2d..ff8da0e693a0 100644 --- a/crypto/openssh/canohost.c +++ b/crypto/openssh/canohost.c @@ -1,20 +1,18 @@ /* - * - * canohost.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sun Jul 2 17:52:22 1995 ylo - * * Functions for returning the canonical host name of the remote site. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: canohost.c,v 1.12 2000/04/14 10:30:30 markus Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.15 2000/09/07 21:13:37 markus Exp $"); #include "packet.h" #include "xmalloc.h" diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c index 871dcb877d4e..e9a64d92f774 100644 --- a/crypto/openssh/channels.c +++ b/crypto/openssh/channels.c @@ -1,29 +1,51 @@ /* - * - * channels.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Fri Mar 24 16:35:24 1995 ylo - * * This file contains functions for generic socket connection forwarding. * There is also code for initiating connection forwarding for X11 connections, * arbitrary tcp/ip connections, and the authentication agent connection. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * * SSH2 support added by Markus Friedl. + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * Copyright (c) 1999 Dug Song. All rights reserved. + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: channels.c,v 1.59 2000/05/30 17:23:36 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.68 2000/09/07 20:40:29 markus Exp $"); #include "ssh.h" #include "packet.h" #include "xmalloc.h" #include "buffer.h" -#include "authfd.h" #include "uidswap.h" #include "readconf.h" #include "servconf.h" @@ -34,18 +56,17 @@ RCSID("$Id: channels.c,v 1.59 2000/05/30 17:23:36 markus Exp $"); #include "ssh2.h" +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include "key.h" +#include "authfd.h" + /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 /* Max len of agent socket */ #define MAX_SOCKET_NAME 100 -/* default window/packet sizes for tcp/x11-fwd-channel */ -#define CHAN_TCP_WINDOW_DEFAULT (8*1024) -#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2) -#define CHAN_X11_WINDOW_DEFAULT (4*1024) -#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) - /* * Pointer to an array containing all allocated channels. The array is * dynamically extended as needed. @@ -135,7 +156,7 @@ Channel * channel_lookup(int id) { Channel *c; - if (id < 0 && id > channels_alloc) { + if (id < 0 || id > channels_alloc) { log("channel_lookup: %d: bad id", id); return NULL; } @@ -240,6 +261,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->cb_arg = NULL; c->cb_event = 0; c->dettach_user = NULL; + c->input_filter = NULL; debug("channel %d: new [%s]", found, remote_name); return found; } @@ -661,7 +683,14 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) } return -1; } - buffer_append(&c->input, buf, len); + if(c->input_filter != NULL) { + if (c->input_filter(c, buf, len) == -1) { + debug("filter stops channel %d", c->self); + chan_read_failed(c); + } + } else { + buffer_append(&c->input, buf, len); + } } return 1; } @@ -932,7 +961,6 @@ channel_output_poll() packet_send(); buffer_consume(&c->input, len); c->remote_window -= len; - debug("channel %d: send data len %d", c->self, len); } } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { if (compat13) @@ -2250,6 +2278,16 @@ channel_cancel_cleanup(int id) } c->dettach_user = NULL; } +void +channel_register_filter(int id, channel_filter_fn *fn) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_filter: %d: bad id", id); + return; + } + c->input_filter = fn; +} void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) @@ -2261,7 +2299,7 @@ channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) channel_register_fds(c, rfd, wfd, efd, extusage); c->type = SSH_CHANNEL_OPEN; /* XXX window size? */ - c->local_window = c->local_window_max = c->local_maxpacket/2; + c->local_window = c->local_window_max = c->local_maxpacket * 2; packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); packet_put_int(c->remote_id); packet_put_int(c->local_window); diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h index 4cafdb959065..c0d60199c14d 100644 --- a/crypto/openssh/channels.h +++ b/crypto/openssh/channels.h @@ -1,4 +1,38 @@ -/* RCSID("$Id: channels.h,v 1.13 2000/05/30 17:23:37 markus Exp $"); */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* RCSID("$OpenBSD: channels.h,v 1.19 2000/09/07 21:13:37 markus Exp $"); */ #ifndef CHANNELS_H #define CHANNELS_H @@ -21,9 +55,13 @@ * Data structure for channel data. This is iniailized in channel_allocate * and cleared in channel_free. */ +struct Channel; +typedef struct Channel Channel; + typedef void channel_callback_fn(int id, void *arg); +typedef int channel_filter_fn(struct Channel *c, char *buf, int len); -typedef struct Channel { +struct Channel { int type; /* channel type/state */ int self; /* my own channel identifier */ int remote_id; /* channel identifier for remote peer */ @@ -61,18 +99,31 @@ typedef struct Channel { void *cb_arg; int cb_event; channel_callback_fn *dettach_user; -} Channel; + + /* filter */ + channel_filter_fn *input_filter; +}; #define CHAN_EXTENDED_IGNORE 0 #define CHAN_EXTENDED_READ 1 #define CHAN_EXTENDED_WRITE 2 +/* default window/packet sizes for tcp/x11-fwd-channel */ +#define CHAN_SES_WINDOW_DEFAULT (32*1024) +#define CHAN_SES_PACKET_DEFAULT (CHAN_SES_WINDOW_DEFAULT/2) +#define CHAN_TCP_WINDOW_DEFAULT (32*1024) +#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2) +#define CHAN_X11_WINDOW_DEFAULT (4*1024) +#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) + + void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage); void channel_open(int id); void channel_request(int id, char *service, int wantconfirm); void channel_request_start(int id, char *service, int wantconfirm); void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); void channel_register_cleanup(int id, channel_callback_fn *fn); +void channel_register_filter(int id, channel_filter_fn *fn); void channel_cancel_cleanup(int id); Channel *channel_lookup(int id); diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c index ca77c6d034de..899f0522a8af 100644 --- a/crypto/openssh/cipher.c +++ b/crypto/openssh/cipher.c @@ -1,18 +1,41 @@ /* - * - * cipher.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Wed Apr 19 17:41:39 1995 ylo + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 1999 Niels Provos. All rights reserved. + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: cipher.c,v 1.27 2000/05/22 18:42:00 markus Exp $"); +RCSID("$OpenBSD: cipher.c,v 1.30 2000/09/07 20:27:50 deraadt Exp $"); #include "ssh.h" #include "cipher.h" @@ -174,14 +197,15 @@ cipher_name(int cipher) int ciphers_valid(const char *names) { - char *ciphers; + char *ciphers, *cp; char *p; int i; if (names == NULL || strcmp(names, "") == 0) return 0; - ciphers = xstrdup(names); - for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) { + ciphers = cp = xstrdup(names); + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { i = cipher_number(p); if (i == -1 || !(cipher_mask2() & (1 << i))) { xfree(ciphers); diff --git a/crypto/openssh/cipher.h b/crypto/openssh/cipher.h index 197d9541eaf2..bc7a5e224312 100644 --- a/crypto/openssh/cipher.h +++ b/crypto/openssh/cipher.h @@ -1,17 +1,16 @@ /* - * - * cipher.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Wed Apr 19 16:50:42 1995 ylo - * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: cipher.h,v 1.17 2000/05/08 17:12:15 markus Exp $"); */ +/* RCSID("$OpenBSD: cipher.h,v 1.19 2000/09/07 20:27:50 deraadt Exp $"); */ #ifndef CIPHER_H #define CIPHER_H diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c index b4c7b287dfae..4f5c39c92736 100644 --- a/crypto/openssh/clientloop.c +++ b/crypto/openssh/clientloop.c @@ -1,28 +1,70 @@ /* - * - * clientloop.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved + * The main loop for the interactive session (client side). * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". * - * Created: Sat Sep 23 12:23:57 1995 ylo * - * The main loop for the interactive session (client side). + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * * * SSH2 support added by Markus Friedl. + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: clientloop.c,v 1.26 2000/05/08 17:42:24 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.34 2000/09/07 20:40:30 markus Exp $"); #include "xmalloc.h" #include "ssh.h" #include "packet.h" #include "buffer.h" -#include "authfd.h" #include "readconf.h" #include "ssh2.h" @@ -30,6 +72,8 @@ RCSID("$Id: clientloop.c,v 1.26 2000/05/08 17:42:24 markus Exp $"); #include "channels.h" #include "dispatch.h" +#include "buffer.h" +#include "bufaux.h" /* Flag indicating that stdin should be redirected from /dev/null. */ extern int stdin_null_flag; @@ -62,6 +106,8 @@ static int in_raw_mode = 0; static int in_non_blocking_mode = 0; /* Common data for the client loop code. */ +static int quit_pending; /* Set to non-zero to quit the client loop. */ +static int escape_char; /* Escape character. */ static int escape_pending; /* Last character was the escape character */ static int last_was_cr; /* Last character was a newline. */ static int exit_status; /* Used to store the exit status of the command. */ @@ -69,13 +115,11 @@ static int stdin_eof; /* EOF has been encountered on standard error. */ static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ static Buffer stderr_buffer; /* Buffer for stderr data. */ +static unsigned long stdin_bytes, stdout_bytes, stderr_bytes; static unsigned int buffer_high;/* Soft max buffer size. */ static int max_fd; /* Maximum file descriptor number in select(). */ static int connection_in; /* Connection to server (input). */ static int connection_out; /* Connection to server (output). */ -static unsigned long stdin_bytes, stdout_bytes, stderr_bytes; -static int quit_pending; /* Set to non-zero to quit the client loop. */ -static int escape_char; /* Escape character. */ void client_init_dispatch(void); @@ -381,17 +425,15 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) } void -client_suspend_self() +client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) { struct winsize oldws, newws; /* Flush stdout and stderr buffers. */ - if (buffer_len(&stdout_buffer) > 0) - atomicio(write, fileno(stdout), buffer_ptr(&stdout_buffer), - buffer_len(&stdout_buffer)); - if (buffer_len(&stderr_buffer) > 0) - atomicio(write, fileno(stderr), buffer_ptr(&stderr_buffer), - buffer_len(&stderr_buffer)); + if (buffer_len(bout) > 0) + atomicio(write, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); + if (buffer_len(berr) > 0) + atomicio(write, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); leave_raw_mode(); @@ -399,9 +441,9 @@ client_suspend_self() * Free (and clear) the buffer to reduce the amount of data that gets * written to swap. */ - buffer_free(&stdin_buffer); - buffer_free(&stdout_buffer); - buffer_free(&stderr_buffer); + buffer_free(bin); + buffer_free(bout); + buffer_free(berr); /* Save old window size. */ ioctl(fileno(stdin), TIOCGWINSZ, &oldws); @@ -418,9 +460,9 @@ client_suspend_self() received_window_change_signal = 1; /* OK, we have been continued by the user. Reinitialize buffers. */ - buffer_init(&stdin_buffer); - buffer_init(&stdout_buffer); - buffer_init(&stderr_buffer); + buffer_init(bin); + buffer_init(bout); + buffer_init(berr); enter_raw_mode(); } @@ -468,12 +510,155 @@ client_process_net_input(fd_set * readset) } } +/* process the characters one by one */ +int +process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) +{ + char string[1024]; + pid_t pid; + int bytes = 0; + unsigned int i; + unsigned char ch; + char *s; + + for (i = 0; i < len; i++) { + /* Get one character at a time. */ + ch = buf[i]; + + if (escape_pending) { + /* We have previously seen an escape character. */ + /* Clear the flag now. */ + escape_pending = 0; + + /* Process the escaped character. */ + switch (ch) { + case '.': + /* Terminate the connection. */ + snprintf(string, sizeof string, "%c.\r\n", escape_char); + buffer_append(berr, string, strlen(string)); + /*stderr_bytes += strlen(string); XXX*/ + + quit_pending = 1; + return -1; + + case 'Z' - 64: + /* Suspend the program. */ + /* Print a message to that effect to the user. */ + snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char); + buffer_append(berr, string, strlen(string)); + /*stderr_bytes += strlen(string); XXX*/ + + /* Restore terminal modes and suspend. */ + client_suspend_self(bin, bout, berr); + + /* We have been continued. */ + continue; + + case '&': + /* XXX does not work yet with proto 2 */ + if (compat20) + continue; + /* + * Detach the program (continue to serve connections, + * but put in background and no more new connections). + */ + if (!stdin_eof) { + /* + * Sending SSH_CMSG_EOF alone does not always appear + * to be enough. So we try to send an EOF character + * first. + */ + packet_start(SSH_CMSG_STDIN_DATA); + packet_put_string("\004", 1); + packet_send(); + /* Close stdin. */ + stdin_eof = 1; + if (buffer_len(bin) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } + /* Restore tty modes. */ + leave_raw_mode(); + + /* Stop listening for new connections. */ + channel_stop_listening(); + + printf("%c& [backgrounded]\n", escape_char); + + /* Fork into background. */ + pid = fork(); + if (pid < 0) { + error("fork: %.100s", strerror(errno)); + continue; + } + if (pid != 0) { /* This is the parent. */ + /* The parent just exits. */ + exit(0); + } + /* The child continues serving connections. */ + continue; /*XXX ? */ + + case '?': + snprintf(string, sizeof string, +"%c?\r\n\ +Supported escape sequences:\r\n\ +~. - terminate connection\r\n\ +~^Z - suspend ssh\r\n\ +~# - list forwarded connections\r\n\ +~& - background ssh (when waiting for connections to terminate)\r\n\ +~? - this message\r\n\ +~~ - send the escape character by typing it twice\r\n\ +(Note that escapes are only recognized immediately after newline.)\r\n", + escape_char); + buffer_append(berr, string, strlen(string)); + continue; + + case '#': + snprintf(string, sizeof string, "%c#\r\n", escape_char); + buffer_append(berr, string, strlen(string)); + s = channel_open_message(); + buffer_append(berr, s, strlen(s)); + xfree(s); + continue; + + default: + if (ch != escape_char) { + buffer_put_char(bin, escape_char); + bytes++; + } + /* Escaped characters fall through here */ + break; + } + } else { + /* + * The previous character was not an escape char. Check if this + * is an escape. + */ + if (last_was_cr && ch == escape_char) { + /* It is. Set the flag and continue to next character. */ + escape_pending = 1; + continue; + } + } + + /* + * Normal character. Record whether it was a newline, + * and append it to the buffer. + */ + last_was_cr = (ch == '\r' || ch == '\n'); + buffer_put_char(bin, ch); + bytes++; + } + return bytes; +} + void client_process_input(fd_set * readset) { + int ret; int len; - pid_t pid; - char buf[8192], *s; + char buf[8192]; /* Read input from stdin. */ if (FD_ISSET(fileno(stdin), readset)) { @@ -515,145 +700,10 @@ client_process_input(fd_set * readset) * Normal, successful read. But we have an escape character * and have to process the characters one by one. */ - unsigned int i; - for (i = 0; i < len; i++) { - unsigned char ch; - /* Get one character at a time. */ - ch = buf[i]; - - if (escape_pending) { - /* We have previously seen an escape character. */ - /* Clear the flag now. */ - escape_pending = 0; - /* Process the escaped character. */ - switch (ch) { - case '.': - /* Terminate the connection. */ - snprintf(buf, sizeof buf, "%c.\r\n", escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - stderr_bytes += strlen(buf); - quit_pending = 1; - return; - - case 'Z' - 64: - /* Suspend the program. */ - /* Print a message to that effect to the user. */ - snprintf(buf, sizeof buf, "%c^Z\r\n", escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - stderr_bytes += strlen(buf); - - /* Restore terminal modes and suspend. */ - client_suspend_self(); - - /* We have been continued. */ - continue; - - case '&': - /* - * Detach the program (continue to serve connections, - * but put in background and no more new connections). - */ - if (!stdin_eof) { - /* - * Sending SSH_CMSG_EOF alone does not always appear - * to be enough. So we try to send an EOF character - * first. - */ - packet_start(SSH_CMSG_STDIN_DATA); - packet_put_string("\004", 1); - packet_send(); - /* Close stdin. */ - stdin_eof = 1; - if (buffer_len(&stdin_buffer) == 0) { - packet_start(SSH_CMSG_EOF); - packet_send(); - } - } - /* Restore tty modes. */ - leave_raw_mode(); - - /* Stop listening for new connections. */ - channel_stop_listening(); - - printf("%c& [backgrounded]\n", escape_char); - - /* Fork into background. */ - pid = fork(); - if (pid < 0) { - error("fork: %.100s", strerror(errno)); - continue; - } - if (pid != 0) { /* This is the parent. */ - /* The parent just exits. */ - exit(0); - } - /* The child continues serving connections. */ - continue; - - case '?': - snprintf(buf, sizeof buf, -"%c?\r\n\ -Supported escape sequences:\r\n\ -~. - terminate connection\r\n\ -~^Z - suspend ssh\r\n\ -~# - list forwarded connections\r\n\ -~& - background ssh (when waiting for connections to terminate)\r\n\ -~? - this message\r\n\ -~~ - send the escape character by typing it twice\r\n\ -(Note that escapes are only recognized immediately after newline.)\r\n", - escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - continue; - - case '#': - snprintf(buf, sizeof buf, "%c#\r\n", escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - s = channel_open_message(); - buffer_append(&stderr_buffer, s, strlen(s)); - xfree(s); - continue; - - default: - if (ch != escape_char) { - /* - * Escape character followed by non-special character. - * Append both to the input buffer. - */ - buf[0] = escape_char; - buf[1] = ch; - buffer_append(&stdin_buffer, buf, 2); - stdin_bytes += 2; - continue; - } - /* - * Note that escape character typed twice - * falls through here; the latter gets processed - * as a normal character below. - */ - break; - } - } else { - /* - * The previous character was not an escape char. Check if this - * is an escape. - */ - if (last_was_cr && ch == escape_char) { - /* It is. Set the flag and continue to next character. */ - escape_pending = 1; - continue; - } - } - - /* - * Normal character. Record whether it was a newline, - * and append it to the buffer. - */ - last_was_cr = (ch == '\r' || ch == '\n'); - buf[0] = ch; - buffer_append(&stdin_buffer, buf, 1); - stdin_bytes += 1; - continue; - } + ret = process_escapes(&stdin_buffer, &stdout_buffer, &stderr_buffer, buf, len); + if (ret == -1) + return; + stdout_bytes += ret; } } } @@ -724,6 +774,15 @@ client_process_buffered_input_packets() dispatch_run(DISPATCH_NONBLOCK, &quit_pending); } +/* scan buf[] for '~' before sending data to the peer */ + +int +simple_escape_filter(Channel *c, char *buf, int len) +{ + /* XXX we assume c->extended is writeable */ + return process_escapes(&c->input, &c->output, &c->extended, buf, len); +} + /* * Implements the interactive session with the server. This is called after * the user has been authenticated, and a command has been started on the @@ -732,7 +791,7 @@ client_process_buffered_input_packets() */ int -client_loop(int have_pty, int escape_char_arg) +client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) { extern Options options; double start_time, total_time; @@ -778,10 +837,13 @@ client_loop(int have_pty, int escape_char_arg) if (have_pty) enter_raw_mode(); - /* Check if we should immediately send of on stdin. */ + /* Check if we should immediately send eof on stdin. */ if (!compat20) client_check_initial_eof_on_stdin(); + if (compat20 && escape_char != -1) + channel_register_filter(ssh2_chan_id, simple_escape_filter); + /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { fd_set readset, writeset; @@ -992,8 +1054,8 @@ client_input_channel_open(int type, int plen) sock = x11_connect_display(); if (sock >= 0) { id = channel_new("x11", SSH_CHANNEL_X11_OPEN, - sock, sock, -1, 4*1024, 32*1024, 0, - xstrdup("x11")); + sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, + CHAN_X11_PACKET_DEFAULT, 0, xstrdup("x11")); c = channel_lookup(id); } } diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c index 1dd0c39d224c..eeb6e2ef1268 100644 --- a/crypto/openssh/compat.c +++ b/crypto/openssh/compat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Markus Friedl. All rights reserved. + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,7 +23,7 @@ */ #include "includes.h" -RCSID("$Id: compat.c,v 1.14 2000/05/22 18:42:01 markus Exp $"); +RCSID("$OpenBSD: compat.c,v 1.23 2000/09/07 21:13:37 markus Exp $"); #include "ssh.h" #include "packet.h" @@ -63,8 +58,10 @@ compat_datafellows(const char *version) } check[] = { {"2.1.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC}, {"2.0.1", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD}, + {"2.", SSH_BUG_HMAC|SSH_COMPAT_SESSIONID_ENCODING}, {NULL, 0} }; + /* process table, return first match */ for (i = 0; check[i].version; i++) { len = strlen(check[i].version); if (strlen(version) >= len && @@ -80,13 +77,13 @@ compat_datafellows(const char *version) int proto_spec(const char *spec) { - char *s, *p; + char *s, *p, *q; int ret = SSH_PROTO_UNKNOWN; if (spec == NULL) return ret; - s = xstrdup(spec); - for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) { + q = s = xstrdup(spec); + for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { switch(atoi(p)) { case 1: if (ret == SSH_PROTO_UNKNOWN) diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h index 9308a6df3016..5be188b791ee 100644 --- a/crypto/openssh/compat.h +++ b/crypto/openssh/compat.h @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -26,7 +21,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* RCSID("$Id: compat.h,v 1.7 2000/05/08 17:42:24 markus Exp $"); */ +/* RCSID("$OpenBSD: compat.h,v 1.10 2000/09/07 20:27:50 deraadt Exp $"); */ #ifndef COMPAT_H #define COMPAT_H @@ -40,6 +35,7 @@ #define SSH_BUG_PUBKEYAUTH 0x02 #define SSH_BUG_HMAC 0x04 #define SSH_BUG_X11FWD 0x08 +#define SSH_COMPAT_SESSIONID_ENCODING 0x10 void enable_compat13(void); void enable_compat20(void); diff --git a/crypto/openssh/compress.c b/crypto/openssh/compress.c index 86ccaa28ae21..93266ed9f35b 100644 --- a/crypto/openssh/compress.c +++ b/crypto/openssh/compress.c @@ -1,20 +1,18 @@ /* - * - * compress.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Wed Oct 25 22:12:46 1995 ylo - * * Interface to packet compression for ssh. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: compress.c,v 1.7 2000/04/14 10:30:31 markus Exp $"); +RCSID("$OpenBSD: compress.c,v 1.9 2000/09/07 20:27:50 deraadt Exp $"); #include "ssh.h" #include "buffer.h" diff --git a/crypto/openssh/compress.h b/crypto/openssh/compress.h index f97561322590..5757164814b8 100644 --- a/crypto/openssh/compress.h +++ b/crypto/openssh/compress.h @@ -1,19 +1,17 @@ /* - * - * compress.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Wed Oct 25 22:12:46 1995 ylo - * * Interface to packet compression for ssh. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: compress.h,v 1.4 2000/04/14 10:30:31 markus Exp $"); */ +/* RCSID("$OpenBSD: compress.h,v 1.6 2000/09/07 20:27:50 deraadt Exp $"); */ #ifndef COMPRESS_H #define COMPRESS_H diff --git a/crypto/openssh/crc32.c b/crypto/openssh/crc32.c index 42c99dad353e..a4e1f27b096a 100644 --- a/crypto/openssh/crc32.c +++ b/crypto/openssh/crc32.c @@ -1,55 +1,48 @@ /* - * The implementation here was originally done by Gary S. Brown. - * I have borrowed the tables directly, and made some minor changes - * to the crc32-function (including changing the interface). - * //ylo + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 */ + #include "includes.h" -RCSID("$Id: crc32.c,v 1.4 1999/11/24 00:26:01 deraadt Exp $"); +RCSID("$OpenBSD: crc32.c,v 1.7 2000/09/07 20:27:51 deraadt Exp $"); #include "crc32.h" - /* ============================================================= */ - /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ - /* code or tables extracted from it, as desired without restriction. */ - /* */ - /* First, the polynomial itself and its table of feedback terms. The */ - /* polynomial is */ - /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ - /* */ - /* Note that we take it "backwards" and put the highest-order term in */ - /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ - /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ - /* the MSB being 1. */ - /* */ - /* Note that the usual hardware shift register implementation, which */ - /* is what we're using (we're merely optimizing it by doing eight-bit */ - /* chunks at a time) shifts bits into the lowest-order term. In our */ - /* implementation, that means shifting towards the right. Why do we */ - /* do it this way? Because the calculated CRC must be transmitted in */ - /* order from highest-order term to lowest-order term. UARTs transmit */ - /* characters in order from LSB to MSB. By storing the CRC this way, */ - /* we hand it to the UART in the order low-byte to high-byte; the UART */ - /* sends each low-bit to hight-bit; and the result is transmission bit */ - /* by bit from highest- to lowest-order term without requiring any bit */ - /* shuffling on our part. Reception works similarly. */ - /* */ - /* The feedback terms table consists of 256, 32-bit entries. Notes: */ - /* */ - /* The table can be generated at runtime if desired; code to do so */ - /* is shown later. It might not be obvious, but the feedback */ - /* terms simply represent the results of eight shift/xor opera- */ - /* tions for all combinations of data and CRC register values. */ - /* */ - /* The values must be right-shifted by eight bits by the "updcrc" */ - /* logic; the shift must be unsigned (bring in zeroes). On some */ - /* hardware you could probably optimize the shift in assembler by */ - /* using byte-swap instructions. */ - /* polynomial $edb88320 */ - /* */ - /* -------------------------------------------------------------------- */ - static unsigned int crc32_tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, @@ -108,7 +101,7 @@ static unsigned int crc32_tab[] = { /* Return a 32-bit CRC of the contents of the buffer. */ unsigned int -crc32(const unsigned char *s, unsigned int len) +ssh_crc32(const unsigned char *s, unsigned int len) { unsigned int i; unsigned int crc32val; diff --git a/crypto/openssh/crc32.h b/crypto/openssh/crc32.h index 4176e8a5f7c8..58c4fbacdac9 100644 --- a/crypto/openssh/crc32.h +++ b/crypto/openssh/crc32.h @@ -1,19 +1,17 @@ /* - * - * crc32.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1992 Tatu Ylonen, Espoo, Finland * All rights reserved - * - * Created: Tue Feb 11 14:37:27 1992 ylo - * * Functions for computing 32-bit CRC. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: crc32.h,v 1.5 2000/04/14 10:30:31 markus Exp $"); */ +/* RCSID("$OpenBSD: crc32.h,v 1.8 2000/09/07 20:27:51 deraadt Exp $"); */ #ifndef CRC32_H #define CRC32_H @@ -22,6 +20,6 @@ * This computes a 32 bit CRC of the data in the buffer, and returns the CRC. * The polynomial used is 0xedb88320. */ -unsigned int crc32(const unsigned char *buf, unsigned int len); +unsigned int ssh_crc32(const unsigned char *buf, unsigned int len); #endif /* CRC32_H */ diff --git a/crypto/openssh/deattack.c b/crypto/openssh/deattack.c index 263e0396c868..74a46c0e7b80 100644 --- a/crypto/openssh/deattack.c +++ b/crypto/openssh/deattack.c @@ -1,5 +1,6 @@ +/* $OpenBSD: deattack.c,v 1.9 2000/09/07 20:27:51 deraadt Exp $ */ + /* - * $Id: deattack.c,v 1.6 1999/11/24 00:26:01 deraadt Exp $ * Cryptographic attack detector for ssh - source code * * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. @@ -50,7 +51,7 @@ void crc_update(u_int32_t *a, u_int32_t b) { b ^= *a; - *a = crc32((unsigned char *) &b, sizeof(b)); + *a = ssh_crc32((unsigned char *) &b, sizeof(b)); } /* detect if a block is used in a particular pattern */ diff --git a/crypto/openssh/dispatch.c b/crypto/openssh/dispatch.c index 9b7def746854..3daac20224d5 100644 --- a/crypto/openssh/dispatch.c +++ b/crypto/openssh/dispatch.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -27,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: dispatch.c,v 1.2 2000/04/14 10:30:31 markus Exp $"); +RCSID("$OpenBSD: dispatch.c,v 1.4 2000/09/07 20:27:51 deraadt Exp $"); #include "ssh.h" #include "dispatch.h" #include "packet.h" diff --git a/crypto/openssh/dispatch.h b/crypto/openssh/dispatch.h index 12084aafe07a..dc9d3dd4ecfd 100644 --- a/crypto/openssh/dispatch.h +++ b/crypto/openssh/dispatch.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ enum { DISPATCH_BLOCK, DISPATCH_NONBLOCK diff --git a/crypto/openssh/dsa.c b/crypto/openssh/dsa.c index 51d7ff285242..4ff4b58f2b49 100644 --- a/crypto/openssh/dsa.c +++ b/crypto/openssh/dsa.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,7 +23,7 @@ */ #include "includes.h" -RCSID("$Id: dsa.c,v 1.7 2000/05/08 17:42:24 markus Exp $"); +RCSID("$OpenBSD: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -53,8 +48,7 @@ RCSID("$Id: dsa.c,v 1.7 2000/05/08 17:42:24 markus Exp $"); #define SIGBLOB_LEN (2*INTBLOB_LEN) Key * -dsa_key_from_blob( - char *blob, int blen) +dsa_key_from_blob(char *blob, int blen) { Buffer b; char *ktype; @@ -66,16 +60,17 @@ dsa_key_from_blob( dump_base64(stderr, blob, blen); #endif /* fetch & parse DSA/DSS pubkey */ - key = key_new(KEY_DSA); - dsa = key->dsa; buffer_init(&b); buffer_append(&b, blob, blen); ktype = buffer_get_string(&b, NULL); if (strcmp(KEX_DSS, ktype) != 0) { - error("dsa_key_from_blob: cannot handle type %s", ktype); - key_free(key); + error("dsa_key_from_blob: cannot handle type %s", ktype); + buffer_free(&b); + xfree(ktype); return NULL; } + key = key_new(KEY_DSA); + dsa = key->dsa; buffer_get_bignum2(&b, dsa->p); buffer_get_bignum2(&b, dsa->q); buffer_get_bignum2(&b, dsa->g); @@ -84,8 +79,8 @@ dsa_key_from_blob( if(rlen != 0) error("dsa_key_from_blob: remaining bytes in key blob %d", rlen); buffer_free(&b); + xfree(ktype); - debug("keytype %s", ktype); #ifdef DEBUG_DSS DSA_print_fp(stderr, dsa, 8); #endif @@ -197,7 +192,6 @@ dsa_verify( DSA_SIG *sig; EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; - char *ktype; unsigned char *sigblob; char *txt; unsigned int len; @@ -227,14 +221,24 @@ dsa_verify( len = signaturelen; } else { /* ietf-drafts */ + char *ktype; buffer_init(&b); buffer_append(&b, (char *) signature, signaturelen); ktype = buffer_get_string(&b, NULL); + if (strcmp(KEX_DSS, ktype) != 0) { + error("dsa_verify: cannot handle type %s", ktype); + buffer_free(&b); + return -1; + } sigblob = (unsigned char *)buffer_get_string(&b, &len); rlen = buffer_len(&b); - if(rlen != 0) + if(rlen != 0) { error("remaining bytes in signature %d", rlen); + buffer_free(&b); + return -1; + } buffer_free(&b); + xfree(ktype); } if (len != SIGBLOB_LEN) { diff --git a/crypto/openssh/dsa.h b/crypto/openssh/dsa.h index 3cece7c1f22b..252e7880beb5 100644 --- a/crypto/openssh/dsa.h +++ b/crypto/openssh/dsa.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef DSA_H #define DSA_H diff --git a/crypto/openssh/getput.h b/crypto/openssh/getput.h index e1aa9bb64b1d..19ff5e14b066 100644 --- a/crypto/openssh/getput.h +++ b/crypto/openssh/getput.h @@ -1,19 +1,17 @@ /* - * - * getput.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Wed Jun 28 22:36:30 1995 ylo - * * Macros for storing and retrieving data in msb first and lsb first order. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: getput.h,v 1.3 2000/04/14 10:30:31 markus Exp $"); */ +/* RCSID("$OpenBSD: getput.h,v 1.5 2000/09/07 20:27:51 deraadt Exp $"); */ #ifndef GETPUT_H #define GETPUT_H diff --git a/crypto/openssh/hmac.c b/crypto/openssh/hmac.c index fe53aa47e7c0..48a176304beb 100644 --- a/crypto/openssh/hmac.c +++ b/crypto/openssh/hmac.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,7 +23,7 @@ */ #include "includes.h" -RCSID("$Id: hmac.c,v 1.2 2000/04/12 09:39:10 markus Exp $"); +RCSID("$OpenBSD: hmac.c,v 1.4 2000/09/07 20:27:51 deraadt Exp $"); #include "xmalloc.h" #include "ssh.h" diff --git a/crypto/openssh/hmac.h b/crypto/openssh/hmac.h index fb6802927392..281300e25c48 100644 --- a/crypto/openssh/hmac.h +++ b/crypto/openssh/hmac.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef HMAC_H #define HMAC_H diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c index bac285da50f9..9c03a468800d 100644 --- a/crypto/openssh/hostfile.c +++ b/crypto/openssh/hostfile.c @@ -1,20 +1,42 @@ /* - * - * hostfile.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved + * Functions for manipulating the known hosts files. * - * Created: Thu Jun 29 07:10:56 1995 ylo + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". * - * Functions for manipulating the known hosts files. * + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * Copyright (c) 1999 Niels Provos. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: hostfile.c,v 1.18 2000/04/29 18:11:52 markus Exp $"); +RCSID("$OpenBSD: hostfile.c,v 1.20 2000/09/07 20:27:51 deraadt Exp $"); #include "packet.h" #include "match.h" @@ -129,7 +151,7 @@ check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *fo ; /* Check if the host name matches. */ - if (!match_hostname(host, cp, (unsigned int) (cp2 - cp))) + if (match_hostname(host, cp, (unsigned int) (cp2 - cp)) != 1) continue; /* Got a match. Skip host name. */ diff --git a/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h index c9bdd7f2e495..9c2353bf986d 100644 --- a/crypto/openssh/hostfile.h +++ b/crypto/openssh/hostfile.h @@ -1,3 +1,14 @@ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ #ifndef HOSTFILE_H #define HOSTFILE_H diff --git a/crypto/openssh/includes.h b/crypto/openssh/includes.h index ef374dfe808f..db090331e372 100644 --- a/crypto/openssh/includes.h +++ b/crypto/openssh/includes.h @@ -1,16 +1,14 @@ /* - * - * includes.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Thu Mar 23 16:29:37 1995 ylo - * * This file includes most of the needed system headers. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #ifndef INCLUDES_H diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c index a6c8174a4251..8a83db47e806 100644 --- a/crypto/openssh/kex.c +++ b/crypto/openssh/kex.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,7 +23,7 @@ */ #include "includes.h" -RCSID("$Id: kex.c,v 1.7 2000/05/25 20:45:20 markus Exp $"); +RCSID("$OpenBSD: kex.c,v 1.10 2000/09/07 20:27:51 deraadt Exp $"); #include "ssh.h" #include "ssh2.h" @@ -287,13 +282,14 @@ char * get_match(char *client, char *server) { char *sproposals[MAX_PROP]; - char *c, *s, *p, *ret; + char *c, *s, *p, *ret, *cp, *sp; int i, j, nproposals; - c = xstrdup(client); - s = xstrdup(server); + c = cp = xstrdup(client); + s = sp = xstrdup(server); - for ((p = strtok(s, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { + for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&sp, SEP)), i++) { if (i < MAX_PROP) sproposals[i] = p; else @@ -301,7 +297,8 @@ get_match(char *client, char *server) } nproposals = i; - for ((p = strtok(c, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { + for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&cp, SEP)), i++) { for (j = 0; j < nproposals; j++) { if (strcmp(p, sproposals[j]) == 0) { ret = xstrdup(p); diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h index 7e5c67024bff..8c89687b6068 100644 --- a/crypto/openssh/kex.h +++ b/crypto/openssh/kex.h @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c index d474f85c666a..f7df0bb1db45 100644 --- a/crypto/openssh/key.c +++ b/crypto/openssh/key.c @@ -1,4 +1,14 @@ /* + * read_bignum(): + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * * Copyright (c) 2000 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -9,11 +19,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -26,10 +31,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * read_bignum(): - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - */ #include "includes.h" #include "ssh.h" @@ -41,6 +42,8 @@ #include "dsa.h" #include "uuencode.h" +RCSID("$OpenBSD: key.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $"); + #define SSH_DSS "ssh-dss" Key * @@ -121,8 +124,6 @@ key_equal(Key *a, Key *b) return 0; } -#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" - /* * Generate key fingerprint in ascii format. * Based on ideas and code from Bjoern Groenvall <bg@sics.se> @@ -130,7 +131,7 @@ key_equal(Key *a, Key *b) char * key_fingerprint(Key *k) { - static char retval[80]; + static char retval[(EVP_MAX_MD_SIZE+1)*3]; unsigned char *blob = NULL; int len = 0; int nlen, elen; @@ -151,15 +152,22 @@ key_fingerprint(Key *k) fatal("key_fingerprint: bad key type %d", k->type); break; } + retval[0] = '\0'; + if (blob != NULL) { - unsigned char d[16]; - EVP_MD_CTX md; - EVP_DigestInit(&md, EVP_md5()); - EVP_DigestUpdate(&md, blob, len); - EVP_DigestFinal(&md, d, NULL); - snprintf(retval, sizeof(retval), FPRINT, - d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], - d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); + int i; + unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD *md = EVP_md5(); + EVP_MD_CTX ctx; + EVP_DigestInit(&ctx, md); + EVP_DigestUpdate(&ctx, blob, len); + EVP_DigestFinal(&ctx, digest, NULL); + for(i = 0; i < md->md_size; i++) { + char hex[4]; + snprintf(hex, sizeof(hex), "%02x:", digest[i]); + strlcat(retval, hex, sizeof(retval)); + } + retval[strlen(retval) - 1] = '\0'; memset(blob, 0, len); xfree(blob); } @@ -328,3 +336,15 @@ key_type(Key *k) } return "unknown"; } +unsigned int +key_size(Key *k){ + switch (k->type) { + case KEY_RSA: + return BN_num_bits(k->rsa->n); + break; + case KEY_DSA: + return BN_num_bits(k->dsa->p); + break; + } + return 0; +} diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h index ed3f770b8be9..8e1e0a98d126 100644 --- a/crypto/openssh/key.h +++ b/crypto/openssh/key.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef KEY_H #define KEY_H @@ -19,7 +42,7 @@ int key_equal(Key *a, Key *b); char *key_fingerprint(Key *k); char *key_type(Key *k); int key_write(Key *key, FILE *f); -unsigned int -key_read(Key *key, char **cpp); +unsigned int key_read(Key *key, char **cpp); +unsigned int key_size(Key *k); #endif diff --git a/crypto/openssh/lib/Makefile b/crypto/openssh/lib/Makefile index aae1677ec7ee..4bbe22216e22 100644 --- a/crypto/openssh/lib/Makefile +++ b/crypto/openssh/lib/Makefile @@ -2,10 +2,10 @@ LIB= ssh SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \ - cipher.c compat.c compress.c crc32.c deattack.c fingerprint.c \ + cipher.c compat.c compress.c crc32.c deattack.c \ hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \ rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c atomicio.c \ - key.c dispatch.c dsa.c kex.c hmac.c uuencode.c aux.c + key.c dispatch.c dsa.c kex.c hmac.c uuencode.c util.c NOPROFILE= yes NOPIC= yes @@ -15,9 +15,9 @@ install: .include <bsd.own.mk> -.if (${KERBEROS} == "yes") +.if (${KERBEROS:L} == "yes") CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV -.if (${AFS} == "yes") +.if (${AFS:L} == "yes") CFLAGS+= -DAFS SRCS+= radix.c .endif # AFS diff --git a/crypto/openssh/log-client.c b/crypto/openssh/log-client.c index 1e3c162cb37e..616d3d0d25b8 100644 --- a/crypto/openssh/log-client.c +++ b/crypto/openssh/log-client.c @@ -1,21 +1,42 @@ /* - * - * log-client.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Mon Mar 20 21:13:40 1995 ylo - * * Client-side versions of debug(), log(), etc. These print to stderr. * This is a stripped down version of log-server.c. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: log-client.c,v 1.8 2000/04/14 10:30:31 markus Exp $"); +RCSID("$OpenBSD: log-client.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -57,6 +78,5 @@ do_log(LogLevel level, const char *fmt, va_list args) if (level == SYSLOG_LEVEL_DEBUG) fprintf(stderr, "debug: "); vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); - fprintf(stderr, "%s", msgbuf); - fprintf(stderr, "\r\n"); + fprintf(stderr, "%s\r\n", msgbuf); } diff --git a/crypto/openssh/log-server.c b/crypto/openssh/log-server.c index 81ba67371f07..11d650b3fad9 100644 --- a/crypto/openssh/log-server.c +++ b/crypto/openssh/log-server.c @@ -1,21 +1,42 @@ /* - * - * log-server.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Mon Mar 20 21:19:30 1995 ylo - * * Server-side versions of debug(), log(), etc. These normally send the output * to the system log. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: log-server.c,v 1.14 2000/04/14 10:30:31 markus Exp $"); +RCSID("$OpenBSD: log-server.c,v 1.16 2000/09/07 20:27:52 deraadt Exp $"); #include <syslog.h> #include "packet.h" diff --git a/crypto/openssh/log.c b/crypto/openssh/log.c index 03038b2fbe41..a6d9e050d35c 100644 --- a/crypto/openssh/log.c +++ b/crypto/openssh/log.c @@ -1,9 +1,42 @@ /* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +/* * Shared versions of debug(), log(), etc. + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.7 2000/01/04 00:07:59 markus Exp $"); +RCSID("$OpenBSD: log.c,v 1.9 2000/09/07 21:13:37 markus Exp $"); #include "ssh.h" #include "xmalloc.h" diff --git a/crypto/openssh/login.c b/crypto/openssh/login.c index 8e40784e2cb0..1d59cd825f73 100644 --- a/crypto/openssh/login.c +++ b/crypto/openssh/login.c @@ -1,24 +1,45 @@ /* - * - * login.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Fri Mar 24 14:51:08 1995 ylo - * * This file performs some of the things login(1) normally does. We cannot * easily use something like login -p -h host -f user, because there are * several different logins around, and it is hard to determined what kind of * login the current system has. Also, we want to be able to execute commands * on a tty. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * Copyright (c) 1999 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: login.c,v 1.13 2000/04/19 07:05:49 deraadt Exp $"); +RCSID("$OpenBSD: login.c,v 1.15 2000/09/07 20:27:52 deraadt Exp $"); #include <util.h> #include <utmp.h> diff --git a/crypto/openssh/match.c b/crypto/openssh/match.c index 00dff8a86130..c373129b853e 100644 --- a/crypto/openssh/match.c +++ b/crypto/openssh/match.c @@ -1,20 +1,18 @@ /* - * - * match.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Thu Jun 22 01:17:50 1995 ylo - * * Simple pattern matching, with '*' and '?' as wildcards. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: match.c,v 1.6 2000/04/14 10:30:31 markus Exp $"); +RCSID("$OpenBSD: match.c,v 1.9 2000/09/07 20:27:52 deraadt Exp $"); #include "ssh.h" @@ -84,8 +82,8 @@ match_pattern(const char *s, const char *pattern) /* * Tries to match the host name (which must be in all lowercase) against the * comma-separated sequence of subpatterns (each possibly preceded by ! to - * indicate negation). Returns true if there is a positive match; zero - * otherwise. + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. */ int @@ -127,15 +125,15 @@ match_hostname(const char *host, const char *pattern, unsigned int len) /* Try to match the subpattern against the host name. */ if (match_pattern(host, sub)) { if (negated) - return 0; /* Fail */ + return -1; /* Negative */ else - got_positive = 1; + got_positive = 1; /* Positive */ } } /* * Return success if got a positive match. If there was a negative - * match, we have already returned zero and never get here. + * match, we have already returned -1 and never get here. */ return got_positive; } diff --git a/crypto/openssh/match.h b/crypto/openssh/match.h index 4625d97691fb..564f5abf97b4 100644 --- a/crypto/openssh/match.h +++ b/crypto/openssh/match.h @@ -1,3 +1,16 @@ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * This file contains various auxiliary functions related to multiple + * precision integers. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ #ifndef MATCH_H #define MATCH_H @@ -10,8 +23,8 @@ int match_pattern(const char *s, const char *pattern); /* * Tries to match the host name (which must be in all lowercase) against the * comma-separated sequence of subpatterns (each possibly preceded by ! to - * indicate negation). Returns true if there is a positive match; zero - * otherwise. + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. */ int match_hostname(const char *host, const char *pattern, unsigned int len); diff --git a/crypto/openssh/mpaux.c b/crypto/openssh/mpaux.c index 3442070e41b2..1ee8df19482b 100644 --- a/crypto/openssh/mpaux.c +++ b/crypto/openssh/mpaux.c @@ -1,21 +1,19 @@ /* - * - * mpaux.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sun Jul 16 04:29:30 1995 ylo - * * This file contains various auxiliary functions related to multiple * precision integers. * -*/ + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ #include "includes.h" -RCSID("$Id: mpaux.c,v 1.12 2000/04/14 10:30:32 markus Exp $"); +RCSID("$OpenBSD: mpaux.c,v 1.14 2000/09/07 20:27:52 deraadt Exp $"); #include <openssl/bn.h> #include "getput.h" diff --git a/crypto/openssh/mpaux.h b/crypto/openssh/mpaux.h index 671fc511a929..9de17276bbae 100644 --- a/crypto/openssh/mpaux.h +++ b/crypto/openssh/mpaux.h @@ -1,19 +1,18 @@ /* - * - * mpaux.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sun Jul 16 04:29:30 1995 ylo - * * This file contains various auxiliary functions related to multiple * precision integers. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: mpaux.h,v 1.6 2000/04/14 10:30:32 markus Exp $"); */ +/* RCSID("$OpenBSD: mpaux.h,v 1.8 2000/09/07 20:27:52 deraadt Exp $"); */ #ifndef MPAUX_H #define MPAUX_H diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h index 9611d89517d8..18db954c588b 100644 --- a/crypto/openssh/myproposal.h +++ b/crypto/openssh/myproposal.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1" #define KEX_DEFAULT_PK_ALG "ssh-dss" #define KEX_DEFAULT_ENCRYPT "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c index fd92fe8f653f..30c90b3b2b9a 100644 --- a/crypto/openssh/nchan.c +++ b/crypto/openssh/nchan.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,7 +23,7 @@ */ #include "includes.h" -RCSID("$Id: nchan.c,v 1.17 2000/05/08 17:44:54 markus Exp $"); +RCSID("$OpenBSD: nchan.c,v 1.19 2000/09/07 20:27:52 deraadt Exp $"); #include "ssh.h" diff --git a/crypto/openssh/nchan.h b/crypto/openssh/nchan.h index 0a2cf35f781f..366b894ae98b 100644 --- a/crypto/openssh/nchan.h +++ b/crypto/openssh/nchan.h @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -27,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* RCSID("$Id: nchan.h,v 1.7 2000/04/03 07:07:15 markus Exp $"); */ +/* RCSID("$OpenBSD: nchan.h,v 1.9 2000/09/07 20:27:52 deraadt Exp $"); */ #ifndef NCHAN_H #define NCHAN_H diff --git a/crypto/openssh/nchan.ms b/crypto/openssh/nchan.ms index eb49cd3b4fad..1679d39f30f3 100644 --- a/crypto/openssh/nchan.ms +++ b/crypto/openssh/nchan.ms @@ -9,11 +9,6 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by Markus Friedl. -.\" 4. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c index 5fa76a315b5e..670c0ed53fbf 100644 --- a/crypto/openssh/packet.c +++ b/crypto/openssh/packet.c @@ -1,23 +1,43 @@ /* - * - * packet.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sat Mar 18 02:40:40 1995 ylo - * * This file contains code implementing the packet protocol and communication * with the other side. This same code is used both on client and server side. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * * SSH2 packet format added by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. All rights reserved. * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: packet.c,v 1.32 2000/05/04 22:22:43 markus Exp $"); +RCSID("$OpenBSD: packet.c,v 1.35 2000/09/07 20:27:52 deraadt Exp $"); #include "xmalloc.h" #include "buffer.h" @@ -479,8 +499,8 @@ packet_send1() buffer_consume(&outgoing_packet, 8 - padding); /* Add check bytes. */ - checksum = crc32((unsigned char *) buffer_ptr(&outgoing_packet), - buffer_len(&outgoing_packet)); + checksum = ssh_crc32((unsigned char *) buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); PUT_32BIT(buf, checksum); buffer_append(&outgoing_packet, buf, 4); @@ -764,7 +784,7 @@ packet_read_poll1(int *payload_len_ptr) #endif /* Compute packet checksum. */ - checksum = crc32((unsigned char *) buffer_ptr(&incoming_packet), + checksum = ssh_crc32((unsigned char *) buffer_ptr(&incoming_packet), buffer_len(&incoming_packet) - 4); /* Skip padding. */ diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h index ac96c505af4b..7a3935399e14 100644 --- a/crypto/openssh/packet.h +++ b/crypto/openssh/packet.h @@ -1,19 +1,17 @@ /* - * - * packet.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sat Mar 18 02:02:14 1995 ylo - * * Interface for the packet protocol functions. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: packet.h,v 1.15 2000/04/14 10:30:32 markus Exp $"); */ +/* RCSID("$OpenBSD: packet.h,v 1.17 2000/09/07 20:27:52 deraadt Exp $"); */ #ifndef PACKET_H #define PACKET_H diff --git a/crypto/openssh/pty.c b/crypto/openssh/pty.c index 430f9e529501..9300bd530415 100644 --- a/crypto/openssh/pty.c +++ b/crypto/openssh/pty.c @@ -1,20 +1,18 @@ /* - * - * pty.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Fri Mar 17 04:37:25 1995 ylo - * * Allocating a pseudo-terminal, and making it the controlling tty. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: pty.c,v 1.13 2000/04/14 10:30:32 markus Exp $"); +RCSID("$OpenBSD: pty.c,v 1.16 2000/09/07 21:13:37 markus Exp $"); #include <util.h> #include "pty.h" diff --git a/crypto/openssh/pty.h b/crypto/openssh/pty.h index a5f9cb22dcc1..13d8e6026cc3 100644 --- a/crypto/openssh/pty.h +++ b/crypto/openssh/pty.h @@ -1,19 +1,18 @@ /* - * - * pty.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Fri Mar 17 05:03:28 1995 ylo - * * Functions for allocating a pseudo-terminal and making it the controlling * tty. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: pty.h,v 1.6 2000/04/14 10:30:32 markus Exp $"); */ +/* RCSID("$OpenBSD: pty.h,v 1.8 2000/09/07 20:27:52 deraadt Exp $"); */ #ifndef PTY_H #define PTY_H diff --git a/crypto/openssh/radix.c b/crypto/openssh/radix.c index 033773344152..842920484821 100644 --- a/crypto/openssh/radix.c +++ b/crypto/openssh/radix.c @@ -1,12 +1,32 @@ /* - * radix.c + * Copyright (c) 1999 Dug Song. All rights reserved. * - * Dug Song <dugsong@UMICH.EDU> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include "uuencode.h" +RCSID("$OpenBSD: radix.c,v 1.13 2000/09/07 20:27:52 deraadt Exp $"); + #ifdef AFS #include <krb.h> diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c index 15b8e6e1711c..2ddf3ed1fec9 100644 --- a/crypto/openssh/readconf.c +++ b/crypto/openssh/readconf.c @@ -1,20 +1,18 @@ /* - * - * readconf.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sat Apr 22 00:03:10 1995 ylo - * * Functions for reading the configuration files. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: readconf.c,v 1.33 2000/05/29 20:20:46 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.47 2000/09/07 21:13:37 markus Exp $"); #include "ssh.h" #include "cipher.h" @@ -92,7 +90,7 @@ typedef enum { oBadOption, oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, - oSkeyAuthentication, + oSkeyAuthentication, oXAuthLocation, #ifdef KRB4 oKerberosAuthentication, #endif /* KRB4 */ @@ -116,6 +114,7 @@ static struct { } keywords[] = { { "forwardagent", oForwardAgent }, { "forwardx11", oForwardX11 }, + { "xauthlocation", oXAuthLocation }, { "gatewayports", oGatewayPorts }, { "useprivilegedport", oUsePrivilegedPort }, { "rhostsauthentication", oRhostsAuthentication }, @@ -163,10 +162,6 @@ static struct { { NULL, 0 } }; -/* Characters considered whitespace in strtok calls. */ -#define WHITESPACE " \t\r\n" - - /* * Adds a local TCP/IP port forward to options. Never returns if there is an * error. @@ -236,18 +231,20 @@ process_config_line(Options *options, const char *host, char *line, const char *filename, int linenum, int *activep) { - char buf[256], *cp, *string, **charptr, *cp2; + char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; int opcode, *intptr, value; u_short fwd_port, fwd_host_port; - /* Skip leading whitespace. */ - cp = line + strspn(line, WHITESPACE); - if (!*cp || *cp == '\n' || *cp == '#') + s = line; + /* Get the keyword. (Each line is supposed to begin with a keyword). */ + keyword = strdelim(&s); + /* Ignore leading whitespace. */ + if (*keyword == '\0') + keyword = strdelim(&s); + if (!*keyword || *keyword == '\n' || *keyword == '#') return 0; - /* Get the keyword. (Each line is supposed to begin with a keyword). */ - cp = strtok(cp, WHITESPACE); - opcode = parse_token(cp, filename, linenum); + opcode = parse_token(keyword, filename, linenum); switch (opcode) { case oBadOption: @@ -257,13 +254,13 @@ process_config_line(Options *options, const char *host, case oForwardAgent: intptr = &options->forward_agent; parse_flag: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); value = 0; /* To avoid compiler warning... */ - if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) value = 1; - else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) value = 0; else fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); @@ -343,16 +340,16 @@ parse_flag: case oStrictHostKeyChecking: intptr = &options->strict_host_key_checking; - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); value = 0; /* To avoid compiler warning... */ - if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) value = 1; - else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) value = 0; - else if (strcmp(cp, "ask") == 0) + else if (strcmp(arg, "ask") == 0) value = 2; else fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); @@ -378,8 +375,8 @@ parse_flag: case oIdentityFile: case oIdentityFile2: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (*activep) { intptr = (opcode == oIdentityFile) ? @@ -391,19 +388,23 @@ parse_flag: charptr = (opcode == oIdentityFile) ? &options->identity_files[*intptr] : &options->identity_files2[*intptr]; - *charptr = xstrdup(cp); + *charptr = xstrdup(arg); *intptr = *intptr + 1; } break; + case oXAuthLocation: + charptr=&options->xauth_location; + goto parse_string; + case oUser: charptr = &options->user; parse_string: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (*activep && *charptr == NULL) - *charptr = xstrdup(cp); + *charptr = xstrdup(arg); break; case oGlobalKnownHostsFile: @@ -429,10 +430,10 @@ parse_string: case oProxyCommand: charptr = &options->proxy_command; string = xstrdup(""); - while ((cp = strtok(NULL, WHITESPACE)) != NULL) { - string = xrealloc(string, strlen(string) + strlen(cp) + 2); + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + string = xrealloc(string, strlen(string) + strlen(arg) + 2); strcat(string, " "); - strcat(string, cp); + strcat(string, arg); } if (*activep && *charptr == NULL) *charptr = string; @@ -443,15 +444,15 @@ parse_string: case oPort: intptr = &options->port; parse_int: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] < '0' || cp[0] > '9') + if (arg[0] < '0' || arg[0] > '9') fatal("%.200s line %d: Bad number.", filename, linenum); /* Octal, decimal, or hex format? */ - value = strtol(cp, &cp2, 0); - if (cp == cp2) + value = strtol(arg, &endofnumber, 0); + if (arg == endofnumber) fatal("%.200s line %d: Bad number.", filename, linenum); if (*activep && *intptr == -1) *intptr = value; @@ -463,65 +464,65 @@ parse_int: case oCipher: intptr = &options->cipher; - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - value = cipher_number(cp); + value = cipher_number(arg); if (value == -1) fatal("%.200s line %d: Bad cipher '%s'.", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (*activep && *intptr == -1) *intptr = value; break; case oCiphers: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - if (!ciphers_valid(cp)) + if (!ciphers_valid(arg)) fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (*activep && options->ciphers == NULL) - options->ciphers = xstrdup(cp); + options->ciphers = xstrdup(arg); break; case oProtocol: intptr = &options->protocol; - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - value = proto_spec(cp); + value = proto_spec(arg); if (value == SSH_PROTO_UNKNOWN) fatal("%.200s line %d: Bad protocol spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (*activep && *intptr == SSH_PROTO_UNKNOWN) *intptr = value; break; case oLogLevel: intptr = (int *) &options->log_level; - cp = strtok(NULL, WHITESPACE); - value = log_level_number(cp); + arg = strdelim(&s); + value = log_level_number(arg); if (value == (LogLevel) - 1) fatal("%.200s line %d: unsupported log level '%s'\n", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (*activep && (LogLevel) * intptr == -1) *intptr = (LogLevel) value; break; case oRemoteForward: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] < '0' || cp[0] > '9') + if (arg[0] < '0' || arg[0] > '9') fatal("%.200s line %d: Badly formatted port number.", filename, linenum); - fwd_port = atoi(cp); - cp = strtok(NULL, WHITESPACE); - if (!cp) + fwd_port = atoi(arg); + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing second argument.", filename, linenum); - if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) fatal("%.200s line %d: Badly formatted host:port.", filename, linenum); if (*activep) @@ -529,18 +530,18 @@ parse_int: break; case oLocalForward: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] < '0' || cp[0] > '9') + if (arg[0] < '0' || arg[0] > '9') fatal("%.200s line %d: Badly formatted port number.", filename, linenum); - fwd_port = atoi(cp); - cp = strtok(NULL, WHITESPACE); - if (!cp) + fwd_port = atoi(arg); + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing second argument.", filename, linenum); - if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) fatal("%.200s line %d: Badly formatted host:port.", filename, linenum); if (*activep) @@ -549,26 +550,26 @@ parse_int: case oHost: *activep = 0; - while ((cp = strtok(NULL, WHITESPACE)) != NULL) - if (match_pattern(host, cp)) { - debug("Applying options for %.100s", cp); + while ((arg = strdelim(&s)) != NULL && *arg != '\0') + if (match_pattern(host, arg)) { + debug("Applying options for %.100s", arg); *activep = 1; break; } - /* Avoid garbage check below, as strtok already returned NULL. */ + /* Avoid garbage check below, as strdelim is done. */ return 0; case oEscapeChar: intptr = &options->escape_char; - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&s); + if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] == '^' && cp[2] == 0 && - (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128) - value = (unsigned char) cp[1] & 31; - else if (strlen(cp) == 1) - value = (unsigned char) cp[0]; - else if (strcmp(cp, "none") == 0) + if (arg[0] == '^' && arg[2] == 0 && + (unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128) + value = (unsigned char) arg[1] & 31; + else if (strlen(arg) == 1) + value = (unsigned char) arg[0]; + else if (strcmp(arg, "none") == 0) value = -2; else { fatal("%.200s line %d: Bad escape character.", @@ -585,9 +586,11 @@ parse_int: } /* Check that there is no garbage at end of line. */ - if (strtok(NULL, WHITESPACE) != NULL) - fatal("%.200s line %d: garbage at end of line.", - filename, linenum); + if ((arg = strdelim(&s)) != NULL && *arg != '\0') + { + fatal("%.200s line %d: garbage at end of line; \"%.200s\".", + filename, linenum, arg); + } return 0; } @@ -644,6 +647,7 @@ initialize_options(Options * options) memset(options, 'X', sizeof(*options)); options->forward_agent = -1; options->forward_x11 = -1; + options->xauth_location = NULL; options->gateway_ports = -1; options->use_privileged_port = -1; options->rhosts_authentication = -1; @@ -700,6 +704,10 @@ fill_default_options(Options * options) options->forward_agent = 0; if (options->forward_x11 == -1) options->forward_x11 = 0; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ if (options->gateway_ports == -1) options->gateway_ports = 0; if (options->use_privileged_port == -1) @@ -727,7 +735,7 @@ fill_default_options(Options * options) if (options->rhosts_rsa_authentication == -1) options->rhosts_rsa_authentication = 1; if (options->fallback_to_rsh == -1) - options->fallback_to_rsh = 1; + options->fallback_to_rsh = 0; if (options->use_rsh == -1) options->use_rsh = 0; if (options->batch_mode == -1) diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h index 7ee91571186c..23df57b4271f 100644 --- a/crypto/openssh/readconf.h +++ b/crypto/openssh/readconf.h @@ -1,19 +1,17 @@ /* - * - * readconf.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Sat Apr 22 00:25:29 1995 ylo - * * Functions for reading the configuration file. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: readconf.h,v 1.18 2000/05/08 17:12:15 markus Exp $"); */ +/* RCSID("$OpenBSD: readconf.h,v 1.21 2000/09/07 20:27:53 deraadt Exp $"); */ #ifndef READCONF_H #define READCONF_H @@ -30,6 +28,7 @@ typedef struct { typedef struct { int forward_agent; /* Forward authentication agent. */ int forward_x11; /* Forward X11 display. */ + char *xauth_location; /* Location for xauth program */ int gateway_ports; /* Allow remote connects to forwarded ports. */ int use_privileged_port; /* Don't use privileged port if false. */ int rhosts_authentication; /* Try rhosts authentication. */ diff --git a/crypto/openssh/readpass.c b/crypto/openssh/readpass.c index 85d88f804610..c38292f15716 100644 --- a/crypto/openssh/readpass.c +++ b/crypto/openssh/readpass.c @@ -32,7 +32,7 @@ */ #include "includes.h" -RCSID("$Id: readpass.c,v 1.10 2000/04/14 10:30:32 markus Exp $"); +RCSID("$OpenBSD: readpass.c,v 1.11 2000/06/20 01:39:44 markus Exp $"); #include "xmalloc.h" #include "ssh.h" diff --git a/crypto/openssh/rsa.c b/crypto/openssh/rsa.c index 002c1cc4f8f0..e5cddc2548c5 100644 --- a/crypto/openssh/rsa.c +++ b/crypto/openssh/rsa.c @@ -1,15 +1,40 @@ /* - * - * rsa.c - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Fri Mar 3 22:07:06 1995 ylo + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 1999 Niels Provos. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Description of the RSA algorithm can be found e.g. from the following sources: + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Description of the RSA algorithm can be found e.g. from the following + * sources: * * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. * @@ -25,17 +50,17 @@ * Hans Riesel: Prime Numbers and Computer Methods for Factorization. * Birkhauser, 1994. * - * The RSA Frequently Asked Questions document by RSA Data Security, Inc., 1995. + * The RSA Frequently Asked Questions document by RSA Data Security, + * Inc., 1995. * - * RSA in 3 lines of perl by Adam Back <aba@atlax.ex.ac.uk>, 1995, as included - * below: + * RSA in 3 lines of perl by Adam Back <aba@atlax.ex.ac.uk>, 1995, as + * included below: * * [gone - had to be deleted - what a pity] - * -*/ + */ #include "includes.h" -RCSID("$Id: rsa.c,v 1.14 2000/04/14 10:30:32 markus Exp $"); +RCSID("$OpenBSD: rsa.c,v 1.16 2000/09/07 20:27:53 deraadt Exp $"); #include "rsa.h" #include "ssh.h" diff --git a/crypto/openssh/rsa.h b/crypto/openssh/rsa.h index 16e319d43129..93a2dac85ccf 100644 --- a/crypto/openssh/rsa.h +++ b/crypto/openssh/rsa.h @@ -1,19 +1,17 @@ /* - * - * rsa.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Fri Mar 3 22:01:06 1995 ylo - * * RSA key generation, encryption and decryption. * -*/ + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ -/* RCSID("$Id: rsa.h,v 1.6 2000/04/14 10:30:32 markus Exp $"); */ +/* RCSID("$OpenBSD: rsa.h,v 1.8 2000/09/07 20:27:53 deraadt Exp $"); */ #ifndef RSA_H #define RSA_H diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1 index 51de6c5e8175..4ef3fe5d7906 100644 --- a/crypto/openssh/scp.1 +++ b/crypto/openssh/scp.1 @@ -9,7 +9,7 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $Id: scp.1,v 1.7 2000/04/12 21:47:50 aaron Exp $ +.\" $Id: scp.1,v 1.10 2000/09/01 15:25:13 deraadt Exp $ .\" .Dd September 25, 1999 .Dt SCP 1 @@ -20,6 +20,7 @@ .Sh SYNOPSIS .Nm scp .Op Fl pqrvC46 +.Op Fl S Ar program .Op Fl P Ar port .Op Fl c Ar cipher .Op Fl i Ar identity_file @@ -98,6 +99,12 @@ because .Fl p is already reserved for preserving the times and modes of the file in .Xr rcp 1 . +.It Fl S Ar program +Name of +.Ar program +to use for the encrypted connection. The program must understand +.Xr ssh 1 +options. .It Fl 4 Forces .Nm @@ -106,6 +113,7 @@ to use IPv4 addresses only. Forces .Nm to use IPv6 addresses only. +.El .Sh AUTHORS Timo Rinne <tri@iki.fi> and Tatu Ylonen <ylo@cs.hut.fi> .Sh HISTORY diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c index 491a78907fca..ec1f3d1f44d5 100644 --- a/crypto/openssh/scp.c +++ b/crypto/openssh/scp.c @@ -1,16 +1,46 @@ /* + * scp - secure remote copy. This is basically patched BSD rcp which + * uses ssh to do the data transfer (instead of using rcmd). * - * scp - secure remote copy. This is basically patched BSD rcp which uses ssh - * to do the data transfer (instead of using rcmd). - * - * NOTE: This version should NOT be suid root. (This uses ssh to do the transfer - * and ssh has the necessary privileges.) + * NOTE: This version should NOT be suid root. (This uses ssh to + * do the transfer and ssh has the necessary privileges.) * * 1995 Timo Rinne <tri@iki.fi>, Tatu Ylonen <ylo@cs.hut.fi> * -*/ + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +/* + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * Copyright (c) 1999 Aaron Campbell. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /* + * Parts from: + * * Copyright (c) 1983, 1990, 1992, 1993, 1995 * The Regents of the University of California. All rights reserved. * @@ -45,7 +75,7 @@ */ #include "includes.h" -RCSID("$Id: scp.c,v 1.30 2000/05/02 18:21:48 deraadt Exp $"); +RCSID("$OpenBSD: scp.c,v 1.39 2000/09/07 20:53:00 markus Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -61,6 +91,7 @@ void progressmeter(int); /* Returns width of the terminal (for progress meter calculations). */ int getttywidth(void); +int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); /* Time a transfer started. */ static struct timeval start; @@ -103,6 +134,9 @@ char *identity = NULL; /* This is the port to use in contacting the remote site (is non-NULL). */ char *port = NULL; +/* This is the program to execute for the secured connection. ("ssh" or -S) */ +char *ssh_program = SSH_PROGRAM; + /* * This function executes the given command as the specified user on the * given host. This returns < 0 if execution fails, and >= 0 otherwise. This @@ -110,13 +144,13 @@ char *port = NULL; */ int -do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) +do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) { int pin[2], pout[2], reserved[2]; if (verbose_mode) fprintf(stderr, "Executing: host %s, user %s, command %s\n", - host, remuser ? remuser : "(unspecified)", cmd); + host, remuser ? remuser : "(unspecified)", cmd); /* * Reserve two descriptors so that the real pipes won't get @@ -136,7 +170,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) /* For a child to execute the command on the remote host using ssh. */ if (fork() == 0) { - char *args[100]; + char *args[100]; /* XXX careful */ unsigned int i; /* Child. */ @@ -148,14 +182,13 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) close(pout[1]); i = 0; - args[i++] = SSH_PROGRAM; + args[i++] = ssh_program; args[i++] = "-x"; args[i++] = "-oFallBackToRsh no"; if (IPv4) args[i++] = "-4"; if (IPv6) args[i++] = "-6"; - args[i++] = "-oFallBackToRsh no"; if (verbose_mode) args[i++] = "-v"; if (compress) @@ -182,8 +215,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) args[i++] = cmd; args[i++] = NULL; - execvp(SSH_PROGRAM, args); - perror(SSH_PROGRAM); + execvp(ssh_program, args); + perror(ssh_program); exit(1); } /* Parent. Close the other side, and return the local side. */ @@ -207,8 +240,6 @@ fatal(const char *fmt,...) exit(255); } -/* This stuff used to be in BSD rcp extern.h. */ - typedef struct { int cnt; char *buf; @@ -224,8 +255,6 @@ int okname(char *); void run_err(const char *,...); void verifydir(char *); -/* Stuff from BSD rcp.c continues. */ - struct passwd *pwd; uid_t userid; int errs, remin, remout; @@ -253,7 +282,7 @@ main(argc, argv) extern int optind; fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF) + while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:")) != EOF) switch (ch) { /* User-visible flags. */ case '4': @@ -271,6 +300,10 @@ main(argc, argv) case 'r': iamrecursive = 1; break; + case 'S': + ssh_program = optarg; + break; + /* Server options. */ case 'd': targetshouldbedirectory = 1; @@ -336,8 +369,8 @@ main(argc, argv) remin = remout = -1; /* Command to be executed on remote system using "ssh". */ (void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", - iamrecursive ? " -r" : "", pflag ? " -p" : "", - targetshouldbedirectory ? " -d" : ""); + iamrecursive ? " -r" : "", pflag ? " -p" : "", + targetshouldbedirectory ? " -d" : ""); (void) signal(SIGPIPE, lostconn); @@ -394,9 +427,9 @@ toremote(targ, argc, argv) if (*src == 0) src = "."; host = strchr(argv[i], '@'); - len = strlen(SSH_PROGRAM) + strlen(argv[i]) + - strlen(src) + (tuser ? strlen(tuser) : 0) + - strlen(thost) + strlen(targ) + CMDNEEDS + 32; + len = strlen(ssh_program) + strlen(argv[i]) + + strlen(src) + (tuser ? strlen(tuser) : 0) + + strlen(thost) + strlen(targ) + CMDNEEDS + 32; bp = xmalloc(len); if (host) { *host++ = 0; @@ -407,19 +440,19 @@ toremote(targ, argc, argv) else if (!okname(suser)) continue; (void) sprintf(bp, - "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", - SSH_PROGRAM, verbose_mode ? " -v" : "", - suser, host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); + "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", + ssh_program, verbose_mode ? " -v" : "", + suser, host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); } else { host = cleanhostname(argv[i]); (void) sprintf(bp, - "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", - SSH_PROGRAM, verbose_mode ? " -v" : "", - host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); + "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", + ssh_program, verbose_mode ? " -v" : "", + host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); } if (verbose_mode) fprintf(stderr, "Executing: %s\n", bp); @@ -431,8 +464,8 @@ toremote(targ, argc, argv) bp = xmalloc(len); (void) sprintf(bp, "%s -t %s", cmd, targ); host = cleanhostname(thost); - if (do_cmd(host, tuser, - bp, &remin, &remout) < 0) + if (do_cmd(host, tuser, bp, &remin, + &remout, argc) < 0) exit(1); if (response() < 0) exit(1); @@ -454,11 +487,11 @@ tolocal(argc, argv) for (i = 0; i < argc - 1; i++) { if (!(src = colon(argv[i]))) { /* Local to local. */ len = strlen(_PATH_CP) + strlen(argv[i]) + - strlen(argv[argc - 1]) + 20; + strlen(argv[argc - 1]) + 20; bp = xmalloc(len); (void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP, - iamrecursive ? " -r" : "", pflag ? " -p" : "", - argv[i], argv[argc - 1]); + iamrecursive ? " -r" : "", pflag ? " -p" : "", + argv[i], argv[argc - 1]); if (verbose_mode) fprintf(stderr, "Executing: %s\n", bp); if (system(bp)) @@ -484,7 +517,7 @@ tolocal(argc, argv) len = strlen(src) + CMDNEEDS + 20; bp = xmalloc(len); (void) sprintf(bp, "%s -f %s", cmd, src); - if (do_cmd(host, suser, bp, &remin, &remout) < 0) { + if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { (void) xfree(bp); ++errs; continue; @@ -541,8 +574,8 @@ syserr: run_err("%s: %s", name, strerror(errno)); * versions expecting microseconds. */ (void) sprintf(buf, "T%lu 0 %lu 0\n", - (unsigned long) stb.st_mtime, - (unsigned long) stb.st_atime); + (unsigned long) stb.st_mtime, + (unsigned long) stb.st_atime); (void) atomicio(write, remout, buf, strlen(buf)); if (response() < 0) goto next; @@ -619,8 +652,8 @@ rsource(name, statp) last++; if (pflag) { (void) sprintf(path, "T%lu 0 %lu 0\n", - (unsigned long) statp->st_mtime, - (unsigned long) statp->st_atime); + (unsigned long) statp->st_mtime, + (unsigned long) statp->st_atime); (void) atomicio(write, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); @@ -628,8 +661,7 @@ rsource(name, statp) } } (void) sprintf(path, "D%04o %d %.1024s\n", - (unsigned int) (statp->st_mode & FILEMODEMASK), - 0, last); + (unsigned int) (statp->st_mode & FILEMODEMASK), 0, last); if (verbose_mode) fprintf(stderr, "Entering directory: %s", path); (void) atomicio(write, remout, path, strlen(path)); @@ -668,7 +700,8 @@ sink(argc, argv) BUF *bp; off_t i, j; int amt, count, exists, first, mask, mode, ofd, omode; - int setimes, size, targisdir, wrerrno = 0; + off_t size; + int setimes, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; struct utimbuf ut; int dummy_usec; @@ -776,7 +809,7 @@ sink(argc, argv) if (need > cursize) namebuf = xmalloc(need); (void) sprintf(namebuf, "%s%s%s", targ, - *targ ? "/" : "", cp); + *targ ? "/" : "", cp); np = namebuf; } else np = targ; @@ -882,7 +915,10 @@ bad: run_err("%s: %s", np, strerror(errno)); run_err("%s: set mode: %s", np, strerror(errno)); } - (void) close(ofd); + if (close(ofd) == -1) { + wrerr = YES; + wrerrno = errno; + } (void) response(); if (setimes && wrerr == NO) { setimes = 0; @@ -944,8 +980,9 @@ response() void usage() { - (void) fprintf(stderr, - "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n"); + (void) fprintf(stderr, "usage: scp " + "[-pqrvC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2; or:\n" + " scp [options] f1 ... fn directory\n"); exit(1); } @@ -972,43 +1009,6 @@ run_err(const char *fmt,...) va_end(ap); } -/* Stuff below is from BSD rcp util.c. */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: scp.c,v 1.30 2000/05/02 18:21:48 deraadt Exp $ - */ - char * colon(cp) char *cp; @@ -1085,7 +1085,7 @@ allocbuf(bp, fd, blksize) size = blksize; else size = blksize + (stb.st_blksize - blksize % stb.st_blksize) % - stb.st_blksize; + stb.st_blksize; if (bp->cnt >= size) return (bp); if (bp->buf == NULL) @@ -1174,10 +1174,10 @@ progressmeter(int flag) if (barlength > 0) { i = barlength * ratio / 100; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "|%.*s%*s|", i, - "*****************************************************************************" - "*****************************************************************************", - barlength - i, ""); + "|%.*s%*s|", i, + "*****************************************************************************" + "*****************************************************************************", + barlength - i, ""); } i = 0; abbrevsize = cursize; @@ -1218,14 +1218,14 @@ progressmeter(int flag) i = remaining / 3600; if (i) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%2d:", i); + "%2d:", i); else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " "); + " "); i = remaining % 3600; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%02d:%02d%s", i / 60, i % 60, - (flag != 1) ? " ETA" : " "); + "%02d:%02d%s", i / 60, i % 60, + (flag != 1) ? " ETA" : " "); } atomicio(write, fileno(stdout), buf, strlen(buf)); diff --git a/crypto/openssh/scp/Makefile b/crypto/openssh/scp/Makefile index 3f59a9fd153e..fc45dfd0238c 100644 --- a/crypto/openssh/scp/Makefile +++ b/crypto/openssh/scp/Makefile @@ -3,12 +3,7 @@ PROG= scp BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif BINDIR= /usr/bin MAN= scp.1 diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c index 4e3e5cc79674..81551081432a 100644 --- a/crypto/openssh/servconf.c +++ b/crypto/openssh/servconf.c @@ -1,18 +1,16 @@ /* - * - * servconf.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Mon Aug 21 15:48:58 1995 ylo - * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: servconf.c,v 1.41 2000/05/22 18:42:01 markus Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.51 2000/09/07 20:27:53 deraadt Exp $"); #include "ssh.h" #include "servconf.h" @@ -44,6 +42,7 @@ initialize_server_options(ServerOptions *options) options->check_mail = -1; options->x11_forwarding = -1; options->x11_display_offset = -1; + options->xauth_location = NULL; options->strict_modes = -1; options->keepalives = -1; options->log_facility = (SyslogFacility) - 1; @@ -74,6 +73,10 @@ initialize_server_options(ServerOptions *options) options->ciphers = NULL; options->protocol = SSH_PROTO_UNKNOWN; options->gateway_ports = -1; + options->num_subsystems = 0; + options->max_startups_begin = -1; + options->max_startups_rate = -1; + options->max_startups = -1; } void @@ -109,6 +112,10 @@ fill_default_server_options(ServerOptions *options) options->x11_forwarding = 0; if (options->x11_display_offset == -1) options->x11_display_offset = 10; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ if (options->strict_modes == -1) options->strict_modes = 1; if (options->keepalives == -1) @@ -153,10 +160,14 @@ fill_default_server_options(ServerOptions *options) options->protocol = SSH_PROTO_1|SSH_PROTO_2; if (options->gateway_ports == -1) options->gateway_ports = 0; + if (options->max_startups == -1) + options->max_startups = 10; + if (options->max_startups_rate == -1) + options->max_startups_rate = 100; /* 100% */ + if (options->max_startups_begin == -1) + options->max_startups_begin = options->max_startups; } -#define WHITESPACE " \t\r\n" - /* Keyword tokens. */ typedef enum { sBadOption, /* == unknown option */ @@ -177,7 +188,7 @@ typedef enum { sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, - sGatewayPorts, sDSAAuthentication + sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups } ServerOpCodes; /* Textual representation of the tokens. */ @@ -219,6 +230,7 @@ static struct { { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, { "x11forwarding", sX11Forwarding }, { "x11displayoffset", sX11DisplayOffset }, + { "xauthlocation", sXAuthLocation }, { "strictmodes", sStrictModes }, { "permitemptypasswords", sEmptyPasswd }, { "uselogin", sUseLogin }, @@ -231,6 +243,8 @@ static struct { { "ciphers", sCiphers }, { "protocol", sProtocol }, { "gatewayports", sGatewayPorts }, + { "subsystem", sSubsystem }, + { "maxstartups", sMaxStartups }, { NULL, 0 } }; @@ -292,10 +306,11 @@ read_server_config(ServerOptions *options, const char *filename) { FILE *f; char line[1024]; - char *cp, **charptr; + char *cp, **charptr, *arg; int linenum, *intptr, value; int bad_options = 0; ServerOpCodes opcode; + int i; f = fopen(filename, "r"); if (!f) { @@ -305,11 +320,14 @@ read_server_config(ServerOptions *options, const char *filename) linenum = 0; while (fgets(line, sizeof(line), f)) { linenum++; - cp = line + strspn(line, WHITESPACE); - if (!*cp || *cp == '#') + cp = line; + arg = strdelim(&cp); + /* Ignore leading whitespace */ + if (*arg == '\0') + arg = strdelim(&cp); + if (!*arg || *arg == '#') continue; - cp = strtok(cp, WHITESPACE); - opcode = parse_token(cp, filename, linenum); + opcode = parse_token(arg, filename, linenum); switch (opcode) { case sBadOption: bad_options++; @@ -324,23 +342,23 @@ read_server_config(ServerOptions *options, const char *filename) if (options->num_ports >= MAX_PORTS) fatal("%s line %d: too many ports.\n", filename, linenum); - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&cp); + if (!arg || *arg == '\0') fatal("%s line %d: missing port number.\n", filename, linenum); - options->ports[options->num_ports++] = atoi(cp); + options->ports[options->num_ports++] = atoi(arg); break; case sServerKeyBits: intptr = &options->server_key_bits; parse_int: - cp = strtok(NULL, WHITESPACE); - if (!cp) { + arg = strdelim(&cp); + if (!arg || *arg == '\0') { fprintf(stderr, "%s line %d: missing integer value.\n", filename, linenum); exit(1); } - value = atoi(cp); + value = atoi(arg); if (*intptr == -1) *intptr = value; break; @@ -354,62 +372,55 @@ parse_int: goto parse_int; case sListenAddress: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&cp); + if (!arg || *arg == '\0') fatal("%s line %d: missing inet addr.\n", filename, linenum); - add_listen_addr(options, cp); + add_listen_addr(options, arg); break; case sHostKeyFile: case sHostDSAKeyFile: charptr = (opcode == sHostKeyFile ) ? &options->host_key_file : &options->host_dsa_key_file; - cp = strtok(NULL, WHITESPACE); - if (!cp) { +parse_filename: + arg = strdelim(&cp); + if (!arg || *arg == '\0') { fprintf(stderr, "%s line %d: missing file name.\n", filename, linenum); exit(1); } if (*charptr == NULL) - *charptr = tilde_expand_filename(cp, getuid()); + *charptr = tilde_expand_filename(arg, getuid()); break; case sPidFile: charptr = &options->pid_file; - cp = strtok(NULL, WHITESPACE); - if (!cp) { - fprintf(stderr, "%s line %d: missing file name.\n", - filename, linenum); - exit(1); - } - if (*charptr == NULL) - *charptr = tilde_expand_filename(cp, getuid()); - break; + goto parse_filename; case sRandomSeedFile: fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", filename, linenum); - cp = strtok(NULL, WHITESPACE); + arg = strdelim(&cp); break; case sPermitRootLogin: intptr = &options->permit_root_login; - cp = strtok(NULL, WHITESPACE); - if (!cp) { + arg = strdelim(&cp); + if (!arg || *arg == '\0') { fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", filename, linenum); exit(1); } - if (strcmp(cp, "without-password") == 0) + if (strcmp(arg, "without-password") == 0) value = 2; - else if (strcmp(cp, "yes") == 0) + else if (strcmp(arg, "yes") == 0) value = 1; - else if (strcmp(cp, "no") == 0) + else if (strcmp(arg, "no") == 0) value = 0; else { fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", - filename, linenum, cp); + filename, linenum, arg); exit(1); } if (*intptr == -1) @@ -419,19 +430,19 @@ parse_int: case sIgnoreRhosts: intptr = &options->ignore_rhosts; parse_flag: - cp = strtok(NULL, WHITESPACE); - if (!cp) { + arg = strdelim(&cp); + if (!arg || *arg == '\0') { fprintf(stderr, "%s line %d: missing yes/no argument.\n", filename, linenum); exit(1); } - if (strcmp(cp, "yes") == 0) + if (strcmp(arg, "yes") == 0) value = 1; - else if (strcmp(cp, "no") == 0) + else if (strcmp(arg, "no") == 0) value = 0; else { fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", - filename, linenum, cp); + filename, linenum, arg); exit(1); } if (*intptr == -1) @@ -508,6 +519,10 @@ parse_flag: intptr = &options->x11_display_offset; goto parse_int; + case sXAuthLocation: + charptr = &options->xauth_location; + goto parse_filename; + case sStrictModes: intptr = &options->strict_modes; goto parse_flag; @@ -530,94 +545,137 @@ parse_flag: case sLogFacility: intptr = (int *) &options->log_facility; - cp = strtok(NULL, WHITESPACE); - value = log_facility_number(cp); + arg = strdelim(&cp); + value = log_facility_number(arg); if (value == (SyslogFacility) - 1) fatal("%.200s line %d: unsupported log facility '%s'\n", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (*intptr == -1) *intptr = (SyslogFacility) value; break; case sLogLevel: intptr = (int *) &options->log_level; - cp = strtok(NULL, WHITESPACE); - value = log_level_number(cp); + arg = strdelim(&cp); + value = log_level_number(arg); if (value == (LogLevel) - 1) fatal("%.200s line %d: unsupported log level '%s'\n", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (*intptr == -1) *intptr = (LogLevel) value; break; case sAllowUsers: - while ((cp = strtok(NULL, WHITESPACE))) { + while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_users >= MAX_ALLOW_USERS) fatal("%s line %d: too many allow users.\n", filename, linenum); - options->allow_users[options->num_allow_users++] = xstrdup(cp); + options->allow_users[options->num_allow_users++] = xstrdup(arg); } break; case sDenyUsers: - while ((cp = strtok(NULL, WHITESPACE))) { + while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_deny_users >= MAX_DENY_USERS) fatal( "%s line %d: too many deny users.\n", filename, linenum); - options->deny_users[options->num_deny_users++] = xstrdup(cp); + options->deny_users[options->num_deny_users++] = xstrdup(arg); } break; case sAllowGroups: - while ((cp = strtok(NULL, WHITESPACE))) { + while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_groups >= MAX_ALLOW_GROUPS) fatal("%s line %d: too many allow groups.\n", filename, linenum); - options->allow_groups[options->num_allow_groups++] = xstrdup(cp); + options->allow_groups[options->num_allow_groups++] = xstrdup(arg); } break; case sDenyGroups: - while ((cp = strtok(NULL, WHITESPACE))) { + while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_deny_groups >= MAX_DENY_GROUPS) fatal("%s line %d: too many deny groups.\n", filename, linenum); - options->deny_groups[options->num_deny_groups++] = xstrdup(cp); + options->deny_groups[options->num_deny_groups++] = xstrdup(arg); } break; case sCiphers: - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&cp); + if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); - if (!ciphers_valid(cp)) + if (!ciphers_valid(arg)) fatal("%s line %d: Bad SSH2 cipher spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (options->ciphers == NULL) - options->ciphers = xstrdup(cp); + options->ciphers = xstrdup(arg); break; case sProtocol: intptr = &options->protocol; - cp = strtok(NULL, WHITESPACE); - if (!cp) + arg = strdelim(&cp); + if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); - value = proto_spec(cp); + value = proto_spec(arg); if (value == SSH_PROTO_UNKNOWN) fatal("%s line %d: Bad protocol spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); + filename, linenum, arg ? arg : "<NONE>"); if (*intptr == SSH_PROTO_UNKNOWN) *intptr = value; break; + case sSubsystem: + if(options->num_subsystems >= MAX_SUBSYSTEMS) { + fatal("%s line %d: too many subsystems defined.", + filename, linenum); + } + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem name.", + filename, linenum); + for (i = 0; i < options->num_subsystems; i++) + if(strcmp(arg, options->subsystem_name[i]) == 0) + fatal("%s line %d: Subsystem '%s' already defined.", + filename, linenum, arg); + options->subsystem_name[options->num_subsystems] = xstrdup(arg); + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem command.", + filename, linenum); + options->subsystem_command[options->num_subsystems] = xstrdup(arg); + options->num_subsystems++; + break; + + case sMaxStartups: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing MaxStartups spec.", + filename, linenum); + if (sscanf(arg, "%d:%d:%d", + &options->max_startups_begin, + &options->max_startups_rate, + &options->max_startups) == 3) { + if (options->max_startups_begin > + options->max_startups || + options->max_startups_rate > 100 || + options->max_startups_rate < 1) + fatal("%s line %d: Illegal MaxStartups spec.", + filename, linenum); + break; + } + intptr = &options->max_startups; + goto parse_int; + default: fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", - filename, linenum, cp, opcode); + filename, linenum, arg, opcode); exit(1); } - if (strtok(NULL, WHITESPACE) != NULL) { - fprintf(stderr, "%s line %d: garbage at end of line.\n", - filename, linenum); + if ((arg = strdelim(&cp)) != NULL && *arg != '\0') { + fprintf(stderr, + "%s line %d: garbage at end of line; \"%.200s\".\n", + filename, linenum, arg); exit(1); } } diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h index 4fa6deea6f55..f00a1284f551 100644 --- a/crypto/openssh/servconf.h +++ b/crypto/openssh/servconf.h @@ -1,19 +1,17 @@ /* - * - * servconf.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * - * Created: Mon Aug 21 15:35:03 1995 ylo - * * Definitions for server configuration data and for the functions reading it. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: servconf.h,v 1.22 2000/05/06 17:45:37 markus Exp $"); */ +/* RCSID("$OpenBSD: servconf.h,v 1.28 2000/09/07 20:27:53 deraadt Exp $"); */ #ifndef SERVCONF_H #define SERVCONF_H @@ -24,6 +22,7 @@ #define MAX_DENY_USERS 256 /* Max # users on deny list. */ #define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ +#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ typedef struct { unsigned int num_ports; @@ -47,6 +46,7 @@ typedef struct { int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ int x11_display_offset; /* What DISPLAY number to start * searching at */ + char *xauth_location; /* Location of xauth program */ int strict_modes; /* If true, require string home dir modes. */ int keepalives; /* If true, set SO_KEEPALIVE. */ char *ciphers; /* Ciphers in order of preference. */ @@ -93,6 +93,15 @@ typedef struct { char *allow_groups[MAX_ALLOW_GROUPS]; unsigned int num_deny_groups; char *deny_groups[MAX_DENY_GROUPS]; + + unsigned int num_subsystems; + char *subsystem_name[MAX_SUBSYSTEMS]; + char *subsystem_command[MAX_SUBSYSTEMS]; + + int max_startups_begin; + int max_startups_rate; + int max_startups; + } ServerOptions; /* * Initializes the server options to special values that indicate that they diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c index 74a800b9d964..ed2886a97831 100644 --- a/crypto/openssh/serverloop.c +++ b/crypto/openssh/serverloop.c @@ -2,12 +2,36 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Sun Sep 10 00:30:37 1995 ylo * Server main loop for handling the interactive session. - */ -/* + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * * SSH2 support by Markus Friedl. * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" @@ -23,6 +47,7 @@ #include "ssh2.h" #include "session.h" #include "dispatch.h" +#include "auth-options.h" static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ @@ -706,14 +731,21 @@ input_direct_tcpip(void) debug("open direct-tcpip: from %s port %d to %s port %d", originator, originator_port, target, target_port); + /* XXX check permission */ + if (no_port_forwarding_flag) { + xfree(target); + xfree(originator); + return -1; + } sock = channel_connect_to(target, target_port); xfree(target); xfree(originator); if (sock < 0) return -1; return channel_new("direct-tcpip", SSH_CHANNEL_OPEN, - sock, sock, -1, 4*1024, 32*1024, 0, xstrdup("direct-tcpip")); + sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, + CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip")); } void @@ -746,7 +778,8 @@ server_input_channel_open(int type, int plen) * CHANNEL_REQUEST messages is registered. */ id = channel_new(ctype, SSH_CHANNEL_LARVAL, - -1, -1, -1, 0, 32*1024, 0, xstrdup("server-session")); + -1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT, + 0, xstrdup("server-session")); if (session_open(id) == 1) { channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, session_input_channel_req, (void *)0); diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c index ce46f1d5a74f..43215358daf6 100644 --- a/crypto/openssh/session.c +++ b/crypto/openssh/session.c @@ -1,14 +1,39 @@ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - */ -/* + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * * SSH2 support by Markus Friedl. * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.15 2000/05/30 17:23:37 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.37 2000/09/07 20:27:53 deraadt Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -26,6 +51,11 @@ RCSID("$OpenBSD: session.c,v 1.15 2000/05/30 17:23:37 markus Exp $"); #include "bufaux.h" #include "ssh2.h" #include "auth.h" +#include "auth-options.h" + +#ifdef HAVE_LOGIN_CAP +#include <login_cap.h> +#endif /* types */ @@ -60,6 +90,7 @@ void session_pty_cleanup(Session *s); void session_proctitle(Session *s); void do_exec_pty(Session *s, const char *command, struct passwd * pw); void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); +void do_login(Session *s); void do_child(const char *command, struct passwd * pw, const char *term, @@ -71,25 +102,23 @@ extern ServerOptions options; extern char *__progname; extern int log_stderr; extern int debug_flag; +extern unsigned int utmp_len; + +extern int startup_pipe; /* Local Xauthority file. */ static char *xauthfile; +/* original command from peer. */ +char *original_command = NULL; + /* data */ #define MAX_SESSIONS 10 Session sessions[MAX_SESSIONS]; -/* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */ -int no_port_forwarding_flag = 0; -int no_agent_forwarding_flag = 0; -int no_x11_forwarding_flag = 0; -int no_pty_flag = 0; - -/* RSA authentication "command=" option. */ -char *forced_command = NULL; - -/* RSA authentication "environment=" options. */ -struct envstring *custom_environment = NULL; +#ifdef HAVE_LOGIN_CAP +static login_cap_t *lc; +#endif /* * Remove local Xauthority file. @@ -143,7 +172,7 @@ void do_authenticated(struct passwd * pw) { Session *s; - int type; + int type, fd; int compression_level = 0, enable_compression_after_reply = 0; int have_pty = 0; char *command; @@ -156,6 +185,10 @@ do_authenticated(struct passwd * pw) * authentication. */ alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } /* * Inform the channel mechanism that we are the server side and that @@ -170,6 +203,13 @@ do_authenticated(struct passwd * pw) s = session_new(); s->pw = pw; +#ifdef HAVE_LOGIN_CAP + if ((lc = login_getclass(pw->pw_class)) == NULL) { + error("unable to get login class"); + return; + } +#endif + /* * We stay in this loop until the client requests to execute a shell * or a command. @@ -248,7 +288,10 @@ do_authenticated(struct passwd * pw) packet_send_debug("X11 forwarding disabled in server configuration file."); break; } -#ifdef XAUTH_PATH + if (!options.xauth_location) { + packet_send_debug("No xauth program; cannot forward with spoofing."); + break; + } if (no_x11_forwarding_flag) { packet_send_debug("X11 forwarding not permitted for this authentication."); break; @@ -284,15 +327,13 @@ do_authenticated(struct passwd * pw) break; } strlcat(xauthfile, "/cookies", MAXPATHLEN); - open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd >= 0) + close(fd); restore_uid(); fatal_add_cleanup(xauthfile_cleanup_proc, NULL); success = 1; break; -#else /* XAUTH_PATH */ - packet_send_debug("No xauth program; cannot forward with spoofing."); - break; -#endif /* XAUTH_PATH */ case SSH_CMSG_AGENT_REQUEST_FORWARDING: if (no_agent_forwarding_flag || compat13) { @@ -333,6 +374,7 @@ do_authenticated(struct passwd * pw) packet_integrity_check(plen, 0, type); } if (forced_command != NULL) { + original_command = command; command = forced_command; debug("Forced command '%.500s'", forced_command); } @@ -492,41 +534,17 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) void do_exec_pty(Session *s, const char *command, struct passwd * pw) { - FILE *f; - char buf[100], *time_string; - char line[256]; - const char *hostname; int fdout, ptyfd, ttyfd, ptymaster; - int quiet_login; pid_t pid; - socklen_t fromlen; - struct sockaddr_storage from; - struct stat st; - time_t last_login_time; if (s == NULL) fatal("do_exec_pty: no session"); ptyfd = s->ptyfd; ttyfd = s->ttyfd; - /* Get remote host name. */ - hostname = get_canonical_hostname(); - - /* - * Get the time when the user last logged in. Buf will be set to - * contain the hostname the last login was from. - */ - if (!options.use_login) { - last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, - buf, sizeof(buf)); - } - /* Fork the child. */ if ((pid = fork()) == 0) { - pid = getpid(); - - /* Child. Reinitialize the log because the pid has - changed. */ + /* Child. Reinitialize the log because the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); /* Close the master side of the pseudo tty. */ @@ -550,67 +568,10 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw) /* Close the extra descriptor for the pseudo tty. */ close(ttyfd); -/* XXXX ? move to do_child() ??*/ - /* - * Get IP address of client. This is needed because we want - * to record where the user logged in from. If the - * connection is not a socket, let the ip address be 0.0.0.0. - */ - memset(&from, 0, sizeof(from)); - if (packet_connection_is_on_socket()) { - fromlen = sizeof(from); - if (getpeername(packet_get_connection_in(), - (struct sockaddr *) & from, &fromlen) < 0) { - debug("getpeername: %.100s", strerror(errno)); - fatal_cleanup(); - } - } - /* Record that there was a login on that terminal. */ - record_login(pid, s->tty, pw->pw_name, pw->pw_uid, hostname, - (struct sockaddr *)&from); + /* record login, etc. similar to login(1) */ + if (command == NULL && !options.use_login) + do_login(s); - /* Check if .hushlogin exists. */ - snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); - quiet_login = stat(line, &st) >= 0; - - /* - * If the user has logged in before, display the time of last - * login. However, don't display anything extra if a command - * has been specified (so that ssh can be used to execute - * commands on a remote machine without users knowing they - * are going to another machine). Login(1) will do this for - * us as well, so check if login(1) is used - */ - if (command == NULL && last_login_time != 0 && !quiet_login && - !options.use_login) { - /* Convert the date to a string. */ - time_string = ctime(&last_login_time); - /* Remove the trailing newline. */ - if (strchr(time_string, '\n')) - *strchr(time_string, '\n') = 0; - /* Display the last login time. Host if displayed - if known. */ - if (strcmp(buf, "") == 0) - printf("Last login: %s\r\n", time_string); - else - printf("Last login: %s from %s\r\n", time_string, buf); - } - /* - * Print /etc/motd unless a command was specified or printing - * it was disabled in server options or login(1) will be - * used. Note that some machines appear to print it in - * /etc/profile or similar. - */ - if (command == NULL && options.print_motd && !quiet_login && - !options.use_login) { - /* Print /etc/motd if it exists. */ - f = fopen("/etc/motd", "r"); - if (f) { - while (fgets(line, sizeof(line), f)) - fputs(line, stdout); - fclose(f); - } - } /* Do common processing for the child, such as execing the command. */ do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty); @@ -648,6 +609,87 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw) } } +const char * +get_remote_name_or_ip(void) +{ + static const char *remote = ""; + if (utmp_len > 0) + remote = get_canonical_hostname(); + if (utmp_len == 0 || strlen(remote) > utmp_len) + remote = get_remote_ipaddr(); + return remote; +} + +/* administrative, login(1)-like work */ +void +do_login(Session *s) +{ + FILE *f; + char *time_string; + char buf[256]; + char hostname[MAXHOSTNAMELEN]; + socklen_t fromlen; + struct sockaddr_storage from; + struct stat st; + time_t last_login_time; + struct passwd * pw = s->pw; + pid_t pid = getpid(); + + /* + * Get IP address of client. If the connection is not a socket, let + * the address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + if (packet_connection_is_on_socket()) { + fromlen = sizeof(from); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + + /* Get the time and hostname when the user last logged in. */ + hostname[0] = '\0'; + last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, + hostname, sizeof(hostname)); + + /* Record that there was a login on that tty from the remote host. */ + record_login(pid, s->tty, pw->pw_name, pw->pw_uid, + get_remote_name_or_ip(), (struct sockaddr *)&from); + + /* Done if .hushlogin exists. */ + snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); +#ifdef HAVE_LOGIN_CAP + if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) +#else + if (stat(buf, &st) >= 0) +#endif + return; + if (last_login_time != 0) { + time_string = ctime(&last_login_time); + if (strchr(time_string, '\n')) + *strchr(time_string, '\n') = 0; + if (strcmp(buf, "") == 0) + printf("Last login: %s\r\n", time_string); + else + printf("Last login: %s from %s\r\n", time_string, hostname); + } + if (options.print_motd) { +#ifdef HAVE_LOGIN_CAP + f = fopen(login_getcapstr(lc, "welcome", "/etc/motd", + "/etc/motd"), "r"); +#else + f = fopen("/etc/motd", "r"); +#endif + if (f) { + while (fgets(buf, sizeof(buf), f)) + fputs(buf, stdout); + fclose(f); + } + } +} + /* * Sets the value of the given variable in the environment. If the variable * already exists, its value is overriden. @@ -738,33 +780,52 @@ do_child(const char *command, struct passwd * pw, const char *term, const char *display, const char *auth_proto, const char *auth_data, const char *ttyname) { - const char *shell, *cp = NULL; + const char *shell, *hostname = NULL, *cp = NULL; char buf[256]; - FILE *f; + char cmd[1024]; + FILE *f = NULL; unsigned int envsize, i; char **env; extern char **environ; struct stat st; char *argv[10]; - f = fopen("/etc/nologin", "r"); - if (f) { - /* /etc/nologin exists. Print its contents and exit. */ - while (fgets(buf, sizeof(buf), f)) - fputs(buf, stderr); - fclose(f); - if (pw->pw_uid != 0) + /* login(1) is only called if we execute the login shell */ + if (options.use_login && command != NULL) + options.use_login = 0; + + if (!options.use_login) { +#ifdef HAVE_LOGIN_CAP + if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) + f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, + _PATH_NOLOGIN), "r"); +#else + if (pw->pw_uid) + f = fopen(_PATH_NOLOGIN, "r"); +#endif + if (f) { + /* /etc/nologin exists. Print its contents and exit. */ + while (fgets(buf, sizeof(buf), f)) + fputs(buf, stderr); + fclose(f); exit(254); + } } - /* Set login name in the kernel. */ - if (setlogin(pw->pw_name) < 0) - error("setlogin failed: %s", strerror(errno)); - - /* Set uid, gid, and groups. */ + /* Set login name, uid, gid, and groups. */ /* Login(1) does this as well, and it needs uid 0 for the "-h" switch, so we let login(1) to this for us. */ if (!options.use_login) { if (getuid() == 0 || geteuid() == 0) { +#ifdef HAVE_LOGIN_CAP + if (setusercontext(lc, pw, pw->pw_uid, + (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { + perror("unable to set user context"); + exit(1); + + } +#else + if (setlogin(pw->pw_name) < 0) + error("setlogin failed: %s", strerror(errno)); if (setgid(pw->pw_gid) < 0) { perror("setgid"); exit(1); @@ -778,15 +839,19 @@ do_child(const char *command, struct passwd * pw, const char *term, /* Permanently switch to the desired uid. */ permanently_set_uid(pw->pw_uid); +#endif } if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) - fatal("Failed to set uids to %d.", (int) pw->pw_uid); + fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); } /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; +#ifdef HAVE_LOGIN_CAP + shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); +#endif #ifdef AFS /* Try to get AFS tokens for the local cell. */ @@ -810,7 +875,12 @@ do_child(const char *command, struct passwd * pw, const char *term, child_set_env(&env, &envsize, "USER", pw->pw_name); child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); child_set_env(&env, &envsize, "HOME", pw->pw_dir); +#ifdef HAVE_LOGIN_CAP + (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH); + child_set_env(&env, &envsize, "PATH", getenv("PATH")); +#else child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); +#endif snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); @@ -847,6 +917,9 @@ do_child(const char *command, struct passwd * pw, const char *term, child_set_env(&env, &envsize, "TERM", term); if (display) child_set_env(&env, &envsize, "DISPLAY", display); + if (original_command) + child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", + original_command); #ifdef KRB4 { @@ -875,6 +948,9 @@ do_child(const char *command, struct passwd * pw, const char *term, for (i = 0; env[i]; i++) fprintf(stderr, " %.200s\n", env[i]); } + /* we have to stash the hostname before we close our socket. */ + if (options.use_login) + hostname = get_remote_name_or_ip(); /* * Close the connection descriptors; note that this is the child, and * the server will still have the socket open, and it is important @@ -911,9 +987,14 @@ do_child(const char *command, struct passwd * pw, const char *term, close(i); /* Change current directory to the user\'s home directory. */ - if (chdir(pw->pw_dir) < 0) + if (chdir(pw->pw_dir) < 0) { fprintf(stderr, "Could not chdir to home directory %s: %s\n", pw->pw_dir, strerror(errno)); +#ifdef HAVE_LOGIN_CAP + if (login_getcapbool(lc, "requirehome", 0)) + exit(1); +#endif + } /* * Must take new environment into use so that .ssh/rc, /etc/sshrc and @@ -948,38 +1029,38 @@ do_child(const char *command, struct passwd * pw, const char *term, pclose(f); } else fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC); - } -#ifdef XAUTH_PATH - else { + } else if (options.xauth_location != NULL) { /* Add authority data to .Xauthority if appropriate. */ if (auth_proto != NULL && auth_data != NULL) { char *screen = strchr(display, ':'); if (debug_flag) { fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n", - XAUTH_PATH, display, auth_proto, auth_data); + options.xauth_location, display, + auth_proto, auth_data); if (screen != NULL) fprintf(stderr, "Adding %.*s/unix%s %s %s\n", - screen-display, display, + (int)(screen-display), display, screen, auth_proto, auth_data); } - f = popen(XAUTH_PATH " -q -", "w"); + snprintf(cmd, sizeof cmd, "%s -q -", + options.xauth_location); + f = popen(cmd, "w"); if (f) { fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data); if (screen != NULL) fprintf(f, "add %.*s/unix%s %s %s\n", - screen-display, display, + (int)(screen-display), display, screen, auth_proto, auth_data); pclose(f); - } else - fprintf(stderr, "Could not run %s -q -\n", - XAUTH_PATH); + } else { + fprintf(stderr, "Could not run %s\n", + cmd); + } } } -#endif /* XAUTH_PATH */ - /* Get the last component of the shell name. */ cp = strrchr(shell, '/'); if (cp) @@ -1031,8 +1112,8 @@ do_child(const char *command, struct passwd * pw, const char *term, } else { /* Launch login(1). */ - execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(), - "-p", "-f", "--", pw->pw_name, NULL); + execl("/usr/bin/login", "login", "-h", hostname, + "-p", "-f", "--", pw->pw_name, NULL); /* Login couldn't be executed, die. */ @@ -1170,6 +1251,8 @@ session_pty_req(Session *s) unsigned int len; char *term_modes; /* encoded terminal modes */ + if (no_pty_flag) + return 0; if (s->ttyfd != -1) return 0; s->term = packet_get_string(&len); @@ -1217,10 +1300,22 @@ session_subsystem_req(Session *s) unsigned int len; int success = 0; char *subsys = packet_get_string(&len); + int i; packet_done(); log("subsystem request for %s", subsys); + for (i = 0; i < options.num_subsystems; i++) { + if(strcmp(subsys, options.subsystem_name[i]) == 0) { + debug("subsystem: exec() %s", options.subsystem_command[i]); + do_exec_no_pty(s, options.subsystem_command[i], s->pw); + success = 1; + } + } + + if (!success) + log("subsystem request for %s failed, subsystem not found", subsys); + xfree(subsys); return success; } @@ -1228,6 +1323,11 @@ session_subsystem_req(Session *s) int session_x11_req(Session *s) { + int fd; + if (no_x11_forwarding_flag) { + debug("X11 forwarding disabled in user configuration file."); + return 0; + } if (!options.x11_forwarding) { debug("X11 forwarding disabled in server configuration file."); return 0; @@ -1268,12 +1368,49 @@ session_x11_req(Session *s) return 0; } strlcat(xauthfile, "/cookies", MAXPATHLEN); - open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd >= 0) + close(fd); restore_uid(); fatal_add_cleanup(xauthfile_cleanup_proc, s); return 1; } +int +session_shell_req(Session *s) +{ + /* if forced_command == NULL, the shell is execed */ + char *shell = forced_command; + packet_done(); + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, shell, s->pw); + else + do_exec_pty(s, shell, s->pw); + return 1; +} + +int +session_exec_req(Session *s) +{ + unsigned int len; + char *command = packet_get_string(&len); + packet_done(); + if (forced_command) { + original_command = command; + command = forced_command; + debug("Forced command '%.500s'", forced_command); + } + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, command, s->pw); + else + do_exec_pty(s, command, s->pw); + if (forced_command == NULL) + xfree(command); + return 1; +} + void session_input_channel_req(int id, void *arg) { @@ -1303,23 +1440,9 @@ session_input_channel_req(int id, void *arg) */ if (c->type == SSH_CHANNEL_LARVAL) { if (strcmp(rtype, "shell") == 0) { - packet_done(); - s->extended = 1; - if (s->ttyfd == -1) - do_exec_no_pty(s, NULL, s->pw); - else - do_exec_pty(s, NULL, s->pw); - success = 1; + success = session_shell_req(s); } else if (strcmp(rtype, "exec") == 0) { - char *command = packet_get_string(&len); - packet_done(); - s->extended = 1; - if (s->ttyfd == -1) - do_exec_no_pty(s, command, s->pw); - else - do_exec_pty(s, command, s->pw); - xfree(command); - success = 1; + success = session_exec_req(s); } else if (strcmp(rtype, "pty-req") == 0) { success = session_pty_req(s); } else if (strcmp(rtype, "x11-req") == 0) { @@ -1523,11 +1646,24 @@ session_proctitle(Session *s) void do_authenticated2(void) { + struct passwd *pw; + /* * Cancel the alarm we set to limit the time taken for * authentication. */ alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } +#ifdef HAVE_LOGIN_CAP + pw = auth_get_user(); + if ((lc = login_getclass(pw->pw_class)) == NULL) { + error("unable to get login class"); + return; + } +#endif server_loop2(); if (xauthfile) xauthfile_cleanup_proc(NULL); diff --git a/crypto/openssh/session.h b/crypto/openssh/session.h index a3427bcb0888..bce99f77cb49 100644 --- a/crypto/openssh/session.h +++ b/crypto/openssh/session.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef SESSION_H #define SESSION_H diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8 new file mode 100644 index 000000000000..9811a3b4266c --- /dev/null +++ b/crypto/openssh/sftp-server.8 @@ -0,0 +1,56 @@ +.\" $OpenBSD: sftp-server.8,v 1.2 2000/09/07 20:27:53 deraadt Exp $ +.\" +.\" Copyright (c) 2000 Markus Friedl. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd August 30, 2000 +.Dt SFTP-SERVER 8 +.Os +.Sh NAME +.Nm sftp-server +.Nd SFTP server subsystem +.Sh SYNOPSIS +.Nm sftp-server +.Sh DESCRIPTION +.Nm +is a program that speaks the server side of SFTP protocol +to stdout and expects client requests from stdin. +.Nm +is not intended to be called directly, but from +.Xr sshd 8 +using the +.Cm Subsystem +option. +See +.Xr sshd 8 +for more information. +.Sh HISTORY +.Nm +first appeared in +.Ox 2.8 . +.Sh AUTHOR +Markus Friedl <markus@openbsd.org> +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 , diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c new file mode 100644 index 000000000000..018a03cc2098 --- /dev/null +++ b/crypto/openssh/sftp-server.c @@ -0,0 +1,1068 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "includes.h" +RCSID("$OpenBSD: sftp-server.c,v 1.6 2000/09/07 20:27:53 deraadt Exp $"); + +#include "ssh.h" +#include "buffer.h" +#include "bufaux.h" +#include "getput.h" +#include "xmalloc.h" + +/* version */ +#define SSH_FILEXFER_VERSION 2 + +/* client to server */ +#define SSH_FXP_INIT 1 +#define SSH_FXP_OPEN 3 +#define SSH_FXP_CLOSE 4 +#define SSH_FXP_READ 5 +#define SSH_FXP_WRITE 6 +#define SSH_FXP_LSTAT 7 +#define SSH_FXP_FSTAT 8 +#define SSH_FXP_SETSTAT 9 +#define SSH_FXP_FSETSTAT 10 +#define SSH_FXP_OPENDIR 11 +#define SSH_FXP_READDIR 12 +#define SSH_FXP_REMOVE 13 +#define SSH_FXP_MKDIR 14 +#define SSH_FXP_RMDIR 15 +#define SSH_FXP_REALPATH 16 +#define SSH_FXP_STAT 17 +#define SSH_FXP_RENAME 18 + +/* server to client */ +#define SSH_FXP_VERSION 2 +#define SSH_FXP_STATUS 101 +#define SSH_FXP_HANDLE 102 +#define SSH_FXP_DATA 103 +#define SSH_FXP_NAME 104 +#define SSH_FXP_ATTRS 105 + +/* portable open modes */ +#define SSH_FXF_READ 0x01 +#define SSH_FXF_WRITE 0x02 +#define SSH_FXF_APPEND 0x04 +#define SSH_FXF_CREAT 0x08 +#define SSH_FXF_TRUNC 0x10 +#define SSH_FXF_EXCL 0x20 + +/* attributes */ +#define SSH_FXA_HAVE_SIZE 0x01 +#define SSH_FXA_HAVE_UGID 0x02 +#define SSH_FXA_HAVE_PERM 0x04 +#define SSH_FXA_HAVE_TIME 0x08 + +/* status messages */ +#define SSH_FX_OK 0x00 +#define SSH_FX_EOF 0x01 +#define SSH_FX_NO_SUCH_FILE 0x02 +#define SSH_FX_PERMISSION_DENIED 0x03 +#define SSH_FX_FAILURE 0x04 +#define SSH_FX_BAD_MESSAGE 0x05 +#define SSH_FX_NO_CONNECTION 0x06 +#define SSH_FX_CONNECTION_LOST 0x07 + + +/* helper */ +#define get_int() buffer_get_int(&iqueue); +#define get_string(lenp) buffer_get_string(&iqueue, lenp); +#define TRACE log + +/* input and output queue */ +Buffer iqueue; +Buffer oqueue; + +/* portable attibutes, etc. */ + +typedef struct Attrib Attrib; +typedef struct Stat Stat; + +struct Attrib +{ + u_int32_t flags; + u_int32_t size_high; + u_int32_t size_low; + u_int64_t size; + u_int32_t uid; + u_int32_t gid; + u_int32_t perm; + u_int32_t atime; + u_int32_t mtime; +}; + +struct Stat +{ + char *name; + char *long_name; + Attrib attrib; +}; + +int +errno_to_portable(int unixerrno) +{ + int ret = 0; + switch (unixerrno) { + case 0: + ret = SSH_FX_OK; + break; + case ENOENT: + case ENOTDIR: + case EBADF: + case ELOOP: + ret = SSH_FX_NO_SUCH_FILE; + break; + case EPERM: + case EACCES: + case EFAULT: + ret = SSH_FX_PERMISSION_DENIED; + break; + case ENAMETOOLONG: + case EINVAL: + ret = SSH_FX_BAD_MESSAGE; + break; + default: + ret = SSH_FX_FAILURE; + break; + } + return ret; +} + +int +flags_from_portable(int pflags) +{ + int flags = 0; + if (pflags & SSH_FXF_READ && + pflags & SSH_FXF_WRITE) { + flags = O_RDWR; + } else if (pflags & SSH_FXF_READ) { + flags = O_RDONLY; + } else if (pflags & SSH_FXF_WRITE) { + flags = O_WRONLY; + } + if (pflags & SSH_FXF_CREAT) + flags |= O_CREAT; + if (pflags & SSH_FXF_TRUNC) + flags |= O_TRUNC; + if (pflags & SSH_FXF_EXCL) + flags |= O_EXCL; + return flags; +} + +void +attrib_clear(Attrib *a) +{ + a->flags = 0; + a->size_low = 0; + a->size_high = 0; + a->size = 0; + a->uid = 0; + a->gid = 0; + a->perm = 0; + a->atime = 0; + a->mtime = 0; +} + +Attrib * +decode_attrib(Buffer *b) +{ + static Attrib a; + attrib_clear(&a); + a.flags = buffer_get_int(b); + if (a.flags & SSH_FXA_HAVE_SIZE) { + a.size_high = buffer_get_int(b); + a.size_low = buffer_get_int(b); + a.size = (((u_int64_t) a.size_high) << 32) + a.size_low; + } + if (a.flags & SSH_FXA_HAVE_UGID) { + a.uid = buffer_get_int(b); + a.gid = buffer_get_int(b); + } + if (a.flags & SSH_FXA_HAVE_PERM) { + a.perm = buffer_get_int(b); + } + if (a.flags & SSH_FXA_HAVE_TIME) { + a.atime = buffer_get_int(b); + a.mtime = buffer_get_int(b); + } + return &a; +} + +void +encode_attrib(Buffer *b, Attrib *a) +{ + buffer_put_int(b, a->flags); + if (a->flags & SSH_FXA_HAVE_SIZE) { + buffer_put_int(b, a->size_high); + buffer_put_int(b, a->size_low); + } + if (a->flags & SSH_FXA_HAVE_UGID) { + buffer_put_int(b, a->uid); + buffer_put_int(b, a->gid); + } + if (a->flags & SSH_FXA_HAVE_PERM) { + buffer_put_int(b, a->perm); + } + if (a->flags & SSH_FXA_HAVE_TIME) { + buffer_put_int(b, a->atime); + buffer_put_int(b, a->mtime); + } +} + +Attrib * +stat_to_attrib(struct stat *st) +{ + static Attrib a; + attrib_clear(&a); + a.flags = 0; + a.flags |= SSH_FXA_HAVE_SIZE; + a.size = st->st_size; + a.size_low = a.size; + a.size_high = (u_int32_t) (a.size >> 32); + a.flags |= SSH_FXA_HAVE_UGID; + a.uid = st->st_uid; + a.gid = st->st_gid; + a.flags |= SSH_FXA_HAVE_PERM; + a.perm = st->st_mode; + a.flags |= SSH_FXA_HAVE_TIME; + a.atime = st->st_atime; + a.mtime = st->st_mtime; + return &a; +} + +Attrib * +get_attrib(void) +{ + return decode_attrib(&iqueue); +} + +/* handle handles */ + +typedef struct Handle Handle; +struct Handle { + int use; + DIR *dirp; + int fd; + char *name; +}; +enum { + HANDLE_UNUSED, + HANDLE_DIR, + HANDLE_FILE +}; +Handle handles[100]; + +void +handle_init(void) +{ + int i; + for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) + handles[i].use = HANDLE_UNUSED; +} + +int +handle_new(int use, char *name, int fd, DIR *dirp) +{ + int i; + for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) { + if (handles[i].use == HANDLE_UNUSED) { + handles[i].use = use; + handles[i].dirp = dirp; + handles[i].fd = fd; + handles[i].name = name; + return i; + } + } + return -1; +} + +int +handle_is_ok(int i, int type) +{ + return i >= 0 && i < sizeof(handles)/sizeof(Handle) && handles[i].use == type; +} + +int +handle_to_string(int handle, char **stringp, int *hlenp) +{ + char buf[1024]; + if (stringp == NULL || hlenp == NULL) + return -1; + snprintf(buf, sizeof buf, "%d", handle); + *stringp = xstrdup(buf); + *hlenp = strlen(*stringp); + return 0; +} + +int +handle_from_string(char *handle, u_int hlen) +{ +/* XXX OVERFLOW ? */ + char *ep; + long lval = strtol(handle, &ep, 10); + int val = lval; + if (*ep != '\0') + return -1; + if (handle_is_ok(val, HANDLE_FILE) || + handle_is_ok(val, HANDLE_DIR)) + return val; + return -1; +} + +char * +handle_to_name(int handle) +{ + if (handle_is_ok(handle, HANDLE_DIR)|| + handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].name; + return NULL; +} + +DIR * +handle_to_dir(int handle) +{ + if (handle_is_ok(handle, HANDLE_DIR)) + return handles[handle].dirp; + return NULL; +} + +int +handle_to_fd(int handle) +{ + if (handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].fd; + return -1; +} + +int +handle_close(int handle) +{ + int ret = -1; + if (handle_is_ok(handle, HANDLE_FILE)) { + ret = close(handles[handle].fd); + handles[handle].use = HANDLE_UNUSED; + } else if (handle_is_ok(handle, HANDLE_DIR)) { + ret = closedir(handles[handle].dirp); + handles[handle].use = HANDLE_UNUSED; + } else { + errno = ENOENT; + } + return ret; +} + +int +get_handle(void) +{ + char *handle; + int val; + u_int hlen; + handle = get_string(&hlen); + val = handle_from_string(handle, hlen); + xfree(handle); + return val; +} + +/* send replies */ + +void +send_msg(Buffer *m) +{ + int mlen = buffer_len(m); + buffer_put_int(&oqueue, mlen); + buffer_append(&oqueue, buffer_ptr(m), mlen); + buffer_consume(m, mlen); +} + +void +send_status(u_int32_t id, u_int32_t error) +{ + Buffer msg; + TRACE("sent status id %d error %d", id, error); + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_STATUS); + buffer_put_int(&msg, id); + buffer_put_int(&msg, error); + send_msg(&msg); + buffer_free(&msg); +} +void +send_data_or_handle(char type, u_int32_t id, char *data, int dlen) +{ + Buffer msg; + buffer_init(&msg); + buffer_put_char(&msg, type); + buffer_put_int(&msg, id); + buffer_put_string(&msg, data, dlen); + send_msg(&msg); + buffer_free(&msg); +} + +void +send_data(u_int32_t id, char *data, int dlen) +{ + TRACE("sent data id %d len %d", id, dlen); + send_data_or_handle(SSH_FXP_DATA, id, data, dlen); +} + +void +send_handle(u_int32_t id, int handle) +{ + char *string; + int hlen; + handle_to_string(handle, &string, &hlen); + TRACE("sent handle id %d handle %d", id, handle); + send_data_or_handle(SSH_FXP_HANDLE, id, string, hlen); + xfree(string); +} + +void +send_names(u_int32_t id, int count, Stat *stats) +{ + Buffer msg; + int i; + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_NAME); + buffer_put_int(&msg, id); + buffer_put_int(&msg, count); + TRACE("sent names id %d count %d", id, count); + for (i = 0; i < count; i++) { + buffer_put_cstring(&msg, stats[i].name); + buffer_put_cstring(&msg, stats[i].long_name); + encode_attrib(&msg, &stats[i].attrib); + } + send_msg(&msg); + buffer_free(&msg); +} + +void +send_attrib(u_int32_t id, Attrib *a) +{ + Buffer msg; + TRACE("sent attrib id %d have 0x%x", id, a->flags); + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_ATTRS); + buffer_put_int(&msg, id); + encode_attrib(&msg, a); + send_msg(&msg); + buffer_free(&msg); +} + +/* parse incoming */ + +void +process_init(void) +{ + Buffer msg; + int version = buffer_get_int(&iqueue); + + TRACE("client version %d", version); + buffer_init(&msg); + buffer_put_char(&msg, SSH_FXP_VERSION); + buffer_put_int(&msg, SSH_FILEXFER_VERSION); + send_msg(&msg); + buffer_free(&msg); +} + +void +process_open(void) +{ + u_int32_t id, pflags; + Attrib *a; + char *name; + int handle, fd, flags, mode, status = SSH_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + pflags = get_int(); + a = get_attrib(); + flags = flags_from_portable(pflags); + mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm : 0666; + TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode); + fd = open(name, flags, mode); + if (fd < 0) { + status = errno_to_portable(errno); + } else { + handle = handle_new(HANDLE_FILE, xstrdup(name), fd, NULL); + if (handle < 0) { + close(fd); + } else { + send_handle(id, handle); + status = SSH_FX_OK; + } + } + if (status != SSH_FX_OK) + send_status(id, status); + xfree(name); +} + +void +process_close(void) +{ + u_int32_t id; + int handle, ret, status = SSH_FX_FAILURE; + + id = get_int(); + handle = get_handle(); + TRACE("close id %d handle %d", id, handle); + ret = handle_close(handle); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); +} + +void +process_read(void) +{ + char buf[64*1024]; + u_int32_t id, off_high, off_low, len; + int handle, fd, ret, status = SSH_FX_FAILURE; + u_int64_t off; + + id = get_int(); + handle = get_handle(); + off_high = get_int(); + off_low = get_int(); + len = get_int(); + + off = (((u_int64_t) off_high) << 32) + off_low; + TRACE("read id %d handle %d off %qd len %d", id, handle, off, len); + if (len > sizeof buf) { + len = sizeof buf; + log("read change len %d", len); + } + fd = handle_to_fd(handle); + if (fd >= 0) { + if (lseek(fd, off, SEEK_SET) < 0) { + error("process_read: seek failed"); + status = errno_to_portable(errno); + } else { + ret = read(fd, buf, len); + if (ret < 0) { + status = errno_to_portable(errno); + } else if (ret == 0) { + status = SSH_FX_EOF; + } else { + send_data(id, buf, ret); + status = SSH_FX_OK; + } + } + } + if (status != SSH_FX_OK) + send_status(id, status); +} + +void +process_write(void) +{ + u_int32_t id, off_high, off_low; + u_int64_t off; + u_int len; + int handle, fd, ret, status = SSH_FX_FAILURE; + char *data; + + id = get_int(); + handle = get_handle(); + off_high = get_int(); + off_low = get_int(); + data = get_string(&len); + + off = (((u_int64_t) off_high) << 32) + off_low; + TRACE("write id %d handle %d off %qd len %d", id, handle, off, len); + fd = handle_to_fd(handle); + if (fd >= 0) { + if (lseek(fd, off, SEEK_SET) < 0) { + status = errno_to_portable(errno); + error("process_write: seek failed"); + } else { +/* XXX ATOMICIO ? */ + ret = write(fd, data, len); + if (ret == -1) { + error("process_write: write failed"); + status = errno_to_portable(errno); + } else if (ret == len) { + status = SSH_FX_OK; + } else { + log("nothing at all written"); + } + } + } + send_status(id, status); + xfree(data); +} + +void +process_do_stat(int do_lstat) +{ + Attrib *a; + struct stat st; + u_int32_t id; + char *name; + int ret, status = SSH_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + TRACE("%sstat id %d name %s", do_lstat ? "l" : "", id, name); + ret = do_lstat ? lstat(name, &st) : stat(name, &st); + if (ret < 0) { + status = errno_to_portable(errno); + } else { + a = stat_to_attrib(&st); + send_attrib(id, a); + status = SSH_FX_OK; + } + if (status != SSH_FX_OK) + send_status(id, status); + xfree(name); +} + +void +process_stat(void) +{ + process_do_stat(0); +} + +void +process_lstat(void) +{ + process_do_stat(1); +} + +void +process_fstat(void) +{ + Attrib *a; + struct stat st; + u_int32_t id; + int fd, ret, handle, status = SSH_FX_FAILURE; + + id = get_int(); + handle = get_handle(); + TRACE("fstat id %d handle %d", id, handle); + fd = handle_to_fd(handle); + if (fd >= 0) { + ret = fstat(fd, &st); + if (ret < 0) { + status = errno_to_portable(errno); + } else { + a = stat_to_attrib(&st); + send_attrib(id, a); + status = SSH_FX_OK; + } + } + if (status != SSH_FX_OK) + send_status(id, status); +} + +struct timeval * +attrib_to_tv(Attrib *a) +{ + static struct timeval tv[2]; + tv[0].tv_sec = a->atime; + tv[0].tv_usec = 0; + tv[1].tv_sec = a->mtime; + tv[1].tv_usec = 0; + return tv; +} + +void +process_setstat(void) +{ + Attrib *a; + u_int32_t id; + char *name; + int ret; + int status = SSH_FX_OK; + + id = get_int(); + name = get_string(NULL); + a = get_attrib(); + TRACE("setstat id %d name %s", id, name); + if (a->flags & SSH_FXA_HAVE_PERM) { + ret = chmod(name, a->perm & 0777); + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH_FXA_HAVE_TIME) { + ret = utimes(name, attrib_to_tv(a)); + if (ret == -1) + status = errno_to_portable(errno); + } + send_status(id, status); + xfree(name); +} + +void +process_fsetstat(void) +{ + Attrib *a; + u_int32_t id; + int handle, fd, ret; + int status = SSH_FX_OK; + + id = get_int(); + handle = get_handle(); + a = get_attrib(); + TRACE("fsetstat id %d handle %d", id, handle); + fd = handle_to_fd(handle); + if (fd < 0) { + status = SSH_FX_FAILURE; + } else { + if (a->flags & SSH_FXA_HAVE_PERM) { + ret = fchmod(fd, a->perm & 0777); + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH_FXA_HAVE_TIME) { + ret = futimes(fd, attrib_to_tv(a)); + if (ret == -1) + status = errno_to_portable(errno); + } + } + send_status(id, status); +} + +void +process_opendir(void) +{ + DIR *dirp = NULL; + char *path; + int handle, status = SSH_FX_FAILURE; + u_int32_t id; + + id = get_int(); + path = get_string(NULL); + TRACE("opendir id %d path %s", id, path); + dirp = opendir(path); + if (dirp == NULL) { + status = errno_to_portable(errno); + } else { + handle = handle_new(HANDLE_DIR, xstrdup(path), 0, dirp); + if (handle < 0) { + closedir(dirp); + } else { + send_handle(id, handle); + status = SSH_FX_OK; + } + + } + if (status != SSH_FX_OK) + send_status(id, status); + xfree(path); +} + +char * +ls_file(char *name, struct stat *st) +{ + char buf[1024]; + snprintf(buf, sizeof buf, "0%o %d %d %qd %d %s", + st->st_mode, st->st_uid, st->st_gid, (long long)st->st_size,(int) st->st_mtime, + name); + return xstrdup(buf); +} + +void +process_readdir(void) +{ + DIR *dirp; + struct dirent *dp; + char *path; + int handle; + u_int32_t id; + + id = get_int(); + handle = get_handle(); + TRACE("readdir id %d handle %d", id, handle); + dirp = handle_to_dir(handle); + path = handle_to_name(handle); + if (dirp == NULL || path == NULL) { + send_status(id, SSH_FX_FAILURE); + } else { + Attrib *a; + struct stat st; + char pathname[1024]; + Stat *stats; + int nstats = 10, count = 0, i; + stats = xmalloc(nstats * sizeof(Stat)); + while ((dp = readdir(dirp)) != NULL) { + if (count >= nstats) { + nstats *= 2; + stats = xrealloc(stats, nstats * sizeof(Stat)); + } +/* XXX OVERFLOW ? */ + snprintf(pathname, sizeof pathname, + "%s/%s", path, dp->d_name); + if (lstat(pathname, &st) < 0) + continue; + a = stat_to_attrib(&st); + stats[count].attrib = *a; + stats[count].name = xstrdup(dp->d_name); + stats[count].long_name = ls_file(dp->d_name, &st); + count++; + /* send up to 100 entries in one message */ + if (count == 100) + break; + } + send_names(id, count, stats); + for(i = 0; i < count; i++) { + xfree(stats[i].name); + xfree(stats[i].long_name); + } + xfree(stats); + } +} + +void +process_remove(void) +{ + char *name; + u_int32_t id; + int status = SSH_FX_FAILURE; + int ret; + + id = get_int(); + name = get_string(NULL); + TRACE("remove id %d name %s", id, name); + ret = remove(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_mkdir(void) +{ + Attrib *a; + u_int32_t id; + char *name; + int ret, mode, status = SSH_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + a = get_attrib(); + mode = (a->flags & SSH_FXA_HAVE_PERM) ? a->perm & 0777 : 0777; + TRACE("mkdir id %d name %s mode 0%o", id, name, mode); + ret = mkdir(name, mode); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_rmdir(void) +{ + u_int32_t id; + char *name; + int ret, status; + + id = get_int(); + name = get_string(NULL); + TRACE("rmdir id %d name %s", id, name); + ret = rmdir(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_realpath(void) +{ + char resolvedname[MAXPATHLEN]; + u_int32_t id; + char *path; + + id = get_int(); + path = get_string(NULL); + TRACE("realpath id %d path %s", id, path); + if (realpath(path, resolvedname) == NULL) { + send_status(id, errno_to_portable(errno)); + } else { + Stat s; + attrib_clear(&s.attrib); + s.name = s.long_name = resolvedname; + send_names(id, 1, &s); + } + xfree(path); +} + +void +process_rename(void) +{ + u_int32_t id; + char *oldpath, *newpath; + int ret, status; + + id = get_int(); + oldpath = get_string(NULL); + newpath = get_string(NULL); + TRACE("rename id %d old %s new %s", id, oldpath, newpath); + ret = rename(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH_FX_OK; + send_status(id, status); + xfree(oldpath); + xfree(newpath); +} + + +/* stolen from ssh-agent */ + +void +process(void) +{ + unsigned int msg_len; + unsigned int type; + unsigned char *cp; + + if (buffer_len(&iqueue) < 5) + return; /* Incomplete message. */ + cp = (unsigned char *) buffer_ptr(&iqueue); + msg_len = GET_32BIT(cp); + if (msg_len > 256 * 1024) { + error("bad message "); + exit(11); + } + if (buffer_len(&iqueue) < msg_len + 4) + return; + buffer_consume(&iqueue, 4); + type = buffer_get_char(&iqueue); + switch (type) { + case SSH_FXP_INIT: + process_init(); + break; + case SSH_FXP_OPEN: + process_open(); + break; + case SSH_FXP_CLOSE: + process_close(); + break; + case SSH_FXP_READ: + process_read(); + break; + case SSH_FXP_WRITE: + process_write(); + break; + case SSH_FXP_LSTAT: + process_lstat(); + break; + case SSH_FXP_FSTAT: + process_fstat(); + break; + case SSH_FXP_SETSTAT: + process_setstat(); + break; + case SSH_FXP_FSETSTAT: + process_fsetstat(); + break; + case SSH_FXP_OPENDIR: + process_opendir(); + break; + case SSH_FXP_READDIR: + process_readdir(); + break; + case SSH_FXP_REMOVE: + process_remove(); + break; + case SSH_FXP_MKDIR: + process_mkdir(); + break; + case SSH_FXP_RMDIR: + process_rmdir(); + break; + case SSH_FXP_REALPATH: + process_realpath(); + break; + case SSH_FXP_STAT: + process_stat(); + break; + case SSH_FXP_RENAME: + process_rename(); + break; + default: + error("Unknown message %d", type); + break; + } +} + +int +main(int ac, char **av) +{ + fd_set rset, wset; + int in, out, max; + ssize_t len, olen; + + handle_init(); + + in = dup(STDIN_FILENO); + out = dup(STDOUT_FILENO); + + max = 0; + if (in > max) + max = in; + if (out > max) + max = out; + + buffer_init(&iqueue); + buffer_init(&oqueue); + + for (;;) { + FD_ZERO(&rset); + FD_ZERO(&wset); + + FD_SET(in, &rset); + olen = buffer_len(&oqueue); + if (olen > 0) + FD_SET(out, &wset); + + if (select(max+1, &rset, &wset, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + exit(2); + } + + /* copy stdin to iqueue */ + if (FD_ISSET(in, &rset)) { + char buf[4*4096]; + len = read(in, buf, sizeof buf); + if (len == 0) { + debug("read eof"); + exit(0); + } else if (len < 0) { + error("read error"); + exit(1); + } else { + buffer_append(&iqueue, buf, len); + } + } + /* send oqueue to stdout */ + if (FD_ISSET(out, &wset)) { + len = write(out, buffer_ptr(&oqueue), olen); + if (len < 0) { + error("write error"); + exit(1); + } else { + buffer_consume(&oqueue, len); + } + } + /* process requests from client */ + process(); + } +} diff --git a/crypto/openssh/sftp-server/Makefile b/crypto/openssh/sftp-server/Makefile new file mode 100644 index 000000000000..1999fec31aa1 --- /dev/null +++ b/crypto/openssh/sftp-server/Makefile @@ -0,0 +1,16 @@ +.PATH: ${.CURDIR}/.. + +PROG= sftp-server +BINOWN= root + +BINMODE?=555 + +BINDIR= /usr/libexec +MAN= sftp-server.8 + +SRCS= sftp-server.c log-server.c + +.include <bsd.prog.mk> + +LDADD+= -lcrypto # -lutil -lz +DPADD+= ${LIBCRYPTO} # ${LIBDES} ${LIBUTIL} ${LIBZ} diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1 index 10363956f8b9..d453fa22cb4f 100644 --- a/crypto/openssh/ssh-add.1 +++ b/crypto/openssh/ssh-add.1 @@ -1,29 +1,53 @@ .\" -*- nroff -*- .\" -.\" ssh-add.1 -.\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" All rights reserved .\" -.\" Created: Sat Apr 22 23:55:14 1995 ylo +.\" As far as I am concerned, the code I have written for this software +.\" can be used freely for any purpose. Any derived versions of this +.\" software must be clearly marked as such, and if the derived work is +.\" incompatible with the protocol description in the RFC file, it must be +.\" called by a name other than "ssh" or "Secure Shell". +.\" +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. .\" -.\" $Id: ssh-add.1,v 1.13 2000/05/03 18:04:38 markus Exp $ +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd September 25, 1999 .Dt SSH-ADD 1 .Os .Sh NAME .Nm ssh-add -.Nd adds RSA identities for the authentication agent +.Nd adds RSA or DSA identities for the authentication agent .Sh SYNOPSIS .Nm ssh-add .Op Fl lLdD .Op Ar .Sh DESCRIPTION .Nm -adds RSA identities to the authentication agent, +adds RSA or DSA identities to the authentication agent, .Xr ssh-agent 1 . When run without arguments, it adds the file .Pa $HOME/.ssh/identity . @@ -63,7 +87,9 @@ used to encrypt the private part of this file. This is the default file added by .Nm when no other files have been specified. -.Pp +.It Pa $HOME/.ssh/id_dsa +Contains the DSA authentication identity of the user. +.El .Sh ENVIRONMENT .Bl -tag -width Ds .It Ev "DISPLAY" and "SSH_ASKPASS" @@ -89,6 +115,7 @@ or related script. may be necessary to redirect the input from .Pa /dev/null to make this work.) +.El .Sh AUTHOR Tatu Ylonen <ylo@cs.hut.fi> .Pp @@ -115,10 +142,6 @@ authentication and ticket passing. supports one-time password authentication with .Xr skey 1 . .El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-agent 1 , diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c index b7a385c171d4..4b33f965447f 100644 --- a/crypto/openssh/ssh-add.c +++ b/crypto/openssh/ssh-add.c @@ -2,22 +2,50 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Thu Apr 6 00:52:24 1995 ylo * Adds an identity to the authentication server, or removes an identity. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: ssh-add.c,v 1.16 2000/04/26 20:56:29 markus Exp $"); +RCSID("$OpenBSD: ssh-add.c,v 1.22 2000/09/07 20:27:54 deraadt Exp $"); +#include <openssl/evp.h> #include <openssl/rsa.h> #include <openssl/dsa.h> #include "rsa.h" #include "ssh.h" #include "xmalloc.h" -#include "authfd.h" -#include "fingerprint.h" #include "key.h" +#include "authfd.h" #include "authfile.h" void @@ -28,10 +56,14 @@ delete_file(AuthenticationConnection *ac, const char *filename) public = key_new(KEY_RSA); if (!load_public_key(filename, public, &comment)) { - printf("Bad key file %s: %s\n", filename, strerror(errno)); - return; + key_free(public); + public = key_new(KEY_DSA); + if (!try_load_public_key(filename, public, &comment)) { + printf("Bad key file %s\n", filename); + return; + } } - if (ssh_remove_identity(ac, public->rsa)) + if (ssh_remove_identity(ac, public)) fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); else fprintf(stderr, "Could not remove identity: %s\n", filename); @@ -39,11 +71,18 @@ delete_file(AuthenticationConnection *ac, const char *filename) xfree(comment); } +/* Send a request to remove all identities. */ void delete_all(AuthenticationConnection *ac) { - /* Send a request to remove all identities. */ - if (ssh_remove_all_identities(ac)) + int success = 1; + + if (!ssh_remove_all_identities(ac, 1)) + success = 0; + /* ignore error-code for ssh2 */ + ssh_remove_all_identities(ac, 2); + + if (success) fprintf(stderr, "All identities removed.\n"); else fprintf(stderr, "Failed to remove all identitities.\n"); @@ -90,17 +129,28 @@ ssh_askpass(char *askpass, char *msg) void add_file(AuthenticationConnection *ac, const char *filename) { + struct stat st; Key *public; Key *private; char *saved_comment, *comment, *askpass = NULL; char buf[1024], msg[1024]; int success; int interactive = isatty(STDIN_FILENO); + int type = KEY_RSA; + if (stat(filename, &st) < 0) { + perror(filename); + exit(1); + } + /* + * try to load the public key. right now this only works for RSA, + * since DSA keys are fully encrypted + */ public = key_new(KEY_RSA); if (!load_public_key(filename, public, &saved_comment)) { - printf("Bad key file %s: %s\n", filename, strerror(errno)); - return; + /* ok, so we will asume this is a DSA key */ + type = KEY_DSA; + saved_comment = xstrdup(filename); } key_free(public); @@ -112,7 +162,7 @@ add_file(AuthenticationConnection *ac, const char *filename) } /* At first, try empty passphrase */ - private = key_new(KEY_RSA); + private = key_new(type); success = load_private_key(filename, "", private, &comment); if (!success) { printf("Need passphrase for %.200s\n", filename); @@ -142,54 +192,40 @@ add_file(AuthenticationConnection *ac, const char *filename) strlcpy(msg, "Bad passphrase, try again", sizeof msg); } } - xfree(saved_comment); - - if (ssh_add_identity(ac, private->rsa, comment)) - fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); + xfree(comment); + if (ssh_add_identity(ac, private, saved_comment)) + fprintf(stderr, "Identity added: %s (%s)\n", filename, saved_comment); else fprintf(stderr, "Could not add identity: %s\n", filename); key_free(private); - xfree(comment); + xfree(saved_comment); } void list_identities(AuthenticationConnection *ac, int fp) { - BIGNUM *e, *n; - int status; + Key *key; char *comment; - int had_identities; + int had_identities = 0; + int version; - e = BN_new(); - n = BN_new(); - had_identities = 0; - for (status = ssh_get_first_identity(ac, e, n, &comment); - status; - status = ssh_get_next_identity(ac, e, n, &comment)) { - unsigned int bits = BN_num_bits(n); - had_identities = 1; - if (fp) { - printf("%d %s %s\n", bits, fingerprint(e, n), comment); - } else { - char *ebuf, *nbuf; - ebuf = BN_bn2dec(e); - if (ebuf == NULL) { - error("list_identities: BN_bn2dec(e) failed."); + for (version = 1; version <= 2; version++) { + for (key = ssh_get_first_identity(ac, &comment, version); + key != NULL; + key = ssh_get_next_identity(ac, &comment, version)) { + had_identities = 1; + if (fp) { + printf("%d %s %s\n", + key_size(key), key_fingerprint(key), comment); } else { - nbuf = BN_bn2dec(n); - if (nbuf == NULL) { - error("list_identities: BN_bn2dec(n) failed."); - } else { - printf("%d %s %s %s\n", bits, ebuf, nbuf, comment); - free(nbuf); - } - free(ebuf); + if (!key_write(key, stdout)) + fprintf(stderr, "key_write failed"); + fprintf(stdout, " %s\n", comment); } + key_free(key); + xfree(comment); } - xfree(comment); } - BN_clear_free(e); - BN_clear_free(n); if (!had_identities) printf("The agent has no identities.\n"); } @@ -213,6 +249,8 @@ main(int argc, char **argv) __progname); exit(1); } + SSLeay_add_all_algorithms(); + /* At first, get a connection to the authentication agent. */ ac = ssh_get_authentication_connection(); if (ac == NULL) { @@ -245,7 +283,8 @@ main(int argc, char **argv) if (no_files) { pw = getpwuid(getuid()); if (!pw) { - fprintf(stderr, "No user found with uid %d\n", (int) getuid()); + fprintf(stderr, "No user found with uid %u\n", + (u_int)getuid()); ssh_close_authentication_connection(ac); exit(1); } diff --git a/crypto/openssh/ssh-add/Makefile b/crypto/openssh/ssh-add/Makefile index 5451e7d31b97..d6dd17528c54 100644 --- a/crypto/openssh/ssh-add/Makefile +++ b/crypto/openssh/ssh-add/Makefile @@ -3,12 +3,7 @@ PROG= ssh-add BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif BINDIR= /usr/bin MAN= ssh-add.1 diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1 index 9f7299d3719e..23c699d5e4b9 100644 --- a/crypto/openssh/ssh-agent.1 +++ b/crypto/openssh/ssh-agent.1 @@ -1,15 +1,38 @@ -.\" $OpenBSD: ssh-agent.1,v 1.12 2000/05/03 18:04:39 markus Exp $ -.\" -.\" -*- nroff -*- -.\" -.\" ssh-agent.1 +.\" $OpenBSD: ssh-agent.1,v 1.16 2000/09/07 20:27:54 deraadt Exp $ .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" All rights reserved .\" -.\" Created: Sat Apr 23 20:10:43 1995 ylo +.\" As far as I am concerned, the code I have written for this software +.\" can be used freely for any purpose. Any derived versions of this +.\" software must be clearly marked as such, and if the derived work is +.\" incompatible with the protocol description in the RFC file, it must be +.\" called by a name other than "ssh" or "Secure Shell". +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd September 25, 1999 .Dt SSH-AGENT 1 @@ -27,14 +50,15 @@ .Oc .Sh DESCRIPTION .Nm -is a program to hold private keys used for RSA authentication. +is a program to hold private keys used for public key authentication +(RSA, DSA). The idea is that .Nm is started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the ssh-agent program. Through use of environment variables the agent can be located -and automatically used for RSA authentication when logging in to other +and automatically used for authentication when logging in to other machines using .Xr ssh 1 . .Pp @@ -128,11 +152,14 @@ This file is not used by but is normally added to the agent using .Xr ssh-add 1 at login time. -.It Pa /tmp/ssh-XXXX/agent.<pid> , +.It Pa $HOME/.ssh/id_dsa +Contains the DSA authentication identity of the user. +.Pq Pa /tmp/ssh-XXXXXXXX/agent.<pid> , Unix-domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. +.El .Sh AUTHOR Tatu Ylonen <ylo@cs.hut.fi> .Pp @@ -159,10 +186,6 @@ authentication and ticket passing. supports one-time password authentication with .Xr skey 1 . .El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c index 18f1315fc4dd..5b178681f84f 100644 --- a/crypto/openssh/ssh-agent.c +++ b/crypto/openssh/ssh-agent.c @@ -1,19 +1,46 @@ -/* $OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.35 2000/09/07 20:27:54 deraadt Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Wed Mar 29 03:46:59 1995 ylo * The authentication agent program. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.35 2000/09/07 20:27:54 deraadt Exp $"); #include "ssh.h" #include "rsa.h" -#include "authfd.h" #include "buffer.h" #include "bufaux.h" #include "xmalloc.h" @@ -21,7 +48,14 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $"); #include "getput.h" #include "mpaux.h" +#include <openssl/evp.h> #include <openssl/md5.h> +#include <openssl/dsa.h> +#include <openssl/rsa.h> +#include "key.h" +#include "authfd.h" +#include "dsa.h" +#include "kex.h" typedef struct { int fd; @@ -36,12 +70,17 @@ unsigned int sockets_alloc = 0; SocketEntry *sockets = NULL; typedef struct { - RSA *key; + Key *key; char *comment; } Identity; -unsigned int num_identities = 0; -Identity *identities = NULL; +typedef struct { + int nentries; + Identity *identities; +} Idtab; + +/* private key table, one per protocol version */ +Idtab idtable[3]; int max_fd = 0; @@ -55,175 +94,244 @@ char socket_dir[1024]; extern char *__progname; void -process_request_identity(SocketEntry *e) +idtab_init(void) +{ + int i; + for (i = 0; i <=2; i++){ + idtable[i].identities = NULL; + idtable[i].nentries = 0; + } +} + +/* return private key table for requested protocol version */ +Idtab * +idtab_lookup(int version) +{ + if (version < 1 || version > 2) + fatal("internal error, bad protocol version %d", version); + return &idtable[version]; +} + +/* return matching private key for given public key */ +Key * +lookup_private_key(Key *key, int *idx, int version) +{ + int i; + Idtab *tab = idtab_lookup(version); + for (i = 0; i < tab->nentries; i++) { + if (key_equal(key, tab->identities[i].key)) { + if (idx != NULL) + *idx = i; + return tab->identities[i].key; + } + } + return NULL; +} + +/* send list of supported public keys to 'client' */ +void +process_request_identities(SocketEntry *e, int version) { + Idtab *tab = idtab_lookup(version); Buffer msg; int i; buffer_init(&msg); - buffer_put_char(&msg, SSH_AGENT_RSA_IDENTITIES_ANSWER); - buffer_put_int(&msg, num_identities); - for (i = 0; i < num_identities; i++) { - buffer_put_int(&msg, BN_num_bits(identities[i].key->n)); - buffer_put_bignum(&msg, identities[i].key->e); - buffer_put_bignum(&msg, identities[i].key->n); - buffer_put_string(&msg, identities[i].comment, - strlen(identities[i].comment)); + buffer_put_char(&msg, (version == 1) ? + SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); + buffer_put_int(&msg, tab->nentries); + for (i = 0; i < tab->nentries; i++) { + Identity *id = &tab->identities[i]; + if (id->key->type == KEY_RSA) { + buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); + buffer_put_bignum(&msg, id->key->rsa->e); + buffer_put_bignum(&msg, id->key->rsa->n); + } else { + unsigned char *blob; + unsigned int blen; + dsa_make_key_blob(id->key, &blob, &blen); + buffer_put_string(&msg, blob, blen); + xfree(blob); + } + buffer_put_cstring(&msg, id->comment); } buffer_put_int(&e->output, buffer_len(&msg)); buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); buffer_free(&msg); } +/* ssh1 only */ void -process_authentication_challenge(SocketEntry *e) +process_authentication_challenge1(SocketEntry *e) { - int i, pub_bits, len; - BIGNUM *pub_e, *pub_n, *challenge; + Key *key, *private; + BIGNUM *challenge; + int i, len; Buffer msg; MD5_CTX md; unsigned char buf[32], mdbuf[16], session_id[16]; unsigned int response_type; buffer_init(&msg); - pub_e = BN_new(); - pub_n = BN_new(); + key = key_new(KEY_RSA); challenge = BN_new(); - pub_bits = buffer_get_int(&e->input); - buffer_get_bignum(&e->input, pub_e); - buffer_get_bignum(&e->input, pub_n); - buffer_get_bignum(&e->input, challenge); - if (buffer_len(&e->input) == 0) { - /* Compatibility code for old servers. */ - memset(session_id, 0, 16); - response_type = 0; - } else { - /* New code. */ - buffer_get(&e->input, (char *) session_id, 16); - response_type = buffer_get_int(&e->input); - } - for (i = 0; i < num_identities; i++) - if (pub_bits == BN_num_bits(identities[i].key->n) && - BN_cmp(pub_e, identities[i].key->e) == 0 && - BN_cmp(pub_n, identities[i].key->n) == 0) { - /* Decrypt the challenge using the private key. */ - rsa_private_decrypt(challenge, challenge, identities[i].key); - - /* Compute the desired response. */ - switch (response_type) { - case 0:/* As of protocol 1.0 */ - /* This response type is no longer supported. */ - log("Compatibility with ssh protocol 1.0 no longer supported."); - buffer_put_char(&msg, SSH_AGENT_FAILURE); - goto send; - - case 1:/* As of protocol 1.1 */ - /* The response is MD5 of decrypted challenge plus session id. */ - len = BN_num_bytes(challenge); - - if (len <= 0 || len > 32) { - fatal("process_authentication_challenge: " - "bad challenge length %d", len); - } - memset(buf, 0, 32); - BN_bn2bin(challenge, buf + 32 - len); - MD5_Init(&md); - MD5_Update(&md, buf, 32); - MD5_Update(&md, session_id, 16); - MD5_Final(mdbuf, &md); - break; - - default: - fatal("process_authentication_challenge: bad response_type %d", - response_type); - break; - } - /* Send the response. */ - buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); - for (i = 0; i < 16; i++) - buffer_put_char(&msg, mdbuf[i]); + buffer_get_int(&e->input); /* ignored */ + buffer_get_bignum(&e->input, key->rsa->e); + buffer_get_bignum(&e->input, key->rsa->n); + buffer_get_bignum(&e->input, challenge); - goto send; + /* Only protocol 1.1 is supported */ + if (buffer_len(&e->input) == 0) + goto failure; + buffer_get(&e->input, (char *) session_id, 16); + response_type = buffer_get_int(&e->input); + if (response_type != 1) + goto failure; + + private = lookup_private_key(key, NULL, 1); + if (private != NULL) { + /* Decrypt the challenge using the private key. */ + rsa_private_decrypt(challenge, challenge, private->rsa); + + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > 32) { + log("process_authentication_challenge: bad challenge length %d", len); + goto failure; } - /* Unknown identity. Send failure. */ + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + + /* Send the response. */ + buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); + for (i = 0; i < 16; i++) + buffer_put_char(&msg, mdbuf[i]); + goto send; + } + +failure: + /* Unknown identity or protocol error. Send failure. */ buffer_put_char(&msg, SSH_AGENT_FAILURE); send: buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); + key_free(key); + BN_clear_free(challenge); + buffer_free(&msg); +} + +/* ssh2 only */ +void +process_sign_request2(SocketEntry *e) +{ + extern int datafellows; + Key *key, *private; + unsigned char *blob, *data, *signature = NULL; + unsigned int blen, dlen, slen = 0; + Buffer msg; + int ok = -1; + + datafellows = 0; + + blob = buffer_get_string(&e->input, &blen); + data = buffer_get_string(&e->input, &dlen); + buffer_get_int(&e->input); /* flags, unused */ + + key = dsa_key_from_blob(blob, blen); + if (key != NULL) { + private = lookup_private_key(key, NULL, 2); + if (private != NULL) + ok = dsa_sign(private, &signature, &slen, data, dlen); + } + key_free(key); + buffer_init(&msg); + if (ok == 0) { + buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); + buffer_put_string(&msg, signature, slen); + } else { + buffer_put_char(&msg, SSH_AGENT_FAILURE); + } + buffer_put_int(&e->output, buffer_len(&msg)); buffer_append(&e->output, buffer_ptr(&msg), - buffer_len(&msg)); + buffer_len(&msg)); buffer_free(&msg); - BN_clear_free(pub_e); - BN_clear_free(pub_n); - BN_clear_free(challenge); + xfree(data); + xfree(blob); + if (signature != NULL) + xfree(signature); } +/* shared */ void -process_remove_identity(SocketEntry *e) +process_remove_identity(SocketEntry *e, int version) { + Key *key = NULL, *private; + unsigned char *blob; + unsigned int blen; unsigned int bits; - unsigned int i; - BIGNUM *dummy, *n; - - dummy = BN_new(); - n = BN_new(); - - /* Get the key from the packet. */ - bits = buffer_get_int(&e->input); - buffer_get_bignum(&e->input, dummy); - buffer_get_bignum(&e->input, n); - - if (bits != BN_num_bits(n)) - log("Warning: identity keysize mismatch: actual %d, announced %d", - BN_num_bits(n), bits); - - /* Check if we have the key. */ - for (i = 0; i < num_identities; i++) - if (BN_cmp(identities[i].key->n, n) == 0) { + int success = 0; + + switch(version){ + case 1: + key = key_new(KEY_RSA); + bits = buffer_get_int(&e->input); + buffer_get_bignum(&e->input, key->rsa->e); + buffer_get_bignum(&e->input, key->rsa->n); + + if (bits != key_size(key)) + log("Warning: identity keysize mismatch: actual %d, announced %d", + key_size(key), bits); + break; + case 2: + blob = buffer_get_string(&e->input, &blen); + key = dsa_key_from_blob(blob, blen); + xfree(blob); + break; + } + if (key != NULL) { + int idx; + private = lookup_private_key(key, &idx, version); + if (private != NULL) { /* * We have this key. Free the old key. Since we * don\'t want to leave empty slots in the middle of * the array, we actually free the key there and copy * data from the last entry. */ - RSA_free(identities[i].key); - xfree(identities[i].comment); - if (i < num_identities - 1) - identities[i] = identities[num_identities - 1]; - num_identities--; - BN_clear_free(dummy); - BN_clear_free(n); - - /* Send success. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); - return; + Idtab *tab = idtab_lookup(version); + key_free(tab->identities[idx].key); + xfree(tab->identities[idx].comment); + if (idx != tab->nentries) + tab->identities[idx] = tab->identities[tab->nentries]; + tab->nentries--; + success = 1; } - /* We did not have the key. */ - BN_clear(dummy); - BN_clear(n); - - /* Send failure. */ + key_free(key); + } buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_FAILURE); + buffer_put_char(&e->output, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } -/* - * Removes all identities from the agent. - */ void -process_remove_all_identities(SocketEntry *e) +process_remove_all_identities(SocketEntry *e, int version) { unsigned int i; + Idtab *tab = idtab_lookup(version); /* Loop over all identities and clear the keys. */ - for (i = 0; i < num_identities; i++) { - RSA_free(identities[i].key); - xfree(identities[i].comment); + for (i = 0; i < tab->nentries; i++) { + key_free(tab->identities[i].key); + xfree(tab->identities[i].comment); } /* Mark that there are no identities. */ - num_identities = 0; + tab->nentries = 0; /* Send success. */ buffer_put_int(&e->output, 1); @@ -231,79 +339,108 @@ process_remove_all_identities(SocketEntry *e) return; } -/* - * Adds an identity to the agent. - */ void -process_add_identity(SocketEntry *e) +process_add_identity(SocketEntry *e, int version) { - RSA *k; - int i; + Key *k = NULL; + RSA *rsa; BIGNUM *aux; BN_CTX *ctx; + char *type; + char *comment; + int success = 0; + Idtab *tab = idtab_lookup(version); - if (num_identities == 0) - identities = xmalloc(sizeof(Identity)); - else - identities = xrealloc(identities, (num_identities + 1) * sizeof(Identity)); - - identities[num_identities].key = RSA_new(); - k = identities[num_identities].key; - buffer_get_int(&e->input); /* bits */ - k->n = BN_new(); - buffer_get_bignum(&e->input, k->n); - k->e = BN_new(); - buffer_get_bignum(&e->input, k->e); - k->d = BN_new(); - buffer_get_bignum(&e->input, k->d); - k->iqmp = BN_new(); - buffer_get_bignum(&e->input, k->iqmp); - /* SSH and SSL have p and q swapped */ - k->q = BN_new(); - buffer_get_bignum(&e->input, k->q); /* p */ - k->p = BN_new(); - buffer_get_bignum(&e->input, k->p); /* q */ - - /* Generate additional parameters */ - aux = BN_new(); - ctx = BN_CTX_new(); - - BN_sub(aux, k->q, BN_value_one()); - k->dmq1 = BN_new(); - BN_mod(k->dmq1, k->d, aux, ctx); - - BN_sub(aux, k->p, BN_value_one()); - k->dmp1 = BN_new(); - BN_mod(k->dmp1, k->d, aux, ctx); - - BN_clear_free(aux); - BN_CTX_free(ctx); - - identities[num_identities].comment = buffer_get_string(&e->input, NULL); - - /* Check if we already have the key. */ - for (i = 0; i < num_identities; i++) - if (BN_cmp(identities[i].key->n, k->n) == 0) { - /* - * We already have this key. Clear and free the new - * data and return success. - */ - RSA_free(k); - xfree(identities[num_identities].comment); + switch (version) { + case 1: + k = key_new(KEY_RSA); + rsa = k->rsa; - /* Send success. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); - return; + /* allocate mem for private key */ + /* XXX rsa->n and rsa->e are already allocated */ + rsa->d = BN_new(); + rsa->iqmp = BN_new(); + rsa->q = BN_new(); + rsa->p = BN_new(); + rsa->dmq1 = BN_new(); + rsa->dmp1 = BN_new(); + + buffer_get_int(&e->input); /* ignored */ + + buffer_get_bignum(&e->input, rsa->n); + buffer_get_bignum(&e->input, rsa->e); + buffer_get_bignum(&e->input, rsa->d); + buffer_get_bignum(&e->input, rsa->iqmp); + + /* SSH and SSL have p and q swapped */ + buffer_get_bignum(&e->input, rsa->q); /* p */ + buffer_get_bignum(&e->input, rsa->p); /* q */ + + /* Generate additional parameters */ + aux = BN_new(); + ctx = BN_CTX_new(); + + BN_sub(aux, rsa->q, BN_value_one()); + BN_mod(rsa->dmq1, rsa->d, aux, ctx); + + BN_sub(aux, rsa->p, BN_value_one()); + BN_mod(rsa->dmp1, rsa->d, aux, ctx); + + BN_clear_free(aux); + BN_CTX_free(ctx); + + break; + case 2: + type = buffer_get_string(&e->input, NULL); + if (strcmp(type, KEX_DSS)) { + buffer_clear(&e->input); + xfree(type); + goto send; } - /* Increment the number of identities. */ - num_identities++; + xfree(type); + + k = key_new(KEY_DSA); + + /* allocate mem for private key */ + k->dsa->priv_key = BN_new(); + + buffer_get_bignum2(&e->input, k->dsa->p); + buffer_get_bignum2(&e->input, k->dsa->q); + buffer_get_bignum2(&e->input, k->dsa->g); + buffer_get_bignum2(&e->input, k->dsa->pub_key); + buffer_get_bignum2(&e->input, k->dsa->priv_key); + + break; + } - /* Send a success message. */ + comment = buffer_get_string(&e->input, NULL); + if (k == NULL) { + xfree(comment); + goto send; + } + success = 1; + if (lookup_private_key(k, NULL, version) == NULL) { + if (tab->nentries == 0) + tab->identities = xmalloc(sizeof(Identity)); + else + tab->identities = xrealloc(tab->identities, + (tab->nentries + 1) * sizeof(Identity)); + tab->identities[tab->nentries].key = k; + tab->identities[tab->nentries].comment = comment; + /* Increment the number of identities. */ + tab->nentries++; + } else { + key_free(k); + xfree(comment); + } +send: buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + buffer_put_char(&e->output, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } +/* dispatch incoming messages */ + void process_message(SocketEntry *e) { @@ -326,20 +463,37 @@ process_message(SocketEntry *e) type = buffer_get_char(&e->input); switch (type) { - case SSH_AGENTC_REQUEST_RSA_IDENTITIES: - process_request_identity(e); - break; + /* ssh1 */ case SSH_AGENTC_RSA_CHALLENGE: - process_authentication_challenge(e); + process_authentication_challenge1(e); + break; + case SSH_AGENTC_REQUEST_RSA_IDENTITIES: + process_request_identities(e, 1); break; case SSH_AGENTC_ADD_RSA_IDENTITY: - process_add_identity(e); + process_add_identity(e, 1); break; case SSH_AGENTC_REMOVE_RSA_IDENTITY: - process_remove_identity(e); + process_remove_identity(e, 1); break; case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: - process_remove_all_identities(e); + process_remove_all_identities(e, 1); + break; + /* ssh2 */ + case SSH2_AGENTC_SIGN_REQUEST: + process_sign_request2(e); + break; + case SSH2_AGENTC_REQUEST_IDENTITIES: + process_request_identities(e, 2); + break; + case SSH2_AGENTC_ADD_IDENTITY: + process_add_identity(e, 2); + break; + case SSH2_AGENTC_REMOVE_IDENTITY: + process_remove_identity(e, 2); + break; + case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: + process_remove_all_identities(e, 2); break; default: /* Unknown message. Respond with failure. */ @@ -640,6 +794,7 @@ main(int ac, char **av) signal(SIGALRM, check_parent_exists); alarm(10); } + idtab_init(); signal(SIGINT, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, cleanup_exit); diff --git a/crypto/openssh/ssh-agent/Makefile b/crypto/openssh/ssh-agent/Makefile index ba78521f5cdc..9301aef67e06 100644 --- a/crypto/openssh/ssh-agent/Makefile +++ b/crypto/openssh/ssh-agent/Makefile @@ -3,12 +3,7 @@ PROG= ssh-agent BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif BINDIR= /usr/bin MAN= ssh-agent.1 diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1 index ea81532e9879..b328ce0c65bb 100644 --- a/crypto/openssh/ssh-keygen.1 +++ b/crypto/openssh/ssh-keygen.1 @@ -1,15 +1,39 @@ .\" -*- nroff -*- .\" -.\" ssh-keygen.1 -.\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" All rights reserved .\" -.\" Created: Sat Apr 22 23:55:14 1995 ylo +.\" As far as I am concerned, the code I have written for this software +.\" can be used freely for any purpose. Any derived versions of this +.\" software must be clearly marked as such, and if the derived work is +.\" incompatible with the protocol description in the RFC file, it must be +.\" called by a name other than "ssh" or "Secure Shell". +.\" +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" -.\" $Id: ssh-keygen.1,v 1.18 2000/05/08 17:26:04 hugh Exp $ +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd September 25, 1999 .Dt SSH-KEYGEN 1 @@ -23,7 +47,7 @@ .Op Fl b Ar bits .Op Fl N Ar new_passphrase .Op Fl C Ar comment -.Op Fl f Ar keyfile +.Op Fl f Ar output_keyfile .Nm ssh-keygen .Fl p .Op Fl P Ar old_passphrase @@ -31,13 +55,13 @@ .Op Fl f Ar keyfile .Nm ssh-keygen .Fl x -.Op Fl f Ar keyfile +.Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl X -.Op Fl f Ar keyfile +.Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl y -.Op Fl f Ar keyfile +.Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl c .Op Fl P Ar passphrase @@ -45,7 +69,7 @@ .Op Fl f Ar keyfile .Nm ssh-keygen .Fl l -.Op Fl f Ar keyfile +.Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl R .Sh DESCRIPTION @@ -188,6 +212,7 @@ The contents of this file should be added to on all machines where you wish to log in using DSA authentication. There is no need to keep the contents of this file secret. +.El .Sh AUTHOR Tatu Ylonen <ylo@cs.hut.fi> .Pp @@ -214,10 +239,6 @@ authentication and ticket passing. supports one-time password authentication with .Xr skey 1 . .El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c index 874acfe92d63..29ee62df5cf2 100644 --- a/crypto/openssh/ssh-keygen.c +++ b/crypto/openssh/ssh-keygen.c @@ -2,12 +2,17 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Mon Mar 27 02:26:40 1995 ylo * Identity and host key generation and maintenance. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: ssh-keygen.c,v 1.26 2000/05/30 17:32:06 markus Exp $"); +RCSID("$OpenBSD: ssh-keygen.c,v 1.31 2000/09/07 20:27:54 deraadt Exp $"); #include <openssl/evp.h> #include <openssl/pem.h> @@ -16,7 +21,6 @@ RCSID("$Id: ssh-keygen.c,v 1.26 2000/05/30 17:32:06 markus Exp $"); #include "ssh.h" #include "xmalloc.h" -#include "fingerprint.h" #include "key.h" #include "rsa.h" #include "dsa.h" @@ -123,13 +127,13 @@ do_convert_to_ssh2(struct passwd *pw) exit(1); } dsa_make_key_blob(k, &blob, &len); - fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n"); + fprintf(stdout, "%s\n", SSH_COM_MAGIC_BEGIN); fprintf(stdout, "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", BN_num_bits(k->dsa->p), pw->pw_name, hostname); dump_base64(stdout, blob, len); - fprintf(stdout, SSH_COM_MAGIC_END "\n"); + fprintf(stdout, "%s\n", SSH_COM_MAGIC_END); key_free(k); xfree(blob); exit(0); @@ -224,8 +228,9 @@ do_print_public(struct passwd *pw) void do_fingerprint(struct passwd *pw) { + /* XXX RSA1 only */ + FILE *f; - BIGNUM *e, *n; Key *public; char *comment = NULL, *cp, *ep, line[16*1024]; int i, skip = 0, num = 1, invalid = 1; @@ -245,13 +250,9 @@ do_fingerprint(struct passwd *pw) key_free(public); exit(0); } - key_free(public); - /* XXX */ f = fopen(identity_file, "r"); if (f != NULL) { - n = BN_new(); - e = BN_new(); while (fgets(line, sizeof(line), f)) { i = strlen(line) - 1; if (line[i] != '\n') { @@ -286,18 +287,17 @@ do_fingerprint(struct passwd *pw) *cp++ = '\0'; } ep = cp; - if (auth_rsa_read_key(&cp, &ignore, e, n)) { + if (auth_rsa_read_key(&cp, &ignore, public->rsa->e, public->rsa->n)) { invalid = 0; comment = *cp ? cp : comment; - printf("%d %s %s\n", BN_num_bits(n), - fingerprint(e, n), + printf("%d %s %s\n", key_size(public), + key_fingerprint(public), comment ? comment : "no comment"); } } - BN_free(e); - BN_free(n); fclose(f); } + key_free(public); if (invalid) { printf("%s is not a valid key file.\n", identity_file); exit(1); @@ -654,7 +654,7 @@ main(int ac, char **av) snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR); if (strstr(identity_file, dotsshdir) != NULL && stat(dotsshdir, &st) < 0) { - if (mkdir(dotsshdir, 0755) < 0) + if (mkdir(dotsshdir, 0700) < 0) error("Could not create directory '%s'.", dotsshdir); else if (!quiet) printf("Created directory '%s'.\n", dotsshdir); diff --git a/crypto/openssh/ssh-keygen/Makefile b/crypto/openssh/ssh-keygen/Makefile index 1f9205919b51..f03f56bf0d60 100644 --- a/crypto/openssh/ssh-keygen/Makefile +++ b/crypto/openssh/ssh-keygen/Makefile @@ -3,12 +3,7 @@ PROG= ssh-keygen BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif BINDIR= /usr/bin MAN= ssh-keygen.1 diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1 index d069ce18184f..78a1bd7d54e6 100644 --- a/crypto/openssh/ssh.1 +++ b/crypto/openssh/ssh.1 @@ -1,15 +1,38 @@ .\" -*- nroff -*- .\" -.\" ssh.1.in -.\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" All rights reserved .\" -.\" Created: Sat Apr 22 21:55:14 1995 ylo +.\" As far as I am concerned, the code I have written for this software +.\" can be used freely for any purpose. Any derived versions of this +.\" software must be clearly marked as such, and if the derived work is +.\" incompatible with the protocol description in the RFC file, it must be +.\" called by a name other than "ssh" or "Secure Shell". +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" -.\" $Id: ssh.1,v 1.54 2000/05/29 20:20:46 markus Exp $ +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd September 25, 1999 .Dt SSH 1 @@ -940,6 +963,13 @@ The argument must be .Dq yes or .Dq no . +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . +.El .Sh ENVIRONMENT .Nm will normally set the following environment variables: @@ -988,7 +1018,7 @@ If the current session has no tty, this variable is not set. .It Ev TZ The timezone variable is set to indicate the present timezone if it -was set when the daemon was started (e.i., the daemon passes the value +was set when the daemon was started (i.e., the daemon passes the value on to new connections). .It Ev USER Set to the name of the user logging in. @@ -1183,6 +1213,7 @@ above. .It Pa libcrypto.so.X.1 A version of this library which includes support for the RSA algorithm is required for proper operation. +.El .Sh AUTHOR OpenSSH is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, @@ -1211,10 +1242,6 @@ supports one-time password authentication with .Xr skey 1 . .El .Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. -.Pp OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song. .Pp diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index f343b41a7b66..4c4b83632e55 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -2,16 +2,44 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Sat Mar 18 16:36:11 1995 ylo * Ssh client program. This program can be used to log into a remote machine. * The software supports strong authentication, encryption, and forwarding * of X11, TCP/IP, and authentication connections. * - * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> in Canada. + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * Copyright (c) 1999 Niels Provos. All rights reserved. + * + * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> + * in Canada (German citizen). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$Id: ssh.c,v 1.54 2000/05/30 17:32:06 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.65 2000/09/07 20:40:30 markus Exp $"); #include <openssl/evp.h> #include <openssl/dsa.h> @@ -21,7 +49,6 @@ RCSID("$Id: ssh.c,v 1.54 2000/05/30 17:32:06 markus Exp $"); #include "ssh.h" #include "packet.h" #include "buffer.h" -#include "authfd.h" #include "readconf.h" #include "uidswap.h" @@ -29,6 +56,7 @@ RCSID("$Id: ssh.c,v 1.54 2000/05/30 17:32:06 markus Exp $"); #include "compat.h" #include "channels.h" #include "key.h" +#include "authfd.h" #include "authfile.h" extern char *__progname; @@ -243,8 +271,8 @@ main(int ac, char **av) cp = strrchr(av0, '/') + 1; else cp = av0; - if (strcmp(cp, "rsh") != 0 && strcmp(cp, "ssh") != 0 && - strcmp(cp, "rlogin") != 0 && strcmp(cp, "slogin") != 0) + if (strcmp(cp, "rsh") && strcmp(cp, "ssh") && strcmp(cp, "rlogin") && + strcmp(cp, "slogin") && strcmp(cp, "remsh")) host = cp; for (optind = 1; optind < ac; optind++) { @@ -451,7 +479,7 @@ main(int ac, char **av) } /* Cannot fork to background if no command. */ - if (fork_after_authentication_flag && buffer_len(&command) == 0) + if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) fatal("Cannot fork into background without a command to execute."); /* Allocate a tty by default if no command specified. */ @@ -480,6 +508,7 @@ main(int ac, char **av) pwcopy.pw_passwd = xstrdup(pw->pw_passwd); pwcopy.pw_uid = pw->pw_uid; pwcopy.pw_gid = pw->pw_gid; + pwcopy.pw_class = xstrdup(pw->pw_class); pwcopy.pw_dir = xstrdup(pw->pw_dir); pwcopy.pw_shell = xstrdup(pw->pw_shell); pw = &pwcopy; @@ -612,7 +641,7 @@ main(int ac, char **av) */ snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_DIR); if (stat(buf, &st) < 0) - if (mkdir(buf, 0755) < 0) + if (mkdir(buf, 0700) < 0) error("Could not create directory '%.200s'.", buf); /* Check if the connection failed, and try "rsh" if appropriate. */ @@ -669,17 +698,17 @@ x11_get_proto(char *proto, int proto_len, char *data, int data_len) FILE *f; int got_data = 0, i; -#ifdef XAUTH_PATH - /* Try to get Xauthority information for the display. */ - snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null", - XAUTH_PATH, getenv("DISPLAY")); - f = popen(line, "r"); - if (f && fgets(line, sizeof(line), f) && - sscanf(line, "%*s %s %s", proto, data) == 2) - got_data = 1; - if (f) - pclose(f); -#endif /* XAUTH_PATH */ + if (options.xauth_location) { + /* Try to get Xauthority information for the display. */ + snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null", + options.xauth_location, getenv("DISPLAY")); + f = popen(line, "r"); + if (f && fgets(line, sizeof(line), f) && + sscanf(line, "%*s %s %s", proto, data) == 2) + got_data = 1; + if (f) + pclose(f); + } /* * If we didn't get authentication data, just make up some * data. The forwarding code will check the validity of the @@ -861,7 +890,7 @@ ssh_session(void) } /* Enter the interactive session. */ - return client_loop(have_tty, tty_flag ? options.escape_char : -1); + return client_loop(have_tty, tty_flag ? options.escape_char : -1, 0); } void @@ -944,31 +973,40 @@ int ssh_session2(void) { int window, packetmax, id; - int in = dup(STDIN_FILENO); - int out = dup(STDOUT_FILENO); - int err = dup(STDERR_FILENO); + int in, out, err; + + if (stdin_null_flag) { + in = open("/dev/null", O_RDONLY); + } else { + in = dup(STDIN_FILENO); + } + out = dup(STDOUT_FILENO); + err = dup(STDERR_FILENO); if (in < 0 || out < 0 || err < 0) - fatal("dump in/out/err failed"); + fatal("dup() in/out/err failed"); /* should be pre-session */ init_local_fwd(); - window = 32*1024; - if (tty_flag) { - packetmax = window/8; - } else { + /* If requested, let ssh continue in the background. */ + if (fork_after_authentication_flag) + if (daemon(1, 1) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + window = CHAN_SES_WINDOW_DEFAULT; + packetmax = CHAN_SES_PACKET_DEFAULT; + if (!tty_flag) { window *= 2; - packetmax = window/2; + packetmax *=2; } - id = channel_new( "session", SSH_CHANNEL_OPENING, in, out, err, - window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session")); - + window, packetmax, CHAN_EXTENDED_WRITE, + xstrdup("client-session")); channel_open(id); channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); - return client_loop(tty_flag, tty_flag ? options.escape_char : -1); + return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); } diff --git a/crypto/openssh/ssh.h b/crypto/openssh/ssh.h index 8f6d1e7d1d9f..f48012f46d88 100644 --- a/crypto/openssh/ssh.h +++ b/crypto/openssh/ssh.h @@ -1,19 +1,18 @@ /* - * - * ssh.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Fri Mar 17 17:09:37 1995 ylo - * * Generic header file for ssh. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: ssh.h,v 1.46 2000/05/17 08:20:15 markus Exp $"); */ +/* RCSID("$OpenBSD: ssh.h,v 1.50 2000/09/07 20:27:54 deraadt Exp $"); */ #ifndef SSH_H #define SSH_H @@ -450,6 +449,9 @@ char *tilde_expand_filename(const char *filename, uid_t my_uid); /* remove newline at end of string */ char *chop(char *s); +/* return next token in configuration line */ +char *strdelim(char **s); + /* set filedescriptor to non-blocking */ void set_nonblock(int fd); @@ -464,7 +466,7 @@ void server_loop(pid_t pid, int fdin, int fdout, int fderr); void server_loop2(void); /* Client side main loop for the interactive session. */ -int client_loop(int have_pty, int escape_char); +int client_loop(int have_pty, int escape_char, int id); /* Linked list of custom environment strings (see auth-rsa.c). */ struct envstring { diff --git a/crypto/openssh/ssh/Makefile b/crypto/openssh/ssh/Makefile index a87d5dce0a44..bd415312cdd7 100644 --- a/crypto/openssh/ssh/Makefile +++ b/crypto/openssh/ssh/Makefile @@ -3,12 +3,7 @@ PROG= ssh BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=4555 -.endif BINDIR= /usr/bin MAN= ssh.1 @@ -20,11 +15,11 @@ SRCS= ssh.c log-client.c readconf.c clientloop.c \ .include <bsd.own.mk> # for AFS -.if (${KERBEROS} == "yes") +.if (${KERBEROS:L} == "yes") CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV LDADD+= -lkrb DPADD+= ${LIBKRB} -.if (${AFS} == "yes") +.if (${AFS:L} == "yes") CFLAGS+= -DAFS LDADD+= -lkafs DPADD+= ${LIBKRBAFS} diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h index 1fa4c0a0ddae..47628ddd4ba2 100644 --- a/crypto/openssh/ssh2.h +++ b/crypto/openssh/ssh2.h @@ -1,4 +1,28 @@ /* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * draft-ietf-secsh-architecture-05.txt * * Transport layer protocol: @@ -28,7 +52,7 @@ * * 192-255 Local extensions */ -/* RCSID("$OpenBSD: ssh2.h,v 1.3 2000/05/15 07:03:12 markus Exp $"); */ +/* RCSID("$OpenBSD: ssh2.h,v 1.4 2000/09/07 20:27:54 deraadt Exp $"); */ /* transport layer: generic */ diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config index 6ecb0efde3f8..cb360d04b597 100644 --- a/crypto/openssh/ssh_config +++ b/crypto/openssh/ssh_config @@ -19,7 +19,7 @@ # RhostsRSAAuthentication yes # RSAAuthentication yes # PasswordAuthentication yes -# FallBackToRsh yes +# FallBackToRsh no # UseRsh no # BatchMode no # CheckHostIP yes diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index 2e54651ea9b6..22fa9dc5fdc9 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -2,13 +2,18 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Sat Mar 18 22:15:47 1995 ylo * Code to connect to a remote host, and to perform the client side of the * login (authentication) dialog. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.74 2000/05/17 16:57:02 markus Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.78 2000/09/07 20:27:54 deraadt Exp $"); #include <openssl/bn.h> #include <openssl/dsa.h> @@ -189,8 +194,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, int gaierr; struct linger linger; - debug("ssh_connect: getuid %d geteuid %d anon %d", - (int) getuid(), (int) geteuid(), anonymous); + debug("ssh_connect: getuid %u geteuid %u anon %d", + (u_int) getuid(), (u_int) geteuid(), anonymous); /* Get default port if port has not been set. */ if (port == 0) { @@ -310,23 +315,28 @@ ssh_exchange_identification() int connection_out = packet_get_connection_out(); /* Read other side\'s version identification. */ - for (i = 0; i < sizeof(buf) - 1; i++) { - int len = read(connection_in, &buf[i], 1); - if (len < 0) - fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); - if (len != 1) - fatal("ssh_exchange_identification: Connection closed by remote host"); - if (buf[i] == '\r') { - buf[i] = '\n'; - buf[i + 1] = 0; - continue; /**XXX wait for \n */ + for (;;) { + for (i = 0; i < sizeof(buf) - 1; i++) { + int len = atomicio(read, connection_in, &buf[i], 1); + if (len < 0) + fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); + if (len != 1) + fatal("ssh_exchange_identification: Connection closed by remote host"); + if (buf[i] == '\r') { + buf[i] = '\n'; + buf[i + 1] = 0; + continue; /**XXX wait for \n */ + } + if (buf[i] == '\n') { + buf[i + 1] = 0; + break; + } } - if (buf[i] == '\n') { - buf[i + 1] = 0; + buf[sizeof(buf) - 1] = 0; + if (strncmp(buf, "SSH-", 4) == 0) break; - } + debug("ssh_exchange_identification: %s", buf); } - buf[sizeof(buf) - 1] = 0; server_version_string = xstrdup(buf); /* @@ -656,7 +666,7 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, /* Get local user name. Use it as server user if no user name was given. */ pw = getpwuid(original_real_uid); if (!pw) - fatal("User id %d not found from user database.", original_real_uid); + fatal("User id %u not found from user database.", original_real_uid); local_user = xstrdup(pw->pw_name); server_user = options.user ? options.user : local_user; diff --git a/crypto/openssh/sshconnect.h b/crypto/openssh/sshconnect.h index 13d395fd634d..146a65baf276 100644 --- a/crypto/openssh/sshconnect.h +++ b/crypto/openssh/sshconnect.h @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef SSHCONNECT_H #define SSHCONNECT_H diff --git a/crypto/openssh/sshconnect1.c b/crypto/openssh/sshconnect1.c index 4360d7283d86..2bb4d5387d10 100644 --- a/crypto/openssh/sshconnect1.c +++ b/crypto/openssh/sshconnect1.c @@ -2,14 +2,18 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Sat Mar 18 22:15:47 1995 ylo * Code to connect to a remote host, and to perform the client side of the * login (authentication) dialog. * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.6 2000/09/07 20:27:54 deraadt Exp $"); #include <openssl/bn.h> #include <openssl/dsa.h> @@ -21,12 +25,12 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $"); #include "ssh.h" #include "buffer.h" #include "packet.h" -#include "authfd.h" #include "cipher.h" #include "mpaux.h" #include "uidswap.h" #include "readconf.h" #include "key.h" +#include "authfd.h" #include "sshconnect.h" #include "authfile.h" @@ -44,27 +48,27 @@ extern char *__progname; int try_agent_authentication() { - int status, type; + int type; char *comment; AuthenticationConnection *auth; unsigned char response[16]; unsigned int i; - BIGNUM *e, *n, *challenge; + int plen, clen; + Key *key; + BIGNUM *challenge; /* Get connection to the agent. */ auth = ssh_get_authentication_connection(); if (!auth) return 0; - e = BN_new(); - n = BN_new(); challenge = BN_new(); + key = key_new(KEY_RSA); /* Loop through identities served by the agent. */ - for (status = ssh_get_first_identity(auth, e, n, &comment); - status; - status = ssh_get_next_identity(auth, e, n, &comment)) { - int plen, clen; + for (key = ssh_get_first_identity(auth, &comment, 1); + key != NULL; + key = ssh_get_next_identity(auth, &comment, 1)) { /* Try this identity. */ debug("Trying RSA authentication via agent with '%.100s'", comment); @@ -72,7 +76,7 @@ try_agent_authentication() /* Tell the server that we are willing to authenticate using this key. */ packet_start(SSH_CMSG_AUTH_RSA); - packet_put_bignum(n); + packet_put_bignum(key->rsa->n); packet_send(); packet_write_wait(); @@ -83,6 +87,7 @@ try_agent_authentication() does not support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); + key_free(key); continue; } /* Otherwise it should have sent a challenge. */ @@ -97,13 +102,16 @@ try_agent_authentication() debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ - if (!ssh_decrypt_challenge(auth, e, n, challenge, - session_id, 1, response)) { - /* The agent failed to authenticate this identifier although it - advertised it supports this. Just return a wrong value. */ + if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) { + /* + * The agent failed to authenticate this identifier + * although it advertised it supports this. Just + * return a wrong value. + */ log("Authentication agent failed to decrypt challenge."); memset(response, 0, sizeof(response)); } + key_free(key); debug("Sending response to RSA challenge."); /* Send the decrypted challenge back to the server. */ @@ -118,10 +126,8 @@ try_agent_authentication() /* The server returns success if it accepted the authentication. */ if (type == SSH_SMSG_SUCCESS) { - debug("RSA authentication accepted by server."); - BN_clear_free(e); - BN_clear_free(n); BN_clear_free(challenge); + debug("RSA authentication accepted by server."); return 1; } /* Otherwise it should return failure. */ @@ -129,11 +135,7 @@ try_agent_authentication() packet_disconnect("Protocol error waiting RSA auth response: %d", type); } - - BN_clear_free(e); - BN_clear_free(n); BN_clear_free(challenge); - debug("RSA authentication using agent refused."); return 0; } diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index 0abcf89a0a07..d225359d03d2 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/openssh/sshconnect2.c @@ -9,11 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.18 2000/09/07 20:27:55 deraadt Exp $"); #include <openssl/bn.h> #include <openssl/rsa.h> @@ -54,6 +49,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $"); #include "dsa.h" #include "sshconnect.h" #include "authfile.h" +#include "authfd.h" /* import */ extern char *client_version_string; @@ -71,7 +67,6 @@ void ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, Buffer *client_kexinit, Buffer *server_kexinit) { - int i; int plen, dlen; unsigned int klen, kout; char *signature = NULL; @@ -265,9 +260,12 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service) char prompt[80]; char *password; - if (attempt++ > options.number_of_password_prompts) + if (attempt++ >= options.number_of_password_prompts) return 0; + if(attempt != 1) + error("Permission denied, please try again."); + snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", server_user, host); password = read_passphrase(prompt, 0); @@ -284,42 +282,32 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service) return 1; } +typedef int sign_fn( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen); + int -ssh2_try_pubkey(char *filename, +ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign, const char *server_user, const char *host, const char *service) { Buffer b; - Key *k; unsigned char *blob, *signature; int bloblen, slen; - struct stat st; - - if (stat(filename, &st) != 0) { - debug("key does not exist: %s", filename); - return 0; - } - debug("try pubkey: %s", filename); + int skip = 0; + int ret = -1; - k = key_new(KEY_DSA); - if (!load_private_key(filename, "", k, NULL)) { - int success = 0; - char *passphrase; - char prompt[300]; - snprintf(prompt, sizeof prompt, - "Enter passphrase for DSA key '%.100s': ", - filename); - passphrase = read_passphrase(prompt, 0); - success = load_private_key(filename, passphrase, k, NULL); - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - if (!success) - return 0; - } dsa_make_key_blob(k, &blob, &bloblen); /* data to be signed */ buffer_init(&b); - buffer_append(&b, session_id2, session_id2_len); + if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) { + buffer_put_string(&b, session_id2, session_id2_len); + skip = buffer_len(&b); + } else { + buffer_append(&b, session_id2, session_id2_len); + skip = session_id2_len; + } buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, server_user); buffer_put_cstring(&b, @@ -332,13 +320,16 @@ ssh2_try_pubkey(char *filename, buffer_put_string(&b, blob, bloblen); /* generate signature */ - dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); - key_free(k); + ret = do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); + if (ret == -1) { + xfree(blob); + buffer_free(&b); + return 0; + } #ifdef DEBUG_DSS buffer_dump(&b); #endif if (datafellows & SSH_BUG_PUBKEYAUTH) { - /* e.g. ssh-2.0.13: data-to-be-signed != data-on-the-wire */ buffer_clear(&b); buffer_append(&b, session_id2, session_id2_len); buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); @@ -355,9 +346,9 @@ ssh2_try_pubkey(char *filename, xfree(signature); /* skip session id and packet type */ - if (buffer_len(&b) < session_id2_len + 1) + if (buffer_len(&b) < skip + 1) fatal("ssh2_try_pubkey: internal error"); - buffer_consume(&b, session_id2_len + 1); + buffer_consume(&b, skip + 1); /* put remaining data from buffer into packet */ packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -367,12 +358,88 @@ ssh2_try_pubkey(char *filename, /* send */ packet_send(); packet_write_wait(); + return 1; } +int +ssh2_try_pubkey(char *filename, + const char *server_user, const char *host, const char *service) +{ + Key *k; + int ret = 0; + struct stat st; + + if (stat(filename, &st) != 0) { + debug("key does not exist: %s", filename); + return 0; + } + debug("try pubkey: %s", filename); + + k = key_new(KEY_DSA); + if (!load_private_key(filename, "", k, NULL)) { + int success = 0; + char *passphrase; + char prompt[300]; + snprintf(prompt, sizeof prompt, + "Enter passphrase for DSA key '%.100s': ", + filename); + passphrase = read_passphrase(prompt, 0); + success = load_private_key(filename, passphrase, k, NULL); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + if (!success) { + key_free(k); + return 0; + } + } + ret = ssh2_sign_and_send_pubkey(k, dsa_sign, server_user, host, service); + key_free(k); + return ret; +} + +int agent_sign( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen) +{ + int ret = -1; + AuthenticationConnection *ac = ssh_get_authentication_connection(); + if (ac != NULL) { + ret = ssh_agent_sign(ac, key, sigp, lenp, data, datalen); + ssh_close_authentication_connection(ac); + } + return ret; +} + +int +ssh2_try_agent(AuthenticationConnection *ac, + const char *server_user, const char *host, const char *service) +{ + static int called = 0; + char *comment; + Key *k; + int ret; + + if (called == 0) { + k = ssh_get_first_identity(ac, &comment, 2); + called ++; + } else { + k = ssh_get_next_identity(ac, &comment, 2); + } + if (k == NULL) + return 0; + debug("trying DSA agent key %s", comment); + xfree(comment); + ret = ssh2_sign_and_send_pubkey(k, agent_sign, server_user, host, service); + key_free(k); + return ret; +} + void ssh_userauth2(const char *server_user, char *host) { + AuthenticationConnection *ac = ssh_get_authentication_connection(); int type; int plen; int sent; @@ -427,12 +494,17 @@ ssh_userauth2(const char *server_user, char *host) debug("partial success"); if (options.dsa_authentication && strstr(auths, "publickey") != NULL) { - while (i < options.num_identity_files2) { - sent = ssh2_try_pubkey( - options.identity_files2[i++], + if (ac != NULL) + sent = ssh2_try_agent(ac, server_user, host, service); - if (sent) - break; + if (!sent) { + while (i < options.num_identity_files2) { + sent = ssh2_try_pubkey( + options.identity_files2[i++], + server_user, host, service); + if (sent) + break; + } } } if (!sent) { @@ -446,6 +518,8 @@ ssh_userauth2(const char *server_user, char *host) fatal("Permission denied (%s).", auths); xfree(auths); } + if (ac != NULL) + ssh_close_authentication_connection(ac); packet_done(); debug("ssh-userauth2 successfull"); } diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8 index 3fb255af05f4..21caf8d0240d 100644 --- a/crypto/openssh/sshd.8 +++ b/crypto/openssh/sshd.8 @@ -1,15 +1,38 @@ .\" -*- nroff -*- .\" -.\" sshd.8.in -.\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" All rights reserved .\" -.\" Created: Sat Apr 22 21:55:14 1995 ylo +.\" As far as I am concerned, the code I have written for this software +.\" can be used freely for any purpose. Any derived versions of this +.\" software must be clearly marked as such, and if the derived work is +.\" incompatible with the protocol description in the RFC file, it must be +.\" called by a name other than "ssh" or "Secure Shell". +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" -.\" $Id: sshd.8,v 1.51 2000/05/08 17:42:31 hugh Exp $ +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd September 25, 1999 .Dt SSHD 8 @@ -26,6 +49,7 @@ .Op Fl h Ar host_key_file .Op Fl k Ar key_gen_time .Op Fl p Ar port +.Op Fl u Ar len .Op Fl V Ar client_protocol_id .Sh DESCRIPTION .Nm @@ -104,7 +128,7 @@ into the machine). .Pp .Ss SSH protocol version 2 .Pp -Version 2 works similar: +Version 2 works similarly: Each host has a host-specific DSA key used to identify the host. However, when the daemon starts, it does not generate a server key. Forward security is provided through a Diffie-Hellman key agreement. @@ -211,6 +235,22 @@ Quiet mode. Nothing is sent to the system log. Normally the beginning, authentication, and termination of each connection is logged. +.It Fl u Ar len +This option is used to specify the size of the field +in the +.Li utmp +structure that holds the remote host name. +If the resolved host name is longer than +.Ar len , +the dotted decimal value will be used instead. +This allows hosts with very long host names that +overflow this field to still be uniquely identified. +Specifying +.Fl u0 +indicates that only dotted decimal addresses +should be put into the +.Pa utmp +file. .It Fl Q Do not print an error message if RSA support is missing. .It Fl V Ar client_protocol_id @@ -257,7 +297,7 @@ and .Ql ? can be used as wildcards in the patterns. -Only group names are valid, a numerical group ID isn't recognized. +Only group names are valid; a numerical group ID isn't recognized. By default login is allowed regardless of the primary group. .Pp .It Cm AllowUsers @@ -270,7 +310,7 @@ and .Ql ? can be used as wildcards in the patterns. -Only user names are valid, a numerical user ID isn't recognized. +Only user names are valid; a numerical user ID isn't recognized. By default login is allowed regardless of the user name. .Pp .It Cm Ciphers @@ -294,7 +334,7 @@ and .Ql ? can be used as wildcards in the patterns. -Only group names are valid, a numerical group ID isn't recognized. +Only group names are valid; a numerical group ID isn't recognized. By default login is allowed regardless of the primary group. .Pp .It Cm DenyUsers @@ -305,7 +345,7 @@ Login is disallowed for user names that match one of the patterns. and .Ql ? can be used as wildcards in the patterns. -Only user names are valid, a numerical user ID isn't recognized. +Only user names are valid; a numerical user ID isn't recognized. By default login is allowed regardless of the user name. .It Cm DSAAuthentication Specifies whether DSA authentication is allowed. @@ -321,7 +361,7 @@ or .Dq no . The default is .Dq no . -.It Cm HostDsaKey +.It Cm HostDSAKey Specifies the file containing the private DSA host key (default .Pa /etc/ssh_host_dsa_key ) used by SSH protocol 2.0. @@ -383,7 +423,8 @@ Specifies whether Kerberos authentication is allowed. This can be in the form of a Kerberos ticket, or if .Cm PasswordAuthentication is yes, the password provided by the user will be validated through -the Kerberos KDC. +the Kerberos KDC. To use this option, the server needs a +Kerberos servtab which allows the verification of the KDC's identity. Default is .Dq yes . .It Cm KerberosOrLocalPasswd @@ -435,11 +476,36 @@ QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. The default is INFO. Logging with level DEBUG violates the privacy of users and is not recommended. +.It Cm MaxStartups +Specifies the maximum number of concurrent unauthenticated connections to the +.Nm +daemon. +Additional connections will be dropped until authentication succeeds or the +.Cm LoginGraceTime +expires for a connection. +The default is 10. +.Pp +Alternatively, random early drop can be enabled by specifying +the three colon separated values +.Dq start:rate:full +(e.g. "10:30:60"). +.Nm +will refuse connection attempts with a probabillity of +.Dq rate/100 +(30%) +if there are currently +.Dq start +(10) +unauthenticated connections. +The probabillity increases linearly and all connection attempts +are refused if the number of unauthenticated connections reaches +.Dq full +(60). .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is .Dq yes . -Note that this option applies to both protocol version 1 and 2. +Note that this option applies to both protocol versions 1 and 2. .It Cm PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. @@ -543,6 +609,16 @@ This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. The default is .Dq yes . +.It Cm Subsystem +Configures an external subsystem (e.g. file transfer daemon). +Arguments should be a subsystem name and a command to execute upon subsystem request. +The command +.Xr sftp-server 8 +implements the +.Dq sftp +file transfer subsystem. +By default no subsystems are defined. +Note that this option applies to protocol version 2 only. .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Nm sshd . @@ -552,7 +628,10 @@ The default is AUTH. .It Cm UseLogin Specifies whether .Xr login 1 -is used. +is used for interactive login sessions. +Note that +.Xr login 1 +is never used for remote command execution. The default is .Dq no . .It Cm X11DisplayOffset @@ -569,6 +648,12 @@ The default is .Dq no . Note that disabling X11 forwarding does not improve security in any way, as users can always install their own forwarders. +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . .El .Sh LOGIN PROCESS When a user successfully logs in, @@ -644,7 +729,7 @@ You don't want to type them in; instead, copy the .Pa identity.pub file and edit it. .Pp -The options (if present) consists of comma-separated option +The options (if present) consist of comma-separated option specifications. No spaces are permitted, except within double quotes. The following option specifications are supported: @@ -718,7 +803,7 @@ and files contain host public keys for all known hosts. The global file should be prepared by the administrator (optional), and the per-user file is -maintained automatically: whenever the user connects an unknown host +maintained automatically: whenever the user connects from an unknown host its key is added to the per-user file. .Pp Each line in these files contains the following fields: hostnames, @@ -793,7 +878,7 @@ Contains the process ID of the listening for connections (if there are several daemons running concurrently for different ports, this contains the pid of the one started last). -The contents of this file are not sensitive; it can be world-readable. +The content of this file is not sensitive; it can be world-readable. .It Pa $HOME/.ssh/authorized_keys Lists the RSA keys that can be used to log into the user's account. This file must be readable by root (which may on some machines imply @@ -821,7 +906,7 @@ These files are consulted when using rhosts with RSA host authentication to check the public key of the host. The key must be listed in one of these files to be accepted. The client uses the same files -to verify that the remote host is the one we intended to connect. +to verify that the remote host is the one it intended to connect. These files should be writable only by root/the owner. .Pa /etc/ssh_known_hosts should be world-readable, and @@ -860,7 +945,7 @@ this file is exactly the same as for .Pa .rhosts . However, this file is not used by rlogin and rshd, so using this permits access using SSH only. -.Pa /etc/hosts.equiv +.It Pa /etc/hosts.equiv This file is used during .Pa .rhosts authentication. @@ -940,6 +1025,7 @@ Like This can be used to specify machine-specific login-time initializations globally. This file should be writable only by root, and should be world-readable. +.El .Sh AUTHOR OpenSSH is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, @@ -968,16 +1054,13 @@ supports one-time password authentication with .Xr skey 1 . .El .Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. -.Pp OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song. .Pp The support for SSH protocol 2 was written by Markus Friedl. .Sh SEE ALSO .Xr scp 1 , +.Xr sftp-server 8 , .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 4a1a47fc9682..e4cfe025c8bc 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -2,19 +2,45 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Fri Mar 17 17:09:28 1995 ylo - * This program is the ssh daemon. It listens for connections from clients, and - * performs authentication, executes use commands or shell, and forwards + * This program is the ssh daemon. It listens for connections from clients, + * and performs authentication, executes use commands or shell, and forwards * information to/from the application to the user client over an encrypted - * connection. This can also handle forwarding of X11, TCP/IP, and authentication - * agent connections. + * connection. This can also handle forwarding of X11, TCP/IP, and + * authentication agent connections. * - * SSH2 implementation, - * Copyright (c) 2000 Markus Friedl. All rights reserved. + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * SSH2 implementation: + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.118 2000/05/25 20:45:20 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.126 2000/09/07 20:27:55 deraadt Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -134,6 +160,9 @@ unsigned char session_id[16]; unsigned char *session_id2 = NULL; int session_id2_len = 0; +/* record remote hostname or ip */ +unsigned int utmp_len = MAXHOSTNAMELEN; + /* Prototypes for various functions defined later in this file. */ void do_ssh1_kex(); void do_ssh2_kex(); @@ -292,7 +321,7 @@ sshd_exchange_identification(int sock_in, int sock_out) /* Read other side\'s version identification. */ for (i = 0; i < sizeof(buf) - 1; i++) { - if (read(sock_in, &buf[i], 1) != 1) { + if (atomicio(read, sock_in, &buf[i], 1) != 1) { log("Did not receive ident string from %s.", get_remote_ipaddr()); fatal_cleanup(); } @@ -345,7 +374,7 @@ sshd_exchange_identification(int sock_in, int sock_out) break; } if (remote_minor < 3) { - packet_disconnect("Your ssh version is too old and" + packet_disconnect("Your ssh version is too old and " "is no longer supported. Please install a newer version."); } else if (remote_minor == 3) { /* note that this disables agent-forwarding */ @@ -396,6 +425,38 @@ destroy_sensitive_data(void) } /* + * returns 1 if connection should be dropped, 0 otherwise. + * dropping starts at connection #max_startups_begin with a probability + * of (max_startups_rate/100). the probability increases linearly until + * all connections are dropped for startups > max_startups + */ +int +drop_connection(int startups) +{ + double p, r; + + if (startups < options.max_startups_begin) + return 0; + if (startups >= options.max_startups) + return 1; + if (options.max_startups_rate == 100) + return 1; + + p = 100 - options.max_startups_rate; + p *= startups - options.max_startups_begin; + p /= (double) (options.max_startups - options.max_startups_begin); + p += options.max_startups_rate; + p /= 100.0; + r = arc4random() / (double) UINT_MAX; + + debug("drop_connection: p %g, r %g", p, r); + return (r < p) ? 1 : 0; +} + +int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */ +int startup_pipe; /* in child */ + +/* * Main program for the daemon. */ int @@ -403,7 +464,7 @@ main(int ac, char **av) { extern char *optarg; extern int optind; - int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1; + int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; pid_t pid; socklen_t fromlen; int silent = 0; @@ -416,6 +477,8 @@ main(int ac, char **av) struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; int listen_sock, maxfd; + int startup_p[2]; + int startups = 0; /* Save argv[0]. */ saved_argv = av; @@ -428,7 +491,7 @@ main(int ac, char **av) initialize_server_options(&options); /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) { + while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:diqQ46")) != EOF) { switch (opt) { case '4': IPv4or6 = AF_INET; @@ -475,6 +538,9 @@ main(int ac, char **av) /* only makes sense with inetd_flag, i.e. no listen() */ inetd_flag = 1; break; + case 'u': + utmp_len = atoi(optarg); + break; case '?': default: fprintf(stderr, "sshd version %s\n", SSH_VERSION); @@ -490,6 +556,7 @@ main(int ac, char **av) fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); fprintf(stderr, " -h file File from which to read host key (default: %s)\n", HOST_KEY_FILE); + fprintf(stderr, " -u len Maximum hostname length for utmp recording\n"); fprintf(stderr, " -4 Use IPv4 only\n"); fprintf(stderr, " -6 Use IPv6 only\n"); exit(1); @@ -629,6 +696,7 @@ main(int ac, char **av) s2 = dup(s1); sock_in = dup(0); sock_out = dup(1); + startup_pipe = -1; /* * We intentionally do not close the descriptors 0, 1, and 2 * as our code for setting the descriptors won\'t work if @@ -737,6 +805,7 @@ main(int ac, char **av) /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ signal(SIGHUP, sighup_handler); + signal(SIGTERM, sigterm_handler); signal(SIGQUIT, sigterm_handler); @@ -744,12 +813,15 @@ main(int ac, char **av) signal(SIGCHLD, main_sigchld_handler); /* setup fd set for listen */ + fdset = NULL; maxfd = 0; for (i = 0; i < num_listen_socks; i++) if (listen_socks[i] > maxfd) maxfd = listen_socks[i]; - fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); - fdset = (fd_set *)xmalloc(fdsetsz); + /* pipes connected to unauthenticated childs */ + startup_pipes = xmalloc(options.max_startups * sizeof(int)); + for (i = 0; i < options.max_startups; i++) + startup_pipes[i] = -1; /* * Stay listening for connections until the system crashes or @@ -758,80 +830,130 @@ main(int ac, char **av) for (;;) { if (received_sighup) sighup_restart(); - /* Wait in select until there is a connection. */ + if (fdset != NULL) + xfree(fdset); + fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); + fdset = (fd_set *)xmalloc(fdsetsz); memset(fdset, 0, fdsetsz); + for (i = 0; i < num_listen_socks; i++) FD_SET(listen_socks[i], fdset); + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1) + FD_SET(startup_pipes[i], fdset); + + /* Wait in select until there is a connection. */ if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) { if (errno != EINTR) error("select: %.100s", strerror(errno)); continue; } + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1 && + FD_ISSET(startup_pipes[i], fdset)) { + /* + * the read end of the pipe is ready + * if the child has closed the pipe + * after successfull authentication + * or if the child has died + */ + close(startup_pipes[i]); + startup_pipes[i] = -1; + startups--; + } for (i = 0; i < num_listen_socks; i++) { if (!FD_ISSET(listen_socks[i], fdset)) continue; - fromlen = sizeof(from); - newsock = accept(listen_socks[i], (struct sockaddr *)&from, - &fromlen); - if (newsock < 0) { - if (errno != EINTR && errno != EWOULDBLOCK) - error("accept: %.100s", strerror(errno)); - continue; - } - if (fcntl(newsock, F_SETFL, 0) < 0) { - error("newsock del O_NONBLOCK: %s", strerror(errno)); - continue; - } - /* - * Got connection. Fork a child to handle it, unless - * we are in debugging mode. - */ - if (debug_flag) { - /* - * In debugging mode. Close the listening - * socket, and start processing the - * connection without forking. - */ - debug("Server will not fork when running in debugging mode."); - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - pid = getpid(); - break; - } else { + fromlen = sizeof(from); + newsock = accept(listen_socks[i], (struct sockaddr *)&from, + &fromlen); + if (newsock < 0) { + if (errno != EINTR && errno != EWOULDBLOCK) + error("accept: %.100s", strerror(errno)); + continue; + } + if (fcntl(newsock, F_SETFL, 0) < 0) { + error("newsock del O_NONBLOCK: %s", strerror(errno)); + continue; + } + if (drop_connection(startups) == 1) { + debug("drop connection #%d", startups); + close(newsock); + continue; + } + if (pipe(startup_p) == -1) { + close(newsock); + continue; + } + + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] == -1) { + startup_pipes[j] = startup_p[0]; + if (maxfd < startup_p[0]) + maxfd = startup_p[0]; + startups++; + break; + } + /* - * Normal production daemon. Fork, and have - * the child process the connection. The - * parent continues listening. + * Got connection. Fork a child to handle it, unless + * we are in debugging mode. */ - if ((pid = fork()) == 0) { + if (debug_flag) { /* - * Child. Close the listening socket, and start using the - * accepted socket. Reinitialize logging (since our pid has - * changed). We break out of the loop to handle the connection. + * In debugging mode. Close the listening + * socket, and start processing the + * connection without forking. */ + debug("Server will not fork when running in debugging mode."); close_listen_socks(); sock_in = newsock; sock_out = newsock; - log_init(av0, options.log_level, options.log_facility, log_stderr); + startup_pipe = -1; + pid = getpid(); break; + } else { + /* + * Normal production daemon. Fork, and have + * the child process the connection. The + * parent continues listening. + */ + if ((pid = fork()) == 0) { + /* + * Child. Close the listening and max_startup + * sockets. Start using the accepted socket. + * Reinitialize logging (since our pid has + * changed). We break out of the loop to handle + * the connection. + */ + startup_pipe = startup_p[1]; + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] != -1) + close(startup_pipes[j]); + close_listen_socks(); + sock_in = newsock; + sock_out = newsock; + log_init(av0, options.log_level, options.log_facility, log_stderr); + break; + } } - } - /* Parent. Stay in the loop. */ - if (pid < 0) - error("fork: %.100s", strerror(errno)); - else - debug("Forked child %d.", pid); + /* Parent. Stay in the loop. */ + if (pid < 0) + error("fork: %.100s", strerror(errno)); + else + debug("Forked child %d.", pid); - /* Mark that the key has been used (it was "given" to the child). */ - key_used = 1; + close(startup_p[1]); - arc4random_stir(); + /* Mark that the key has been used (it was "given" to the child). */ + key_used = 1; - /* Close the new socket (the child is now taking care of it). */ - close(newsock); - } /* for (i = 0; i < num_listen_socks; i++) */ + arc4random_stir(); + + /* Close the new socket (the child is now taking care of it). */ + close(newsock); + } /* child process check (or debug mode) */ if (num_listen_socks < 0) break; diff --git a/crypto/openssh/sshd/Makefile b/crypto/openssh/sshd/Makefile index f74a03253756..0adfcd6391fe 100644 --- a/crypto/openssh/sshd/Makefile +++ b/crypto/openssh/sshd/Makefile @@ -5,15 +5,16 @@ BINOWN= root BINMODE=555 BINDIR= /usr/sbin MAN= sshd.8 +CFLAGS+=-DHAVE_LOGIN_CAP SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \ pty.c log-server.c login.c servconf.c serverloop.c \ - auth.c auth1.c auth2.c session.c + auth.c auth1.c auth2.c auth-options.c session.c .include <bsd.own.mk> # for KERBEROS and AFS -.if (${KERBEROS} == "yes") -.if (${AFS} == "yes") +.if (${KERBEROS:L} == "yes") +.if (${AFS:L} == "yes") CFLAGS+= -DAFS LDADD+= -lkafs DPADD+= ${LIBKRBAFS} @@ -24,7 +25,7 @@ LDADD+= -lkrb DPADD+= ${LIBKRB} .endif # KERBEROS -.if (${SKEY} == "yes") +.if (${SKEY:L} == "yes") SRCS+= auth-skey.c .endif @@ -33,13 +34,13 @@ SRCS+= auth-skey.c LDADD+= -lcrypto -lutil -lz DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} -.if (${TCP_WRAPPERS} == "yes") +.if (${TCP_WRAPPERS:L} == "yes") CFLAGS+= -DLIBWRAP LDADD+= -lwrap DPADD+= ${LIBWRAP} .endif -.if (${SKEY} == "yes") +.if (${SKEY:L} == "yes") CFLAGS+= -DSKEY LDADD+= -lskey DPADD+= ${SKEY} diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index 0366ee48542e..71e73ba9dc00 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/sshd_config @@ -49,3 +49,7 @@ PermitEmptyPasswords no #CheckMail yes #UseLogin no + +# Uncomment if you want to enable sftp +#Subsystem sftp /usr/libexec/sftp-server +#MaxStartups 10:30:60 diff --git a/crypto/openssh/tildexpand.c b/crypto/openssh/tildexpand.c index 4ecb785be532..f25f7d96b265 100644 --- a/crypto/openssh/tildexpand.c +++ b/crypto/openssh/tildexpand.c @@ -2,11 +2,16 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Wed Jul 12 01:07:36 1995 ylo + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: tildexpand.c,v 1.6 1999/12/06 19:10:38 deraadt Exp $"); +RCSID("$OpenBSD: tildexpand.c,v 1.8 2000/09/07 20:27:55 deraadt Exp $"); #include "xmalloc.h" #include "ssh.h" diff --git a/crypto/openssh/ttymodes.c b/crypto/openssh/ttymodes.c index 25f501349424..a7a3e9301087 100644 --- a/crypto/openssh/ttymodes.c +++ b/crypto/openssh/ttymodes.c @@ -2,15 +2,20 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Tue Mar 21 15:59:15 1995 ylo * Encoding and decoding of terminal modes in a portable way. * Much of the format is defined in ttymodes.h; it is included multiple times * into this file with the appropriate macro definitions to generate the * suitable code. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: ttymodes.c,v 1.6 2000/04/14 10:30:34 markus Exp $"); +RCSID("$OpenBSD: ttymodes.c,v 1.8 2000/09/07 20:27:55 deraadt Exp $"); #include "packet.h" #include "ssh.h" diff --git a/crypto/openssh/ttymodes.h b/crypto/openssh/ttymodes.h index f8243f61f875..a26e4fa5b61a 100644 --- a/crypto/openssh/ttymodes.h +++ b/crypto/openssh/ttymodes.h @@ -1,18 +1,17 @@ /* - * - * ttymodes.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> * SGTTY stuff contributed by Janne Snabb <snabb@niksula.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Tue Mar 21 15:42:09 1995 ylo - * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: ttymodes.h,v 1.7 2000/04/14 10:30:34 markus Exp $"); */ +/* RCSID("$OpenBSD: ttymodes.h,v 1.9 2000/09/07 20:27:55 deraadt Exp $"); */ /* The tty mode description is a stream of bytes. The stream consists of * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c index 20f04cf9bdc2..8e7c4797e4de 100644 --- a/crypto/openssh/uidswap.c +++ b/crypto/openssh/uidswap.c @@ -2,12 +2,17 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Sat Sep 9 01:56:14 1995 ylo * Code for uid-swapping. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: uidswap.c,v 1.6 2000/04/14 10:30:34 markus Exp $"); +RCSID("$OpenBSD: uidswap.c,v 1.9 2000/09/07 20:27:55 deraadt Exp $"); #include "ssh.h" #include "uidswap.h" @@ -43,15 +48,15 @@ temporarily_use_uid(uid_t uid) /* Set the effective uid to the given (unprivileged) uid. */ if (seteuid(uid) == -1) - debug("seteuid %d: %.100s", (int) uid, strerror(errno)); + debug("seteuid %u: %.100s", (u_int) uid, strerror(errno)); #else /* SAVED_IDS_WORK_WITH_SETUID */ /* Propagate the privileged uid to all of our uids. */ if (setuid(geteuid()) < 0) - debug("setuid %d: %.100s", (int) geteuid(), strerror(errno)); + debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno)); /* Set the effective uid to the given (unprivileged) uid. */ if (seteuid(uid) == -1) - debug("seteuid %d: %.100s", (int) uid, strerror(errno)); + debug("seteuid %u: %.100s", (u_int) uid, strerror(errno)); #endif /* SAVED_IDS_WORK_WITH_SETEUID */ } @@ -64,7 +69,7 @@ restore_uid() #ifdef SAVED_IDS_WORK_WITH_SETEUID /* Set the effective uid back to the saved uid. */ if (seteuid(saved_euid) < 0) - debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno)); + debug("seteuid %u: %.100s", (u_int) saved_euid, strerror(errno)); #else /* SAVED_IDS_WORK_WITH_SETEUID */ /* * We are unable to restore the real uid to its unprivileged value. @@ -83,5 +88,5 @@ void permanently_set_uid(uid_t uid) { if (setuid(uid) < 0) - debug("setuid %d: %.100s", (int) uid, strerror(errno)); + debug("setuid %u: %.100s", (u_int) uid, strerror(errno)); } diff --git a/crypto/openssh/uidswap.h b/crypto/openssh/uidswap.h index c08a37004616..ff6fad4c1f4b 100644 --- a/crypto/openssh/uidswap.h +++ b/crypto/openssh/uidswap.h @@ -1,15 +1,13 @@ /* - * - * uidswap.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved * - * Created: Sat Sep 9 01:43:15 1995 ylo - * Last modified: Sat Sep 9 02:34:04 1995 ylo - * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #ifndef UIDSWAP_H diff --git a/crypto/openssh/util.c b/crypto/openssh/util.c new file mode 100644 index 000000000000..71808f14ddb2 --- /dev/null +++ b/crypto/openssh/util.c @@ -0,0 +1,99 @@ +/* $OpenBSD: util.c,v 1.5 2000/09/07 20:27:55 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: util.c,v 1.5 2000/09/07 20:27:55 deraadt Exp $"); + +#include "ssh.h" + +char * +chop(char *s) +{ + char *t = s; + while (*t) { + if(*t == '\n' || *t == '\r') { + *t = '\0'; + return s; + } + t++; + } + return s; + +} + +void +set_nonblock(int fd) +{ + int val; + if (isatty(fd)) { + /* do not mess with tty's */ + debug("no set_nonblock for tty fd %d", fd); + return; + } + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return; + } + if (val & O_NONBLOCK) + return; + debug("fd %d setting O_NONBLOCK", fd); + val |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) + if (errno != ENODEV) + error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", + fd, strerror(errno)); +} + +/* Characters considered whitespace in strsep calls. */ +#define WHITESPACE " \t\r\n" + +char * +strdelim(char **s) +{ + char *old; + int wspace = 0; + + if (*s == NULL) + return NULL; + + old = *s; + + *s = strpbrk(*s, WHITESPACE "="); + if (*s == NULL) + return (old); + + /* Allow only one '=' to be skipped */ + if (*s[0] == '=') + wspace = 1; + *s[0] = '\0'; + + *s += strspn(*s + 1, WHITESPACE) + 1; + if (*s[0] == '=' && !wspace) + *s += strspn(*s + 1, WHITESPACE) + 1; + + return (old); +} diff --git a/crypto/openssh/uuencode.c b/crypto/openssh/uuencode.c index fc84d5a5830b..38de418a26a1 100644 --- a/crypto/openssh/uuencode.c +++ b/crypto/openssh/uuencode.c @@ -1,11 +1,36 @@ +/* $OpenBSD: uuencode.c,v 1.7 2000/09/07 20:27:55 deraadt Exp $ */ + /* * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "includes.h" #include "xmalloc.h" #include <resolv.h> +RCSID("$OpenBSD: uuencode.c,v 1.7 2000/09/07 20:27:55 deraadt Exp $"); + int uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize) diff --git a/crypto/openssh/uuencode.h b/crypto/openssh/uuencode.h index c92c62744cc2..dca80ec1adf4 100644 --- a/crypto/openssh/uuencode.h +++ b/crypto/openssh/uuencode.h @@ -1,3 +1,27 @@ +/* + * Copyright (c) 1999 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #ifndef UUENCODE_H #define UUENCODE_H int uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize); diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index d577644d61e7..bfd432719847 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -1 +1 @@ -#define SSH_VERSION "OpenSSH-2.1" +#define SSH_VERSION "OpenSSH_2.2.0" diff --git a/crypto/openssh/xmalloc.c b/crypto/openssh/xmalloc.c index 31550991a2be..738c9cdc3902 100644 --- a/crypto/openssh/xmalloc.c +++ b/crypto/openssh/xmalloc.c @@ -2,13 +2,18 @@ * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * Created: Mon Mar 20 21:23:10 1995 ylo * Versions of malloc and friends that check their results, and never return * failure (they call fatal if they encounter an error). + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ #include "includes.h" -RCSID("$Id: xmalloc.c,v 1.6 2000/04/14 10:30:34 markus Exp $"); +RCSID("$OpenBSD: xmalloc.c,v 1.8 2000/09/07 20:27:55 deraadt Exp $"); #include "ssh.h" diff --git a/crypto/openssh/xmalloc.h b/crypto/openssh/xmalloc.h index 31291ea4ace5..59a598ed6df1 100644 --- a/crypto/openssh/xmalloc.h +++ b/crypto/openssh/xmalloc.h @@ -1,20 +1,20 @@ /* - * - * xmalloc.h - * * Author: Tatu Ylonen <ylo@cs.hut.fi> - * * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved - * * Created: Mon Mar 20 22:09:17 1995 ylo * * Versions of malloc and friends that check their results, and never return * failure (they call fatal if they encounter an error). * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$Id: xmalloc.h,v 1.3 2000/04/14 10:30:34 markus Exp $"); */ +/* RCSID("$OpenBSD: xmalloc.h,v 1.5 2000/09/07 20:27:56 deraadt Exp $"); */ #ifndef XMALLOC_H #define XMALLOC_H |