diff options
author | Alex Wilson <alex.wilson@joyent.com> | 2015-08-11 00:23:16 +0000 |
---|---|---|
committer | Alex Wilson <alex.wilson@joyent.com> | 2015-09-03 14:05:34 -0700 |
commit | d0c1b872bd54d7989a1f97af5d5d86ec4a13cabe (patch) | |
tree | 76af59311a3eb0011f3012489d059212ea21cd21 /usr/src | |
parent | 42d2cb6faf809f84bbfd0fd73fe6f644b8417053 (diff) | |
download | illumos-joyent-d0c1b872bd54d7989a1f97af5d5d86ec4a13cabe.tar.gz |
OS-4689 Remove SunSSH from illumos-joyent
OS-4688 Switch platform over to using recent OpenSSH
Reviewed by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src')
299 files changed, 0 insertions, 81466 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index 0f8de0abb3..e1f5b733a0 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -280,7 +280,6 @@ COMMON_SUBDIRS = \ cmd/split \ cmd/srptadm \ cmd/srptsvc \ - cmd/ssh \ cmd/stat \ cmd/stmfadm \ cmd/stmfsvc \ diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 8bb04e9a29..1f098842b9 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -382,7 +382,6 @@ COMMON_SUBDIRS= \ srchtxt \ srptadm \ srptsvc \ - ssh \ stat \ stmfadm \ stmfproxy \ @@ -682,7 +681,6 @@ MSGSUBDIRS= \ sort \ split \ srptadm \ - ssh \ stat \ stmfadm \ stmsboot \ diff --git a/usr/src/cmd/Makefile.check b/usr/src/cmd/Makefile.check index f442650fca..d3b6dcc4a4 100644 --- a/usr/src/cmd/Makefile.check +++ b/usr/src/cmd/Makefile.check @@ -129,7 +129,6 @@ MANIFEST_SUBDIRS= \ rpcsvc/rpc.bootparamd \ sendmail/lib \ smbsrv/smbd \ - ssh/etc \ svc/milestone \ tsol/labeld \ tsol/tnctl \ diff --git a/usr/src/cmd/ssh/Makefile b/usr/src/cmd/ssh/Makefile deleted file mode 100644 index 62f30b3f36..0000000000 --- a/usr/src/cmd/ssh/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -include ../Makefile.cmd - -# libopenbsd-compat and libssh are used by all SSH binaries, and sftp-server is -# also used as an internal part of sshd. -SUBDIRS= \ - etc \ - libopenbsd-compat \ - libssh \ - sftp-server \ - .WAIT \ - ssh \ - sshd \ - scp \ - ssh-add \ - ssh-agent \ - ssh-keygen \ - ssh-keysign \ - ssh-keyscan \ - sftp \ - ssh-http-proxy-connect \ - ssh-socks5-proxy-connect - -MSGFILE=ssh.po -POFILE=_messages.po - -CLOBBERFILES += $(MSGFILE) THIRDPARTYLICENSE - -.KEEP_STATE: - -all := TARGET= all -clean := TARGET= clean -clobber := TARGET= clobber -delete := TARGET= delete -install := TARGET= install -lint := TARGET= lint -catalog := TARGET= catalog -package := TARGET= package -_msg := TARGET= _msg -$(POFILE) := TARGET= $(POFILE) - -all clean install lint $(POFILE): $(SUBDIRS) -clobber: $(SUBDIRS) clobber_local -clobber_local: - $(RM) $(CLOBBERFILES) - -all install: THIRDPARTYLICENSE - -check: $(CHECKHDRS) - -# See Makefile.msg.targ for $(MSGFILE) update instructions -_msg: - $(RM) $(POFILE) - $(TOUCH) $(POFILE) - $(MAKE) $(POFILE) XGETTEXT=$(GNUXGETTEXT) - $(CP) $(POFILE) $(MSGFILE) - $(CP) $(MSGFILE) $(MSGDOMAIN) - -$(SUBDIRS): FRC - cd $@; pwd; $(MAKE) $(TARGET) - -# skip the summary; just include the actual license clauses. -THIRDPARTYLICENSE: doc/LICENCE - $(SED) -n '/1)/,$$p' doc/LICENCE > $@ - -FRC: diff --git a/usr/src/cmd/ssh/Makefile.msg.targ b/usr/src/cmd/ssh/Makefile.msg.targ deleted file mode 100644 index df56774c25..0000000000 --- a/usr/src/cmd/ssh/Makefile.msg.targ +++ /dev/null @@ -1,39 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -POFILE = _messages.po -XGETFLAGS = -o $(POFILE_DIR)/$(POFILE) --foreign-user --strict -j -n -E \ - --width=72 \ - --omit-header \ - --keyword=fatal \ - --keyword=error \ - --keyword=verbose \ - --keyword=packet_send_debug \ - --keyword=packet_disconnect - -$(POFILE): - $(RM) $@ - $(COMPILE.cpp) $(SRCS) > $(POFILE).i.c - $(XGETTEXT) $(XGETFLAGS) $(POFILE).i.c - $(RM) $(POFILE).i.c - diff --git a/usr/src/cmd/ssh/Makefile.ssh-common b/usr/src/cmd/ssh/Makefile.ssh-common deleted file mode 100644 index 25a9c2560f..0000000000 --- a/usr/src/cmd/ssh/Makefile.ssh-common +++ /dev/null @@ -1,93 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# Copyright 2012 Milan Jurik. All rights reserved. -# -# Common definitions for all of usr/src/cmd/ssh subdirs -# - - -TEXT_DOMAIN=SUNW_OST_OSCMD - -CFLAGS += $(CCVERBOSE) -LDFLAGS += $(MAPFILE.NGB:%=-M%) - -SSH_VERSION=\"Sun_SSH_1.5\" - -C99MODE= $(C99_ENABLE) - -CPPFLAGS = -DSSH_VERSION=$(SSH_VERSION) \ - -I../include -I../../include \ - -D_FILE_OFFSET_BITS=64 \ - -erroff=E_STATEMENT_NOT_REACHED \ - $(CPPFLAGS.master) - -SSH_COMMON_LDLIBS = \ - -L../libssh/$(MACH) -lssh \ - -L../libopenbsd-compat/$(MACH) -lopenbsd-compat - -$(PROG): $(MAPFILE.NGB) - -# -# Some the lint -erroff flags listed below are because of deficiencies in -# lint not because we are hiding real errors or to avoid massive resync- -# hindering changes that will not be returned to OpenSSH. -# -# OpenSSH has several instances of "do {...} while (0);" - a common -# idiom in C macros, but it elicits E_CONSTANT_CONDITION from lint. -# -# The MD5 macros in <openssl/md5.h> trigger E_EXPR_NULL_EFFECT. -# -# Lots of function return values are ignored in OpenSSH. -# -# Lots of globals could be static, sometimes due to portable code paths -# which are dead on Solaris. -# -LINTFLAGS += \ - -erroff=E_FUNC_ARG_UNUSED \ - -erroff=E_NAME_USED_NOT_DEF2 \ - -erroff=E_FUNC_DECL_VAR_ARG2 \ - -erroff=E_INCONS_VAL_TYPE_DECL2 \ - -erroff=E_INCONS_ARG_DECL2 \ - -erroff=E_STATIC_UNUSED \ - -erroff=E_STATEMENT_NOT_REACHED \ - -erroff=E_FUNC_RET_ALWAYS_IGNOR2 \ - -erroff=E_FUNC_RET_MAYBE_IGNORED2 \ - -erroff=E_GLOBAL_COULD_BE_STATIC2 \ - -erroff=E_CONSTANT_CONDITION \ - -erroff=E_EXPR_NULL_EFFECT \ - -erroff=E_STMT_NOT_REACHED \ - -errtags=yes - -CERRWARN += -_gcc=-Wno-parentheses -CERRWARN += -_gcc=-Wno-uninitialized -CERRWARN += -_gcc=-Wno-unused-function -CERRWARN += -_gcc=-Wno-unused-variable - -ROOTLIBSSH= $(ROOTLIB)/ssh -ROOTLIBSSHPROG= $(PROG:%=$(ROOTLIBSSH)/%) - -POFILE= _messages.po - -$(ROOTLIBSSH)/%: % - $(INS.file) diff --git a/usr/src/cmd/ssh/README.altprivsep b/usr/src/cmd/ssh/README.altprivsep deleted file mode 100644 index f91dbbd2a1..0000000000 --- a/usr/src/cmd/ssh/README.altprivsep +++ /dev/null @@ -1,687 +0,0 @@ - Copyright 2008 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - Sun's Alternative "Privilege Separation" for OpenSSH - - -Table of Contents - -1. Introduction -2. What is "Privilege?" -3. Analysis of the SSH Protocols -3.1. Privileged Resources, Operations, in the SSH Protocols -4. OpenSSH's Privilege Separation -5. SUNWssh's Alternative Privilege Separation -6. Comparison of the OpenSSH and SUNWssh PrivSep Models -7. Future Directions -8. Guide to the AltPrivSep Source Code -A. References - - - - - -1. Introduction - - Implementations of SSH servers require some degree of privilege in - order to function properly. Often such implementations retain such - privilege throughout normal operation even while users are logged - in. This means that vulnerabilities in the implementation of the - protocols can be exploited in such ways as to escalate the privilege - that would normally be accorded to mer-mortal users. - - The OpenSSH team introduced support for "privilege separation" in - the OpenSSH ssh server some years ago to minimize the extent of - extant, undiscovered vulnerabilities in the OpenSSH server source - code. The basic concept is to have a multi-process server - implementation where one process, the "monitor" is privileged and - implements a smaller protocol than the ssh protocols, and thus is, - hopefully, less likely to sport exploitable security bugs. - - The ssh team at Sun agrees with the basic OpenSSH privilege - separation concept, but disagrees with its design. - - Here we present our alternative to the OpenSSH design. We begin - with the question of just what is "privilege" and follow on with an - analysis of the SSH protocols vis-a-vis privilege. Then we briefly - describe the OpenSSH model, followed by an exposition of our - alternative model. - - -2. What is "Privilege?" - - Privilege, in a traditional Unix sense, is that which the "root" - user can do that other users cannot directly do. In Solaris 10 - there is a new approach to this sort of privilege with the aim of - running much of the operating system with the Least Privilege - required; root's privilege is broken down into many privileges and - these are managed through privilege sets. We won't go into the - details of Solaris 10's Least Privilege facility here. - - But privilege is also access to data and resources that can be used - to escalate the privilege of those who have access to them. For - example: secret, or private cryptographic keys used in - authentication. Network security typically requires the use of - cryptographic keys for authentication. - - -3. Analysis of the SSH Protocols - - There are two or, rather three SSH protocols: - - - version 1 - - version 1.5 - - version 2 - - Version 1 and 1.5 are much the same, from our point of view; version - 2 is significantly different from the other two. - - Familiarity by the reader with the specifications for these - protocols is not assumed, but would be beneficial to the reader. - - Quite roughly, these protocols consist of the following: - - a) initial version exchange (for protocol version negotiation) - b) a binary encoding of message data - c) message syntaxes for the protocols' messages - d) specifications on use of cryptography for transport - privacy (encryption) and integrity protection - e) a key exchange protocol (which also authenticates servers to - clients) - f) a protocol for user authentication - g) a session protocol - h) a re-keying protocol (v2-only) - - Some of these parts of the ssh protocols are quite complex, some - quite straightforward. Altogether implementation of the ssh - protocols requires a source code base of significant size. - - The OpenSSH implementation relies on OpenSSL for cryptographic - service, on libz for compression service and miscellaneous other - libraries. Besides these OpenSSH consists of several tens of - thousands of lines of source code in C. - - SUNWssh is based on OpenSSH, so it is comparable in size and - complexity to OpenSSH. - - There is, then, plenty of space for security bugs in the OpenSSH, - and, therefore, also in the SUNWssh source code bases. - - The OpenSSH team designed and implemented a "privilege separation" - feature in their ssh server to reduce the risk that a security bug - in OpenSSH could be successfully exploited and an attacker's - privilege escalated. - - -3.1. Privileged Resources, Operations, in the SSH Protocols - - What privileges does an SSH server need then? - - Observation with Solaris 10's ppriv(1) and truss(1) commands as well - as analysis of the ssh protocols leads to conclude as follows. - - No privilege or privileged resources are needed to implement the - parts (a)-(d) mentioned in section 3. - - - For key exchange and server authentication (e) an ssh server requires: - - - Access to the host's ssh private keys. - - - Access to the host's GSS-API acceptor credentials. [SSHv2-only] - - - An ssh server requires practically all privileges for user - authentication (f) (at least PAM does), particularly - PRIV_PROC_SETID, for logging the user in. - - - Post-authentication an ssh server requires the following privileges: - - - Those required for auditing a user's subsequent logout. - - That is, PRIV_PROC_AUDIT. - - - - Those required for record keeping (i.e., utmpx/wtmpx logging). - - That is, either open file descriptor for those files or - PRIV_FILE_DAC_WRITE or otherwise access to those files, perhaps - through a special user id or group id which would be granted - write access through the ACLs on those files. - - Since SSHv2 allows clients to open many channels with - pseudo-terminals a server may need to open and close utmpx/wtmpx - records multiple times in the lifetime of an SSHv2 connection. - - - - Those required for accessing the host's ssh private keys for - SSHv2 re-keying. [SSHv2-only] - - These keys can be (and are) loaded at server startup time, - requiring PRIV_FILE_DAC_READ, or access through file ACLs, at - that time, but not thence. - - - - Those required for accessing the host's GSS-API acceptor - credentials for SSHv2 re-keying. - - These credentials may require a large set of privileges. The - Solaris 10 Kerberos V GSS-API mechanism, for example, requires - PRIV_FILE_DAC_READ (for access to the system keytab) and - PRIV_FILE_DAC_WRITE (for access to the Kerberos V replay cache). - - - It is worth pointing out that because of a wrinkle in the - specification of the SSHv2 protocol and various implementations, - access to a host's ssh private keys can allow one not only to - impersonate the host as a server (which is, in practice, difficult), - but also to impersonate the host as a client (which is quite easy to - do) using "hostbased" user authentication. - - It is entirely possible to have one-process server implementation - that drops most privileges and access to privileged resources after - user authentication succeeds. Such an implementation would make - some privileges, such as PRIV_PROC_SETID, available to any attacker - that successfully exploited a security bug in the ssh server. - - But such an implementation would also have to retain access to - resources needed for authenticating the server, which, as described - above, can be used to impersonate the server, in some cases with - ease. - - -4. OpenSSH's Privilege Separation - - The OpenSSH privilege separation model is quite complex. - - It consists of a monitor, which retains all privileges and access to - privileged resources, and two processes which run with much less - privilege: one process running as a special user, "sshd," for - hosting all phases of the SSH protocols up to and including - authentication, and one process running as the actual user that logs - in and which hosts all phases of the SSH protocols post-user- - authentication. - - The monitor and its companion processes speak a private protocol - over IPC. This protocol is intended to be smaller and simpler than - the SSH wire protocols. - - In practice the OpenSSH monitor protocols relating to user - authentication are neither smaller nor simpler than the SSH user - authentication protocols; and though they are different they also - transport much the same data, including RSA/DSA signatures, - usernames, PAM conversations, and GSS-API context and MIC tokens. - - The key exchange protocols have been broken down into their - essentials and the monitor serves only services such as signing - server replies with private host keys. - - Note also that the OpenSSH monitor protocol uses the same encodings - as the SSH protocols and uses the same implementation of those - encodings. - - -5. SUNWssh's Alternative Privilege Separation - - The Sun Microsystems ssh team believes that the OpenSSH team has - reached the point of diminishing returns in attempting to separate - processing of the user authentication protocols and that the OpenSSH - approach to privilege separation of the key exchange protocols has - led to a situation in which the monitor acts as an oracle, willing - to sign anything provided by the unprivileged processes that talk to - it. - - The Sun ssh team proposes a somewhat different privilege separation - implementation that shares with the OpenSSH model the goal of - minimizing and simplifying the protocol spoken by the monitor, but - little source code. - - We eschew any temptation to apply the privilege separation concept - to the version negotiation, initial key exchange and user - authentication phases of the ssh protocols (but see section 7). - - Instead we focus on separating processing of auditing, record - keeping and re-keying from processing of the session protocols. We - also wish to avoid creating any oracles in the monitor. - - This approach allows us to have a very simple monitor protocol. Our - monitor protocol consists of the following operations: - - - record a new pseudo-terminal session - - record the end of a pseudo-terminal session - - process a re-key protocol messages - - get keys negotiated during re-keying to the session process to it - can use them - - Logout auditing is done when the session process dies and so does - not require a monitor protocol message. - - By processing all re-key protocol messages in the monitor we prevent - the creation of oracles in the monitor. This is so because the - monitor signs only material which it has generated and over which an - attacker would have little influence (through the attackers offered - DH public key, for example). - - Odds and ends: - - - If the monitor receives SIGHUP, SIGTERM or SIGINT it will call - fatal_cleanup(), and thence will forcibly shutdown(3SOCKET) the - ssh connection socket, causing its child to exit, and audit a - logout. - - - The monitor does not attempt to update utmpx/wtmpx independently - of its child -- it depends on the child asking it to. - - - The child now is unable to chown() ptys back to root. That's Ok, - other services on Solaris do the same and everything still works - because of grantpt(3C). - - - The sshd server process (the one that will become a monitor) - forks a child process before the key exchange starts. The reason - for it is that if we forked after that we would end up using - PKCS#11 sessions initialized in the monitor unless - UseOpenSSLEngine was explicitly set to 'no'. Using any existing - PKCS#11 sessions or object handles over fork is what the PKCS#11 - standard explicitly prohibits. To solve that, we would have to - rekey before fork and then newly initialize the engine in the - child, together with the new crypto contexts initialized with the - keys produced by the key re-exchange. And, that wouldn't help in - situations where the client does not support rekeying which also - includes the whole protocol version 1. The pre-fork solution is - simpler and also much faster. So, the key exchange and - authentication is fully done in the child server process while - the monitor waits aside to read the authentication context that - is needed for further operation. The child drops privileges after - the authentication finishes. - - With the ssh client, the situation is slightly more complicated. - Given the fact that the user can request to go to the background - during the connection using the ~& sequence we must be prepared - to rekey before forking, to reinitialize the engine in the child - after that, and then set the new crypto contexts with the new - keys. If the server we are communicating with does not support - rekeying we will not use the engine at all. We expect this - situation to be extremely rare and will not offer any workaround - for that. This also includes the protocol version 1. However, - this version is already considered obsolete and should not be used - if possible. - -6. Comparison of the OpenSSH and SUNWssh PrivSep Models - - The OpenSSH server involves three processes which we will term - "pre-session," "session" and "monitor." - - The OpenSSH pre-session process implements: - - - the ssh version string exchange - - the ssh message encoding/decoding - - most of the initial key exchange protocols - - transport protection - - part of the user authentication protocols - - The OpenSSH session process implements: - - - the ssh message encoding/decoding - - transport protection - - most of the re-keying protocols - - the session protocols - - The OpenSSH monitor process implements: - - - the ssh message encoding/decoding - - parts of the key exchange and re-key protocols (primarily signing - of server replies with host private keys) - - most of the user authentication protocols, specifically: - - - evaluation of ~/.ssh/authorized_keys (for pubkey userauth) - - evaluation of known hosts files (for hostbased userauth) - - evaluation of .shosts/.rhosts files (for hostbased userauth) - - verification of signatures w/ public keys (pubkey, hostbased) - - PAM API calls, conversation function - - GSS-API calls - - Note that any vulnerabilities in the parsing of authorized_keys, - known hosts and .shosts/rhosts files are as exploitable in the - monitor as in a server w/o privilege separation. - - Similarly for any vulnerabilities in PAM modules and GSS-API - mechanisms. - - The SUNWssh server involves two processes which we will term - "session" and "monitor." - - The SUNWssh monitor process implements: - - - the ssh version string exchange - - the ssh message encoding/decoding - - transport protection - - all of the key exchange and re-key protocols - - all of the user authentication protocols - - The SUNWssh session process implements: - - - the ssh message encoding/decoding - - transport protection - - the session protocols - - Obviously all of these processes also implement their side of the - monitor protocols. - - The OpenSSH 3.5p1 monitor protocol, on Solaris, has approximately 20 - monitor request and corresponding response messages. - - The SUNWssh monitor protocol has 5 monitor request and response - messages; additionally, the monitor processes standard re-key - messages (but note: the monitor and the session process IPC is - completely unencrypted), which amounts to about 14 more messages - altogether. - - Much of the OpenSSH monitor protocol is a variation of the - on-the-wire ssh protocols, with some contents re-packaging. We - believe this does not afford the monitor much additional, if any - protection from attacks in the key exchange and user authentication - protocols. - - The re-packaging that is done in the OpenSSH monitor protocol is - risky business. By separating the act of signing some blob of data - from computing that blob of data one can create an oracle; this is - exactly what happened in the OpenSSH case. - - As you can see in the next section, the SUNWssh privilege separation - could evolve somewhat in the OpenSSH direction by saving the monitor - all transport protection work, but we cannot save the monitor much, - if any work relating to authentication or key exchange. - - -7. Future Directions - - The SUNWssh server privilege separation implementation could stand - several improvements. - - The first improvement would be to have a single system-wide monitor. - This would reduce resource consumption. The work needed to - implement such an enhancement is very similar to the work needed to - produce an SSH API and library, and it is not trivial. If this is - not done then at least dropping PRIV_PROC_SETID and instead setting - the saved-set-user-id in the monitor to that of the logged in user - would be nice. - - The second enhancement would be to add a "none" host key algorithm - to SSHv2 and a corresponding option in SUNWssh to disallow re-keying - with any other host key algorithm. This would allow customers to - configure their server and monitor so that no re-key protocol - messages need be processed by the monitor. - - A third enhancement would be to enhance the GSS-API mechanisms to - require fewer privileges. In practice this means overhauling the - Kerberos V mechanism's replay cache. This would allow the monitor - to run with fewer privileges. - - Further, even without improving the Kerberos V mechanism's replay - cache it should be possible to drop at least PRIV_PROC_FORK/EXEC/ - SESSION. - - A fourth enhancement would to have the unprivileged process handle - all transport protection and proxy to the monitor all key exchange - and user authentication protocol messages. This is a variation on - the OpenSSH model, but without the re-packaging of ssh message - contents seen there. After authentication succeeds the monitor - could either change the unprivileged process' credentials (as can be - done with ppriv(1) or the unprivileged process would, as in OpenSSH, - pass the session keys/IVs/keystate to the monitor which would then - pass them to a new process, the session process, that would then run - as the logged in user. - - -8. Guide to the AltPrivSep Source Code - - - First, a brief introduction to the SUNWssh/OpenSSH source code. - - The source code is organized as follows: - - $SRC/cmd/ssh/etc/ - | - +-> config files - - $SRC/cmd/ssh/include/ - | - +-> header files (note: none are installed/shipped) - - $SRC/cmd/ssh/libopenbsd-compat/common/ - | - +-> misc. portability source code - - $SRC/cmd/ssh/libssh/common/ - | - +-> implementation of encoding, transport protection, - various wrappers around cryptography, the key exchange - and host authentication protocols, the session - protocols, and misc. other code - - cipher.c - mac.c - compress.c - packet.c - | - +-> transport protocol - - buffer.c - bufaux.c - | - +-> encoding - - channels.c - nchan.c - | - +-> session protocol - - kex.c - kexdh.c - kexgex.c - | - +-> key exchange/re-key code common to ssh and sshd - - kexdhs.c - kexgexs.c - kexgsss.c - | - +-> key exchange/re-key code (server only) - - kexdhc.c - kexgexc.c - kexgssc.c - | - +-> key exchange/re-key code (client only) - - dh.c - rsa.c - mpaux.c - ssh-rsa.c - ssh-dss.c - ssh-gss.c - | - +-> crypto wrappers/utilities - - log.c - | - +-> logging, including debug logging, on stderr or - syslog - - - $SRC/cmd/ssh/ssh/ - | - +-> ssh(1) - - $SRC/cmd/ssh/sshd/ - | - +-> sshd(1M), including auditing, implementation of user - authentication and the OpenSSH and SUNWssh monitors - - sshd.c - | - +-> main() - - auth*.c - | - +-> user authentication - - serverloop.c - session.c - | - +-> session protocols - - bsmaudit.[ch] - sshlogin.c - loginrec.c - | - +-> auditing and record-keeping - - $SRC/cmd/ssh/<misc commands>/ - | - +-> scp, sftp, sftp-server, ssh-agent, ssh-add, ... - - - The SUNWssh altprivsep adds two new source files: - - $SRC/cmd/ssh/include/altprivsep.h - $SRC/cmd/ssh/sshd/altprivsep.c - | - +-> monitor start routine, altprivsep_packet_*() routines - for communication with the monitor, routines to help - with key exchanges, service procedures for the monitor, - etc... - - and modifies the following: - - $SRC/cmd/ssh/include/config.h - | - +> adds cpp define "ALTPRIVSEP" - - $SRC/cmd/ssh/include/ssh2.h - | - +-> adds private message type "SSH2_PRIV_MSG_ALTPRIVSEP" (254) - - $SRC/cmd/ssh/include/packet.h - | - +-> adds prototypes for several simple utility functions, - some of which are specifically meant to avoid having to - link altprivsep.c into ssh(1) - - $SRC/cmd/ssh/libssh/common/kex.c - $SRC/cmd/ssh/libssh/common/packet.c - | - +-> implements the hooks needed to proxy re-key messages - to/from the monitor - - $SRC/cmd/ssh/sshd/Makefile - | - +-> adds altprivsep.o to list of objects linked into sshd(1M) - - $SRC/cmd/ssh/sshd/serverloop.c - | - +-> adds an event loop for the monitor - modifies the usual event loops for SSHv2 - - $SRC/cmd/ssh/sshd/session.c - | - +-> modifies do_login() and session_pty_cleanup2() to call - altprivsep_record_login/logout() instead of - record_login/logout(). - - modifies do_exec_pty() so that the server waits for the - call to altprivsep_record_login() in child process to - complete before returning so that the server and the - child processes do not compete for monitor IPC I/O. - - $SRC/cmd/ssh/include/log.h - $SRC/cmd/ssh/libssh/common/log.c - | - +-> adds an internal interface, set_log_txt_prefix() so that - the monitor's debug and log messages get prefixed with a - string ("monitor ") that indicates they are from the - monitor - - $SRC/cmd/ssh/sshd/sshd.c - | - +-> modifies the body of code that follows the user - authentication phase of the ssh protocols so as to start - the monitor and move the relevant code into the monitor - or session processes as appropriate while dropping - privileges and access to privileged resources in the - session process - - The monitor uses the packet.h interfaces to communicate with the - session process as though it were its ssh client peer, but always - uses the "none" cipher, mac and compression algorithms and installs - even handlers only for the relevant key exchange messages and the - private monitor message used for the other monitor services. - - The monitor serves the following services: - - - APS_MSG_NEWKEYS_REQ -> used to obtain keys/IVs after re-keys - - APS_MSG_RECORD_LOGIN -> used to update utmpx/wtmpx - - APS_MSG_RECORD_LOGOUT -> used to update utmpx/wtmpx - - The session and monitor processes communicate over a pipe. - - All monitor IPC I/O from the session process is blocking (though the - pipe is set to non-blocking I/O). The monitor protocol is entirely - synchronous and relies on the re-key protocols being entirely - synchronous also (which they are, unlike the session protocols). - - The kex.c and packet.c files are minimally modified, primarily to - prevent the monitor from handling SSH_MSG_NEWKEYS messages as a - normal ssh server should, instead letting the session process - process SSH_MSG_NEWKEYS messages by requesting the new keys - negotiated with client from the monitor. - - Note that for SSHv1 no on-the-wire messages are processed by the - monitor after authentication. In fact, the monitor thinks it's - running SSHv2, even if the on-the-wire protocol is v1. - - -A. References - - The IETF SECSH Working Group: - - http://www.ietf.org/html.charters/secsh-charter.html - - The SSHv2 architecture, assigned numbers: - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-architecture-16.txt - http://www.ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-06.txt - - New cipher modes for SSHv2: - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-newmodes-02.txt - - The SSHv2 "transport," including initial key exchange and re-key - protocols, but excluding negotiable DH group size and GSS-API-based - key exchange: - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-transport-18.txt - - Additional key exchange protocols for SSHv2: - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt - http://www.ietf.org/internet-drafts/draft-ietf-secsh-dh-group-exchange-04.txt - - Base user authentication spec for SSHv2 (includes none, password, - pubkey and hostbased user authentication): - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-userauth-21.txt - - SSHv2 user authentication using PAM-style prompting: - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-auth-kbdinteract-06.txt - - SSHv2 user authentication using the GSS-API: - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt - - SSHv2 "session" protocol (i.e., the protocol used for pty sessions, - port forwarding, agent forwarding, X display forwarding, etc...): - - http://www.ietf.org/internet-drafts/draft-ietf-secsh-connect-19.txt diff --git a/usr/src/cmd/ssh/THIRDPARTYLICENSE.descrip b/usr/src/cmd/ssh/THIRDPARTYLICENSE.descrip deleted file mode 100644 index 7e936fffc7..0000000000 --- a/usr/src/cmd/ssh/THIRDPARTYLICENSE.descrip +++ /dev/null @@ -1 +0,0 @@ -OPENSSH SOFTWARE diff --git a/usr/src/cmd/ssh/doc/COPYING.Ylonen b/usr/src/cmd/ssh/doc/COPYING.Ylonen deleted file mode 100644 index ad17df17a0..0000000000 --- a/usr/src/cmd/ssh/doc/COPYING.Ylonen +++ /dev/null @@ -1,70 +0,0 @@ -This file is part of the ssh software, Copyright (c) 1995 Tatu Ylonen, Finland - - -COPYING POLICY AND OTHER LEGAL ISSUES - -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". - -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. - -[ RSA is no longer included. ] -[ IDEA is no longer included. ] -[ DES is now external. ] -[ GMP is now external. No more GNU licence. ] -[ Zlib is now external. ] -[ The make-ssh-known-hosts script is no longer included. ] -[ TSS has been removed. ] -[ MD5 is now external. ] -[ RC4 support has been removed (RC4 is used internally for arc4random). ] -[ Blowfish is now external. ] - -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. - -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. - -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. diff --git a/usr/src/cmd/ssh/doc/CREDITS b/usr/src/cmd/ssh/doc/CREDITS deleted file mode 100644 index 8831cdd5ac..0000000000 --- a/usr/src/cmd/ssh/doc/CREDITS +++ /dev/null @@ -1,87 +0,0 @@ -Tatu Ylonen <ylo@cs.hut.fi> - Creator of SSH - -Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, -Theo de Raadt, and Dug Song - Creators of OpenSSH - -Alain St-Denis <Alain.St-Denis@ec.gc.ca> - Irix fix -Alexandre Oliva <oliva@lsd.ic.unicamp.br> - AIX fixes -Andre Lucas <andre.lucas@dial.pipex.com> - new login code, many fixes -Andreas Steinmetz <ast@domdv.de> - Shadow password expiry support -Andrew McGill <andrewm@datrix.co.za> - SCO fixes -Andrew Stribblehill <a.d.stribblehill@durham.ac.uk> - Bugfixes -Andy Sloane <andy@guildsoftware.com> - bugfixes -Aran Cox <acox@cv.telegroup.com> - SCO bugfixes -Arkadiusz Miskiewicz <misiek@pld.org.pl> - IPv6 compat fixes -Ben Lindstrom <mouring@pconline.com> - NeXT support -Ben Taylor <bent@clark.net> - Solaris debugging and fixes -Bratislav ILICH <bilic@zepter.ru> - Configure fix -Charles Levert <charles@comm.polymtl.ca> - SunOS 4 & bug fixes -Chip Salzenberg <chip@valinux.com> - Assorted patches -Chris Adams <cmadams@hiwaay.net> - OSF SIA support -Chris Saia <csaia@wtower.com> - SuSE packaging -Chris, the Young One <cky@pobox.com> - Password auth fixes -Christos Zoulas <christos@zoulas.com> - Autoconf fixes -Chun-Chung Chen <cjj@u.washington.edu> - RPM fixes -Corinna Vinschen <vinschen@cygnus.com> - Cygwin support -Dan Brosemer <odin@linuxfreak.com> - Autoconf support, build fixes -Darren Hall <dhall@virage.org> - AIX patches -David Agraz <dagraz@jahoopa.com> - Build fixes -David Del Piero <David.DelPiero@qed.qld.gov.au> - bug fixes -David Hesprich <darkgrue@gue-tech.org> - Configure fixes -David Rankin <drankin@bohemians.lexington.ky.us> - libwrap, AIX, NetBSD fixes -Ed Eden <ede370@stl.rural.usda.gov> - configure fixes -Garrick James <garrick@james.net> - configure fixes -Gary E. Miller <gem@rellim.com> - SCO support -Ged Lodder <lodder@yacc.com.au> - HPUX fixes and enhancements -Gert Doering <gd@hilb1.medat.de> - bug and portability fixes -HARUYAMA Seigo <haruyama@nt.phys.s.u-tokyo.ac.jp> - Translations & doc fixes -Hideaki YOSHIFUJI <yoshfuji@ecei.tohoku.ac.jp> - IPv6 and bug fixes -Hiroshi Takekawa <takekawa@sr3.t.u-tokyo.ac.jp> - Configure fixes -Holger Trapp <Holger.Trapp@Informatik.TU-Chemnitz.DE> - KRB4/AFS config patch -IWAMURO Motonori <iwa@mmp.fujitsu.co.jp> - bugfixes -Jani Hakala <jahakala@cc.jyu.fi> - Patches -Jarno Huuskonen <jhuuskon@hytti.uku.fi> - Bugfixes -Jim Knoble <jmknoble@pobox.com> - Many patches -Jonchen (email unknown) - the original author of PAM support of SSH -Juergen Keil <jk@tools.de> - scp bugfixing -KAMAHARA Junzo <kamahara@cc.kshosen.ac.jp> - Configure fixes -Kees Cook <cook@cpoint.net> - scp fixes -Kenji Miyake <kenji@miyake.org> - Configure fixes -Kevin O'Connor <kevin_oconnor@standardandpoors.com> - RSAless operation -Kevin Steves <stevesk@sweden.hp.com> - HP support, bugfixes, improvements -Kiyokazu SUTO <suto@ks-and-ks.ne.jp> - Bugfixes -Larry Jones <larry.jones@sdrc.com> - Bugfixes -Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - Bugfixes -Marc G. Fournier <marc.fournier@acadiau.ca> - Solaris patches -Martin Johansson <fatbob@acc.umu.se> - Linux fixes -Mark Miller <markm@swoon.net> - Bugfixes -Matt Richards <v2matt@btv.ibm.com> - AIX patches -Michael Stone <mstone@cs.loyola.edu> - Irix enhancements -Nakaji Hiroyuki <nakaji@tutrp.tut.ac.jp> - Sony News-OS patch -Nalin Dahyabhai <nalin.dahyabhai@pobox.com> - PAM environment patch -Nate Itkin <nitkin@europa.com> - SunOS 4.1.x fixes -Niels Kristian Bech Jensen <nkbj@image.dk> - Assorted patches -Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> - Security fixes -Pavel Troller <patrol@omni.sinus.cz> - Bugfixes -Pekka Savola <pekkas@netcore.fi> - Bugfixes -Peter Kocks <peter.kocks@baygate.com> - Makefile fixes -Phil Hands <phil@hands.com> - Debian scripts, assorted patches -Phil Karn <karn@ka9q.ampr.org> - Autoconf fixes -Philippe WILLEM <Philippe.WILLEM@urssaf.fr> - Bugfixes -Phill Camp <P.S.S.Camp@ukc.ac.uk> - login code fix -Rip Loomis <loomisg@cist.saic.com> - Solaris package support, fixes -SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp> - Multiple bugfixes -Simon Wilkinson <sxw@dcs.ed.ac.uk> - PAM fixes -Svante Signell <svante.signell@telia.com> - Bugfixes -Thomas Neumann <tom@smart.ruhr.de> - Shadow passwords -Tim Rice <tim@multitalents.net> - Portability & SCO fixes -Tobias Oetiker <oetiker@ee.ethz.ch> - Bugfixes -Tom Bertelson's <tbert@abac.com> - AIX auth fixes -Tor-Ake Fransson <torake@hotmail.com> - AIX support -Tudor Bosman <tudorb@jm.nu> - MD5 password support -Udo Schweigert <ust@cert.siemens.de> - ReliantUNIX support -Zack Weinberg <zack@wolery.cumb.org> - GNOME askpass enhancement - -Apologies to anyone I have missed. - -Damien Miller <djm@mindrot.org> diff --git a/usr/src/cmd/ssh/doc/ChangeLog b/usr/src/cmd/ssh/doc/ChangeLog deleted file mode 100644 index 7333c81a3e..0000000000 --- a/usr/src/cmd/ssh/doc/ChangeLog +++ /dev/null @@ -1,2590 +0,0 @@ -20001106 - - (djm) Use Jim's new 1.0.3 askpass in Redhat RPMs - - (djm) Manually fix up missed diff hunks (mainly RCS idents) - - (djm) Remove UPGRADING document in favour of a link to the better - maintained FAQ on www.openssh.com - - (djm) Fix multiple dependancy on gnome-libs from Pekka Savola - <pekkas@netcore.fi> - - (djm) Don't need X11-askpass in RPM spec file if building without it - from Pekka Savola <pekkas@netcore.fi> - - (djm) Release 2.3.0p1 - -20001105 - - (bal) Sync with OpenBSD: - - markus@cvs.openbsd.org 2000/10/31 9:31:58 - [compat.c] - handle all old openssh versions - - markus@cvs.openbsd.org 2000/10/31 13:1853 - [deattack.c] - so that large packets do not wrap "n"; from netbsd - - (bal) rijndel.c - fix up RCSID to match OpenBSD tree - - (bal) auth2-skey.c - Checked in. Missing from portable tree. - - (bal) Reworked NEWS-OS and NeXT ports to extract waitpid() and - setsid() into more common files - - (stevesk) pty.c: use __hpux to identify HP-UX. - - (bal) Missed auth-skey.o in Makefile.in and minor correction to - bsd-waitpid.c - -20001029 - - (stevesk) Fix typo in auth.c: USE_PAM not PAM - - (stevesk) Create contrib/cygwin/ directory; patch from - Corinna Vinschen <vinschen@redhat.com> - - (bal) Resolved more $xno and $xyes issues in configure.in - - (bal) next-posix.h - spelling and forgot a prototype - -20001028 - - (djm) fix select hack in serverloop.c from Philippe WILLEM - <Philippe.WILLEM@urssaf.fr> - - (djm) Fix mangled AIXAUTHENTICATE code - - (djm) authctxt->pw may be NULL. Fix from Markus Friedl - <markus.friedl@informatik.uni-erlangen.de> - - (djm) Sync with OpenBSD: - - markus@cvs.openbsd.org 2000/10/16 15:46:32 - [ssh.1] - fixes from pekkas@netcore.fi - - markus@cvs.openbsd.org 2000/10/17 14:28:11 - [atomicio.c] - return number of characters processed; ok deraadt@ - - markus@cvs.openbsd.org 2000/10/18 12:04:02 - [atomicio.c] - undo - - markus@cvs.openbsd.org 2000/10/18 12:23:02 - [scp.c] - replace atomicio(read,...) with read(); ok deraadt@ - - markus@cvs.openbsd.org 2000/10/18 12:42:00 - [session.c] - restore old record login behaviour - - deraadt@cvs.openbsd.org 2000/10/19 10:41:13 - [auth-skey.c] - fmt string problem in unused code - - provos@cvs.openbsd.org 2000/10/19 10:45:16 - [sshconnect2.c] - don't reference freed memory. okay deraadt@ - - markus@cvs.openbsd.org 2000/10/21 11:04:23 - [canohost.c] - typo, eramore@era-t.ericsson.se; ok niels@ - - markus@cvs.openbsd.org 2000/10/23 13:31:55 - [cipher.c] - non-alignment dependent swap_bytes(); from - simonb@wasabisystems.com/netbsd - - markus@cvs.openbsd.org 2000/10/26 12:38:28 - [compat.c] - add older vandyke products - - markus@cvs.openbsd.org 2000/10/27 01:32:19 - [channels.c channels.h clientloop.c serverloop.c session.c] - [ssh.c util.c] - enable non-blocking IO on channels, and tty's (except for the - client ttys). - -20001027 - - (djm) Increase REKEY_BYTES to 2^24 for arc4random - -20001025 - - (djm) Added WARNING.RNG file and modified configure to ask users of the - builtin entropy code to read it. - - (djm) Prefer builtin regex to PCRE. - - (bal) Added USE_PIPS defined to NeXT configure.in since scp hangs randomly. - - (bal) Apply fixes to configure.in pointed out by Pavel Roskin - <proski@gnu.org> - -20001020 - - (djm) Don't define _REENTRANT for SNI/Reliant Unix - - (bal) Imported NEWS-OS waitpid() macros into NeXT. Since implementation - is more correct then current version. - -20001018 - - (stevesk) Add initial support for setproctitle(). Current - support is for the HP-UX pstat(PSTAT_SETCMD, ...) method. - - (stevesk) Add egd startup scripts to contrib/hpux/ - -20001017 - - (djm) Add -lregex to cywin libs from Corinna Vinschen - <vinschen@cygnus.com> - - (djm) Don't rely on atomicio's retval to determine length of askpass - supplied passphrase. Problem report from Lutz Jaenicke - <Lutz.Jaenicke@aet.TU-Cottbus.DE> - - (bal) Changed from GNU rx to PCRE on suggestion from djm. - - (bal) Integrated Sony NEWS-OS patches from NAKAJI Hirouyuki - <nakaji@tutrp.tut.ac.jp> - -20001016 - - (djm) Sync with OpenBSD: - - markus@cvs.openbsd.org 2000/10/14 04:01:15 - [cipher.c] - debug3 - - markus@cvs.openbsd.org 2000/10/14 04:07:23 - [scp.c] - remove spaces from arguments; from djm@mindrot.org - - markus@cvs.openbsd.org 2000/10/14 06:09:46 - [ssh.1] - Cipher is for SSH-1 only - - markus@cvs.openbsd.org 2000/10/14 06:12:09 - [servconf.c servconf.h serverloop.c session.c sshd.8] - AllowTcpForwarding; from naddy@ - - markus@cvs.openbsd.org 2000/10/14 06:16:56 - [auth2.c compat.c compat.h sshconnect2.c version.h] - OpenSSH_2.3; note that is is not complete, but the version number - needs to be changed for interoperability reasons - - markus@cvs.openbsd.org 2000/10/14 06:19:45 - [auth-rsa.c] - do not send RSA challenge if key is not allowed by key-options; from - eivind@ThinkSec.com - - markus@cvs.openbsd.org 2000/10/15 08:14:01 - [rijndael.c session.c] - typos; from stevesk@sweden.hp.com - - markus@cvs.openbsd.org 2000/10/15 08:18:31 - [rijndael.c] - typo - - (djm) Copy manpages back over from OpenBSD - too tedious to wade - through diffs - - (djm) Added condrestart to Redhat init script. Patch from Pekka Savola - <pekkas@netcore.fi> - - (djm) Update version in Redhat spec file - - (djm) Merge some of Nalin Dahyabhai <nalin@redhat.com> changes from the - Redhat 7.0 spec file - - (djm) Make inability to read/write PRNG seedfile non-fatal - - -20001015 - - (djm) Fix ssh2 hang on background processes at logout. - -20001014 - - (bal) Add support for realpath and getcwd for platforms with broken - or missing realpath implementations for sftp-server. - - (bal) Corrected mistake in INSTALL in regards to GNU rx library - - (bal) Add support for GNU rx library for those lacking regexp support - - (djm) Don't accept PAM_PROMPT_ECHO_ON messages during initial auth - - (djm) Revert SSH2 serverloop hack, will find a better way. - - (djm) Add workaround for Linux 2.4's gratuitious errno change. Patch - from Martin Johansson <fatbob@acc.umu.se> - - (djm) Big OpenBSD sync: - - markus@cvs.openbsd.org 2000/09/30 10:27:44 - [log.c] - allow loglevel debug - - markus@cvs.openbsd.org 2000/10/03 11:59:57 - [packet.c] - hmac->mac - - markus@cvs.openbsd.org 2000/10/03 12:03:03 - [auth-krb4.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c auth1.c] - move fake-auth from auth1.c to individual auth methods, disables s/key in - debug-msg - - markus@cvs.openbsd.org 2000/10/03 12:16:48 - ssh.c - do not resolve canonname, i have no idea why this was added oin ossh - - markus@cvs.openbsd.org 2000/10/09 15:30:44 - ssh-keygen.1 ssh-keygen.c - -X now reads private ssh.com DSA keys, too. - - markus@cvs.openbsd.org 2000/10/09 15:32:34 - auth-options.c - clear options on every call. - - markus@cvs.openbsd.org 2000/10/09 15:51:00 - authfd.c authfd.h - interop with ssh-agent2, from <res@shore.net> - - markus@cvs.openbsd.org 2000/10/10 14:20:45 - compat.c - use rexexp for version string matching - - provos@cvs.openbsd.org 2000/10/10 22:02:18 - [kex.c kex.h myproposal.h ssh.h ssh2.h sshconnect2.c sshd.c dh.c dh.h] - First rough implementation of the diffie-hellman group exchange. The - client can ask the server for bigger groups to perform the diffie-hellman - in, thus increasing the attack complexity when using ciphers with longer - keys. University of Windsor provided network, T the company. - - markus@cvs.openbsd.org 2000/10/11 13:59:52 - [auth-rsa.c auth2.c] - clear auth options unless auth sucessfull - - markus@cvs.openbsd.org 2000/10/11 14:00:27 - [auth-options.h] - clear auth options unless auth sucessfull - - markus@cvs.openbsd.org 2000/10/11 14:03:27 - [scp.1 scp.c] - support 'scp -o' with help from mouring@pconline.com - - markus@cvs.openbsd.org 2000/10/11 14:11:35 - [dh.c] - Wall - - markus@cvs.openbsd.org 2000/10/11 14:14:40 - [auth.h auth2.c readconf.c readconf.h readpass.c servconf.c servconf.h] - [ssh.h sshconnect2.c sshd_config auth2-skey.c cli.c cli.h] - add support for s/key (kbd-interactive) to ssh2, based on work by - mkiernan@avantgo.com and me - - markus@cvs.openbsd.org 2000/10/11 14:27:24 - [auth.c auth1.c auth2.c authfile.c cipher.c cipher.h kex.c kex.h] - [myproposal.h packet.c readconf.c session.c ssh.c ssh.h sshconnect1.c] - [sshconnect2.c sshd.c] - new cipher framework - - markus@cvs.openbsd.org 2000/10/11 14:45:21 - [cipher.c] - remove DES - - markus@cvs.openbsd.org 2000/10/12 03:59:20 - [cipher.c cipher.h sshconnect1.c sshconnect2.c sshd.c] - enable DES in SSH-1 clients only - - markus@cvs.openbsd.org 2000/10/12 08:21:13 - [kex.h packet.c] - remove unused - - markus@cvs.openbsd.org 2000/10/13 12:34:46 - [sshd.c] - Kludge for F-Secure Macintosh < 1.0.2; appro@fy.chalmers.se - - markus@cvs.openbsd.org 2000/10/13 12:59:15 - [cipher.c cipher.h myproposal.h rijndael.c rijndael.h] - rijndael/aes support - - markus@cvs.openbsd.org 2000/10/13 13:10:54 - [sshd.8] - more info about -V - - markus@cvs.openbsd.org 2000/10/13 13:12:02 - [myproposal.h] - prefer no compression - - (djm) Fix scp user@host handling - - (djm) Don't clobber ssh_prng_cmds on install - - (stevesk) Include config.h in rijndael.c so we define intXX_t and - u_intXX_t types on all platforms. - - (stevesk) rijndael.c: cleanup missing declaration warnings. - - (stevesk) ~/.hushlogin shouldn't cause required password change to - be bypassed. - - (stevesk) Display correct path to ssh-askpass in configure output. - Report from Lutz Jaenicke. - -20001007 - - (stevesk) Print PAM return value in PAM log messages to aid - with debugging. - - (stevesk) Fix detection of pw_class struct member in configure; - patch from KAMAHARA Junzo <kamahara@cc.kshosen.ac.jp> - -20001002 - - (djm) Fix USER_PATH, report from Kevin Steves <stevesk@sweden.hp.com> - - (djm) Add host system and CC to end-of-configure report. Suggested by - Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - -20000931 - - (djm) Cygwin fixes from Corinna Vinschen <vinschen@cygnus.com> - -20000930 - - (djm) Irix ssh_prng_cmds path fix from Pekka Savola <pekkas@netcore.fi> - - (djm) Support in bsd-snprintf.c for long long conversions from - Ben Lindstrom <mouring@pconline.com> - - (djm) Cleanup NeXT support from Ben Lindstrom <mouring@pconline.com> - - (djm) Ignore SIGPIPEs from serverloop to child. Fixes crashes with - very short lived X connections. Bug report from Tobias Oetiker - <oetiker@ee.ethz.ch>. Fix from Markus Friedl <markus@cvs.openbsd.org> - - (djm) Add recent InitScripts as a RPM dependancy for openssh-server - patch from Pekka Savola <pekkas@netcore.fi> - - (djm) Forgot to cvs add LICENSE file - - (djm) Add LICENSE to RPM spec files - - (djm) CVS OpenBSD sync: - - markus@cvs.openbsd.org 2000/09/26 13:59:59 - [clientloop.c] - use debug2 - - markus@cvs.openbsd.org 2000/09/27 15:41:34 - [auth2.c sshconnect2.c] - use key_type() - - markus@cvs.openbsd.org 2000/09/28 12:03:18 - [channels.c] - debug -> debug2 cleanup - - (djm) Irix strips "/dev/tty" from [uw]tmp entries (other systems only - strip "/dev/"). Fix loginrec.c based on patch from Alain St-Denis - <Alain.St-Denis@ec.gc.ca> - - (djm) Fix 9 character passphrase failure with gnome-ssh-askpass. - Problem was caused by interrupted read in ssh-add. Report from Donald - J. Barry <don@astro.cornell.edu> - -20000929 - - (djm) Fix SSH2 not terminating until all background tasks done problem. - - (djm) Another off-by-one fix from Pavel Kankovsky - <peak@argo.troja.mff.cuni.cz> - - (djm) Clean up. Strip some unnecessary differences with OpenBSD's code, - tidy necessary differences. Use Markus' new debugN() in entropy.c - - (djm) Merged big SCO portability patch from Tim Rice - <tim@multitalents.net> - -20000926 - - (djm) Update X11-askpass to 1.0.2 in RPM spec file - - (djm) Define _REENTRANT to pickup strtok_r() on HP/UX - - (djm) Security: fix off-by-one buffer overrun in fake-getnameinfo.c. - Report and fix from Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> - -20000924 - - (djm) Merged cleanup patch from Mark Miller <markm@swoon.net> - - (djm) A bit more cleanup - created cygwin_util.h - - (djm) Include strtok_r() from OpenBSD libc. Fixes report from Mark Miller - <markm@swoon.net> - -20000923 - - (djm) Fix address logging in utmp from Kevin Steves - <stevesk@sweden.hp.com> - - (djm) Redhat spec and manpage fixes from Pekka Savola <pekkas@netcore.fi> - - (djm) Seperate tests for int64_t and u_int64_t types - - (djm) Tweak password expiry checking at suggestion of Kevin Steves - <stevesk@sweden.hp.com> - - (djm) NeXT patch from Ben Lindstrom <mouring@pconline.com> - - (djm) Use printf %lld instead of %qd in sftp-server.c. Fix from - Michael Stone <mstone@cs.loyola.edu> - - (djm) OpenBSD CVS sync: - - markus@cvs.openbsd.org 2000/09/17 09:38:59 - [sshconnect2.c sshd.c] - fix DEBUG_KEXDH - - markus@cvs.openbsd.org 2000/09/17 09:52:51 - [sshconnect.c] - yes no; ok niels@ - - markus@cvs.openbsd.org 2000/09/21 04:55:11 - [sshd.8] - typo - - markus@cvs.openbsd.org 2000/09/21 05:03:54 - [serverloop.c] - typo - - markus@cvs.openbsd.org 2000/09/21 05:11:42 - scp.c - utime() to utimes(); mouring@pconline.com - - markus@cvs.openbsd.org 2000/09/21 05:25:08 - sshconnect2.c - change login logic in ssh2, allows plugin of other auth methods - - markus@cvs.openbsd.org 2000/09/21 05:25:35 - [auth2.c channels.c channels.h clientloop.c dispatch.c dispatch.h] - [serverloop.c] - add context to dispatch_run - - markus@cvs.openbsd.org 2000/09/21 05:07:52 - authfd.c authfd.h ssh-agent.c - bug compat for old ssh.com software - -20000920 - - (djm) Fix bad path substitution. Report from Andrew Miner - <asminer@cs.iastate.edu> - -20000916 - - (djm) Fix SSL search order from Lutz Jaenicke - <Lutz.Jaenicke@aet.TU-Cottbus.DE> - - (djm) New SuSE spec from Corinna Vinschen <corinna@vinschen.de> - - (djm) Update CygWin support from Corinna Vinschen <vinschen@cygnus.com> - - (djm) Use a real struct sockaddr inside the fake struct sockaddr_storage. - Patch from Larry Jones <larry.jones@sdrc.com> - - (djm) Add Steve VanDevender's <stevev@darkwing.uoregon.edu> PAM - password change patch. - - (djm) Bring licenses on my stuff in line with OpenBSD's - - (djm) Cleanup auth-passwd.c and unify HP/UX authentication. Patch from - Kevin Steves <stevesk@sweden.hp.com> - - (djm) Shadow expiry check fix from Pavel Troller <patrol@omni.sinus.cz> - - (djm) Re-enable int64_t types - we need them for sftp - - (djm) Use libexecdir from configure , rather than libexecdir/ssh - - (djm) Update Redhat SPEC file accordingly - - (djm) Add Kevin Steves <stevesk@sweden.hp.com> HP/UX contrib files - - (djm) Add Charles Levert <charles@comm.polymtl.ca> getpgrp patch - - (djm) Fix password auth on HP/UX 10.20. Patch from Dirk De Wachter - <Dirk.DeWachter@rug.ac.be> - - (djm) Fixprogs and entropy list fixes from Larry Jones - <larry.jones@sdrc.com> - - (djm) Fix for SuSE spec file from Takashi YOSHIDA - <tyoshida@gemini.rc.kyushu-u.ac.jp> - - (djm) Merge OpenBSD changes: - - markus@cvs.openbsd.org 2000/09/05 02:59:57 - [session.c] - print hostname (not hushlogin) - - markus@cvs.openbsd.org 2000/09/05 13:18:48 - [authfile.c ssh-add.c] - enable ssh-add -d for DSA keys - - markus@cvs.openbsd.org 2000/09/05 13:20:49 - [sftp-server.c] - cleanup - - markus@cvs.openbsd.org 2000/09/06 03:46:41 - [authfile.h] - prototype - - deraadt@cvs.openbsd.org 2000/09/07 14:27:56 - [ALL] - cleanup copyright notices on all files. I have attempted to be - accurate with the details. everything is now under Tatu's licence - (which I copied from his readme), and/or the core-sdi bsd-ish thing - for deattack, or various openbsd developers under a 2-term bsd - licence. We're not changing any rules, just being accurate. - - markus@cvs.openbsd.org 2000/09/07 14:40:30 - [channels.c channels.h clientloop.c serverloop.c ssh.c] - cleanup window and packet sizes for ssh2 flow control; ok niels - - markus@cvs.openbsd.org 2000/09/07 14:53:00 - [scp.c] - typo - - markus@cvs.openbsd.org 2000/09/07 15:13:37 - [auth-options.c auth-options.h auth-rh-rsa.c auth-rsa.c auth.c] - [authfile.h canohost.c channels.h compat.c hostfile.h log.c match.h] - [pty.c readconf.c] - some more Copyright fixes - - markus@cvs.openbsd.org 2000/09/08 03:02:51 - [README.openssh2] - bye bye - - deraadt@cvs.openbsd.org 2000/09/11 18:38:33 - [LICENCE cipher.c] - a few more comments about it being ARC4 not RC4 - - markus@cvs.openbsd.org 2000/09/12 14:53:11 - [log-client.c log-server.c log.c ssh.1 ssh.c ssh.h sshd.8 sshd.c] - multiple debug levels - - markus@cvs.openbsd.org 2000/09/14 14:25:15 - [clientloop.c] - typo - - deraadt@cvs.openbsd.org 2000/09/15 01:13:51 - [ssh-agent.c] - check return value for setenv(3) for failure, and deal appropriately - -20000913 - - (djm) Fix server not exiting with jobs in background. - -20000905 - - (djm) Import OpenBSD CVS changes - - markus@cvs.openbsd.org 2000/08/31 15:52:24 - [Makefile sshd.8 sshd_config sftp-server.8 sftp-server.c] - implement a SFTP server. interops with sftp2, scp2 and the windows - client from ssh.com - - markus@cvs.openbsd.org 2000/08/31 15:56:03 - [README.openssh2] - sync - - markus@cvs.openbsd.org 2000/08/31 16:05:42 - [session.c] - Wall - - markus@cvs.openbsd.org 2000/08/31 16:09:34 - [authfd.c ssh-agent.c] - add a flag to SSH2_AGENTC_SIGN_REQUEST for future extensions - - deraadt@cvs.openbsd.org 2000/09/01 09:25:13 - [scp.1 scp.c] - cleanup and fix -S support; stevesk@sweden.hp.com - - markus@cvs.openbsd.org 2000/09/01 16:29:32 - [sftp-server.c] - portability fixes - - markus@cvs.openbsd.org 2000/09/01 16:32:41 - [sftp-server.c] - fix cast; mouring@pconline.com - - itojun@cvs.openbsd.org 2000/09/03 09:23:28 - [ssh-add.1 ssh.1] - add missing .El against .Bl. - - markus@cvs.openbsd.org 2000/09/04 13:03:41 - [session.c] - missing close; ok theo - - markus@cvs.openbsd.org 2000/09/04 13:07:21 - [session.c] - fix get_last_login_time order; from andre@van-veen.de - - markus@cvs.openbsd.org 2000/09/04 13:10:09 - [sftp-server.c] - more cast fixes; from mouring@pconline.com - - markus@cvs.openbsd.org 2000/09/04 13:06:04 - [session.c] - set SSH_ORIGINAL_COMMAND; from Leakin@dfw.nostrum.com, bet@rahul.net - - (djm) Cleanup after import. Fix sftp-server compilation, Makefile - - (djm) Merge cygwin support from Corinna Vinschen <vinschen@cygnus.com> - -20000903 - - (djm) Fix Redhat init script - -20000901 - - (djm) Pick up Jim's new X11-askpass - - (djm) Release 2.2.0p1 - -20000831 - - (djm) Workaround SIGPIPE problems on SCO. Fix from Aran Cox - <acox@cv.telegroup.com> - - (djm) Pick up new version (2.2.0) from OpenBSD CVS - -20000830 - - (djm) Compile warning fixes from Mark Miller <markm@swoon.net> - - (djm) Periodically rekey arc4random - - (djm) Clean up diff against OpenBSD. - - (djm) HPUX 11 needs USE_PIPES as well: Kevin Steves - <stevesk@sweden.hp.com> - - (djm) Quieten the pam delete credentials error message - - (djm) Fix printing of $DISPLAY hack if set by system type. Report from - Kevin Steves <stevesk@sweden.hp.com> - - (djm) NeXT patch from Ben Lindstrom <mouring@pconline.com> - - (djm) Fix doh in bsd-arc4random.c - -20000829 - - (djm) Fix ^C ignored issue on Solaris. Diagnosis from Gert - Doering <gert@greenie.muc.de>, John Horne <J.Horne@plymouth.ac.uk> and - Garrick James <garrick@james.net> - - (djm) Check for SCO pty naming style (ptyp%d/ttyp%d). Based on fix from - Bastian Trompetter <btrompetter@firemail.de> - - (djm) NeXT tweaks from Ben Lindstrom <mouring@pconline.com> - - More OpenBSD updates: - - deraadt@cvs.openbsd.org 2000/08/24 15:46:59 - [scp.c] - off_t in sink, to fix files > 2GB, i think, test is still running ;-) - - deraadt@cvs.openbsd.org 2000/08/25 10:10:06 - [session.c] - Wall - - markus@cvs.openbsd.org 2000/08/26 04:33:43 - [compat.c] - ssh.com-2.3.0 - - markus@cvs.openbsd.org 2000/08/27 12:18:05 - [compat.c] - compatibility with future ssh.com versions - - deraadt@cvs.openbsd.org 2000/08/27 21:50:55 - [auth-krb4.c session.c ssh-add.c sshconnect.c uidswap.c] - print uid/gid as unsigned - - markus@cvs.openbsd.org 2000/08/28 13:51:00 - [ssh.c] - enable -n and -f for ssh2 - - markus@cvs.openbsd.org 2000/08/28 14:19:53 - [ssh.c] - allow combination of -N and -f - - markus@cvs.openbsd.org 2000/08/28 14:20:56 - [util.c] - util.c - - markus@cvs.openbsd.org 2000/08/28 14:22:02 - [util.c] - undo - - markus@cvs.openbsd.org 2000/08/28 14:23:38 - [util.c] - don't complain if setting NONBLOCK fails with ENODEV - -20000823 - - (djm) Define USE_PIPES to avoid socketpair problems on HPUX 10 and SunOS 4 - Avoids "scp never exits" problem. Reports from Lutz Jaenicke - <Lutz.Jaenicke@aet.TU-Cottbus.DE> and Tamito KAJIYAMA - <kajiyama@grad.sccs.chukyo-u.ac.jp> - - (djm) Pick up LOGIN_PROGRAM from environment or PATH if not set by headers - - (djm) Add local version to version.h - - (djm) Don't reseed arc4random everytime it is used - - (djm) OpenBSD CVS updates: - - deraadt@cvs.openbsd.org 2000/08/18 20:07:23 - [ssh.c] - accept remsh as a valid name as well; roman@buildpoint.com - - deraadt@cvs.openbsd.org 2000/08/18 20:17:13 - [deattack.c crc32.c packet.c] - rename crc32() to ssh_crc32() to avoid zlib name clash. do not move to - libz crc32 function yet, because it has ugly "long"'s in it; - oneill@cs.sfu.ca - - deraadt@cvs.openbsd.org 2000/08/18 20:26:08 - [scp.1 scp.c] - -S prog support; tv@debian.org - - deraadt@cvs.openbsd.org 2000/08/18 20:50:07 - [scp.c] - knf - - deraadt@cvs.openbsd.org 2000/08/18 20:57:33 - [log-client.c] - shorten - - markus@cvs.openbsd.org 2000/08/19 12:48:11 - [channels.c channels.h clientloop.c ssh.c ssh.h] - support for ~. in ssh2 - - deraadt@cvs.openbsd.org 2000/08/19 15:29:40 - [crc32.h] - proper prototype - - markus@cvs.openbsd.org 2000/08/19 15:34:44 - [authfd.c authfd.h key.c key.h ssh-add.1 ssh-add.c ssh-agent.1] - [ssh-agent.c ssh-keygen.c sshconnect1.c sshconnect2.c Makefile] - [fingerprint.c fingerprint.h] - add SSH2/DSA support to the agent and some other DSA related cleanups. - (note that we cannot talk to ssh.com's ssh2 agents) - - markus@cvs.openbsd.org 2000/08/19 15:55:52 - [channels.c channels.h clientloop.c] - more ~ support for ssh2 - - markus@cvs.openbsd.org 2000/08/19 16:21:19 - [clientloop.c] - oops - - millert@cvs.openbsd.org 2000/08/20 12:25:53 - [session.c] - We have to stash the result of get_remote_name_or_ip() before we - close our socket or getpeername() will get EBADF and the process - will exit. Only a problem for "UseLogin yes". - - millert@cvs.openbsd.org 2000/08/20 12:30:59 - [session.c] - Only check /etc/nologin if "UseLogin no" since login(1) may have its - own policy on determining who is allowed to login when /etc/nologin - is present. Also use the _PATH_NOLOGIN define. - - millert@cvs.openbsd.org 2000/08/20 12:42:43 - [auth1.c auth2.c session.c ssh.c] - Add calls to setusercontext() and login_get*(). We basically call - setusercontext() in most places where previously we did a setlogin(). - Add default login.conf file and put root in the "daemon" login class. - - millert@cvs.openbsd.org 2000/08/21 10:23:31 - [session.c] - Fix incorrect PATH setting; noted by Markus. - -20000818 - - (djm) OpenBSD CVS changes: - - markus@cvs.openbsd.org 2000/07/22 03:14:37 - [servconf.c servconf.h sshd.8 sshd.c sshd_config] - random early drop; ok theo, niels - - deraadt@cvs.openbsd.org 2000/07/26 11:46:51 - [ssh.1] - typo - - deraadt@cvs.openbsd.org 2000/08/01 11:46:11 - [sshd.8] - many fixes from pepper@mail.reppep.com - - provos@cvs.openbsd.org 2000/08/01 13:01:42 - [Makefile.in util.c aux.c] - rename aux.c to util.c to help with cygwin port - - deraadt@cvs.openbsd.org 2000/08/02 00:23:31 - [authfd.c] - correct sun_len; Alexander@Leidinger.net - - provos@cvs.openbsd.org 2000/08/02 10:27:17 - [readconf.c sshd.8] - disable kerberos authentication by default - - provos@cvs.openbsd.org 2000/08/02 11:27:05 - [sshd.8 readconf.c auth-krb4.c] - disallow kerberos authentication if we can't verify the TGT; from - dugsong@ - kerberos authentication is on by default only if you have a srvtab. - - markus@cvs.openbsd.org 2000/08/04 14:30:07 - [auth.c] - unused - - markus@cvs.openbsd.org 2000/08/04 14:30:35 - [sshd_config] - MaxStartups - - markus@cvs.openbsd.org 2000/08/15 13:20:46 - [authfd.c] - cleanup; ok niels@ - - markus@cvs.openbsd.org 2000/08/17 14:05:10 - [session.c] - cleanup login(1)-like jobs, no duplicate utmp entries - - markus@cvs.openbsd.org 2000/08/17 14:06:34 - [session.c sshd.8 sshd.c] - sshd -u len, similar to telnetd - - (djm) Lastlog was not getting closed after writing login entry - - (djm) Add Solaris package support from Rip Loomis <loomisg@cist.saic.com> - -20000816 - - (djm) Replacement for inet_ntoa for Irix (which breaks on gcc) - - (djm) Fix strerror replacement for old SunOS. Based on patch from - Charles Levert <charles@comm.polymtl.ca> - - (djm) Seperate arc4random into seperate file and use OpenSSL's RC4 - implementation. - - (djm) SUN_LEN macro for systems which lack it - -20000815 - - (djm) More SunOS 4.1.x fixes from Nate Itkin <nitkin@europa.com> - - (djm) Avoid failures on Irix when ssh is not setuid. Fix from - Michael Stone <mstone@cs.loyola.edu> - - (djm) Don't seek in directory based lastlogs - - (djm) Fix --with-ipaddr-display configure option test. Patch from - Jarno Huuskonen <jhuuskon@messi.uku.fi> - - (djm) Fix AIX limits from Alexandre Oliva <oliva@lsd.ic.unicamp.br> - -20000813 - - (djm) Add $(srcdir) to includes when compiling (for VPATH). Report from - Fabrice bacchella <fabrice.bacchella@marchfirst.fr> - -20000809 - - (djm) Define AIX hard limits if headers don't. Report from - Bill Painter <william.t.painter@lmco.com> - - (djm) utmp direct write & SunOS 4 patch from Charles Levert - <charles@comm.polymtl.ca> - -20000808 - - (djm) Cleanup Redhat RPMs. Generate keys at runtime rather than install - time, spec file cleanup. - -20000807 - - (djm) Set 0755 on binaries during install. Report from Lutz Jaenicke - - (djm) Suppress error messages on channel close shutdown() failurs - works around Linux bug. Patch from Zack Weinberg <zack@wolery.cumb.org> - - (djm) Add some more entropy collection commands from Lutz Jaenicke - -20000725 - - (djm) Fix autoconf typo: HAVE_BINRESVPORT_AF -> HAVE_BINDRESVPORT_AF - -20000721 - - (djm) OpenBSD CVS updates: - - markus@cvs.openbsd.org 2000/07/16 02:27:22 - [authfd.c authfd.h channels.c clientloop.c ssh-add.c ssh-agent.c ssh.c] - [sshconnect1.c sshconnect2.c] - make ssh-add accept dsa keys (the agent does not) - - djm@cvs.openbsd.org 2000/07/17 19:25:02 - [sshd.c] - Another closing of stdin; ok deraadt - - markus@cvs.openbsd.org 2000/07/19 18:33:12 - [dsa.c] - missing free, reorder - - markus@cvs.openbsd.org 2000/07/20 16:23:14 - [ssh-keygen.1] - document input and output files - -20000720 - - (djm) Spec file fix from Petr Novotny <Petr.Novotny@antek.cz> - -20000716 - - (djm) Release 2.1.1p4 - -20000715 - - (djm) OpenBSD CVS updates - - provos@cvs.openbsd.org 2000/07/13 16:53:22 - [aux.c readconf.c servconf.c ssh.h] - allow multiple whitespace but only one '=' between tokens, bug report from - Ralf S. Engelschall <rse@engelschall.com> but different fix. okay deraadt@ - - provos@cvs.openbsd.org 2000/07/13 17:14:09 - [clientloop.c] - typo; todd@fries.net - - provos@cvs.openbsd.org 2000/07/13 17:19:31 - [scp.c] - close can fail on AFS, report error; from Greg Hudson <ghudson@mit.edu> - - markus@cvs.openbsd.org 2000/07/14 16:59:46 - [readconf.c servconf.c] - allow leading whitespace. ok niels - - djm@cvs.openbsd.org 2000/07/14 22:01:38 - [ssh-keygen.c ssh.c] - Always create ~/.ssh with mode 700; ok Markus - - Fixes for SunOS 4.1.4 from Gordon Atwood <gordon@cs.ualberta.ca> - - Include floatingpoint.h for entropy.c - - strerror replacement - -20000712 - - (djm) Remove -lresolve for Reliant Unix - - (djm) OpenBSD CVS Updates: - - deraadt@cvs.openbsd.org 2000/07/11 02:11:34 - [session.c sshd.c ] - make MaxStartups code still work with -d; djm - - deraadt@cvs.openbsd.org 2000/07/11 13:17:45 - [readconf.c ssh_config] - disable FallBackToRsh by default - - (djm) Replace in_addr_t with u_int32_t in bsd-inet_aton.c. Report from - Ben Lindstrom <mouring@pconline.com> - - (djm) Make building of X11-Askpass and GNOME-Askpass optional in RPM - spec file. - - (djm) Released 2.1.1p3 - -20000711 - - (djm) Fixup for AIX getuserattr() support from Tom Bertelson - <tbert@abac.com> - - (djm) ReliantUNIX support from Udo Schweigert <ust@cert.siemens.de> - - (djm) NeXT: dirent structures to get scp working from Ben Lindstrom - <mouring@pconline.com> - - (djm) Fix broken inet_ntoa check and ut_user/ut_name confusion, report - from Jim Watt <jimw@peisj.pebio.com> - - (djm) Replaced bsd-snprintf.c with one from Mutt source tree, it is known - to compile on more platforms (incl NeXT). - - (djm) Added bsd-inet_aton and configure support for NeXT - - (djm) Misc NeXT fixes from Ben Lindstrom <mouring@pconline.com> - - (djm) OpenBSD CVS updates: - - markus@cvs.openbsd.org 2000/06/26 03:22:29 - [authfd.c] - cleanup, less cut&paste - - markus@cvs.openbsd.org 2000/06/26 15:59:19 - [servconf.c servconf.h session.c sshd.8 sshd.c] - MaxStartups: limit number of unauthenticated connections, work by - theo and me - - deraadt@cvs.openbsd.org 2000/07/05 14:18:07 - [session.c] - use no_x11_forwarding_flag correctly; provos ok - - provos@cvs.openbsd.org 2000/07/05 15:35:57 - [sshd.c] - typo - - aaron@cvs.openbsd.org 2000/07/05 22:06:58 - [scp.1 ssh-agent.1 ssh-keygen.1 sshd.8] - Insert more missing .El directives. Our troff really should identify - these and spit out a warning. - - todd@cvs.openbsd.org 2000/07/06 21:55:04 - [auth-rsa.c auth2.c ssh-keygen.c] - clean code is good code - - deraadt@cvs.openbsd.org 2000/07/07 02:14:29 - [serverloop.c] - sense of port forwarding flag test was backwards - - provos@cvs.openbsd.org 2000/07/08 17:17:31 - [compat.c readconf.c] - replace strtok with strsep; from David Young <dyoung@onthejob.net> - - deraadt@cvs.openbsd.org 2000/07/08 19:21:15 - [auth.h] - KNF - - ho@cvs.openbsd.org 2000/07/08 19:27:33 - [compat.c readconf.c] - Better conditions for strsep() ending. - - ho@cvs.openbsd.org 2000/07/10 10:27:05 - [readconf.c] - Get the correct message on errors. (niels@ ok) - - ho@cvs.openbsd.org 2000/07/10 10:30:25 - [cipher.c kex.c servconf.c] - strtok() --> strsep(). (niels@ ok) - - (djm) Fix problem with debug mode and MaxStartups - - (djm) Don't generate host keys when $(DESTDIR) is set (e.g. during RPM - builds) - - (djm) Add strsep function from OpenBSD libc for systems that lack it - -20000709 - - (djm) Only enable PAM_TTY kludge for Linux. Problem report from - Kevin Steves <stevesk@sweden.hp.com> - - (djm) Match prototype and function declaration for rresvport_af. - Problem report from Niklas Edmundsson <nikke@ing.umu.se> - - (djm) Missing $(DESTDIR) on host-key target causing problems with RPM - builds. Problem report from Gregory Leblanc <GLeblanc@cu-portland.edu> - - (djm) Replace ut_name with ut_user. Patch from Jim Watt - <jimw@peisj.pebio.com> - - (djm) Fix pam sprintf fix - - (djm) Cleanup entropy collection code a little more. Split initialisation - from seeding, perform intialisation immediatly at start, be careful with - uids. Based on problem report from Jim Watt <jimw@peisj.pebio.com> - - (djm) More NeXT compatibility from Ben Lindstrom <mouring@pconline.com> - Including sigaction() et al. replacements - - (djm) AIX getuserattr() session initialisation from Tom Bertelson - <tbert@abac.com> - -20000708 - - (djm) Fix bad fprintf format handling in auth-pam.c. Patch from - Aaron Hopkins <aaron@die.net> - - (djm) Fix incorrect configure handling of --with-rsh-path option. Fix from - Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - - (djm) Fixed undefined variables for OSF SIA. Report from - Baars, Henk <Hendrik.Baars@nl.origin-it.com> - - (djm) Handle EWOULDBLOCK returns from read() and write() in atomicio.c - Fix from Marquess, Steve Mr JMLFDC <Steve.Marquess@DET.AMEDD.ARMY.MIL> - - (djm) Don't use inet_addr. - -20000702 - - (djm) Fix brace mismatch from Corinna Vinschen <vinschen@cygnus.com> - - (djm) Stop shadow expiry checking from preventing logins with NIS. Based - on fix from HARUYAMA Seigo <haruyama@nt.phys.s.u-tokyo.ac.jp> - - (djm) Use standard OpenSSL functions in auth-skey.c. Patch from - Chris, the Young One <cky@pobox.com> - - (djm) Fix scp progress meter on really wide terminals. Based on patch - from James H. Cloos Jr. <cloos@jhcloos.com> - -20000701 - - (djm) Fix Tru64 SIA problems reported by John P Speno <speno@isc.upenn.edu> - - (djm) Login fixes from Tom Bertelson <tbert@abac.com> - - (djm) Replace "/bin/sh" with _PATH_BSHELL. Report from Corinna Vinschen - <vinschen@cygnus.com> - - (djm) Replace "/usr/bin/login" with LOGIN_PROGRAM - - (djm) Added check for broken snprintf() functions which do not correctly - terminate output string and attempt to use replacement. - - (djm) Released 2.1.1p2 - -20000628 - - (djm) Fixes to lastlog code for Irix - - (djm) Use atomicio in loginrec - - (djm) Patch from Michael Stone <mstone@cs.loyola.edu> to add support for - Irix 6.x array sessions, project id's, and system audit trail id. - - (djm) Added 'distprep' make target to simplify packaging - - (djm) Added patch from Chris Adams <cmadams@hiwaay.net> to add OSF SIA - support. Enable using "USE_SIA=1 ./configure [options]" - -20000627 - - (djm) Fixes to login code - not setting li->uid, cleanups - - (djm) Formatting - -20000626 - - (djm) Better fix to aclocal tests from Garrick James <garrick@james.net> - - (djm) Account expiry support from Andreas Steinmetz <ast@domdv.de> - - (djm) Added password expiry checking (no password change support) - - (djm) Make EGD failures non-fatal if OpenSSL's entropy pool is still OK - based on patch from Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - - (djm) Fix fixed EGD code. - - OpenBSD CVS update - - provos@cvs.openbsd.org 2000/06/25 14:17:58 - [channels.c] - correct check for bad channel ids; from Wei Dai <weidai@eskimo.com> - -20000623 - - (djm) Use sa_family_t in prototype for rresvport_af. Patch from - Svante Signell <svante.signell@telia.com> - - (djm) Autoconf logic to define sa_family_t if it is missing - - OpenBSD CVS Updates: - - markus@cvs.openbsd.org 2000/06/22 10:32:27 - [sshd.c] - missing atomicio; report from Steve.Marquess@DET.AMEDD.ARMY.MIL - - djm@cvs.openbsd.org 2000/06/22 17:55:00 - [auth-krb4.c key.c radix.c uuencode.c] - Missing CVS idents; ok markus - -20000622 - - (djm) Automatically generate host key during "make install". Suggested - by Gary E. Miller <gem@rellim.com> - - (djm) Paranoia before kill() system call - - OpenBSD CVS Updates: - - markus@cvs.openbsd.org 2000/06/18 18:50:11 - [auth2.c compat.c compat.h sshconnect2.c] - make userauth+pubkey interop with ssh.com-2.2.0 - - markus@cvs.openbsd.org 2000/06/18 20:56:17 - [dsa.c] - mem leak + be more paranoid in dsa_verify. - - markus@cvs.openbsd.org 2000/06/18 21:29:50 - [key.c] - cleanup fingerprinting, less hardcoded sizes - - markus@cvs.openbsd.org 2000/06/19 19:39:45 - [atomicio.c auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] - [auth-rsa.c auth-skey.c authfd.c authfd.h authfile.c bufaux.c bufaux.h] - [buffer.c buffer.h canohost.c channels.c channels.h cipher.c cipher.h] - [clientloop.c compat.c compat.h compress.c compress.h crc32.c crc32.h] - [deattack.c dispatch.c dsa.c fingerprint.c fingerprint.h getput.h hmac.c] - [kex.c log-client.c log-server.c login.c match.c mpaux.c mpaux.h nchan.c] - [nchan.h packet.c packet.h pty.c pty.h readconf.c readconf.h readpass.c] - [rsa.c rsa.h scp.c servconf.c servconf.h ssh-add.c ssh-keygen.c ssh.c] - [ssh.h tildexpand.c ttymodes.c ttymodes.h uidswap.c xmalloc.c xmalloc.h] - OpenBSD tag - - markus@cvs.openbsd.org 2000/06/21 10:46:10 - sshconnect2.c missing free; nuke old comment - -20000620 - - (djm) Replace use of '-o' and '-a' logical operators in configure tests - with '||' and '&&'. As suggested by Jim Knoble <jmknoble@pint-stowp.cx> - to fix SCO Unixware problem reported by Gary E. Miller <gem@rellim.com> - - (djm) Typo in loginrec.c - -20000618 - - (djm) Add summary of configure options to end of ./configure run - - (djm) Not all systems define RUSAGE_SELF & RUSAGE_CHILDREN. Report from - Michael Stone <mstone@cs.loyola.edu> - - (djm) rusage is a privileged operation on some Unices (incl. - Solaris 2.5.1). Report from Paul D. Smith <pausmith@nortelnetworks.com> - - (djm) Avoid PAM failures when running without a TTY. Report from - Martin Petrak <petrak@spsknm.schools.sk> - - (djm) Include sys/types.h when including netinet/in.h in configure tests. - Patch from Jun-ichiro itojun Hagino <itojun@iijlab.net> - - (djm) Started merge of Ben Lindstrom's <mouring@pconline.com> NeXT support - - OpenBSD CVS updates: - - deraadt@cvs.openbsd.org 2000/06/17 09:58:46 - [channels.c] - everyone says "nix it" (remove protocol 2 debugging message) - - markus@cvs.openbsd.org 2000/06/17 13:24:34 - [sshconnect.c] - allow extended server banners - - markus@cvs.openbsd.org 2000/06/17 14:30:10 - [sshconnect.c] - missing atomicio, typo - - jakob@cvs.openbsd.org 2000/06/17 16:52:34 - [servconf.c servconf.h session.c sshd.8 sshd_config] - add support for ssh v2 subsystems. ok markus@. - - deraadt@cvs.openbsd.org 2000/06/17 18:57:48 - [readconf.c servconf.c] - include = in WHITESPACE; markus ok - - markus@cvs.openbsd.org 2000/06/17 19:09:10 - [auth2.c] - implement bug compatibility with ssh-2.0.13 pubkey, server side - - markus@cvs.openbsd.org 2000/06/17 21:00:28 - [compat.c] - initial support for ssh.com's 2.2.0 - - markus@cvs.openbsd.org 2000/06/17 21:16:09 - [scp.c] - typo - - markus@cvs.openbsd.org 2000/06/17 22:05:02 - [auth-rsa.c auth2.c serverloop.c session.c auth-options.c auth-options.h] - split auth-rsa option parsing into auth-options - add options support to authorized_keys2 - - markus@cvs.openbsd.org 2000/06/17 22:42:54 - [session.c] - typo - -20000613 - - (djm) Fixes from Andrew McGill <andrewm@datrix.co.za>: - - Platform define for SCO 3.x which breaks on /dev/ptmx - - Detect and try to fix missing MAXPATHLEN - - (djm) Fix short copy in loginrec.c (based on patch from Phill Camp - <P.S.S.Camp@ukc.ac.uk> - -20000612 - - (djm) Glob manpages in RPM spec files to catch compressed files - - (djm) Full license in auth-pam.c - - (djm) Configure fixes from SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp> - - (andre) AIX, lastlog, configure fixes from Tom Bertelson <tbert@abac.com>: - - Don't try to retrieve lastlog from wtmp/wtmpx if DISABLE_LASTLOG is - def'd - - Set AIX to use preformatted manpages - -20000610 - - (djm) Minor doc tweaks - - (djm) Fix for configure on bash2 from Jim Knoble <jmknoble@jmknoble.cx> - -20000609 - - (djm) Patch from Kenji Miyake <kenji@miyake.org> to disable utmp usage - (in favour of utmpx) on Solaris 8 - -20000606 - - (djm) Cleanup of entropy.c. Reorganised code, removed second pass through - list of commands (by default). Removed verbose debugging (by default). - - (djm) Increased command entropy estimates and default entropy collection - timeout - - (djm) Remove duplicate headers from loginrec.c - - (djm) Don't add /usr/local/lib to library search path on Irix - - (djm) Fix rsh path in RPMs. Report from Jason L Tibbitts III - <tibbs@math.uh.edu> - - (djm) Warn user if grabs fail in GNOME askpass. Patch from Zack Weinberg - <zack@wolery.cumb.org> - - (djm) OpenBSD CVS updates: - - todd@cvs.openbsd.org - [sshconnect2.c] - teach protocol v2 to count login failures properly and also enable an - explanation of why the password prompt comes up again like v1; this is NOT - crypto - - markus@cvs.openbsd.org - [readconf.c readconf.h servconf.c servconf.h session.c ssh.1 ssh.c sshd.8] - xauth_location support; pr 1234 - [readconf.c sshconnect2.c] - typo, unused - [session.c] - allow use_login only for login sessions, otherwise remote commands are - execed with uid==0 - [sshd.8] - document UseLogin better - [version.h] - OpenSSH 2.1.1 - [auth-rsa.c] - fix match_hostname() logic for auth-rsa: deny access if we have a - negative match or no match at all - [channels.c hostfile.c match.c] - don't panic if mkdtemp fails for authfwd; jkb@yahoo-inc.com via - kris@FreeBSD.org - -20000606 - - (djm) Added --with-cflags, --with-ldflags and --with-libs options to - configure. - -20000604 - - Configure tweaking for new login code on Irix 5.3 - - (andre) login code changes based on djm feedback - -20000603 - - (andre) New login code - - Remove bsd-login.[ch] and all the OpenBSD-derived code in login.c - - Add loginrec.[ch], logintest.c and autoconf code - -20000531 - - Cleanup of auth.c, login.c and fake-* - - Cleanup of auth-pam.c, save and print "account expired" error messages - - Fix EGD read bug by IWAMURO Motonori <iwa@mmp.fujitsu.co.jp> - - Rewrote bsd-login to use proper utmp API if available. Major cleanup - of fallback DIY code. - -20000530 - - Define atexit for old Solaris - - Fix buffer overrun in login.c for systems which use syslen in utmpx. - patch from YOSHIFUJI Hideaki <yoshfuji@cerberus.nemoto.ecei.tohoku.ac.jp> - - OpenBSD CVS updates: - - markus@cvs.openbsd.org - [session.c] - make x11-fwd work w/ localhost (xauth add host/unix:11) - [cipher.c compat.c readconf.c servconf.c] - check strtok() != NULL; ok niels@ - [key.c] - fix key_read() for uuencoded keys w/o '=' - [serverloop.c] - group ssh1 vs. ssh2 in serverloop - [kex.c kex.h myproposal.h sshconnect2.c sshd.c] - split kexinit/kexdh, factor out common code - [readconf.c ssh.1 ssh.c] - forwardagent defaults to no, add ssh -A - - theo@cvs.openbsd.org - [session.c] - just some line shortening - - Released 2.1.0p3 - -20000520 - - Xauth fix from Markus Friedl <markus.friedl@informatik.uni-erlangen.de> - - Don't touch utmp if USE_UTMPX defined - - SunOS 4.x support from Todd C. Miller <Todd.Miller@courtesan.com> - - SIGCHLD fix for AIX and HPUX from Tom Bertelson <tbert@abac.com> - - HPUX and Configure fixes from Lutz Jaenicke - <Lutz.Jaenicke@aet.TU-Cottbus.DE> - - Use mkinstalldirs script to make directories instead of non-portable - "install -d". Suggested by Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - - Doc cleanup - -20000518 - - Include Andre Lucas' fixprogs script. Forgot to "cvs add" it yesterday - - OpenBSD CVS updates: - - markus@cvs.openbsd.org - [sshconnect.c] - copy only ai_addrlen bytes; misiek@pld.org.pl - [auth.c] - accept an empty shell in authentication; bug reported by - chris@tinker.ucr.edu - [serverloop.c] - we don't have stderr for interactive terminal sessions (fcntl errors) - -20000517 - - Fix from Andre Lucas <andre.lucas@dial.pipex.com> - - Fixes command line printing segfaults (spotter: Bladt Norbert) - - Fixes erroneous printing of debug messages to syslog - - Fixes utmp for MacOS X (spotter: Aristedes Maniatis) - - Gives useful error message if PRNG initialisation fails - - Reduced ssh startup delay - - Measures cumulative command time rather than the time between reads - after select() - - 'fixprogs' perl script to eliminate non-working entropy commands, and - optionally run 'ent' to measure command entropy - - Applied Tom Bertelson's <tbert@abac.com> AIX authentication fix - - Avoid WCOREDUMP complation errors for systems that lack it - - Avoid SIGCHLD warnings from entropy commands - - Fix HAVE_PAM_GETENVLIST setting from Simon Wilkinson <sxw@dcs.ed.ac.uk> - - OpenBSD CVS update: - - markus@cvs.openbsd.org - [ssh.c] - fix usage() - [ssh2.h] - draft-ietf-secsh-architecture-05.txt - [ssh.1] - document ssh -T -N (ssh2 only) - [channels.c serverloop.c ssh.h sshconnect.c sshd.c aux.c] - enable nonblocking IO for sshd w/ proto 1, too; split out common code - [aux.c] - missing include - - Several patches from SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp> - - INSTALL typo and URL fix - - Makefile fix - - Solaris fixes - - Checking for ssize_t and memmove. Based on patch from SAKAI Kiyotaka - <ksakai@kso.netwk.ntt-at.co.jp> - - RSAless operation patch from kevin_oconnor@standardandpoors.com - - Detect OpenSSL seperatly from RSA - - Better test for RSA (more compatible with RSAref). Based on work by - Ed Eden <ede370@stl.rural.usda.gov> - -20000513 - - Fix for non-recognised DSA keys from Arkadiusz Miskiewicz - <misiek@pld.org.pl> - -20000511 - - Fix for prng_seed permissions checking from Lutz Jaenicke - <Lutz.Jaenicke@aet.TU-Cottbus.DE> - - "make host-key" fix for Irix - -20000509 - - OpenBSD CVS update - - markus@cvs.openbsd.org - [cipher.h myproposal.h readconf.c readconf.h servconf.c ssh.1 ssh.c] - [ssh.h sshconnect1.c sshconnect2.c sshd.8] - - complain about invalid ciphers in SSH1 (e.g. arcfour is SSH2 only) - - hugh@cvs.openbsd.org - [ssh.1] - - zap typo - [ssh-keygen.1] - - One last nit fix. (markus approved) - [sshd.8] - - some markus certified spelling adjustments - - markus@cvs.openbsd.org - [auth2.c channels.c clientloop.c compat compat.h dsa.c kex.c] - [sshconnect2.c ] - - bug compat w/ ssh-2.0.13 x11, split out bugs - [nchan.c] - - no drain if ibuf_empty, fixes x11fwd problems; tests by fries@ - [ssh-keygen.c] - - handle escapes in real and original key format, ok millert@ - [version.h] - - OpenSSH-2.1 - - Moved all the bsd-* and fake-* stuff into new libopenbsd-compat.a - - Doc updates - - Cleanup of bsd-base64 headers, bugfix definitions of __b64_*. Reported - by Andre Lucas <andre.lucas@dial.pipex.com> - -20000508 - - Makefile and RPM spec fixes - - Generate DSA host keys during "make key" or RPM installs - - OpenBSD CVS update - - markus@cvs.openbsd.org - [clientloop.c sshconnect2.c] - - make x11-fwd interop w/ ssh-2.0.13 - [README.openssh2] - - interop w/ SecureFX - - Release 2.0.0beta2 - - - Configure caching and cleanup patch from Andre Lucas' - <andre.lucas@dial.pipex.com> - -20000507 - - Remove references to SSLeay. - - Big OpenBSD CVS update - - markus@cvs.openbsd.org - [clientloop.c] - - typo - [session.c] - - update proctitle on pty alloc/dealloc, e.g. w/ windows client - [session.c] - - update proctitle for proto 1, too - [channels.h nchan.c serverloop.c session.c sshd.c] - - use c-style comments - - deraadt@cvs.openbsd.org - [scp.c] - - more atomicio - - markus@cvs.openbsd.org - [channels.c] - - set O_NONBLOCK - [ssh.1] - - update AUTHOR - [readconf.c ssh-keygen.c ssh.h] - - default DSA key file ~/.ssh/id_dsa - [clientloop.c] - - typo, rm verbose debug - - deraadt@cvs.openbsd.org - [ssh-keygen.1] - - document DSA use of ssh-keygen - [sshd.8] - - a start at describing what i understand of the DSA side - [ssh-keygen.1] - - document -X and -x - [ssh-keygen.c] - - simplify usage - - markus@cvs.openbsd.org - [sshd.8] - - there is no rhosts_dsa - [ssh-keygen.1] - - document -y, update -X,-x - [nchan.c] - - fix close for non-open ssh1 channels - [servconf.c servconf.h ssh.h sshd.8 sshd.c ] - - s/DsaKey/HostDSAKey/, document option - [sshconnect2.c] - - respect number_of_password_prompts - [channels.c channels.h servconf.c servconf.h session.c sshd.8] - - GatewayPorts for sshd, ok deraadt@ - [ssh-add.1 ssh-agent.1 ssh.1] - - more doc on: DSA, id_dsa, known_hosts2, authorized_keys2 - [ssh.1] - - more info on proto 2 - [sshd.8] - - sync AUTHOR w/ ssh.1 - [key.c key.h sshconnect.c] - - print key type when talking about host keys - [packet.c] - - clear padding in ssh2 - [dsa.c key.c radix.c ssh.h sshconnect1.c uuencode.c uuencode.h] - - replace broken uuencode w/ libc b64_ntop - [auth2.c] - - log failure before sending the reply - [key.c radix.c uuencode.c] - - remote trailing comments before calling __b64_pton - [auth2.c readconf.c readconf.h servconf.c servconf.h ssh.1] - [sshconnect2.c sshd.8] - - add DSAAuthetication option to ssh/sshd, document SSH2 in sshd.8 - - Bring in b64_ntop and b64_pton from OpenBSD libc (bsd-base64.[ch]) - -20000502 - - OpenBSD CVS update - [channels.c] - - init all fds, close all fds. - [sshconnect2.c] - - check whether file exists before asking for passphrase - [servconf.c servconf.h sshd.8 sshd.c] - - PidFile, pr 1210 - [channels.c] - - EINTR - [channels.c] - - unbreak, ok niels@ - [sshd.c] - - unlink pid file, ok niels@ - [auth2.c] - - Add missing #ifdefs; ok - markus - - Add Andre Lucas' <andre.lucas@dial.pipex.com> patch to read entropy - gathering commands from a text file - - Release 2.0.0beta1 - -20000501 - - OpenBSD CVS update - [packet.c] - - send debug messages in SSH2 format - [scp.c] - - fix very rare EAGAIN/EINTR issues; based on work by djm - [packet.c] - - less debug, rm unused - [auth2.c] - - disable kerb,s/key in ssh2 - [sshd.8] - - Minor tweaks and typo fixes. - [ssh-keygen.c] - - Put -d into usage and reorder. markus ok. - - Include missing headers for OpenSSL tests. Fix from Phil Karn - <karn@ka9q.ampr.org> - - Fixed __progname symbol collisions reported by Andre Lucas - <andre.lucas@dial.pipex.com> - - Merged bsd-login ttyslot and AIX utmp patch from Gert Doering - <gd@hilb1.medat.de> - - Add some missing ifdefs to auth2.c - - Deprecate perl-tk askpass. - - Irix portability fixes - don't include netinet headers more than once - - Make sure we don't save PRNG seed more than once - -20000430 - - Merge HP-UX fixes and TCB support from Ged Lodder <lodder@yacc.com.au> - - Integrate Andre Lucas' <andre.lucas@dial.pipex.com> entropy collection - patch. - - Adds timeout to entropy collection - - Disables slow entropy sources - - Load and save seed file - - Changed entropy seed code to user per-user seeds only (server seed is - saved in root's .ssh directory) - - Use atexit() and fatal cleanups to save seed on exit - - More OpenBSD updates: - [session.c] - - don't call chan_write_failed() if we are not writing - [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c] - - keysize warnings error() -> log() - -20000429 - - Merge big update to OpenSSH-2.0 from OpenBSD CVS - [README.openssh2] - - interop w/ F-secure windows client - - sync documentation - - ssh_host_dsa_key not ssh_dsa_key - [auth-rsa.c] - - missing fclose - [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c] - [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c] - [sshd.c uuencode.c uuencode.h authfile.h] - - add DSA pubkey auth and other SSH2 fixes. use ssh-keygen -[xX] - for trading keys with the real and the original SSH, directly from the - people who invented the SSH protocol. - [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h] - [sshconnect1.c sshconnect2.c] - - split auth/sshconnect in one file per protocol version - [sshconnect2.c] - - remove debug - [uuencode.c] - - add trailing = - [version.h] - - OpenSSH-2.0 - [ssh-keygen.1 ssh-keygen.c] - - add -R flag: exit code indicates if RSA is alive - [sshd.c] - - remove unused - silent if -Q is specified - [ssh.h] - - host key becomes /etc/ssh_host_dsa_key - [readconf.c servconf.c ] - - ssh/sshd default to proto 1 and 2 - [uuencode.c] - - remove debug - [auth2.c ssh-keygen.c sshconnect2.c sshd.c] - - xfree DSA blobs - [auth2.c serverloop.c session.c] - - cleanup logging for sshd/2, respect PasswordAuth no - [sshconnect2.c] - - less debug, respect .ssh/config - [README.openssh2 channels.c channels.h] - - clientloop.c session.c ssh.c - - support for x11-fwding, client+server - -20000421 - - Merge fix from OpenBSD CVS - [ssh-agent.c] - - Fix memory leak per connection. Report from Andy Spiegl <Andy@Spiegl.de> - via Debian bug #59926 - - Define __progname in session.c if libc doesn't - - Remove indentation on autoconf #include statements to avoid bug in - DEC Tru64 compiler. Report and fix from David Del Piero - <David.DelPiero@qed.qld.gov.au> - -20000420 - - Make fixpaths work with perl4, patch from Andre Lucas - <andre.lucas@dial.pipex.com> - - Sync with OpenBSD CVS: - [clientloop.c login.c serverloop.c ssh-agent.c ssh.h sshconnect.c sshd.c] - - pid_t - [session.c] - - remove bogus chan_read_failed. this could cause data - corruption (missing data) at end of a SSH2 session. - - Merge fixes from Debian patch from Phil Hands <phil@hands.com> - - Allow setting of PAM service name through CFLAGS (SSHD_PAM_SERVICE) - - Use vhangup to clean up Linux ttys - - Force posix getopt processing on GNU libc systems - - Debian bug #55910 - remove references to ssl(8) manpages - - Debian bug #58031 - ssh_config lies about default cipher - -20000419 - - OpenBSD CVS updates - [channels.c] - - fix pr 1196, listen_port and port_to_connect interchanged - [scp.c] - - after completion, replace the progress bar ETA counter with a final - elapsed time; my idea, aaron wrote the patch - [ssh_config sshd_config] - - show 'Protocol' as an example, ok markus@ - [sshd.c] - - missing xfree() - - Add missing header to bsd-misc.c - -20000416 - - Reduce diff against OpenBSD source - - All OpenSSL includes are now unconditionally referenced as - openssl/foo.h - - Pick up formatting changes - - Other minor changed (typecasts, etc) that I missed - -20000415 - - OpenBSD CVS updates. - [ssh.1 ssh.c] - - ssh -2 - [auth.c channels.c clientloop.c packet.c packet.h serverloop.c] - [session.c sshconnect.c] - - check payload for (illegal) extra data - [ALL] - whitespace cleanup - -20000413 - - INSTALL doc updates - - Merged OpenBSD updates to include paths. - -20000412 - - OpenBSD CVS updates: - - [channels.c] - repair x11-fwd - - [sshconnect.c] - fix passwd prompt for ssh2, less debugging output. - - [clientloop.c compat.c dsa.c kex.c sshd.c] - less debugging output - - [kex.c kex.h sshconnect.c sshd.c] - check for reasonable public DH values - - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c] - [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c] - add Cipher and Protocol options to ssh/sshd, e.g.: - ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers - arcfour,3des-cbc' - - [sshd.c] - print 1.99 only if server supports both - -20000408 - - Avoid some compiler warnings in fake-get*.c - - Add IPTOS macros for systems which lack them - - Only set define entropy collection macros if they are found - - More large OpenBSD CVS updates: - - [auth.c auth.h servconf.c servconf.h serverloop.c session.c] - [session.h ssh.h sshd.c README.openssh2] - ssh2 server side, see README.openssh2; enable with 'sshd -2' - - [channels.c] - no adjust after close - - [sshd.c compat.c ] - interop w/ latest ssh.com windows client. - -20000406 - - OpenBSD CVS update: - - [channels.c] - close efd on eof - - [clientloop.c compat.c ssh.c sshconnect.c myproposal.h] - ssh2 client implementation, interops w/ ssh.com and lsh servers. - - [sshconnect.c] - missing free. - - [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c] - remove unused argument, split cipher_mask() - - [clientloop.c] - re-order: group ssh1 vs. ssh2 - - Make Redhat spec require openssl >= 0.9.5a - -20000404 - - Add tests for RAND_add function when searching for OpenSSL - - OpenBSD CVS update: - - [packet.h packet.c] - ssh2 packet format - - [packet.h packet.c nchan2.ms nchan.h compat.h compat.c] - [channels.h channels.c] - channel layer support for ssh2 - - [kex.h kex.c hmac.h hmac.c dsa.c dsa.h] - DSA, keyexchange, algorithm agreement for ssh2 - - Generate manpages before make install not at the end of make all - - Don't seed the rng quite so often - - Always reseed rng when requested - -20000403 - - Wrote entropy collection routines for systems that lack /dev/random - and EGD - - Disable tests and typedefs for 64 bit types. They are currently unused. - -20000401 - - Big OpenBSD CVS update (mainly beginnings of SSH2 infrastructure) - - [auth.c session.c sshd.c auth.h] - split sshd.c -> auth.c session.c sshd.c plus cleanup and goto-removal - - [bufaux.c bufaux.h] - support ssh2 bignums - - [channels.c channels.h clientloop.c sshd.c nchan.c nchan.h packet.c] - [readconf.c ssh.c ssh.h serverloop.c] - replace big switch() with function tables (prepare for ssh2) - - [ssh2.h] - ssh2 message type codes - - [sshd.8] - reorder Xr to avoid cutting - - [serverloop.c] - close(fdin) if fdin != fdout, shutdown otherwise, ok theo@ - - [channels.c] - missing close - allow bigger packets - - [cipher.c cipher.h] - support ssh2 ciphers - - [compress.c] - cleanup, less code - - [dispatch.c dispatch.h] - function tables for different message types - - [log-server.c] - do not log() if debuggin to stderr - rename a cpp symbol, to avoid param.h collision - - [mpaux.c] - KNF - - [nchan.c] - sync w/ channels.c - -20000326 - - Better tests for OpenSSL w/ RSAref - - Added replacement setenv() function from OpenBSD libc. Suggested by - Ben Lindstrom <mouring@pconline.com> - - OpenBSD CVS update - - [auth-krb4.c] - -Wall - - [auth-rh-rsa.c auth-rsa.c hostfile.c hostfile.h key.c key.h match.c] - [match.h ssh.c ssh.h sshconnect.c sshd.c] - initial support for DSA keys. ok deraadt@, niels@ - - [cipher.c cipher.h] - remove unused cipher_attack_detected code - - [scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] - Fix some formatting problems I missed before. - - [ssh.1 sshd.8] - fix spelling errors, From: FreeBSD - - [ssh.c] - switch to raw mode only if he _get_ a pty (not if we _want_ a pty). - -20000324 - - Released 1.2.3 - -20000317 - - Clarified --with-default-path option. - - Added -blibpath handling for AIX to work around stupid runtime linking. - Problem elucidated by gshapiro@SENDMAIL.ORG by way of Jim Knoble - <jmknoble@pobox.com> - - Checks for 64 bit int types. Problem report from Mats Fredholm - <matsf@init.se> - - OpenBSD CVS updates: - - [atomicio.c auth-krb4.c bufaux.c channels.c compress.c fingerprint.c] - [packet.h radix.c rsa.c scp.c ssh-agent.c ssh-keygen.c sshconnect.c] - [sshd.c] - pedantic: signed vs. unsigned, void*-arithm, etc - - [ssh.1 sshd.8] - Various cleanups and standardizations. - - Runtime error fix for HPUX from Otmar Stahl - <O.Stahl@lsw.uni-heidelberg.de> - -20000316 - - Fixed configure not passing LDFLAGS to Solaris. Report from David G. - Hesprich <dghespri@sprintparanet.com> - - Propogate LD through to Makefile - - Doc cleanups - - Added blurb about "scp: command not found" errors to UPGRADING - -20000315 - - Fix broken CFLAGS handling during search for OpenSSL. Fixes va_list - problems with gcc/Solaris. - - Don't free argument to putenv() after use (in setenv() replacement). - Report from Seigo Tanimura <tanimura@r.dl.itc.u-tokyo.ac.jp> - - Created contrib/ subdirectory. Included helpers from Phil Hands' - Debian package, README file and chroot patch from Ricardo Cerqueira - <rmcc@clix.pt> - - Moved gnome-ssh-askpass.c to contrib directory and removed config - option. - - Slight cleanup to doc files - - Configure fix from Bratislav ILICH <bilic@zepter.ru> - -20000314 - - Include macro for IN6_IS_ADDR_V4MAPPED. Report from - peter@frontierflying.com - - Include /usr/local/include and /usr/local/lib for systems that don't - do it themselves - - -R/usr/local/lib for Solaris - - Fix RSAref detection - - Fix IN6_IS_ADDR_V4MAPPED macro - -20000311 - - Detect RSAref - - OpenBSD CVS change - [sshd.c] - - disallow guessing of root password - - More configure fixes - - IPv6 workarounds from Hideaki YOSHIFUJI <yoshfuji@ecei.tohoku.ac.jp> - -20000309 - - OpenBSD CVS updates to v1.2.3 - [ssh.h atomicio.c] - - int atomicio -> ssize_t (for alpha). ok deraadt@ - [auth-rsa.c] - - delay MD5 computation until client sends response, free() early, cleanup. - [cipher.c] - - void* -> unsigned char*, ok niels@ - [hostfile.c] - - remove unused variable 'len'. fix comments. - - remove unused variable - [log-client.c log-server.c] - - rename a cpp symbol, to avoid param.h collision - [packet.c] - - missing xfree() - - getsockname() requires initialized tolen; andy@guildsoftware.com - - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; - from Holger.Trapp@Informatik.TU-Chemnitz.DE - [pty.c pty.h] - - register cleanup for pty earlier. move code for pty-owner handling to - pty.c ok provos@, dugsong@ - [readconf.c] - - turn off x11-fwd for the client, too. - [rsa.c] - - PKCS#1 padding - [scp.c] - - allow '.' in usernames; from jedgar@fxp.org - [servconf.c] - - typo: ignore_user_known_hosts int->flag; naddy@mips.rhein-neckar.de - - sync with sshd_config - [ssh-keygen.c] - - enable ssh-keygen -l -f ~/.ssh/known_hosts, ok deraadt@ - [ssh.1] - - Change invalid 'CHAT' loglevel to 'VERBOSE' - [ssh.c] - - suppress AAAA query host when '-4' is used; from shin@nd.net.fujitsu.co.jp - - turn off x11-fwd for the client, too. - [sshconnect.c] - - missing xfree() - - retry rresvport_af(), too. from sumikawa@ebina.hitachi.co.jp. - - read error vs. "Connection closed by remote host" - [sshd.8] - - ie. -> i.e., - - do not link to a commercial page.. - - sync with sshd_config - [sshd.c] - - no need for poll.h; from bright@wintelcom.net - - log with level log() not fatal() if peer behaves badly. - - don't panic if client behaves strange. ok deraadt@ - - make no-port-forwarding for RSA keys deny both -L and -R style fwding - - delay close() of pty until the pty has been chowned back to root - - oops, fix comment, too. - - missing xfree() - - move XAUTHORITY to subdir. ok dugsong@. fixes debian bug #57907, too. - (http://cgi.debian.org/cgi-bin/bugreport.cgi?archive=no&bug=57907) - - register cleanup for pty earlier. move code for pty-owner handling to - pty.c ok provos@, dugsong@ - - create x11 cookie file - - fix pr 1113, fclose() -> pclose(), todo: remote popen() - - version 1.2.3 - - Cleaned up - - Removed warning workaround for Linux and devpts filesystems (no longer - required after OpenBSD updates) - -20000308 - - Configure fix from Hiroshi Takekawa <takekawa@sr3.t.u-tokyo.ac.jp> - -20000307 - - Released 1.2.2p1 - -20000305 - - Fix DEC compile fix - - Explicitly seed OpenSSL's PRNG before checking rsa_alive() - - Check for getpagesize in libucb.a if not found in libc. Fix for old - Solaris from Andre Lucas <andre.lucas@dial.pipex.com> - - Check for libwrap if --with-tcp-wrappers option specified. Suggestion - Mate Wierdl <mw@moni.msci.memphis.edu> - -20000303 - - Added "make host-key" target, Suggestion from Dominik Brettnacher - <domi@saargate.de> - - Don't permanently fail on bind() if getaddrinfo has more choices left for - us. Needed to work around messy IPv6 on Linux. Patch from Arkadiusz - Miskiewicz <misiek@pld.org.pl> - - DEC Unix compile fix from David Del Piero <David.DelPiero@qed.qld.gov.au> - - Manpage fix from David Del Piero <David.DelPiero@qed.qld.gov.au> - -20000302 - - Big cleanup of autoconf code - - Rearranged to be a little more logical - - Added -R option for Solaris - - Rewrote OpenSSL detection code. Now uses AC_TRY_RUN with a test program - to detect library and header location _and_ ensure library has proper - RSA support built in (this is a problem with OpenSSL 0.9.5). - - Applied pty cleanup patch from markus.friedl@informatik.uni-erlangen.de - - Avoid warning message with Unix98 ptys - - Warning was valid - possible race condition on PTYs. Avoided using - platform-specific code. - - Document some common problems - - Allow root access to any key. Patch from - markus.friedl@informatik.uni-erlangen.de - -20000207 - - Removed SOCKS code. Will support through a ProxyCommand. - -20000203 - - Fixed SEGVs in authloop, fix from vbzoli@hbrt.hu - - Add --with-ssl-dir option - -20000202 - - Fix lastlog code for directory based lastlogs. Fix from Josh Durham - <jmd@aoe.vt.edu> - - Documentation fixes from HARUYAMA Seigo <haruyama@nt.phys.s.u-tokyo.ac.jp> - - Added URLs to Japanese translations of documents by HARUYAMA Seigo - <haruyama@nt.phys.s.u-tokyo.ac.jp> - -20000201 - - Use socket pairs by default (instead of pipes). Prevents race condition - on several (buggy) OSs. Report and fix from tridge@linuxcare.com - -20000127 - - Seed OpenSSL's random number generator before generating RSA keypairs - - Split random collector into seperate file - - Compile fix from Andre Lucas <andre.lucas@dial.pipex.com> - -20000126 - - Released 1.2.2 stable - - - NeXT keeps it lastlog in /usr/adm. Report from - mouring@newton.pconline.com - - Added note in UPGRADING re interop with commercial SSH using idea. - Report from Jim Knoble <jmknoble@pobox.com> - - Fix linking order for Kerberos/AFS. Fix from Holget Trapp - <Holger.Trapp@Informatik.TU-Chemnitz.DE> - -20000125 - - Fix NULL pointer dereference in login.c. Fix from Andre Lucas - <andre.lucas@dial.pipex.com> - - Reorder PAM initialisation so it does not mess up lastlog. Reported - by Andre Lucas <andre.lucas@dial.pipex.com> - - Use preformatted manpages on SCO, report from Gary E. Miller - <gem@rellim.com> - - New URL for x11-ssh-askpass. - - Fixpaths was missing /etc/ssh_known_hosts. Report from Jim Knoble - <jmknoble@pobox.com> - - Added 'DESTDIR' option to Makefile to ease package building. Patch from - Jim Knoble <jmknoble@pobox.com> - - Updated RPM spec files to use DESTDIR - -20000124 - - Pick up version 1.2.2 from OpenBSD CVS (no changes, just version number - increment) - -20000123 - - OpenBSD CVS: - - [packet.c] - getsockname() requires initialized tolen; andy@guildsoftware.com - - AIX patch from Matt Richards <v2matt@btv.ibm.com> and David Rankin - <drankin@bohemians.lexington.ky.us> - - Fix lastlog support, patch from Andre Lucas <andre.lucas@dial.pipex.com> - -20000122 - - Fix compilation of bsd-snprintf.c on Solaris, fix from Ben Taylor - <bent@clark.net> - - Merge preformatted manpage patch from Andre Lucas - <andre.lucas@dial.pipex.com> - - Make IPv4 use the default in RPM packages - - Irix uses preformatted manpages - - Missing htons() in bsd-bindresvport.c, fix from Holger Trapp - <Holger.Trapp@Informatik.TU-Chemnitz.DE> - - OpenBSD CVS updates: - - [packet.c] - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; - from Holger.Trapp@Informatik.TU-Chemnitz.DE - - [sshd.c] - log with level log() not fatal() if peer behaves badly. - - [readpass.c] - instead of blocking SIGINT, catch it ourselves, so that we can clean - the tty modes up and kill ourselves -- instead of our process group - leader (scp, cvs, ...) going away and leaving us in noecho mode. - people with cbreak shells never even noticed.. - - [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] - ie. -> i.e., - -20000120 - - Don't use getaddrinfo on AIX - - Update to latest OpenBSD CVS: - - [auth-rsa.c] - - fix user/1056, sshd keeps restrictions; dbt@meat.net - - [sshconnect.c] - - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. - - destroy keys earlier - - split key exchange (kex) and user authentication (user-auth), - ok: provos@ - - [sshd.c] - - no need for poll.h; from bright@wintelcom.net - - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. - - split key exchange (kex) and user authentication (user-auth), - ok: provos@ - - Big manpage and config file cleanup from Andre Lucas - <andre.lucas@dial.pipex.com> - - Re-added latest (unmodified) OpenBSD manpages - - Doc updates - - NetBSD patch from David Rankin <drankin@bohemians.lexington.ky.us> and - Christos Zoulas <christos@netbsd.org> - -20000119 - - SCO compile fixes from Gary E. Miller <gem@rellim.com> - - Compile fix from Darren_Hall@progressive.com - - Linux/glibc-2.1.2 takes a *long* time to look up names for AF_UNSPEC - addresses using getaddrinfo(). Added a configure switch to make the - default lookup mode AF_INET - -20000118 - - Fixed --with-pid-dir option - - Makefile fix from Gary E. Miller <gem@rellim.com> - - Compile fix for HPUX and Solaris from Andre Lucas - <andre.lucas@dial.pipex.com> - -20000117 - - Clean up bsd-bindresvport.c. Use arc4random() for picking initial - port, ignore EINVAL errors (Linux) when searching for free port. - - Revert __snprintf -> snprintf aliasing. Apparently Solaris - __snprintf isn't. Report from Theo de Raadt <theo@cvs.openbsd.org> - - Document location of Redhat PAM file in INSTALL. - - Fixed X11 forwarding bug on Linux. libc advertises AF_INET6 - INADDR_ANY_INIT addresses via getaddrinfo, but may not be able to - deliver (no IPv6 kernel support) - - Released 1.2.1pre27 - - - Fix rresvport_af failure errors (logic error in bsd-bindresvport.c) - - Fix --with-ipaddr-display option test. Fix from Jarno Huuskonen - <jhuuskon@hytti.uku.fi> - - Fix hang on logout if processes are still using the pty. Needs - further testing. - - Patch from Christos Zoulas <christos@zoulas.com> - - Try $prefix first when looking for OpenSSL. - - Include sys/types.h when including sys/socket.h in test programs - - Substitute PID directory in sshd.8. Suggestion from Andrew - Stribblehill <a.d.stribblehill@durham.ac.uk> - -20000116 - - Renamed --with-xauth-path to --with-xauth - - Added --with-pid-dir option - - Released 1.2.1pre26 - - - Compilation fix from Kiyokazu SUTO <suto@ks-and-ks.ne.jp> - - Fixed broken bugfix for /dev/ptmx on Linux systems which lack - openpty(). Report from Kiyokazu SUTO <suto@ks-and-ks.ne.jp> - -20000115 - - Add --with-xauth-path configure directive and explicit test for - /usr/openwin/bin/xauth for Solaris systems. Report from Anders - Nordby <anders@fix.no> - - Fix incorrect detection of /dev/ptmx on Linux systems that lack - openpty. Report from John Seifarth <john@waw.be> - - Look for intXX_t and u_intXX_t in sys/bitypes.h if they are not in - sys/types.h. Fixes problems on SCO, report from Gary E. Miller - <gem@rellim.com> - - Use __snprintf and __vnsprintf if they are found where snprintf and - vnsprintf are lacking. Suggested by Ben Taylor <bent@shell.clark.net> - and others. - -20000114 - - Merged OpenBSD IPv6 patch: - - [sshd.c sshd.8 sshconnect.c ssh.h ssh.c servconf.h servconf.c scp.1] - [scp.c packet.h packet.c login.c log.c canohost.c channels.c] - [hostfile.c sshd_config] - ipv6 support: mostly gethostbyname->getaddrinfo/getnameinfo, new - features: sshd allows multiple ListenAddress and Port options. note - that libwrap is not IPv6-ready. (based on patches from - fujiwara@rcac.tdi.co.jp) - - [ssh.c canohost.c] - more hints (hints.ai_socktype=SOCK_STREAM) for getaddrinfo, - from itojun@ - - [channels.c] - listen on _all_ interfaces for X11-Fwd (hints.ai_flags = AI_PASSIVE) - - [packet.h] - allow auth-kerberos for IPv4 only - - [scp.1 sshd.8 servconf.h scp.c] - document -4, -6, and 'ssh -L 2022/::1/22' - - [ssh.c] - 'ssh @host' is illegal (null user name), from - karsten@gedankenpolizei.de - - [sshconnect.c] - better error message - - [sshd.c] - allow auth-kerberos for IPv4 only - - Big IPv6 merge: - - Cleanup overrun in sockaddr copying on RHL 6.1 - - Replacements for getaddrinfo, getnameinfo, etc based on versions - from patch from KIKUCHI Takahiro <kick@kyoto.wide.ad.jp> - - Replacement for missing structures on systems that lack IPv6 - - record_login needed to know about AF_INET6 addresses - - Borrowed more code from OpenBSD: rresvport_af and requisites - -20000110 - - Fixes to auth-skey to enable it to use the standard OpenSSL libraries - -20000107 - - New config.sub and config.guess to fix problems on SCO. Supplied - by Gary E. Miller <gem@rellim.com> - - SCO build fix from Gary E. Miller <gem@rellim.com> - - Released 1.2.1pre25 - -20000106 - - Documentation update & cleanup - - Better KrbIV / AFS detection, based on patch from: - Holger Trapp <Holger.Trapp@Informatik.TU-Chemnitz.DE> - -20000105 - - Fixed annoying DES corruption problem. libcrypt has been - overriding symbols in libcrypto. Removed libcrypt and crypt.h - altogether (libcrypto includes its own crypt(1) replacement) - - Added platform-specific rules for Irix 6.x. Included warning that - they are untested. - -20000103 - - Add explicit make rules for files proccessed by fixpaths. - - Fix "make install" in RPM spec files. Report from Tenkou N. Hattori - <tnh@kondara.org> - - Removed "nullok" directive from default PAM configuration files. - Added information on enabling EmptyPasswords on openssh+PAM in - UPGRADING file. - - OpenBSD CVS updates - - [ssh-agent.c] - cleanup_exit() for SIGTERM/SIGHUP, too. from fgsch@ and - dgaudet@arctic.org - - [sshconnect.c] - compare correct version for 1.3 compat mode - -20000102 - - Prevent multiple inclusion of config.h and defines.h. Suggested - by Andre Lucas <andre.lucas@dial.pipex.com> - - Properly clean up on exit of ssh-agent. Patch from Dean Gaudet - <dgaudet@arctic.org> - -19991231 - - Fix password support on systems with a mixture of shadowed and - non-shadowed passwords (e.g. NIS). Report and fix from - HARUYAMA Seigo <haruyama@nt.phys.s.u-tokyo.ac.jp> - - Fix broken autoconf typedef detection. Report from Marc G. - Fournier <marc.fournier@acadiau.ca> - - Fix occasional crash on LinuxPPC. Patch from Franz Sirl - <Franz.Sirl-kernel@lauterbach.com> - - Prevent typedefs from being compiled more than once. Report from - Marc G. Fournier <marc.fournier@acadiau.ca> - - Fill in ut_utaddr utmp field. Report from Benjamin Charron - <iretd@bigfoot.com> - - Really fix broken default path. Fix from Jim Knoble - <jmknoble@pobox.com> - - Remove test for quad_t. No longer needed. - - Released 1.2.1pre24 - - - Added support for directory-based lastlogs - - Really fix typedefs, patch from Ben Taylor <bent@clark.net> - -19991230 - - OpenBSD CVS updates: - - [auth-passwd.c] - check for NULL 1st - - Removed most of the pam code into its own file auth-pam.[ch]. This - cleaned up sshd.c up significantly. - - PAM authentication was incorrectly interpreting - "PermitRootLogin without-password". Report from Matthias Andree - <ma@dt.e-technik.uni-dortmund.de - - Several other cleanups - - Merged Dante SOCKS support patch from David Rankin - <drankin@bohemians.lexington.ky.us> - - Updated documentation with ./configure options - - Released 1.2.1pre23 - -19991229 - - Applied another NetBSD portability patch from David Rankin - <drankin@bohemians.lexington.ky.us> - - Fix --with-default-path option. - - Autodetect perl, patch from David Rankin - <drankin@bohemians.lexington.ky.us> - - Print whether OpenSSH was compiled with RSARef, patch from - Nalin Dahyabhai <nalin@thermo.stat.ncsu.edu> - - Calls to pam_setcred, patch from Nalin Dahyabhai - <nalin@thermo.stat.ncsu.edu> - - Detect missing size_t and typedef it. - - Rename helper.[ch] to (more appropriate) bsd-misc.[ch] - - Minor Makefile cleaning - -19991228 - - Replacement for getpagesize() for systems which lack it - - NetBSD login.c compile fix from David Rankin - <drankin@bohemians.lexington.ky.us> - - Fully set ut_tv if present in utmp or utmpx - - Portability fixes for Irix 5.3 (now compiles OK!) - - autoconf and other misc cleanups - - Merged AIX patch from Darren Hall <dhall@virage.org> - - Cleaned up defines.h - - Released 1.2.1pre22 - -19991227 - - Automatically correct paths in manpages and configuration files. Patch - and script from Andre Lucas <andre.lucas@dial.pipex.com> - - Removed credits from README to CREDITS file, updated. - - Added --with-default-path to specify custom path for server - - Removed #ifdef trickery from acconfig.h into defines.h - - PAM bugfix. PermitEmptyPassword was being ignored. - - Fixed PAM config files to allow empty passwords if server does. - - Explained spurious PAM auth warning workaround in UPGRADING - - Use last few chars of tty line as ut_id - - New SuSE RPM spec file from Chris Saia <csaia@wtower.com> - - OpenBSD CVS updates: - - [packet.h auth-rhosts.c] - check format string for packet_disconnect and packet_send_debug, too - - [channels.c] - use packet_get_maxsize for channels. consistence. - -19991226 - - Enabled utmpx support by default for Solaris - - Cleanup sshd.c PAM a little more - - Revised RPM package to include Jim Knoble's <jmknoble@pobox.com> - X11 ssh-askpass program. - - Disable logging of PAM success and failures, PAM is verbose enough. - Unfortunatly there is currently no way to disable auth failure - messages. Mention this in UPGRADING file and sent message to PAM - developers - - OpenBSD CVS update: - - [ssh-keygen.1 ssh.1] - remove ref to .ssh/random_seed, mention .ssh/environment in - .Sh FILES, too - - Released 1.2.1pre21 - - Fixed implicit '.' in default path, report from Jim Knoble - <jmknoble@pobox.com> - - Redhat RPM spec fixes from Jim Knoble <jmknoble@pobox.com> - -19991225 - - More fixes from Andre Lucas <andre.lucas@dial.pipex.com> - - Cleanup of auth-passwd.c for shadow and MD5 passwords - - Cleanup and bugfix of PAM authentication code - - Released 1.2.1pre20 - - - Merged fixes from Ben Taylor <bent@clark.net> - - Fixed configure support for PAM. Reported by Naz <96na@eng.cam.ac.uk> - - Disabled logging of PAM password authentication failures when password - is empty. (e.g start of authentication loop). Reported by Naz - <96na@eng.cam.ac.uk>) - -19991223 - - Merged later HPUX patch from Andre Lucas - <andre.lucas@dial.pipex.com> - - Above patch included better utmpx support from Ben Taylor - <bent@clark.net> - -19991222 - - Fix undefined fd_set type in ssh.h from Povl H. Pedersen - <pope@netguide.dk> - - Fix login.c breakage on systems which lack ut_host in struct - utmp. Reported by Willard Dawson <willard.dawson@sbs.siemens.com> - -19991221 - - Integration of large HPUX patch from Andre Lucas - <andre.lucas@dial.pipex.com>. Integrating it had a few other - benefits: - - Ability to disable shadow passwords at configure time - - Ability to disable lastlog support at configure time - - Support for IP address in $DISPLAY - - OpenBSD CVS update: - - [sshconnect.c] - say "REMOTE HOST IDENTIFICATION HAS CHANGED" - - Fix DISABLE_SHADOW support - - Allow MD5 passwords even if shadow passwords are disabled - - Release 1.2.1pre19 - -19991218 - - Redhat init script patch from Chun-Chung Chen - <cjj@u.washington.edu> - - Avoid breakage on systems without IPv6 headers - -19991216 - - Makefile changes for Solaris from Peter Kocks - <peter.kocks@baygate.com> - - Minor updates to docs - - Merged OpenBSD CVS changes: - - [authfd.c ssh-agent.c] - keysize warnings talk about identity files - - [packet.c] - "Connection closed by x.x.x.x": fatal() -> log() - - Correctly handle empty passwords in shadow file. Patch from: - "Chris, the Young One" <cky@pobox.com> - - Released 1.2.1pre18 - -19991215 - - Integrated patchs from Juergen Keil <jk@tools.de> - - Avoid void* pointer arithmatic - - Use LDFLAGS correctly - - Fix SIGIO error in scp - - Simplify status line printing in scp - - Added better test for inline functions compiler support from - Darren_Hall@progressive.com - -19991214 - - OpenBSD CVS Changes - - [canohost.c] - fix get_remote_port() and friends for sshd -i; - Holger.Trapp@Informatik.TU-Chemnitz.DE - - [mpaux.c] - make code simpler. no need for memcpy. niels@ ok - - [pty.c] - namebuflen not sizeof namebuflen; bnd@ep-ag.com via djm@mindrot.org - fix proto; markus - - [ssh.1] - typo; mark.baushke@solipsa.com - - [channels.c ssh.c ssh.h sshd.c] - type conflict for 'extern Type *options' in channels.c; dot@dotat.at - - [sshconnect.c] - move checking of hostkey into own function. - - [version.h] - OpenSSH-1.2.1 - - Clean up broken includes in pty.c - - Some older systems don't have poll.h, they use sys/poll.h instead - - Doc updates - -19991211 - - Fix compilation on systems with AFS. Reported by - aloomis@glue.umd.edu - - Fix installation on Solaris. Reported by - Gordon Rowell <gordonr@gormand.com.au> - - Fix gccisms (__attribute__ and inline). Report by edgy@us.ibm.com, - patch from Markus Friedl <markus.friedl@informatik.uni-erlangen.de> - - Auto-locate xauth. Patch from David Agraz <dagraz@jahoopa.com> - - Compile fix from David Agraz <dagraz@jahoopa.com> - - Avoid compiler warning in bsd-snprintf.c - - Added pam_limits.so to default PAM config. Suggested by - Jim Knoble <jmknoble@pobox.com> - -19991209 - - Import of patch from Ben Taylor <bent@clark.net>: - - Improved PAM support - - "uninstall" rule for Makefile - - utmpx support - - Should fix PAM problems on Solaris - - OpenBSD CVS updates: - - [readpass.c] - avoid stdio; based on work by markus, millert, and I - - [sshd.c] - make sure the client selects a supported cipher - - [sshd.c] - fix sighup handling. accept would just restart and daemon handled - sighup only after the next connection was accepted. use poll on - listen sock now. - - [sshd.c] - make that a fatal - - Applied patch from David Rankin <drankin@bohemians.lexington.ky.us> - to fix libwrap support on NetBSD - - Released 1.2pre17 - -19991208 - - Compile fix for Solaris with /dev/ptmx from - David Agraz <dagraz@jahoopa.com> - -19991207 - - sshd Redhat init script patch from Jim Knoble <jmknoble@pobox.com> - fixes compatability with 4.x and 5.x - - Fixed default SSH_ASKPASS - - Fix PAM account and session being called multiple times. Problem - reported by Adrian Baugh <adrian@merlin.keble.ox.ac.uk> - - Merged more OpenBSD changes: - - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c] - move atomicio into it's own file. wrap all socket write()s which - were doing write(sock, buf, len) != len, with atomicio() calls. - - [auth-skey.c] - fd leak - - [authfile.c] - properly name fd variable - - [channels.c] - display great hatred towards strcpy - - [pty.c pty.h sshd.c] - use openpty() if it exists (it does on BSD4_4) - - [tildexpand.c] - check for ~ expansion past MAXPATHLEN - - Modified helper.c to use new atomicio function. - - Reformat Makefile a little - - Moved RC4 routines from rc4.[ch] into helper.c - - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX) - - Updated SuSE spec from Chris Saia <csaia@wtower.com> - - Tweaked Redhat spec - - Clean up bad imports of a few files (forgot -kb) - - Released 1.2pre16 - -19991204 - - Small cleanup of PAM code in sshd.c - - Merged OpenBSD CVS changes: - - [auth-krb4.c auth-passwd.c auth-skey.c ssh.h] - move skey-auth from auth-passwd.c to auth-skey.c, same for krb4 - - [auth-rsa.c] - warn only about mismatch if key is _used_ - warn about keysize-mismatch with log() not error() - channels.c readconf.c readconf.h ssh.c ssh.h sshconnect.c - ports are u_short - - [hostfile.c] - indent, shorter warning - - [nchan.c] - use error() for internal errors - - [packet.c] - set loglevel for SSH_MSG_DISCONNECT to log(), not fatal() - serverloop.c - indent - - [ssh-add.1 ssh-add.c ssh.h] - document $SSH_ASKPASS, reasonable default - - [ssh.1] - CheckHostIP is not available for connects via proxy command - - [sshconnect.c] - typo - easier to read client code for passwd and skey auth - turn of checkhostip for proxy connects, since we don't know the remote ip - -19991126 - - Add definition for __P() - - Added [v]snprintf() replacement for systems that lack it - -19991125 - - More reformatting merged from OpenBSD CVS - - Merged OpenBSD CVS changes: - - [channels.c] - fix packet_integrity_check() for !have_hostname_in_open. - report from mrwizard@psu.edu via djm@ibs.com.au - - [channels.c] - set SO_REUSEADDR and SO_LINGER for forwarded ports. - chip@valinux.com via damien@ibs.com.au - - [nchan.c] - it's not an error() if shutdown_write failes in nchan. - - [readconf.c] - remove dead #ifdef-0-code - - [readconf.c servconf.c] - strcasecmp instead of tolower - - [scp.c] - progress meter overflow fix from damien@ibs.com.au - - [ssh-add.1 ssh-add.c] - SSH_ASKPASS support - - [ssh.1 ssh.c] - postpone fork_after_authentication until command execution, - request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au - plus: use daemon() for backgrounding - - Added BSD compatible install program and autoconf test, thanks to - Niels Kristian Bech Jensen <nkbj@image.dk> - - Solaris fixing, thanks to Ben Taylor <bent@clark.net> - - Merged beginnings of AIX support from Tor-Ake Fransson <torake@hotmail.com> - - Release 1.2pre15 - -19991124 - - Merged very large OpenBSD source code reformat - - OpenBSD CVS updates - - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] - [ssh.h sshd.8 sshd.c] - syslog changes: - * Unified Logmessage for all auth-types, for success and for failed - * Standard connections get only ONE line in the LOG when level==LOG: - Auth-attempts are logged only, if authentication is: - a) successfull or - b) with passwd or - c) we had more than AUTH_FAIL_LOG failues - * many log() became verbose() - * old behaviour with level=VERBOSE - - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] - tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE - messages. allows use of s/key in windows (ttssh, securecrt) and - ssh-1.2.27 clients without 'ssh -v', ok: niels@ - - [sshd.8] - -V, for fallback to openssh in SSH2 compatibility mode - - [sshd.c] - fix sigchld race; cjc5@po.cwru.edu - -19991123 - - Added SuSE package files from Chris Saia <csaia@wtower.com> - - Restructured package-related files under packages/* - - Added generic PAM config - - Numerous little Solaris fixes - - Add recommendation to use GNU make to INSTALL document - -19991122 - - Make <enter> close gnome-ssh-askpass (Debian bug #50299) - - OpenBSD CVS Changes - - [ssh-keygen.c] - don't create ~/.ssh only if the user wants to store the private - key there. show fingerprint instead of public-key after - keygeneration. ok niels@ - - Added OpenBSD bsd-strlcat.c, created bsd-strlcat.h - - Added timersub() macro - - Tidy RCSIDs of bsd-*.c - - Added autoconf test and macro to deal with old PAM libraries - pam_strerror definition (one arg vs two). - - Fix EGD problems (Thanks to Ben Taylor <bent@clark.net>) - - Retry /dev/urandom reads interrupted by signal (report from - Robert Hardy <rhardy@webcon.net>) - - Added a setenv replacement for systems which lack it - - Only display public key comment when presenting ssh-askpass dialog - - Released 1.2pre14 - - - Configure, Make and changelog corrections from Tudor Bosman - <tudorb@jm.nu> and Niels Kristian Bech Jensen <nkbj@image.dk> - -19991121 - - OpenBSD CVS Changes: - - [channels.c] - make this compile, bad markus - - [log.c readconf.c servconf.c ssh.h] - bugfix: loglevels are per host in clientconfig, - factor out common log-level parsing code. - - [servconf.c] - remove unused index (-Wall) - - [ssh-agent.c] - only one 'extern char *__progname' - - [sshd.8] - document SIGHUP, -Q to synopsis - - [sshconnect.c serverloop.c sshd.c packet.c packet.h] - [channels.c clientloop.c] - SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@ - [hope this time my ISP stays alive during commit] - - [OVERVIEW README] typos; green@freebsd - - [ssh-keygen.c] - replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me) - exit if writing the key fails (no infinit loop) - print usage() everytime we get bad options - - [ssh-keygen.c] overflow, djm@mindrot.org - - [sshd.c] fix sigchld race; cjc5@po.cwru.edu - -19991120 - - Merged more Solaris support from Marc G. Fournier - <marc.fournier@acadiau.ca> - - Wrote autoconf tests for integer bit-types - - Fixed enabling kerberos support - - Fix segfault in ssh-keygen caused by buffer overrun in filename - handling. - -19991119 - - Merged PAM buffer overrun patch from Chip Salzenberg <chip@valinux.com> - - Merged OpenBSD CVS changes - - [auth-rhosts.c auth-rsa.c ssh-agent.c sshconnect.c sshd.c] - more %d vs. %s in fmt-strings - - [authfd.c] - Integers should not be printed with %s - - EGD uses a socket, not a named pipe. Duh. - - Fix includes in fingerprint.c - - Fix scp progress bar bug again. - - Move ssh-askpass from ${libdir}/ssh to ${libexecdir}/ssh at request of - David Rankin <drankin@bohemians.lexington.ky.us> - - Added autoconf option to enable Kerberos 4 support (untested) - - Added autoconf option to enable AFS support (untested) - - Added autoconf option to enable S/Key support (untested) - - Added autoconf option to enable TCP wrappers support (compiles OK) - - Renamed BSD helper function files to bsd-* - - Added tests for login and daemon and enable OpenBSD replacements for - when they are absent. - - Added non-PAM MD5 password support patch from Tudor Bosman <tudorb@jm.nu> - -19991118 - - Merged OpenBSD CVS changes - - [scp.c] foregroundproc() in scp - - [sshconnect.h] include fingerprint.h - - [sshd.c] bugfix: the log() for passwd-auth escaped during logging - changes. - - [ssh.1] Spell my name right. - - Added openssh.com info to README - -19991117 - - Merged OpenBSD CVS changes - - [ChangeLog.Ylonen] noone needs this anymore - - [authfd.c] close-on-exec for auth-socket, ok deraadt - - [hostfile.c] - in known_hosts key lookup the entry for the bits does not need - to match, all the information is contained in n and e. This - solves the problem with buggy servers announcing the wrong - modulus length. markus and me. - - [serverloop.c] - bugfix: check for space if child has terminated, from: - iedowse@maths.tcd.ie - - [ssh-add.1 ssh-add.c ssh-keygen.1 ssh-keygen.c sshconnect.c] - [fingerprint.c fingerprint.h] - rsa key fingerprints, idea from Bjoern Groenvall <bg@sics.se> - - [ssh-agent.1] typo - - [ssh.1] add OpenSSH information to AUTHOR section. okay markus@ - - [sshd.c] - force logging to stderr while loading private key file - (lost while converting to new log-levels) - -19991116 - - Fix some Linux libc5 problems reported by Miles Wilson <mw@mctitle.com> - - Merged OpenBSD CVS changes: - - [auth-rh-rsa.c auth-rsa.c authfd.c authfd.h hostfile.c mpaux.c] - [mpaux.h ssh-add.c ssh-agent.c ssh.h ssh.c sshd.c] - the keysize of rsa-parameter 'n' is passed implizit, - a few more checks and warnings about 'pretended' keysizes. - - [cipher.c cipher.h packet.c packet.h sshd.c] - remove support for cipher RC4 - - [ssh.c] - a note for legay systems about secuity issues with permanently_set_uid(), - the private hostkey and ptrace() - - [sshconnect.c] - more detailed messages about adding and checking hostkeys - -19991115 - - Merged OpenBSD CVS changes: - - [ssh-add.c] change passphrase loop logic and remove ref to - $DISPLAY, ok niels - - Changed to ssh-add.c broke askpass support. Revised it to be a little more - modular. - - Revised autoconf support for enabling/disabling askpass support. - - Merged more OpenBSD CVS changes: - [auth-krb4.c] - - disconnect if getpeername() fails - - missing xfree(*client) - [canohost.c] - - disconnect if getpeername() fails - - fix comment: we _do_ disconnect if ip-options are set - [sshd.c] - - disconnect if getpeername() fails - - move checking of remote port to central place - [auth-rhosts.c] move checking of remote port to central place - [log-server.c] avoid extra fd per sshd, from millert@ - [readconf.c] print _all_ bad config-options in ssh(1), too - [readconf.h] print _all_ bad config-options in ssh(1), too - [ssh.c] print _all_ bad config-options in ssh(1), too - [sshconnect.c] disconnect if getpeername() fails - - OpenBSD's changes to sshd.c broke the PAM stuff, re-merged it. - - Various small cleanups to bring diff (against OpenBSD) size down. - - Merged more Solaris compability from Marc G. Fournier - <marc.fournier@acadiau.ca> - - Wrote autoconf tests for __progname symbol - - RPM spec file fixes from Jim Knoble <jmknoble@pobox.com> - - Released 1.2pre12 - - - Another OpenBSD CVS update: - - [ssh-keygen.1] fix .Xr - -19991114 - - Solaris compilation fixes (still imcomplete) - -19991113 - - Build patch from Niels Kristian Bech Jensen <nkbj@image.dk> - - Don't install config files if they already exist - - Fix inclusion of additional preprocessor directives from acconfig.h - - Removed redundant inclusions of config.h - - Added 'Obsoletes' lines to RPM spec file - - Merged OpenBSD CVS changes: - - [bufaux.c] save a view malloc/memcpy/memset/free's, ok niels - - [scp.c] fix overflow reported by damien@ibs.com.au: off_t - totalsize, ok niels,aaron - - Delay fork (-f option) in ssh until after port forwarded connections - have been initialised. Patch from Jani Hakala <jahakala@cc.jyu.fi> - - Added shadow password patch from Thomas Neumann <tom@smart.ruhr.de> - - Added ifdefs to auth-passwd.c to exclude it when PAM is enabled - - Tidied default config file some more - - Revised Redhat initscript to fix bug: sshd (re)start would fail - if executed from inside a ssh login. - -19991112 - - Merged changes from OpenBSD CVS - - [sshd.c] session_key_int may be zero - - [auth-rh-rsa.c servconf.c servconf.h ssh.h sshd.8 sshd.c sshd_config] - IgnoreUserKnownHosts(default=no), used for RhostRSAAuth, ok - deraadt,millert - - Brought default sshd_config more in line with OpenBSD's - - Grab server in gnome-ssh-askpass (Debian bug #49872) - - Released 1.2pre10 - - - Added INSTALL documentation - - Merged yet more changes from OpenBSD CVS - - [auth-rh-rsa.c auth-rhosts.c auth-rsa.c channels.c clientloop.c] - [ssh.c ssh.h sshconnect.c sshd.c] - make all access to options via 'extern Options options' - and 'extern ServerOptions options' respectively; - options are no longer passed as arguments: - * make options handling more consistent - * remove #include "readconf.h" from ssh.h - * readconf.h is only included if necessary - - [mpaux.c] clear temp buffer - - [servconf.c] print _all_ bad options found in configfile - - Make ssh-askpass support optional through autoconf - - Fix nasty division-by-zero error in scp.c - - Released 1.2pre11 - -19991111 - - Added (untested) Entropy Gathering Daemon (EGD) support - - Fixed /dev/urandom fd leak (Debian bug #49722) - - Merged OpenBSD CVS changes: - - [auth-rh-rsa.c] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too - - [ssh.1] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too - - [sshd.8] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too - - Fix integer overflow which was messing up scp's progress bar for large - file transfers. Fix submitted to OpenBSD developers. Report and fix - from Kees Cook <cook@cpoint.net> - - Merged more OpenBSD CVS changes: - - [auth-krb4.c auth-passwd.c] remove x11- and krb-cleanup from fatal() - + krb-cleanup cleanup - - [clientloop.c log-client.c log-server.c ] - [readconf.c readconf.h servconf.c servconf.h ] - [ssh.1 ssh.c ssh.h sshd.8] - add LogLevel {QUIET, FATAL, ERROR, INFO, CHAT, DEBUG} to ssh/sshd, - obsoletes QuietMode and FascistLogging in sshd. - - [sshd.c] fix fatal/assert() bug reported by damien@ibs.com.au: - allow session_key_int != sizeof(session_key) - [this should fix the pre-assert-removal-core-files] - - Updated default config file to use new LogLevel option and to improve - readability - -19991110 - - Merged several minor fixes: - - ssh-agent commandline parsing - - RPM spec file now installs ssh setuid root - - Makefile creates libdir - - Merged beginnings of Solaris compability from Marc G. Fournier - <marc.fournier@acadiau.ca> - -19991109 - - Autodetection of SSL/Crypto library location via autoconf - - Fixed location of ssh-askpass to follow autoconf - - Integrated Makefile patch from Niels Kristian Bech Jensen <nkbj@image.dk> - - Autodetection of RSAref library for US users - - Minor doc updates - - Merged OpenBSD CVS changes: - - [rsa.c] bugfix: use correct size for memset() - - [sshconnect.c] warn if announced size of modulus 'n' != real size - - Added GNOME passphrase requestor (use --with-gnome-askpass) - - RPM build now creates subpackages - - Released 1.2pre9 - -19991108 - - Removed debian/ directory. This is now being maintained separately. - - Added symlinks for slogin in RPM spec file - - Fixed permissions on manpages in RPM spec file - - Added references to required libraries in README file - - Removed config.h.in from CVS - - Removed pwdb support (better pluggable auth is provided by glibc) - - Made PAM and requisite libdl optional - - Removed lots of unnecessary checks from autoconf - - Added support and autoconf test for openpty() function (Unix98 pty support) - - Fix for scp not finding ssh if not installed as /usr/bin/ssh - - Added TODO file - - Merged parts of Debian patch From Phil Hands <phil@hands.com>: - - Added ssh-askpass program - - Added ssh-askpass support to ssh-add.c - - Create symlinks for slogin on install - - Fix "distclean" target in makefile - - Added example for ssh-agent to manpage - - Added support for PAM_TEXT_INFO messages - - Disable internal /etc/nologin support if PAM enabled - - Merged latest OpenBSD CVS changes: - - [all] replace assert() with error, fatal or packet_disconnect - - [sshd.c] don't send fail-msg but disconnect if too many authentication - failures - - [sshd.c] remove unused argument. ok dugsong - - [sshd.c] typo - - [rsa.c] clear buffers used for encryption. ok: niels - - [rsa.c] replace assert() with error, fatal or packet_disconnect - - [auth-krb4.c] remove unused argument. ok dugsong - - Fixed coredump after merge of OpenBSD rsa.c patch - - Released 1.2pre8 - -19991102 - - Merged change from OpenBSD CVS - - One-line cleanup in sshd.c - -19991030 - - Integrated debian package support from Dan Brosemer <odin@linuxfreak.com> - - Merged latest updates for OpenBSD CVS: - - channels.[ch] - remove broken x11 fix and document istate/ostate - - ssh-agent.c - call setsid() regardless of argv[] - - ssh.c - save a few lines when disabling rhosts-{rsa-}auth - - Documentation cleanups - - Renamed README -> README.Ylonen - - Renamed README.openssh ->README - -19991029 - - Renamed openssh* back to ssh* at request of Theo de Raadt - - Incorporated latest changes from OpenBSD's CVS - - Integrated Makefile patch from Niels Kristian Bech Jensen <nkbj@image.dk> - - Integrated PAM env patch from Nalin Dahyabhai <nalin.dahyabhai@pobox.com> - - Make distclean now removed configure script - - Improved PAM logging - - Added some debug() calls for PAM - - Removed redundant subdirectories - - Integrated part of a patch from Dan Brosemer <odin@linuxfreak.com> for - building on Debian. - - Fixed off-by-one error in PAM env patch - - Released 1.2pre6 - -19991028 - - Further PAM enhancements. - - Much cleaner - - Now uses account and session modules for all logins. - - Integrated patch from Dan Brosemer <odin@linuxfreak.com> - - Build fixes - - Autoconf - - Change binary names to open* - - Fixed autoconf script to detect PAM on RH6.1 - - Added tests for libpwdb, and OpenBSD functions to autoconf - - Released 1.2pre4 - - - Imported latest OpenBSD CVS code - - Updated README.openssh - - Released 1.2pre5 - -19991027 - - Adapted PAM patch. - - Released 1.0pre2 - - - Excised my buggy replacements for strlcpy and mkdtemp - - Imported correct OpenBSD strlcpy and mkdtemp routines. - - Reduced arc4random_stir entropy read to 32 bytes (256 bits) - - Picked up correct version number from OpenBSD - - Added sshd.pam PAM configuration file - - Added sshd.init Redhat init script - - Added openssh.spec RPM spec file - - Released 1.2pre3 - -19991026 - - Fixed include paths of OpenSSL functions - - Use OpenSSL MD5 routines - - Imported RC4 code from nanocrypt - - Wrote replacements for OpenBSD arc4random* functions - - Wrote replacements for strlcpy and mkdtemp - - Released 1.0pre1 diff --git a/usr/src/cmd/ssh/doc/INSTALL b/usr/src/cmd/ssh/doc/INSTALL deleted file mode 100644 index 9112b92b57..0000000000 --- a/usr/src/cmd/ssh/doc/INSTALL +++ /dev/null @@ -1,199 +0,0 @@ -1. Prerequisites ----------------- - -You will need working installations of Zlib and OpenSSL. - -Zlib: -http://www.freesoftware.com/pub/infozip/zlib/ - -OpenSSL 0.9.5a or greater: -http://www.openssl.org/ - -RPMs of OpenSSL are available at http://violet.ibs.com.au/openssh/files/support - -OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system -supports it. PAM is standard on Redhat and Debian Linux and on Solaris. - -PAM: -http://www.kernel.org/pub/linux/libs/pam/ - -If you wish to build the GNOME passphrase requester, you will need the GNOME -libraries and headers. - -GNOME: -http://www.gnome.org/ - -Alternatively, Jim Knoble <jmknoble@pobox.com> has written an excellent X11 -passphrase requester. This is maintained separately at: - -http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html - -The Entropy Gathering Daemon (EGD) is supported if you have a system which -lacks /dev/random and don't want to use OpenSSH's internal entropy collection. - -EGD: -http://www.lothar.com/tech/crypto/ - -GNU Make: -ftp://ftp.gnu.org/gnu/make/ - -OpenSSH has only been tested with GNU make. It may work with other -'make' programs, but you are on your own. - -pcre (POSIX Regular Expression library): -ftp://ftp.cus.cam.ac.uk/pub/software/programs/pcre/ - -Most platforms do not required this. However older 4.3 BSD do not -have a posix regex library. - - -2. Building / Installation --------------------------- - -To install OpenSSH with default options: - -./configure -make -make install - -This will install the OpenSSH binaries in /usr/local/bin, configuration files -in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different -installation prefix, use the --prefix option to configure: - -./configure --prefix=/opt -make -make install - -Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override -specific paths, for example: - -./configure --prefix=/opt --sysconfdir=/etc/ssh -make -make install - -This will install the binaries in /opt/{bin,lib,sbin}, but will place the -configuration files in /etc/ssh. - -If you are using PAM, you will need to manually install a PAM -control file as "/etc/pam.d/sshd" (or wherever your system -prefers to keep them). A generic PAM configuration is included as -"contrib/sshd.pam.generic", you may need to edit it before using it on -your system. If you are using a recent version of Redhat Linux, the -config file in contrib/redhat/sshd.pam should be more useful. -Failure to install a valid PAM file may result in an inability to -use password authentication. - -There are a few other options to the configure script: - ---with-rsh=PATH allows you to specify the path to your rsh program. -Normally ./configure will search the current $PATH for 'rsh'. You -may need to specify this option if rsh is not in your path or has a -different name. - ---without-pam will disable PAM support. PAM is automatically detected -and switched on if found. - ---enable-gnome-askpass will build the GNOME passphrase dialog. You -need a working installation of GNOME, including the development -headers, for this to work. - ---with-random=/some/file allows you to specify an alternate source of -random numbers (the default is /dev/urandom). Unless you are absolutely -sure of what you are doing, it is best to leave this alone. - ---with-egd-pool=/some/file allows you to enable Entropy Gathering -Daemon support and to specify a EGD pool socket. Use this if your -Unix lacks /dev/random and you don't want to use OpenSSH's builtin -entropy collection support. - ---with-lastlog=FILE will specify the location of the lastlog file. -./configure searches a few locations for lastlog, but may not find -it if lastlog is installed in a different place. - ---without-lastlog will disable lastlog support entirely. - ---with-kerberos4=PATH will enable Kerberos IV support. You will need -to have the Kerberos libraries and header files installed for this -to work. Use the optional PATH argument to specify the root of your -Kerberos installation. - ---with-afs=PATH will enable AFS support. You will need to have the -Kerberos IV and the AFS libraries and header files installed for this -to work. Use the optional PATH argument to specify the root of your -AFS installation. AFS requires Kerberos support to be enabled. - ---with-skey will enable S/Key one time password support. You will need -the S/Key libraries and header files installed for this to work. - ---with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny) -support. You will need libwrap.a and tcpd.h installed. - ---with-md5-passwords will enable the use of MD5 passwords. Enable this -if your operating system uses MD5 passwords without using PAM. - ---with-utmpx enables utmpx support. utmpx support is automatic for -some platforms. - ---without-shadow disables shadow password support. - ---with-ipaddr-display forces the use of a numeric IP address in the -$DISPLAY environment variable. Some broken systems need this. - ---with-default-path=PATH allows you to specify a default $PATH for sessions -started by sshd. This replaces the standard path entirely. - ---with-pid-dir=PATH specifies the directory in which the ssh.pid file is -created. - ---with-xauth=PATH specifies the location of the xauth binary - ---with-ipv4-default instructs OpenSSH to use IPv4 by default for new -connections. Normally OpenSSH will try attempt to lookup both IPv6 and -IPv4 addresses. On Linux/glibc-2.1.2 this causes long delays in name -resolution. If this option is specified, you can still attempt to -connect to IPv6 addresses using the command line option '-6'. - ---with-ssl-dir=DIR allows you to specify where your OpenSSL libraries -are installed. - ---with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to -real (AF_INET) IPv4 addresses. Works around some quirks on Linux. - -If you need to pass special options to the compiler or linker, you -can specify these as environment variables before running ./configure. -For example: - -CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure - -3. Configuration ----------------- - -The runtime configuration files are installed by in ${prefix}/etc or -whatever you specified as your --sysconfdir (/usr/local/etc by default). - -The default configuration should be instantly usable, though you should -review it to ensure that it matches your security requirements. - -To generate a host key, run "make host-key". Alternately you can do so -manually using the following commands: - - ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N "" - ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N "" - -Replacing /etc/ssh with the correct path to the configuration directory. -(${prefix}/etc or whatever you specified with --sysconfdir during -configuration) - -If you have configured OpenSSH with EGD support, ensure that EGD is -running and has collected some Entropy. - -For more information on configuration, please refer to the manual pages -for sshd, ssh and ssh-agent. - -4. Problems? ------------- - -If you experience problems compiling, installing or running OpenSSH. -Please refer to the "reporting bugs" section of the webpage at -http://www.openssh.com/ - diff --git a/usr/src/cmd/ssh/doc/LICENCE b/usr/src/cmd/ssh/doc/LICENCE deleted file mode 100644 index 04d6fe18e3..0000000000 --- a/usr/src/cmd/ssh/doc/LICENCE +++ /dev/null @@ -1,194 +0,0 @@ -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 replaced with ARC4 support from OpenSSL - - 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> - -3a) - Various parts are from the University of California. - - * Copyright (c) 1983, 1987, 1989-1995 - * 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. - - * Copyright (c) 1989, 1991, 1993, 1994 - * 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. - * - * 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. - -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/usr/src/cmd/ssh/doc/OVERVIEW b/usr/src/cmd/ssh/doc/OVERVIEW deleted file mode 100644 index 7f34ac45bd..0000000000 --- a/usr/src/cmd/ssh/doc/OVERVIEW +++ /dev/null @@ -1,164 +0,0 @@ -This document is intended for those who wish to read the ssh source -code. This tries to give an overview of the structure of the code. - -Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi> -Updated 17 Nov 1995. -Updated 19 Oct 1999 for OpenSSH-1.2 - -The software consists of ssh (client), sshd (server), scp, sdist, and -the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and -make-ssh-known-hosts. The main program for each of these is in a .c -file with the same name. - -There are some subsystems/abstractions that are used by a number of -these programs. - - Buffer manipulation routines - - - These provide an arbitrary size buffer, where data can be appended. - Data can be consumed from either end. The code is used heavily - throughout ssh. The basic buffer manipulation functions are in - buffer.c (header buffer.h), and additional code to manipulate specific - data types is in bufaux.c. - - Compression Library - - - Ssh uses the GNU GZIP compression library (ZLIB). - - Encryption/Decryption - - - Ssh contains several encryption algorithms. These are all - accessed through the cipher.h interface. The interface code is - in cipher.c, and the implementations are in libc. - - Multiple Precision Integer Library - - - Uses the SSLeay BIGNUM sublibrary. - - Some auxiliary functions for mp-int manipulation are in mpaux.c. - - Random Numbers - - - Uses arc4random() and such. - - RSA key generation, encryption, decryption - - - Ssh uses the RSA routines in libssl. - - RSA key files - - - RSA keys are stored in files with a special format. The code to - read/write these files is in authfile.c. The files are normally - encrypted with a passphrase. The functions to read passphrases - are in readpass.c (the same code is used to read passwords). - - Binary packet protocol - - - The ssh binary packet protocol is implemented in packet.c. The - code in packet.c does not concern itself with packet types or their - execution; it contains code to build packets, to receive them and - extract data from them, and the code to compress and/or encrypt - packets. CRC code comes from crc32.c. - - - The code in packet.c calls the buffer manipulation routines - (buffer.c, bufaux.c), compression routines (compress.c, zlib), - and the encryption routines. - - X11, TCP/IP, and Agent forwarding - - - Code for various types of channel forwarding is in channels.c. - The file defines a generic framework for arbitrary communication - channels inside the secure channel, and uses this framework to - implement X11 forwarding, TCP/IP forwarding, and authentication - agent forwarding. - The new, Protocol 1.5, channel close implementation is in nchan.c - - Authentication agent - - - Code to communicate with the authentication agent is in authfd.c. - - Authentication methods - - - Code for various authentication methods resides in auth-*.c - (auth-passwd.c, auth-rh-rsa.c, auth-rhosts.c, auth-rsa.c). This - code is linked into the server. The routines also manipulate - known hosts files using code in hostfile.c. Code in canohost.c - is used to retrieve the canonical host name of the remote host. - Code in match.c is used to match host names. - - - In the client end, authentication code is in sshconnect.c. It - reads Passwords/passphrases using code in readpass.c. It reads - RSA key files with authfile.c. It communicates the - authentication agent using authfd.c. - - The ssh client - - - The client main program is in ssh.c. It first parses arguments - and reads configuration (readconf.c), then calls ssh_connect (in - sshconnect.c) to open a connection to the server (possibly via a - proxy), and performs authentication (ssh_login in sshconnect.c). - It then makes any pty, forwarding, etc. requests. It may call - code in ttymodes.c to encode current tty modes. Finally it - calls client_loop in clientloop.c. This does the real work for - the session. - - - The client is suid root. It tries to temporarily give up this - rights while reading the configuration data. The root - privileges are only used to make the connection (from a - privileged socket). Any extra privileges are dropped before - calling ssh_login. - - Pseudo-tty manipulation and tty modes - - - Code to allocate and use a pseudo tty is in pty.c. Code to - encode and set terminal modes is in ttymodes.c. - - Logging in (updating utmp, lastlog, etc.) - - - The code to do things that are done when a user logs in are in - login.c. This includes things such as updating the utmp, wtmp, - and lastlog files. Some of the code is in sshd.c. - - Writing to the system log and terminal - - - The programs use the functions fatal(), log(), debug(), error() - in many places to write messages to system log or user's - terminal. The implementation that logs to system log is in - log-server.c; it is used in the server program. The other - programs use an implementation that sends output to stderr; it - is in log-client.c. The definitions are in ssh.h. - - The sshd server (daemon) - - - The sshd daemon starts by processing arguments and reading the - configuration file (servconf.c). It then reads the host key, - starts listening for connections, and generates the server key. - The server key will be regenerated every hour by an alarm. - - - When the server receives a connection, it forks, disables the - regeneration alarm, and starts communicating with the client. - They first perform identification string exchange, then - negotiate encryption, then perform authentication, preparatory - operations, and finally the server enters the normal session - mode by calling server_loop in serverloop.c. This does the real - work, calling functions in other modules. - - - The code for the server is in sshd.c. It contains a lot of - stuff, including: - - server main program - - waiting for connections - - processing new connection - - authentication - - preparatory operations - - building up the execution environment for the user program - - starting the user program. - - Auxiliary files - - - There are several other files in the distribution that contain - various auxiliary routines: - ssh.h the main header file for ssh (various definitions) - getput.h byte-order independent storage of integers - includes.h includes most system headers. Lots of #ifdefs. - tildexpand.c expand tilde in file names - uidswap.c uid-swapping - xmalloc.c "safe" malloc routines diff --git a/usr/src/cmd/ssh/doc/README b/usr/src/cmd/ssh/doc/README deleted file mode 100644 index f94e2ed1c5..0000000000 --- a/usr/src/cmd/ssh/doc/README +++ /dev/null @@ -1,70 +0,0 @@ -[ A Japanese translation of this document is available at -[ http://www.unixuser.org/%7Eharuyama/security/openssh/index.html -[ Thanks to HARUYAMA Seigo <haruyama@nt.phys.s.u-tokyo.ac.jp> - -******* IMPORTANT -* On systmes which lack a /dev/random driver, version of this port -* prior to 1.2.2 were not correctly seeding OpenSSL's random number -* pool. This resulted in lower quality RSA keys being generated. If -* you generated host or user keys with v1.2.2 or previous versions, -* please generate new ones using a more recent version. - -This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other -Unices. - -OpenSSH is based on the last free version of Tatu Ylonen's SSH with -all patent-encumbered algorithms removed (to external libraries), all -known security bugs fixed, new features reintroduced and many other -clean-ups. More information about SSH itself can be found in the file -README.Ylonen. OpenSSH has been created by Aaron Campbell, Bob Beck, -Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song. It has a -homepage at http://www.openssh.com/ - -This port consists of the re-introduction of autoconf support, PAM -support (for Linux and Solaris), EGD[1] support and replacements for -OpenBSD library functions that are (regrettably) absent from other -unices. This port has been best tested on Linux, Solaris, HPUX, NetBSD -and Irix. Support for AIX, SCO, NeXT and other Unices is underway. -This version actively tracks changes in the OpenBSD CVS repository. - -The PAM support is now more functional than the popular packages of -commercial ssh-1.2.x. It checks "account" and "session" modules for -all logins, not just when using password authentication. - -OpenSSH depends on Zlib[2], OpenSSL[3] and optionally PAM[4]. - -There is now several mailing lists for this port of OpenSSH. Please -refer to http://www.openssh.com/list.html for details on how to join. - -Please send bug reports and patches to the mailing list -openssh-unix-dev@mindrot.org. The list is open to posting by -unsubscribed users. - -If you are a citizen of the USA or another country which restricts -export of cryptographic products, then please refrain from sending -crypto-related code or patches to the list. We cannot accept them. -Other code contribution are accepted, but please follow the OpenBSD -style guidelines[5]. - -Please refer to the INSTALL document for information on how to install -OpenSSH on your system. There are a number of differences between this -port of OpenSSH and F-Secure SSH 1.x, please refer to the OpenSSH FAQ[6] -for details and general tips. - -Damien Miller <djm@mindrot.org> - -Miscellania - - -This version of SSH is based upon code retrieved from the OpenBSD CVS -repository which in turn was based on the last free -version of SSH released by Tatu Ylonen. - -References - - -[0] http://www.openssh.com/faq.html -[1] http://www.lothar.com/tech/crypto/ -[2] ftp://ftp.freesoftware.com/pub/infozip/zlib/ -[3] http://www.openssl.org/ -[4] http://www.kernel.org/pub/linux/libs/pam/ (PAM is standard on Solaris) -[5] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9&apropos=0&manpath=OpenBSD+Current -[6] http://www.openssh.com/faq.html diff --git a/usr/src/cmd/ssh/doc/README.Ylonen b/usr/src/cmd/ssh/doc/README.Ylonen deleted file mode 100644 index 38987b926a..0000000000 --- a/usr/src/cmd/ssh/doc/README.Ylonen +++ /dev/null @@ -1,567 +0,0 @@ - -[ Please note that this file has not been updated for OpenSSH and - covers the ssh-1.2.12 release from Dec 1995 only. ] - -Ssh (Secure Shell) is a program to log into another computer over a -network, to execute commands in a remote machine, and to move files -from one machine to another. It provides strong authentication and -secure communications over insecure channels. It is inteded as a -replacement for rlogin, rsh, rcp, and rdist. - -See the file INSTALL for installation instructions. See COPYING for -license terms and other legal issues. See RFC for a description of -the protocol. There is a WWW page for ssh; see http://www.cs.hut.fi/ssh. - -This file has been updated to match ssh-1.2.12. - - -FEATURES - - o Strong authentication. Closes several security holes (e.g., IP, - routing, and DNS spoofing). New authentication methods: .rhosts - together with RSA based host authentication, and pure RSA - authentication. - - o Improved privacy. All communications are automatically and - transparently encrypted. RSA is used for key exchange, and a - conventional cipher (normally IDEA, DES, or triple-DES) for - encrypting the session. Encryption is started before - authentication, and no passwords or other information is - transmitted in the clear. Encryption is also used to protect - against spoofed packets. - - o Secure X11 sessions. The program automatically sets DISPLAY on - the server machine, and forwards any X11 connections over the - secure channel. Fake Xauthority information is automatically - generated and forwarded to the remote machine; the local client - automatically examines incoming X11 connections and replaces the - fake authorization data with the real data (never telling the - remote machine the real information). - - o Arbitrary TCP/IP ports can be redirected through the encrypted channel - in both directions (e.g., for e-cash transactions). - - o No retraining needed for normal users; everything happens - automatically, and old .rhosts files will work with strong - authentication if administration installs host key files. - - o Never trusts the network. Minimal trust on the remote side of - the connection. Minimal trust on domain name servers. Pure RSA - authentication never trusts anything but the private key. - - o Client RSA-authenticates the server machine in the beginning of - every connection to prevent trojan horses (by routing or DNS - spoofing) and man-in-the-middle attacks, and the server - RSA-authenticates the client machine before accepting .rhosts or - /etc/hosts.equiv authentication (to prevent DNS, routing, or - IP-spoofing). - - o Host authentication key distribution can be centrally by the - administration, automatically when the first connection is made - to a machine (the key obtained on the first connection will be - recorded and used for authentication in the future), or manually - by each user for his/her own use. The central and per-user host - key repositories are both used and complement each other. Host - keys can be generated centrally or automatically when the software - is installed. Host authentication keys are typically 1024 bits. - - o Any user can create any number of user authentication RSA keys for - his/her own use. Each user has a file which lists the RSA public - keys for which proof of possession of the corresponding private - key is accepted as authentication. User authentication keys are - typically 1024 bits. - - o The server program has its own server RSA key which is - automatically regenerated every hour. This key is never saved in - any file. Exchanged session keys are encrypted using both the - server key and the server host key. The purpose of the separate - server key is to make it impossible to decipher a captured session by - breaking into the server machine at a later time; one hour from - the connection even the server machine cannot decipher the session - key. The key regeneration interval is configurable. The server - key is normally 768 bits. - - o An authentication agent, running in the user's laptop or local - workstation, can be used to hold the user's RSA authentication - keys. Ssh automatically forwards the connection to the - authentication agent over any connections, and there is no need to - store the RSA authentication keys on any machine in the network - (except the user's own local machine). The authentication - protocols never reveal the keys; they can only be used to verify - that the user's agent has a certain key. Eventually the agent - could rely on a smart card to perform all authentication - computations. - - o The software can be installed and used (with restricted - functionality) even without root privileges. - - o The client is customizable in system-wide and per-user - configuration files. Most aspects of the client's operation can - be configured. Different options can be specified on a per-host basis. - - o Automatically executes conventional rsh (after displaying a - warning) if the server machine is not running sshd. - - o Optional compression of all data with gzip (including forwarded X11 - and TCP/IP port data), which may result in significant speedups on - slow connections. - - o Complete replacement for rlogin, rsh, and rcp. - - -WHY TO USE SECURE SHELL - -Currently, almost all communications in computer networks are done -without encryption. As a consequence, anyone who has access to any -machine connected to the network can listen in on any communication. -This is being done by hackers, curious administrators, employers, -criminals, industrial spies, and governments. Some networks leak off -enough electromagnetic radiation that data may be captured even from a -distance. - -When you log in, your password goes in the network in plain -text. Thus, any listener can then use your account to do any evil he -likes. Many incidents have been encountered worldwide where crackers -have started programs on workstations without the owners knowledge -just to listen to the network and collect passwords. Programs for -doing this are available on the Internet, or can be built by a -competent programmer in a few hours. - -Any information that you type or is printed on your screen can be -monitored, recorded, and analyzed. For example, an intruder who has -penetrated a host connected to a major network can start a program -that listens to all data flowing in the network, and whenever it -encounters a 16-digit string, it checks if it is a valid credit card -number (using the check digit), and saves the number plus any -surrounding text (to catch expiration date and holder) in a file. -When the intruder has collected a few thousand credit card numbers, he -makes smallish mail-order purchases from a few thousand stores around -the world, and disappears when the goods arrive but before anyone -suspects anything. - -Businesses have trade secrets, patent applications in preparation, -pricing information, subcontractor information, client data, personnel -data, financial information, etc. Currently, anyone with access to -the network (any machine on the network) can listen to anything that -goes in the network, without any regard to normal access restrictions. - -Many companies are not aware that information can so easily be -recovered from the network. They trust that their data is safe -since nobody is supposed to know that there is sensitive information -in the network, or because so much other data is transferred in the -network. This is not a safe policy. - -Individual persons also have confidential information, such as -diaries, love letters, health care documents, information about their -personal interests and habits, professional data, job applications, -tax reports, political documents, unpublished manuscripts, etc. - -One should also be aware that economical intelligence and industrial -espionage has recently become a major priority of the intelligence -agencies of major governments. President Clinton recently assigned -economical espionage as the primary task of the CIA, and the French -have repeatedly been publicly boasting about their achievements on -this field. - - -There is also another frightening aspect about the poor security of -communications. Computer storage and analysis capability has -increased so much that it is feasible for governments, major -companies, and criminal organizations to automatically analyze, -identify, classify, and file information about millions of people over -the years. Because most of the work can be automated, the cost of -collecting this information is getting very low. - -Government agencies may be able to monitor major communication -systems, telephones, fax, computer networks, etc., and passively -collect huge amounts of information about all people with any -significant position in the society. Most of this information is not -sensitive, and many people would say there is no harm in someone -getting that information. However, the information starts to get -sensitive when someone has enough of it. You may not mind someone -knowing what you bought from the shop one random day, but you might -not like someone knowing every small thing you have bought in the last -ten years. - -If the government some day starts to move into a more totalitarian -direction (one should remember that Nazi Germany was created by -democratic elections), there is considerable danger of an ultimate -totalitarian state. With enough information (the automatically -collected records of an individual can be manually analyzed when the -person becomes interesting), one can form a very detailed picture of -the individual's interests, opinions, beliefs, habits, friends, -lovers, weaknesses, etc. This information can be used to 1) locate -any persons who might oppose the new system 2) use deception to -disturb any organizations which might rise against the government 3) -eliminate difficult individuals without anyone understanding what -happened. Additionally, if the government can monitor communications -too effectively, it becomes too easy to locate and eliminate any -persons distributing information contrary to the official truth. - -Fighting crime and terrorism are often used as grounds for domestic -surveillance and restricting encryption. These are good goals, but -there is considerable danger that the surveillance data starts to get -used for questionable purposes. I find that it is better to tolerate -a small amount of crime in the society than to let the society become -fully controlled. I am in favor of a fairly strong state, but the -state must never get so strong that people become unable to spread -contra-offical information and unable to overturn the government if it -is bad. The danger is that when you notice that the government is -too powerful, it is too late. Also, the real power may not be where -the official government is. - -For these reasons (privacy, protecting trade secrets, and making it -more difficult to create a totalitarian state), I think that strong -cryptography should be integrated to the tools we use every day. -Using it causes no harm (except for those who wish to monitor -everything), but not using it can cause huge problems. If the society -changes in undesirable ways, then it will be to late to start -encrypting. - -Encryption has had a "military" or "classified" flavor to it. There -are no longer any grounds for this. The military can and will use its -own encryption; that is no excuse to prevent the civilians from -protecting their privacy and secrets. Information on strong -encryption is available in every major bookstore, scientific library, -and patent office around the world, and strong encryption software is -available in every country on the Internet. - -Some people would like to make it illegal to use encryption, or to -force people to use encryption that governments can break. This -approach offers no protection if the government turns bad. Also, the -"bad guys" will be using true strong encryption anyway. Good -encryption techniques are too widely known to make them disappear. -Thus, any "key escrow encryption" or other restrictions will only help -monitor ordinary people and petty criminals. It does not help against -powerful criminals, terrorists, or espionage, because they will know -how to use strong encryption anyway. (One source for internationally -available encryption software is http://www.cs.hut.fi/crypto.) - - -OVERVIEW OF SECURE SHELL - -The software consists of a number of programs. - - sshd Server program run on the server machine. This - listens for connections from client machines, and - whenever it receives a connection, it performs - authentication and starts serving the client. - - ssh This is the client program used to log into another - machine or to execute commands on the other machine. - "slogin" is another name for this program. - - scp Securely copies files from one machine to another. - - ssh-keygen Used to create RSA keys (host keys and user - authentication keys). - - ssh-agent Authentication agent. This can be used to hold RSA - keys for authentication. - - ssh-add Used to register new keys with the agent. - - make-ssh-known-hosts - Used to create the /etc/ssh_known_hosts file. - - -Ssh is the program users normally use. It is started as - - ssh host - -or - - ssh host command - -The first form opens a new shell on the remote machine (after -authentication). The latter form executes the command on the remote -machine. - -When started, the ssh connects sshd on the server machine, verifies -that the server machine really is the machine it wanted to connect, -exchanges encryption keys (in a manner which prevents an outside -listener from getting the keys), performs authentication using .rhosts -and /etc/hosts.equiv, RSA authentication, or conventional password -based authentication. The server then (normally) allocates a -pseudo-terminal and starts an interactive shell or user program. - -The TERM environment variable (describing the type of the user's -terminal) is passed from the client side to the remote side. Also, -terminal modes will be copied from the client side to the remote side -to preserve user preferences (e.g., the erase character). - -If the DISPLAY variable is set on the client side, the server will -create a dummy X server and set DISPLAY accordingly. Any connections -to the dummy X server will be forwarded through the secure channel, -and will be made to the real X server from the client side. An -arbitrary number of X programs can be started during the session, and -starting them does not require anything special from the user. (Note -that the user must not manually set DISPLAY, because then it would -connect directly to the real display instead of going through the -encrypted channel). This behavior can be disabled in the -configuration file or by giving the -x option to the client. - -Arbitrary IP ports can be forwarded over the secure channel. The -program then creates a port on one side, and whenever a connection is -opened to this port, it will be passed over the secure channel, and a -connection will be made from the other side to a specified host:port -pair. Arbitrary IP forwarding must always be explicitly requested, -and cannot be used to forward privileged ports (unless the user is -root). It is possible to specify automatic forwards in a per-user -configuration file, for example to make electronic cash systems work -securely. - -If there is an authentication agent on the client side, connection to -it will be automatically forwarded to the server side. - -For more infomation, see the manual pages ssh(1), sshd(8), scp(1), -ssh-keygen(1), ssh-agent(1), ssh-add(1), and make-ssh-known-hosts(1) -included in this distribution. - - -X11 CONNECTION FORWARDING - -X11 forwarding serves two purposes: it is a convenience to the user -because there is no need to set the DISPLAY variable, and it provides -encrypted X11 connections. I cannot think of any other easy way to -make X11 connections encrypted; modifying the X server, clients or -libraries would require special work for each machine, vendor and -application. Widely used IP-level encryption does not seem likely for -several years. Thus what we have left is faking an X server on the -same machine where the clients are run, and forwarding the connections -to a real X server over the secure channel. - -X11 forwarding works as follows. The client extracts Xauthority -information for the server. It then creates random authorization -data, and sends the random data to the server. The server allocates -an X11 display number, and stores the (fake) Xauthority data for this -display. Whenever an X11 connection is opened, the server forwards -the connection over the secure channel to the client, and the client -parses the first packet of the X11 protocol, substitutes real -authentication data for the fake data (if the fake data matched), and -forwards the connection to the real X server. - -If the display does not have Xauthority data, the server will create a -unix domain socket in /tmp/.X11-unix, and use the unix domain socket -as the display. No authentication information is forwarded in this -case. X11 connections are again forwarded over the secure channel. -To the X server the connections appear to come from the client -machine, and the server must have connections allowed from the local -machine. Using authentication data is always recommended because not -using it makes the display insecure. If XDM is used, it automatically -generates the authentication data. - -One should be careful not to use "xin" or "xstart" or other similar -scripts that explicitly set DISPLAY to start X sessions in a remote -machine, because the connection will then not go over the secure -channel. The recommended way to start a shell in a remote machine is - - xterm -e ssh host & - -and the recommended way to execute an X11 application in a remote -machine is - - ssh -n host emacs & - -If you need to type a password/passphrase for the remote machine, - - ssh -f host emacs - -may be useful. - - - -RSA AUTHENTICATION - -RSA authentication is based on public key cryptograpy. The idea is -that there are two encryption keys, one for encryption and another for -decryption. It is not possible (on human timescale) to derive the -decryption key from the encryption key. The encryption key is called -the public key, because it can be given to anyone and it is not -secret. The decryption key, on the other hand, is secret, and is -called the private key. - -RSA authentication is based on the impossibility of deriving the -private key from the public key. The public key is stored on the -server machine in the user's $HOME/.ssh/authorized_keys file. The -private key is only kept on the user's local machine, laptop, or other -secure storage. Then the user tries to log in, the client tells the -server the public key that the user wishes to use for authentication. -The server then checks if this public key is admissible. If so, it -generates a 256 bit random number, encrypts it with the public key, -and sends the value to the client. The client then decrypts the -number with its private key, computes a 128 bit MD5 checksum from the -resulting data, and sends the checksum back to the server. (Only a -checksum is sent to prevent chosen-plaintext attacks against RSA.) -The server checks computes a checksum from the correct data, -and compares the checksums. Authentication is accepted if the -checksums match. (Theoretically this indicates that the client -only probably knows the correct key, but for all practical purposes -there is no doubt.) - -The RSA private key can be protected with a passphrase. The -passphrase can be any string; it is hashed with MD5 to produce an -encryption key for IDEA, which is used to encrypt the private part of -the key file. With passphrase, authorization requires access to the key -file and the passphrase. Without passphrase, authorization only -depends on possession of the key file. - -RSA authentication is the most secure form of authentication supported -by this software. It does not rely on the network, routers, domain -name servers, or the client machine. The only thing that matters is -access to the private key. - -All this, of course, depends on the security of the RSA algorithm -itself. RSA has been widely known since about 1978, and no effective -methods for breaking it are known if it is used properly. Care has -been taken to avoid the well-known pitfalls. Breaking RSA is widely -believed to be equivalent to factoring, which is a very hard -mathematical problem that has received considerable public research. -So far, no effective methods are known for numbers bigger than about -512 bits. However, as computer speeds and factoring methods are -increasing, 512 bits can no longer be considered secure. The -factoring work is exponential, and 768 or 1024 bits are widely -considered to be secure in the near future. - - -RHOSTS AUTHENTICATION - -Conventional .rhosts and hosts.equiv based authentication mechanisms -are fundamentally insecure due to IP, DNS (domain name server) and -routing spoofing attacks. Additionally this authentication method -relies on the integrity of the client machine. These weaknesses is -tolerable, and been known and exploited for a long time. - -Ssh provides an improved version of these types of authentication, -because they are very convenient for the user (and allow easy -transition from rsh and rlogin). It permits these types of -authentication, but additionally requires that the client host be -authenticated using RSA. - -The server has a list of host keys stored in /etc/ssh_known_host, and -additionally each user has host keys in $HOME/.ssh/known_hosts. Ssh -uses the name servers to obtain the canonical name of the client host, -looks for its public key in its known host files, and requires the -client to prove that it knows the private host key. This prevents IP -and routing spoofing attacks (as long as the client machine private -host key has not been compromized), but is still vulnerable to DNS -attacks (to a limited extent), and relies on the integrity of the -client machine as to who is requesting to log in. This prevents -outsiders from attacking, but does not protect against very powerful -attackers. If maximal security is desired, only RSA authentication -should be used. - -It is possible to enable conventional .rhosts and /etc/hosts.equiv -authentication (without host authentication) at compile time by giving -the option --with-rhosts to configure. However, this is not -recommended, and is not done by default. - -These weaknesses are present in rsh and rlogin. No improvement in -security will be obtained unless rlogin and rsh are completely -disabled (commented out in /etc/inetd.conf). This is highly -recommended. - - -WEAKEST LINKS IN SECURITY - -One should understand that while this software may provide -cryptographically secure communications, it may be easy to -monitor the communications at their endpoints. - -Basically, anyone with root access on the local machine on which you -are running the software may be able to do anything. Anyone with root -access on the server machine may be able to monitor your -communications, and a very talented root user might even be able to -send his/her own requests to your authentication agent. - -One should also be aware that computers send out electromagnetic -radition that can sometimes be picked up hundreds of meters away. -Your keyboard is particularly easy to listen to. The image on your -monitor might also be seen on another monitor in a van parked behind -your house. - -Beware that unwanted visitors might come to your home or office and -use your machine while you are away. They might also make -modifications or install bugs in your hardware or software. - -Beware that the most effective way for someone to decrypt your data -may be with a rubber hose. - - -LEGAL ISSUES - -As far as I am concerned, anyone is permitted to use this software -freely. However, see the file COPYING for detailed copying, -licensing, and distribution information. - -In some countries, particularly France, Russia, Iraq, and Pakistan, -it may be illegal to use any encryption at all without a special -permit, and the rumor has it that you cannot get a permit for any -strong encryption. - -This software may be freely imported into the United States; however, -the United States Government may consider re-exporting it a criminal -offence. - -Note that any information and cryptographic algorithms used in this -software are publicly available on the Internet and at any major -bookstore, scientific library, or patent office worldwide. - -THERE IS NO WARRANTY FOR THIS PROGRAM. Please consult the file -COPYING for more information. - - -MAILING LISTS AND OTHER INFORMATION - -There is a mailing list for ossh. It is ossh@sics.se. If you would -like to join, send a message to majordomo@sics.se with "subscribe -ssh" in body. - -The WWW home page for ssh is http://www.cs.hut.fi/ssh. It contains an -archive of the mailing list, and detailed information about new -releases, mailing lists, and other relevant issues. - -Bug reports should be sent to ossh-bugs@sics.se. - - -ABOUT THE AUTHOR - -This software was written by Tatu Ylonen <ylo@cs.hut.fi>. I work as a -researcher at Helsinki University of Technology, Finland. For more -information, see http://www.cs.hut.fi/~ylo/. My PGP public key is -available via finger from ylo@cs.hut.fi and from the key servers. I -prefer PGP encrypted mail. - -The author can be contacted via ordinary mail at - Tatu Ylonen - Helsinki University of Technology - Otakaari 1 - FIN-02150 ESPOO - Finland - - Fax. +358-0-4513293 - - -ACKNOWLEDGEMENTS - -I thank Tero Kivinen, Timo Rinne, Janne Snabb, and Heikki Suonsivu for -their help and comments in the design, implementation and porting of -this software. I also thank numerous contributors, including but not -limited to Walker Aumann, Jurgen Botz, Hans-Werner Braun, Stephane -Bortzmeyer, Adrian Colley, Michael Cooper, David Dombek, Jerome -Etienne, Bill Fithen, Mark Fullmer, Bert Gijsbers, Andreas Gustafsson, -Michael Henits, Steve Johnson, Thomas Koenig, Felix Leitner, Gunnar -Lindberg, Andrew Macpherson, Marc Martinec, Paul Mauvais, Donald -McKillican, Leon Mlakar, Robert Muchsel, Mark Treacy, Bryan -O'Sullivan, Mikael Suokas, Ollivier Robert, Jakob Schlyter, Tomasz -Surmacz, Alvar Vinacua, Petri Virkkula, Michael Warfield, and -Cristophe Wolfhugel. - -Thanks also go to Philip Zimmermann, whose PGP software and the -associated legal battle provided inspiration, motivation, and many -useful techniques, and to Bruce Schneier whose book Applied -Cryptography has done a great service in widely distributing knowledge -about cryptographic methods. - - -Copyright (c) 1995 Tatu Ylonen, Espoo, Finland. diff --git a/usr/src/cmd/ssh/doc/WARNING.RNG b/usr/src/cmd/ssh/doc/WARNING.RNG deleted file mode 100644 index 21f4901c98..0000000000 --- a/usr/src/cmd/ssh/doc/WARNING.RNG +++ /dev/null @@ -1,79 +0,0 @@ -This document contains a description of portable OpenSSH's random -number collection code. An alternate reading of this text could -well be titled "Why I should pressure my system vendor to supply -/dev/random in their OS". - -Why is this important? OpenSSH depends on good, unpredictable numbers -for generating keys, performing digital signatures and forming -cryptographic challenges. If the random numbers that it uses are -predictable, then the strength of the whole system is compromised. - -A particularly pernicious problem arises with DSA keys (used by the -ssh2 protocol). Performing a DSA signature (which is required for -authentication), entails the use of a 160 bit random number. If an -attacker can predict this number, then they can deduce your *private* -key and impersonate you or your hosts. - -If you are using the builtin random number support (configure will -tell you if this is the case), then read this document in its entirety. - -Please also request that your OS vendor provides a kernel-based random -number collector (/dev/random) in future versions of your operating -systems by default. - -On to the description... - -The portable OpenSSH contains random number collection support for -systems which lack a kernel entropy pool (/dev/random). - -This collector operates by executing the programs listed in -($etcdir)/ssh_prng_cmds, reading their output and adding it to the -PRNG supplied by OpenSSL (which is hash-based). It also stirs in the -output of several system calls and timings from the execution of the -programs that it runs. - -The ssh_prng_cmds file also specifies a 'rate' for each program. This -represents the number of bits of randomness per byte of output from -the specified program. - -The random number code will also read and save a seed file to -~/.ssh/prng_seed. This contents of this file are added to the random -number generator at startup. The goal here is to maintain as much -randomness between sessions as possible. - -The entropy collection code has two main problems: - -1. It is slow. - -Executing each program in the list can take a large amount of time, -especially on slower machines. Additionally some program can take a -disproportionate time to execute. - -This can be tuned by the administrator. To debug the entropy -collection is great detail, turn on full debugging ("ssh -v -v -v" or -"sshd -d -d -d"). This will list each program as it is executed, how -long it took to execute, its exit status and whether and how much data -it generated. You can the find the culprit programs which are causing -the real slow-downs. - -The entropy collector will timeout programs which take too long -to execute, the actual timeout used can be adjusted with the ---with-entropy-timeout configure option. OpenSSH will not try to -re-execute programs which have not been found, have had a non-zero -exit status or have timed out more than a couple of times. - -2. Estimating the real 'rate' of program outputs is non-trivial - -The shear volume of the task is problematic: there are currently -around 50 commands in the ssh_prng_cmds list, portable OpenSSH -supports at least 12 different OSs. That is already 600 sets of data -to be analysed, without taking into account the numerous differences -between versions of each OS. - -On top of this, the different commands can produce varying amounts of -usable data depending on how busy the machine is, how long it has been -up and various other factors. - -To make matters even more complex, some of the commands are reporting -largely the same data as other commands (eg. the various "ps" calls). - diff --git a/usr/src/cmd/ssh/doc/nchan.ms b/usr/src/cmd/ssh/doc/nchan.ms deleted file mode 100644 index 1679d39f30..0000000000 --- a/usr/src/cmd/ssh/doc/nchan.ms +++ /dev/null @@ -1,97 +0,0 @@ -.\" -.\" 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. -.\" -.TL -OpenSSH Channel Close Protocol 1.5 Implementation -.SH -Channel Input State Diagram -.PS -reset -l=1 -s=1.2 -ellipsewid=s*ellipsewid -boxwid=s*boxwid -ellipseht=s*ellipseht -S1: ellipse "INPUT" "OPEN" -move right 2*l from last ellipse.e -S4: ellipse "INPUT" "CLOSED" -move down l from last ellipse.s -S3: ellipse "INPUT" "WAIT" "OCLOSED" -move down l from 1st ellipse.s -S2: ellipse "INPUT" "WAIT" "DRAIN" -arrow "" "rcvd OCLOSE/" "shutdown_read" "send IEOF" from S1.e to S4.w -arrow "ibuf_empty/" "send IEOF" from S2.e to S3.w -arrow from S1.s to S2.n -box invis "read_failed/" "shutdown_read" with .e at last arrow.c -arrow from S3.n to S4.s -box invis "rcvd OCLOSE/" "-" with .w at last arrow.c -ellipse wid .9*ellipsewid ht .9*ellipseht at S4 -arrow "start" "" from S1.w+(-0.5,0) to S1.w -arrow from S2.ne to S4.sw -box invis "rcvd OCLOSE/ " with .e at last arrow.c -box invis " send IEOF" with .w at last arrow.c -.PE -.SH -Channel Output State Diagram -.PS -S1: ellipse "OUTPUT" "OPEN" -move right 2*l from last ellipse.e -S3: ellipse "OUTPUT" "WAIT" "IEOF" -move down l from last ellipse.s -S4: ellipse "OUTPUT" "CLOSED" -move down l from 1st ellipse.s -S2: ellipse "OUTPUT" "WAIT" "DRAIN" -arrow "" "write_failed/" "shutdown_write" "send OCLOSE" from S1.e to S3.w -arrow "obuf_empty ||" "write_failed/" "shutdown_write" "send OCLOSE" from S2.e to S4.w -arrow from S1.s to S2.n -box invis "rcvd IEOF/" "-" with .e at last arrow.c -arrow from S3.s to S4.n -box invis "rcvd IEOF/" "-" with .w at last arrow.c -ellipse wid .9*ellipsewid ht .9*ellipseht at S4 -arrow "start" "" from S1.w+(-0.5,0) to S1.w -.PE -.SH -Notes -.PP -The input buffer is filled with data from the socket -(the socket represents the local consumer/producer of the -forwarded channel). -The data is then sent over the INPUT-end (transmit-end) of the channel to the -remote peer. -Data sent by the peer is received on the OUTPUT-end (receive-end), -saved in the output buffer and written to the socket. -.PP -If the local protocol instance has forwarded all data on the -INPUT-end of the channel, it sends an IEOF message to the peer. -If the peer receives the IEOF and has consumed all -data he replies with an OCLOSE. -When the local instance receives the OCLOSE -he considers the INPUT-half of the channel closed. -The peer has his OUTOUT-half closed. -.PP -A channel can be deallocated by a protocol instance -if both the INPUT- and the OUTOUT-half on his -side of the channel are closed. -Note that when an instance is unable to consume the -received data, he is permitted to send an OCLOSE -before the matching IEOF is received. diff --git a/usr/src/cmd/ssh/doc/nchan2.ms b/usr/src/cmd/ssh/doc/nchan2.ms deleted file mode 100644 index 1b119d1353..0000000000 --- a/usr/src/cmd/ssh/doc/nchan2.ms +++ /dev/null @@ -1,64 +0,0 @@ -.TL -OpenSSH Channel Close Protocol 2.0 Implementation -.SH -Channel Input State Diagram -.PS -reset -l=1 -s=1.2 -ellipsewid=s*ellipsewid -boxwid=s*boxwid -ellipseht=s*ellipseht -S1: ellipse "INPUT" "OPEN" -move right 2*l from last ellipse.e -S3: ellipse invis -move down l from last ellipse.s -S4: ellipse "INPUT" "CLOSED" -move down l from 1st ellipse.s -S2: ellipse "INPUT" "WAIT" "DRAIN" -arrow from S1.e to S4.n -box invis "rcvd CLOSE/" "shutdown_read" with .sw at last arrow.c -arrow "ibuf_empty ||" "rcvd CLOSE/" "send EOF" "" from S2.e to S4.w -arrow from S1.s to S2.n -box invis "read_failed/" "shutdown_read" with .e at last arrow.c -ellipse wid .9*ellipsewid ht .9*ellipseht at S4 -arrow "start" "" from S1.w+(-0.5,0) to S1.w -.PE -.SH -Channel Output State Diagram -.PS -S1: ellipse "OUTPUT" "OPEN" -move right 2*l from last ellipse.e -S3: ellipse invis -move down l from last ellipse.s -S4: ellipse "OUTPUT" "CLOSED" -move down l from 1st ellipse.s -S2: ellipse "OUTPUT" "WAIT" "DRAIN" -arrow from S1.e to S4.n -box invis "write_failed/" "shutdown_write" with .sw at last arrow.c -arrow "obuf_empty ||" "write_failed/" "shutdown_write" "" from S2.e to S4.w -arrow from S1.s to S2.n -box invis "rcvd EOF ||" "rcvd CLOSE/" "-" with .e at last arrow.c -ellipse wid .9*ellipsewid ht .9*ellipseht at S4 -arrow "start" "" from S1.w+(-0.5,0) to S1.w -.PE -.SH -Notes -.PP -The input buffer is filled with data from the socket -(the socket represents the local consumer/producer of the -forwarded channel). -The data is then sent over the INPUT-end (transmit-end) of the channel to the -remote peer. -Data sent by the peer is received on the OUTPUT-end (receive-end), -saved in the output buffer and written to the socket. -.PP -If the local protocol instance has forwarded all data on the -INPUT-end of the channel, it sends an EOF message to the peer. -.PP -A CLOSE message is sent to the peer if -both the INPUT- and the OUTOUT-half of the local -end of the channel are closed. -.PP -The channel can be deallocated by a protocol instance -if a CLOSE message he been both sent and received. diff --git a/usr/src/cmd/ssh/etc/Makefile b/usr/src/cmd/ssh/etc/Makefile deleted file mode 100644 index 305f328f34..0000000000 --- a/usr/src/cmd/ssh/etc/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MANIFEST = ssh.xml -SVCMETHOD = sshd - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -SSHASKPASS= $(ROOTLIBSSH)/ssh-askpass -ETCSSHDIR= $(ROOTETC)/ssh -DIRS= $(ETCSSHDIR) $(ROOTLIBSSH) - -FILES= sshd_config ssh_config moduli - -ETCSSHFILES= $(FILES:%=$(ETCSSHDIR)/%) - -$(ETCSSHFILES) := FILEMODE= 644 - -ROOTMANIFESTDIR = $(ROOTSVCNETWORK) - -$(ETCSSHDIR)/% : % - $(INS.file) - -$(DIRS): - $(INS.dir) - -$(ROOTLIBSSH)/%: % - $(INS.file) - -$(POFILE): - -all lint clean clobber _msg: - -install: all $(DIRS) $(ETCSSHFILES) $(ROOTMANIFEST) $(ROOTSVCMETHOD) \ - $(SSHASKPASS) - -check: $(CHKMANIFEST) - -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/etc/moduli b/usr/src/cmd/ssh/etc/moduli deleted file mode 100644 index c4a77c93a1..0000000000 --- a/usr/src/cmd/ssh/etc/moduli +++ /dev/null @@ -1,163 +0,0 @@ -#ident "%Z%%M% %I% %E% SMI" -# -# This document does not constitute an API. The /etc/ssh/moduli file -# may not exist or may have a different content or interpretation in a -# future release. The existence of this notice does not imply that any -# other documentation that lacks this notice constitutes an API. -# -# Time Type Tests Tries Size Generator Modulus -20010328182134 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449C221CB -20010328182222 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449C95A43 -20010328182256 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449CC8CFB -20010328182409 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449D9BDB7 -20010328182628 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449FB6EF3 -20010328182708 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A000153 -20010328182758 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A06E9EB -20010328182946 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A1F2C93 -20010328183015 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A206ADB -20010328183112 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A2A109B -20010328183143 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A2BC1BB -20010328183301 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A3ADCEB -20010328183532 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A5E8BAF -20010328183646 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A6D54D7 -20010328183712 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A6EC46F -20010328184223 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AB8626F -20010328184337 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AC7DC73 -20010328184634 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AEFF073 -20010328184714 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AF594FF -20010328184807 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AFEEC53 -20010328184910 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B0B3513 -20010328185030 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B165707 -20010328185334 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B3A9673 -20010328185423 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B426623 -20010328185451 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B4427DB -20010328185637 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B5E3FC7 -20010328185720 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B65964B -20010328185757 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B6A9373 -20010328185844 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B7203B3 -20010328185933 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B7A9FFF -20010328190006 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B7DAAD3 -20010328190054 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B855C2F -20010328190139 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B8C53EB -20010328190304 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B9F26C3 -20010328190329 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BA00697 -20010328190412 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BA54313 -20010328190506 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BAEEF27 -20010328190550 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BB5CE0B -20010328200734 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC33395187 -20010328201124 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC334ED15B -20010328201358 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3359FC07 -20010328201537 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC335F7A83 -20010328201829 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC336D1433 -20010328202120 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC337B253B -20010328202848 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC33A3D43F -20010328203335 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC33BF24A3 -20010328204332 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC34011B8B -20010328204443 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3402A92F -20010328204617 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3406D343 -20010328205458 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3436FA2B -20010328210413 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3471CF1B -20010328213513 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC352AF5EF -20010328215014 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC358CC3CB -20010328215520 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35A9B7FF -20010328215733 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35B2927F -20010328220114 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35C47323 -20010328220334 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35CFA9C3 -20010328220653 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35E0BB37 -20010328220915 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35E9CC23 -20010328221256 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35FD7D67 -20010328221457 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC36052CCB -20010328222639 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC364A1E07 -20010328224126 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC36AD5557 -20010328225125 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC36EE57BF -20010328225751 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3716A70B -20010328225943 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC371D010B -20010328230054 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC371EB5C7 -20010328230301 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC37275F4B -20010328230628 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3738C3F3 -20010329000424 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853ACAACAB -20010329001637 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853AE5BE0F -20010329002229 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853AEDE2D3 -20010329003652 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853B0F32CB -20010329005040 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853B30E503 -20010329014643 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853BC9AF57 -20010329021950 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853C205263 -20010329023256 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853C3F2E53 -20010329031049 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853CA28BBF -20010329032045 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853CB81103 -20010329052113 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853DF13B47 -20010329052449 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853DF3ED53 -20010329060404 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853E5D25E7 -20010329062856 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853E9CF013 -20010329063152 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853E9E1CEB -20010329070601 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853EF58B7F -20010329071302 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F017697 -20010329072011 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F0E72D3 -20010329072445 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F14CE17 -20010329073641 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F2EEBA3 -20010329075209 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F52E927 -20010329080750 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F776F8B -20010329084002 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853FC98043 -20010329084744 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853FD7EAAF -20010329090209 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853FF9AF5F -20010329093527 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385404E330B -20010329094652 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938540672D1F -20010329103445 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938540E4B213 -20010329111418 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993854144947F -20010329112031 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385414F223B -20010329112413 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938541522073 -20010329114209 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385417C8E53 -20010329125026 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385422E41AB -20010329132045 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385427DD3FF -20010329134105 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938542AFA2D7 -20010329134914 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938542C04A37 -20010403222140 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0AB16DAF -20010403225231 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0AC56CFF -20010404053436 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0C2F4B7F -20010404092851 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D04E7F7 -20010404093943 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D07794B -20010404102659 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D2BE8CF -20010404112553 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D5D012B -20010404174625 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0EA59E17 -20010404184645 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0ED6DA4F -20010404193402 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0EFB39B3 -20010404230716 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0FB07C1B -20010405044433 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B10DD9FC3 -20010405053429 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B11038737 -20010405062826 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B112E24E7 -20010405092601 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B11C9E9FB -20010405113007 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B123803EB -20010405122212 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B12612ED3 -20010405182035 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B13A25087 -20010405210758 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B142C4E23 -20010405220222 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B145878F3 -20010406020130 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B152AF6AB -20010406053538 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B15E78C8B -20010406073014 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1649BFEF -20010406074100 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B164D4E3F -20010406103625 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B16E07B33 -20010406131946 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B17706243 -20010406170234 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B182FD957 -20010406182949 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B18768903 -20010406203157 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B18DCFC3B -20010407022825 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1A1AF797 -20010407071024 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1B1551E7 -20010407112402 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1BF78EC7 -20010407123215 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1C30021B -20010407161504 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1CF27743 -20010407171629 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1D25FAD7 -20010407191502 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1D8C2753 -20010420002705 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10C1E08F3 -20010420005243 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10C219FB3 -20010420035225 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10C660B3F -20010420145749 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10D741313 -20010420205718 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10DD41193 -20010420232458 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10E0AB4EF -20010421003952 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10E22F857 -20010421013245 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10E31828B -20010421085157 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10EE28B2B -20010421092617 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10EE97A3B -20010421135621 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10F52C463 -20010422012438 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C110627AF3 -20010422042530 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C110A793B3 -20010422163438 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C111D2A227 diff --git a/usr/src/cmd/ssh/etc/ssh-askpass b/usr/src/cmd/ssh/etc/ssh-askpass deleted file mode 100644 index f2735a9103..0000000000 --- a/usr/src/cmd/ssh/etc/ssh-askpass +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/ksh -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -prompt=$(echo $1 | sed s/_/__/g) -ICON=/usr/share/pixmaps/blueprint-keyring.png -exec /usr/bin/zenity --entry --title "ssh-askpass" \ - --text="$prompt" --hide-text --window-icon=$ICON diff --git a/usr/src/cmd/ssh/etc/ssh.xml b/usr/src/cmd/ssh/etc/ssh.xml deleted file mode 100644 index 3a08195ff1..0000000000 --- a/usr/src/cmd/ssh/etc/ssh.xml +++ /dev/null @@ -1,169 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- - CDDL HEADER START - - The contents of this file are subject to the terms of the - Common Development and Distribution License (the "License"). - You may not use this file except in compliance with the License. - - You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - or http://www.opensolaris.org/os/licensing. - See the License for the specific language governing permissions - and limitations under the License. - - When distributing Covered Code, include this CDDL HEADER in each - file and include the License file at usr/src/OPENSOLARIS.LICENSE. - If applicable, add the following below this CDDL HEADER, with the - fields enclosed by brackets "[]" replaced with your own identifying - information: Portions Copyright [yyyy] [name of copyright owner] - - CDDL HEADER END - - Copyright 2009 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - NOTE: This service manifest is not editable; its contents will - be overwritten by package or patch operations, including - operating system upgrade. Make customizations in a different - file. ---> - -<service_bundle type='manifest' name='SUNWsshdr:ssh'> - -<service - name='network/ssh' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency name='fs-local' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri - value='svc:/system/filesystem/local' /> - </dependency> - - <dependency name='fs-autofs' - grouping='optional_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/filesystem/autofs' /> - </dependency> - - <dependency name='net-loopback' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/network/loopback' /> - </dependency> - - <dependency name='net-physical' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/network/physical' /> - </dependency> - - <dependency name='cryptosvc' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/cryptosvc' /> - </dependency> - - <dependency name='utmp' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/utmp' /> - </dependency> - - <dependency name='network_ipfilter' - grouping='optional_all' - restart_on='error' - type='service'> - <service_fmri value='svc:/network/ipfilter:default' /> - </dependency> - - <dependency name='config_data' - grouping='require_all' - restart_on='restart' - type='path'> - <service_fmri - value='file://localhost/etc/ssh/sshd_config' /> - </dependency> - - <dependent - name='ssh_multi-user-server' - grouping='optional_all' - restart_on='none'> - <service_fmri - value='svc:/milestone/multi-user-server' /> - </dependent> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/sshd start' - timeout_seconds='60'/> - - <exec_method - type='method' - name='stop' - exec=':kill' - timeout_seconds='60' /> - - <exec_method - type='method' - name='refresh' - exec='/lib/svc/method/sshd restart' - timeout_seconds='60' /> - - <property_group name='startd' - type='framework'> - <!-- sub-process core dumps shouldn't restart session --> - <propval name='ignore_error' - type='astring' value='core,signal' /> - </property_group> - - <property_group name='general' type='framework'> - <!-- to start stop sshd --> - <propval name='action_authorization' type='astring' - value='solaris.smf.manage.ssh' /> - </property_group> - - <property_group name='firewall_context' type='com.sun,fw_definition'> - <propval name='name' type='astring' value='ssh' /> - <propval name='ipf_method' type='astring' - value='/lib/svc/method/sshd ipfilter' /> - </property_group> - - <property_group name='firewall_config' type='com.sun,fw_configuration'> - <propval name='policy' type='astring' value='use_global' /> - <propval name='apply_to' type='astring' value='' /> - <propval name='exceptions' type='astring' value='' /> - <propval name='value_authorization' type='astring' - value='solaris.smf.value.firewall.config' /> - </property_group> - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - SSH server - </loctext> - </common_name> - <documentation> - <manpage title='sshd' section='1M' manpath='/usr/share/man' /> - </documentation> - </template> - -</service> - -</service_bundle> diff --git a/usr/src/cmd/ssh/etc/ssh_config b/usr/src/cmd/ssh/etc/ssh_config deleted file mode 100644 index cdb9d97d45..0000000000 --- a/usr/src/cmd/ssh/etc/ssh_config +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -# ident "%Z%%M% %I% %E% SMI" -# -# This file provides defaults for ssh(1). -# The values can be changed in per-user configuration files $HOME/.ssh/config -# or on the command line of ssh(1). - -# Configuration data is parsed as follows: -# 1. command line options -# 2. user-specific file -# 3. system-wide file /etc/ssh/ssh_config -# -# Any configuration value is only changed the first time it is set. -# host-specific definitions should be at the beginning of the -# configuration file, and defaults at the end. - -# Example (matches compiled in defaults): -# -# Host * -# ForwardAgent no -# ForwardX11 no -# PubkeyAuthentication yes -# PasswordAuthentication yes -# FallBackToRsh no -# UseRsh no -# BatchMode no -# CheckHostIP yes -# StrictHostKeyChecking ask -# EscapeChar ~ diff --git a/usr/src/cmd/ssh/etc/sshd b/usr/src/cmd/ssh/etc/sshd deleted file mode 100644 index 043ce20f7e..0000000000 --- a/usr/src/cmd/ssh/etc/sshd +++ /dev/null @@ -1,116 +0,0 @@ -#!/sbin/sh -# -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -. /lib/svc/share/ipf_include.sh -. /lib/svc/share/smf_include.sh - -SSHDIR=/etc/ssh -KEYGEN="/usr/bin/ssh-keygen -q" -PIDFILE=/var/run/sshd.pid - -# Checks to see if RSA, and DSA host keys are available -# if any of these keys are not present, the respective keys are created. -create_key() -{ - keypath=$1 - keytype=$2 - - if [ ! -f $keypath ]; then - # - # HostKey keywords in sshd_config may be preceded or - # followed by a mix of any number of space or tabs, - # and optionally have an = between keyword and - # argument. We use two grep invocations such that we - # can match HostKey case insensitively but still have - # the case of the path name be significant, keeping - # the pattern somewhat more readable. - # - # The character classes below contain one literal - # space and one literal tab. - # - grep -i "^[ ]*HostKey[ ]*=\{0,1\}[ ]*$keypath" \ - $SSHDIR/sshd_config | grep "$keypath" > /dev/null 2>&1 - - if [ $? -eq 0 ]; then - echo Creating new $keytype public/private host key pair - $KEYGEN -f $keypath -t $keytype -N '' - if [ $? -ne 0 ]; then - echo "Could not create $keytype key: $keypath" - exit $SMF_EXIT_ERR_CONFIG - fi - fi - fi -} - -create_ipf_rules() -{ - FMRI=$1 - ipf_file=`fmri_to_file ${FMRI} $IPF_SUFFIX` - policy=`get_policy ${FMRI}` - - # - # Get port from /etc/ssh/sshd_config - # - tports=`grep "^Port" /etc/ssh/sshd_config 2>/dev/null | \ - awk '{print $2}'` - - echo "# $FMRI" >$ipf_file - for port in $tports; do - generate_rules $FMRI $policy "tcp" "any" $port $ipf_file - done -} - -# This script is being used for two purposes: as part of an SMF -# start/stop/refresh method, and as a sysidconfig(1M)/sys-unconfig(1M) -# application. -# -# Both, the SMF methods and sysidconfig/sys-unconfig use different -# arguments.. - -case $1 in - # sysidconfig/sys-unconfig arguments (-c and -u) -'-c') - create_key $SSHDIR/ssh_host_rsa_key rsa - create_key $SSHDIR/ssh_host_dsa_key dsa - ;; - -'-u') - # sys-unconfig(1M) knows how to remove ssh host keys, so there's - # nothing to do here. - : - ;; - - # SMF arguments (start and restart [really "refresh"]) - -'ipfilter') - create_ipf_rules $2 - ;; - -'start') - # - # If host keys don't exist when the service is started, create - # them; sysidconfig is not run in every situation (such as on - # the install media). - # - create_key $SSHDIR/ssh_host_rsa_key rsa - create_key $SSHDIR/ssh_host_dsa_key dsa - - /usr/lib/ssh/sshd - ;; - -'restart') - if [ -f "$PIDFILE" ]; then - /usr/bin/kill -HUP `/usr/bin/cat $PIDFILE` - fi - ;; - -*) - echo "Usage: $0 { start | restart }" - exit 1 - ;; -esac - -exit $? diff --git a/usr/src/cmd/ssh/etc/sshd_config b/usr/src/cmd/ssh/etc/sshd_config deleted file mode 100644 index fd4aa5df46..0000000000 --- a/usr/src/cmd/ssh/etc/sshd_config +++ /dev/null @@ -1,145 +0,0 @@ -# -# Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. -# -# Configuration file for sshd(1m) (see also sshd_config(4)) -# - -# Protocol versions supported -# -# The sshd shipped in this release of Solaris has support for major versions -# 1 and 2. It is recommended due to security weaknesses in the v1 protocol -# that sites run only v2 if possible. Support for v1 is provided to help sites -# with existing ssh v1 clients/servers to transition. -# Support for v1 may not be available in a future release of Solaris. -# -# To enable support for v1 an RSA1 key must be created with ssh-keygen(1). -# RSA and DSA keys for protocol v2 are created by /etc/init.d/sshd if they -# do not already exist, RSA1 keys for protocol v1 are not automatically created. - -# Uncomment ONLY ONE of the following Protocol statements. - -# Only v2 (recommended) -Protocol 2 - -# Both v1 and v2 (not recommended) -#Protocol 2,1 - -# Only v1 (not recommended) -#Protocol 1 - -# Listen port (the IANA registered port number for ssh is 22) -Port 22 - -# The default listen address is all interfaces, this may need to be changed -# if you wish to restrict the interfaces sshd listens on for a multi homed host. -# Multiple ListenAddress entries are allowed. - -# IPv4 only -#ListenAddress 0.0.0.0 -# IPv4 & IPv6 -ListenAddress :: - -# If port forwarding is enabled (default), specify if the server can bind to -# INADDR_ANY. -# This allows the local port forwarding to work when connections are received -# from any remote host. -GatewayPorts no - -# X11 tunneling options -X11Forwarding yes -X11DisplayOffset 10 -X11UseLocalhost yes - -# The maximum number of concurrent unauthenticated connections to sshd. -# start:rate:full see sshd(1) for more information. -# The default is 10 unauthenticated clients. -#MaxStartups 10:30:60 - -# Banner to be printed before authentication starts. -#Banner /etc/issue - -# Should sshd print the /etc/motd file and check for mail. -# On Solaris it is assumed that the login shell will do these (eg /etc/profile). -PrintMotd no - -# KeepAlive specifies whether keep alive messages are sent to the client. -# See sshd(1) for detailed description of what this means. -# Note that the client may also be sending keep alive messages to the server. -KeepAlive yes - -# Syslog facility and level -SyslogFacility auth -LogLevel info - -# -# Authentication configuration -# - -# Host private key files -# Must be on a local disk and readable only by the root user (root:sys 600). -HostKey /etc/ssh/ssh_host_rsa_key -HostKey /etc/ssh/ssh_host_dsa_key - -# Length of the server key -# Default 768, Minimum 512 -ServerKeyBits 768 - -# sshd regenerates the key every KeyRegenerationInterval seconds. -# The key is never stored anywhere except the memory of sshd. -# The default is 1 hour (3600 seconds). -KeyRegenerationInterval 3600 - -# Ensure secure permissions on users .ssh directory. -StrictModes yes - -# Length of time in seconds before a client that hasn't completed -# authentication is disconnected. -# Default is 600 seconds. 0 means no time limit. -LoginGraceTime 600 - -# Maximum number of retries for authentication -# Default is 6. Default (if unset) for MaxAuthTriesLog is MaxAuthTries / 2 -MaxAuthTries 6 -MaxAuthTriesLog 3 - -# Are logins to accounts with empty passwords allowed. -# If PermitEmptyPasswords is no, pass PAM_DISALLOW_NULL_AUTHTOK -# to pam_authenticate(3PAM). -PermitEmptyPasswords no - -# To disable tunneled clear text passwords, change PasswordAuthentication to no. -PasswordAuthentication yes - -# Are root logins permitted using sshd. -# Note that sshd uses pam_authenticate(3PAM) so the root (or any other) user -# maybe denied access by a PAM module regardless of this setting. -# Valid options are yes, without-password, no. -PermitRootLogin no - -# sftp subsystem -Subsystem sftp internal-sftp - - -# SSH protocol v1 specific options -# -# The following options only apply to the v1 protocol and provide -# some form of backwards compatibility with the very weak security -# of /usr/bin/rsh. Their use is not recommended and the functionality -# will be removed when support for v1 protocol is removed. - -# Should sshd use .rhosts and .shosts for password less authentication. -IgnoreRhosts yes -RhostsAuthentication no - -# Rhosts RSA Authentication -# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts. -# If the user on the client side is not root then this won't work on -# Solaris since /usr/bin/ssh is not installed setuid. -RhostsRSAAuthentication no - -# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication. -#IgnoreUserKnownHosts yes - -# Is pure RSA authentication allowed. -# Default is yes -RSAAuthentication yes diff --git a/usr/src/cmd/ssh/include/altprivsep.h b/usr/src/cmd/ssh/include/altprivsep.h deleted file mode 100644 index fb230d28a7..0000000000 --- a/usr/src/cmd/ssh/include/altprivsep.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _ALTPRIVSEP_H -#define _ALTPRIVSEP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include "auth.h" -#include "kex.h" - -#define APS_MSG_NEWKEYS_REQ 0 -#define APS_MSG_NEWKEYS_REP 1 -#define APS_MSG_RECORD_LOGIN 2 -#define APS_MSG_RECORD_LOGOUT 3 -#define APS_MSG_START_REKEX 4 -#define APS_MSG_AUTH_CONTEXT 5 - -void altprivsep_start_and_do_monitor(int use_engine, int inetd, int newsock, - int statup_pipe); -int altprivsep_get_pipe_fd(void); - -/* child-side handler of re-key packets */ -void altprivsep_rekey(int type, u_int32_t seq, void *ctxt); - -/* Calls _to_ monitor from unprivileged process */ -void altprivsep_process_input(fd_set *rset); -void altprivsep_record_login(pid_t pid, const char *ttyname); -void altprivsep_record_logout(pid_t pid); -void altprivsep_start_rekex(void); -void altprivsep_send_auth_context(Authctxt *authctxt); - -/* Functions for use in the monitor */ -void aps_input_altpriv_msg(int type, u_int32_t seq, void *ctxt); - -#ifdef __cplusplus -} -#endif - -#endif /* _ALTPRIVSEP_H */ diff --git a/usr/src/cmd/ssh/include/atomicio.h b/usr/src/cmd/ssh/include/atomicio.h deleted file mode 100644 index e1ba7b21e6..0000000000 --- a/usr/src/cmd/ssh/include/atomicio.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2006 Damien Miller. All rights reserved. - * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. - * 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 _ATOMICIO_H -#define _ATOMICIO_H - -/* $OpenBSD: atomicio.h,v 1.4 2001/06/26 06:32:46 itojun Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Ensure all of data on socket comes through. f==read || f==write - */ -ssize_t atomicio(ssize_t (*)(), int, void *, size_t); - -#define vwrite (ssize_t (*)(int, void *, size_t))write - -/* - * ensure all of data on socket comes through. f==readv || f==writev - */ -size_t atomiciov(ssize_t (*)(int, const struct iovec *, int), - int, const struct iovec *, int); - -#ifdef __cplusplus -} -#endif - -#endif /* _ATOMICIO_H */ diff --git a/usr/src/cmd/ssh/include/auth-options.h b/usr/src/cmd/ssh/include/auth-options.h deleted file mode 100644 index 31d7fd6ce1..0000000000 --- a/usr/src/cmd/ssh/include/auth-options.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $OpenBSD: auth-options.h,v 1.12 2002/07/21 18:34:43 stevesk Exp $ */ - -#ifndef _AUTH_OPTIONS_H -#define _AUTH_OPTIONS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -/* Linked list of custom environment strings */ -struct envstring { - struct envstring *next; - char *s; -}; - -/* 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; - -int auth_parse_options(struct passwd *, char *, char *, u_long); -void auth_clear_options(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _AUTH_OPTIONS_H */ diff --git a/usr/src/cmd/ssh/include/auth-pam.h b/usr/src/cmd/ssh/include/auth-pam.h deleted file mode 100644 index 3c3dd409fd..0000000000 --- a/usr/src/cmd/ssh/include/auth-pam.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2000 Damien Miller. 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) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* $Id: auth-pam.h,v 1.16 2002/07/23 00:44:07 stevesk Exp $ */ - -#ifndef _AUTH_PAM_H -#define _AUTH_PAM_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "includes.h" -#ifdef USE_PAM - -char * derive_pam_svc_name(Authmethod *method); -void new_start_pam(Authctxt *authctxt, struct pam_conv *conv); -int auth_pam_password(Authctxt *authctxt, const char *password); -int do_pam_non_initial_userauth(Authctxt *authctxt); -int finish_userauth_do_pam(Authctxt *authctxt); -void finish_pam(Authctxt *authctxt); -char **fetch_pam_environment(Authctxt *authctxt); -void free_pam_environment(char **env); -void message_cat(char **p, const char *a); -void print_pam_messages(void); - -#define AUTHPAM_DONE(ac) (ac != NULL && \ - ac->pam != NULL && \ - ac->pam->h != NULL && \ - ac->pam->state == PAM_S_DONE) - -#define AUTHPAM_RETVAL(ac, rv) ((ac != NULL && ac->pam != NULL) ? \ - ac->pam->last_pam_retval : rv) - -#define AUTHPAM_ERROR(ac, rv) ((ac != NULL && ac->pam != NULL && \ - ac->pam->last_pam_retval != PAM_SUCCESS) ? \ - ac->pam->last_pam_retval : rv) - -#endif /* USE_PAM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _AUTH_PAM_H */ diff --git a/usr/src/cmd/ssh/include/auth.h b/usr/src/cmd/ssh/include/auth.h deleted file mode 100644 index c932fafa6d..0000000000 --- a/usr/src/cmd/ssh/include/auth.h +++ /dev/null @@ -1,325 +0,0 @@ -/* $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $ */ - -#ifndef _AUTH_H -#define _AUTH_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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. - * - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "key.h" -#include "hostfile.h" -#include <openssl/rsa.h> - -#ifdef USE_PAM -#include <security/pam_appl.h> -#endif /* USE_PAM */ - -#ifdef HAVE_LOGIN_CAP -#include <login_cap.h> -#endif -#ifdef BSD_AUTH -#include <bsd_auth.h> -#endif -#ifdef KRB5 -#include <krb5.h> -#endif - -typedef struct Authctxt Authctxt; -typedef struct Authmethod Authmethod; -typedef struct KbdintDevice KbdintDevice; - -#ifdef USE_PAM -typedef struct pam_stuff pam_stuff; - -struct pam_stuff { - Authctxt *authctxt; - pam_handle_t *h; - int state; - int last_pam_retval; -}; - -/* See auth-pam.h and auth-pam.c */ - -#define PAM_S_DONE_ACCT_MGMT 0x01 /* acct_mgmt done */ -#define PAM_S_DONE_SETCRED 0x02 /* setcred done */ -#define PAM_S_DONE_OPEN_SESSION 0x04 /* open_session done */ -#define PAM_S_DONE 0x07 /* all done */ -#endif /* USE_PAM */ - -struct Authctxt { - int success; - int valid; - int attempt; /* all userauth attempt count */ - int init_attempt; /* passwd/kbd-int attempt count */ - int failures; - int init_failures; - int unwind_dispatch_loop; - int v1_auth_type; - char *v1_auth_name; - Authmethod *method; - char *user; - char *service; - struct passwd *pw; - char *style; - void *kbdintctxt; /* XXX Switch to method_data; - v1 still needs this*/ -#ifdef USE_PAM - pam_stuff *pam; - char *cuser; /* client side user, needed for setting - PAM_AUSER for hostbased authentication - using roles */ - u_long last_login_time; /* need to get the time of - last login before calling - pam_open_session() */ - char last_login_host[MAXHOSTNAMELEN]; - int pam_retval; /* pam_stuff is cleaned before - BSM login failure auditing */ -#endif /* USE_PAM */ - - /* SUNW - What follows remains to reduce diffs with OpenSSH but - * is not used in Solaris. The Solaris SSH internal - * architecture requires that this stuff move into the - * Authmethod method_data. - */ -#ifndef SUNW_SSH -#ifdef BSD_AUTH - auth_session_t *as; -#endif -#ifdef KRB4 - char *krb4_ticket_file; -#endif -#ifdef KRB5 - krb5_context krb5_ctx; - krb5_auth_context krb5_auth_ctx; - krb5_ccache krb5_fwd_ccache; - krb5_principal krb5_user; - char *krb5_ticket_file; -#endif - void *methoddata; -#endif /* SUNW_SSH */ -}; - -struct Authmethod { - char *name; - int *enabled; - /* - * Userauth method state tracking fields updated in - * input_userauth_request() and auth-pam.c. - * - * The "void (*userauth)(Authctxt *authctxt)" function - * communicates the userauth result (success, failure, - * "postponed," abandoned) through the 'authenticated', - * 'postponed' and 'abandoned' fields. Partial success is - * indicated by requiring other userauths to be used by setting - * their 'required' or 'sufficient' fields. - * - * Individual methods should only ever set 'not_again' if it - * makes no sense to complete the same userauth more than once, - * and they should set any methods' sufficient or required flags - * in order to force partial authentication and require that - * more userauths be tried. The (void *) 'method_data' and - * 'hist_method_data' pointers can be used by methods such as - * pubkey which may make sense to run more than once during - * userauth or which may require multiple round tripes (e.g., - * keyboard-interactive) and which need to keep some state; - * 'hist_method_data' is there specifically for pubkey userauth - * where multiple successful attempts should all use different - * keys. - * - * The "attempts," "abandons," "successes" and "failures" fields - * count the number of times a method has been attempted, - * abandoned, and has succeeded or failed. Note that pubkey - * userauth does not double-count sig-less probes that are - * followed by a pubkey request for the same pubkey anw with a - * signature. - */ - void (*userauth)(Authctxt *authctxt); - void (*abandon)(Authctxt *, Authmethod *); - void *method_data; - void *hist_method_data; - unsigned int is_initial; - unsigned int attempts:8; - unsigned int abandons:8; - unsigned int successes:8; - unsigned int failures:8; - /* - * Post-attempt state booleans (authenticated, abandoned, etc...) - */ - unsigned int authenticated:1; - unsigned int not_again:1; - unsigned int sufficient:1; - unsigned int required:1; - unsigned int postponed:1; - unsigned int abandoned:1; - /* - * NOTE: multi-round-trip userauth methods can either - * recursively call dispatch_run and detect abandonment - * within their message handlers (as PAM kbd-int does) or - * set the postponed flag and let input_userauth_request() - * detect abandonment (i.e., initiation of some userauth - * method before completion of a started, multi-round-trip - * userauth method). - * - */ -}; - -/* - * Keyboard interactive device: - * init_ctx returns: non NULL upon success - * query returns: 0 - success, otherwise failure - * respond returns: 0 - success, 1 - need further interaction, - * otherwise - failure - */ -struct KbdintDevice -{ - const char *name; - void* (*init_ctx)(Authctxt*); - int (*query)(void *ctx, char **name, char **infotxt, - u_int *numprompts, char ***prompts, u_int **echo_on); - int (*respond)(void *ctx, u_int numresp, char **responses); - void (*free_ctx)(void *ctx); -}; - -int auth_rhosts(struct passwd *, const char *); -int -auth_rhosts2(struct passwd *, const char *, const char *, const char *); - -int auth_rhosts_rsa(struct passwd *, char *, Key *); -int auth_password(Authctxt *, const char *); -int auth_rsa(struct passwd *, BIGNUM *); -int auth_rsa_challenge_dialog(Key *); -BIGNUM *auth_rsa_generate_challenge(Key *); -int auth_rsa_verify_response(Key *, BIGNUM *, u_char[]); -int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); - -int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); -int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); -int user_key_allowed(struct passwd *, Key *); - -#ifdef KRB4 -#include <krb.h> -int auth_krb4(Authctxt *, KTEXT, char **, KTEXT); -int auth_krb4_password(Authctxt *, const char *); -void krb4_cleanup_proc(void *); - -#ifdef AFS -#include <kafs.h> -int auth_krb4_tgt(Authctxt *, const char *); -int auth_afs_token(Authctxt *, const char *); -#endif /* AFS */ - -#endif /* KRB4 */ - -#ifdef KRB5 -int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); -int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); -int auth_krb5_password(Authctxt *authctxt, const char *password); -void krb5_cleanup_proc(void *authctxt); -#endif /* KRB5 */ - -#include "auth-pam.h" -#include "auth2-pam.h" - -Authctxt *do_authentication(void); -Authctxt *do_authentication2(void); - -#ifdef HAVE_BSM -void audit_failed_login_cleanup(void *); -#endif /* HAVE_BSM */ - -int userauth_check_partial_failure(Authctxt *authctxt); -void userauth_force_kbdint(void); - -Authctxt *authctxt_new(void); -void auth_log(Authctxt *, int, char *, char *); -void userauth_finish(Authctxt *, char *); -void userauth_user_svc_change(Authctxt *authctxt, - char *user, - char *service); -int auth_root_allowed(char *); - -char *auth2_read_banner(void); - -void privsep_challenge_enable(void); - -void auth2_challenge(Authctxt *, char *); -void auth2_challenge_abandon(Authctxt *); -int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); -int bsdauth_respond(void *, u_int, char **); -int skey_query(void *, char **, char **, u_int *, char ***, u_int **); -int skey_respond(void *, u_int, char **); - -struct passwd * getpwnamallow(const char *user); - -int run_auth_hook(const char *, const char *, const char *); - -char *get_challenge(Authctxt *); -int verify_response(Authctxt *, const char *); - -struct passwd * auth_get_user(void); - -char *authorized_keys_file(struct passwd *); -char *authorized_keys_file2(struct passwd *); - -int -secure_filename(FILE *, const char *, struct passwd *, char *, size_t); - -HostStatus -check_key_in_hostfiles(struct passwd *, Key *, const char *, - const char *, const char *); - -/* hostkey handling */ -#ifndef lint -Key *get_hostkey_by_index(int); -Key *get_hostkey_by_type(int); -int get_hostkey_index(Key *); -#endif /* lint */ -int ssh1_session_key(BIGNUM *); - -/* debug messages during authentication */ -void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); -void auth_debug_send(void); -void auth_debug_reset(void); - -#define AUTH_FAIL_MAX 6 -#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) -#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" - -#define SKEY_PROMPT "\nS/Key Password: " - -#ifdef __cplusplus -} -#endif - -#endif /* _AUTH_H */ diff --git a/usr/src/cmd/ssh/include/auth2-pam.h b/usr/src/cmd/ssh/include/auth2-pam.h deleted file mode 100644 index dae25c0819..0000000000 --- a/usr/src/cmd/ssh/include/auth2-pam.h +++ /dev/null @@ -1,38 +0,0 @@ -/* $Id: auth2-pam.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _AUTH2_PAM_H -#define _AUTH2_PAM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "includes.h" -#ifdef USE_PAM - -typedef struct Convctxt Convctxt; - -struct Convctxt { - int abandoned, finished, num_received, num_expected; - int *prompts; - struct pam_response *responses; -}; - -int kbdint_pam_abandon_chk(Authctxt *authctxt, Authmethod *method); -void kbdint_pam_abandon(Authctxt *authctxt, Authmethod *method); - -void auth2_pam(Authctxt *authctxt); - -#endif /* USE_PAM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _AUTH2_PAM_H */ diff --git a/usr/src/cmd/ssh/include/authfd.h b/usr/src/cmd/ssh/include/authfd.h deleted file mode 100644 index 81b27cc0e6..0000000000 --- a/usr/src/cmd/ssh/include/authfd.h +++ /dev/null @@ -1,103 +0,0 @@ -/* $OpenBSD: authfd.h,v 1.31 2002/09/11 18:27:25 stevesk Exp $ */ - -#ifndef _AUTHFD_H -#define _AUTHFD_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -#include "buffer.h" - -/* Messages for the authentication agent connection. */ -#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 -#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 -#define SSH_AGENTC_RSA_CHALLENGE 3 -#define SSH_AGENT_RSA_RESPONSE 4 -#define SSH_AGENT_FAILURE 5 -#define SSH_AGENT_SUCCESS 6 -#define SSH_AGENTC_ADD_RSA_IDENTITY 7 -#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 -#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 - -/* private OpenSSH extensions for SSH2 */ -#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 - -/* smartcard */ -#define SSH_AGENTC_ADD_SMARTCARD_KEY 20 -#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 - -/* lock/unlock the agent */ -#define SSH_AGENTC_LOCK 22 -#define SSH_AGENTC_UNLOCK 23 - -/* add key with constraints */ -#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 -#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 - -#define SSH_AGENT_CONSTRAIN_LIFETIME 1 -#define SSH_AGENT_CONSTRAIN_CONFIRM 2 - -/* extended failure messages */ -#define SSH2_AGENT_FAILURE 30 - -/* additional error code for ssh.com's ssh-agent2 */ -#define SSH_COM_AGENT2_FAILURE 102 - -#define SSH_AGENT_OLD_SIGNATURE 0x01 - -typedef struct { - int fd; - Buffer identities; - int howmany; -} AuthenticationConnection; - -int ssh_agent_present(void); -int ssh_get_authentication_socket(void); -void ssh_close_authentication_socket(int); - -AuthenticationConnection *ssh_get_authentication_connection(void); -void ssh_close_authentication_connection(AuthenticationConnection *); -int ssh_get_num_identities(AuthenticationConnection *, int); -Key *ssh_get_first_identity(AuthenticationConnection *, char **, int); -Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); -int ssh_add_identity(AuthenticationConnection *, Key *, const char *); -int ssh_add_identity_constrained(AuthenticationConnection *, Key *, const char *, u_int); -int ssh_remove_identity(AuthenticationConnection *, Key *); -int ssh_remove_all_identities(AuthenticationConnection *, int); -int ssh_lock_agent(AuthenticationConnection *, int, const char *); -int ssh_update_card(AuthenticationConnection *, int, const char *, const char *); - -int -ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16], - u_int, u_char[16]); - -int -ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *, - u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _AUTHFD_H */ diff --git a/usr/src/cmd/ssh/include/authfile.h b/usr/src/cmd/ssh/include/authfile.h deleted file mode 100644 index 68031d32cb..0000000000 --- a/usr/src/cmd/ssh/include/authfile.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $OpenBSD: authfile.h,v 1.10 2002/05/23 19:24:30 markus Exp $ */ - -#ifndef _AUTHFILE_H -#define _AUTHFILE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -int key_save_private(Key *, const char *, const char *, const char *); -Key *key_load_public(const char *, char **); -Key *key_load_public_type(int, const char *, char **); -Key *key_load_private(const char *, const char *, char **); -Key *key_load_private_type(int, const char *, const char *, char **); -Key *key_load_private_pem(int, int, const char *, char **); - -#ifdef __cplusplus -} -#endif - -#endif /* _AUTHFILE_H */ diff --git a/usr/src/cmd/ssh/include/base64.h b/usr/src/cmd/ssh/include/base64.h deleted file mode 100644 index 7e2ccf7d3e..0000000000 --- a/usr/src/cmd/ssh/include/base64.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _BASE64_H -#define _BASE64_H - -/* $Id: base64.h,v 1.3 2002/02/26 16:59:59 stevesk Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -#include "config.h" - -#ifndef HAVE___B64_NTOP -# ifndef HAVE_B64_NTOP -int b64_ntop(u_char const *src, size_t srclength, char *target, - size_t targsize); -int b64_pton(u_char const *src, u_char *target, size_t targsize); -# endif /* !HAVE_B64_NTOP */ -# define __b64_ntop b64_ntop -# define __b64_pton b64_pton -#endif /* HAVE___B64_NTOP */ - -#ifdef __cplusplus -} -#endif - -#endif /* _BASE64_H */ diff --git a/usr/src/cmd/ssh/include/bindresvport.h b/usr/src/cmd/ssh/include/bindresvport.h deleted file mode 100644 index 9cd968bf9b..0000000000 --- a/usr/src/cmd/ssh/include/bindresvport.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Id: bindresvport.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _BINDRESVPORT_H -#define _BINDRESVPORT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#ifndef HAVE_BINDRESVPORT_SA -int bindresvport_sa(int sd, struct sockaddr *sa); -#endif /* !HAVE_BINDRESVPORT_SA */ - -#ifdef __cplusplus -} -#endif - -#endif /* _BINDRESVPORT_H */ diff --git a/usr/src/cmd/ssh/include/bsd-arc4random.h b/usr/src/cmd/ssh/include/bsd-arc4random.h deleted file mode 100644 index c9238636c5..0000000000 --- a/usr/src/cmd/ssh/include/bsd-arc4random.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 1999-2000 Damien Miller. 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 _BSD_ARC4RANDOM_H -#define _BSD_ARC4RANDOM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* $Id: bsd-arc4random.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#include "config.h" - -#ifndef HAVE_ARC4RANDOM -unsigned int arc4random(void); -void arc4random_stir(void); -#endif /* !HAVE_ARC4RANDOM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _BSD_ARC4RANDOM_H */ diff --git a/usr/src/cmd/ssh/include/bsd-cray.h b/usr/src/cmd/ssh/include/bsd-cray.h deleted file mode 100644 index 8b8f9113c7..0000000000 --- a/usr/src/cmd/ssh/include/bsd-cray.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * $Id: bsd-cray.h,v 1.5 2002/09/26 00:38:51 tim Exp $ - * - * bsd-cray.h - * - * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) - * Significant portions provided by - * Wayne Schroeder, SDSC <schroeder@sdsc.edu> - * William Jones, UTexas <jones@tacc.utexas.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. - * - * Created: Apr 22 16.34:00 2002 wp - * - * This file contains functions required for proper execution - * on UNICOS systems. - * - */ - -#ifndef _BSD_CRAY_H -#define _BSD_CRAY_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _UNICOS -void cray_init_job(struct passwd *); /* init cray job */ -void cray_job_termination_handler(int); /* process end of job signal */ -void cray_login_failure(char *username, int errcode); -int cray_access_denied(char *username); -extern char cray_tmpdir[]; /* cray tmpdir */ -#ifndef IA_SSHD -#define IA_SSHD IA_LOGIN -#endif -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _BSD_CRAY_H */ diff --git a/usr/src/cmd/ssh/include/bsd-cygwin_util.h b/usr/src/cmd/ssh/include/bsd-cygwin_util.h deleted file mode 100644 index dc44268563..0000000000 --- a/usr/src/cmd/ssh/include/bsd-cygwin_util.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id: bsd-cygwin_util.h,v 1.7 2002/04/15 22:00:52 stevesk Exp $ */ - -#ifndef _BSD_CYGWIN_UTIL_H -#define _BSD_CYGWIN_UTIL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * cygwin_util.c - * - * Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com> - * - * 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. - * - * Created: Sat Sep 02 12:17:00 2000 cv - * - * This file contains functions for forcing opened file descriptors to - * binary mode on Windows systems. - */ - -#ifdef HAVE_CYGWIN - -#include <io.h> - -int binary_open(const char *filename, int flags, ...); -int binary_pipe(int fd[2]); -int check_nt_auth(int pwd_authenticated, struct passwd *pw); -int check_ntsec(const char *filename); -void register_9x_service(void); - -#define open binary_open -#define pipe binary_pipe - -#endif /* HAVE_CYGWIN */ - -#ifdef __cplusplus -} -#endif - -#endif /* _BSD_CYGWIN_UTIL_H */ diff --git a/usr/src/cmd/ssh/include/bsd-getpeereid.h b/usr/src/cmd/ssh/include/bsd-getpeereid.h deleted file mode 100644 index 44430f7619..0000000000 --- a/usr/src/cmd/ssh/include/bsd-getpeereid.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Id: bsd-getpeereid.h,v 1.1 2002/09/12 00:33:02 djm Exp $ */ - -#ifndef _BSD_GETPEEREID_H -#define _BSD_GETPEEREID_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#include <sys/types.h> /* For uid_t, gid_t */ - -#ifndef HAVE_GETPEEREID -int getpeereid(int , uid_t *, gid_t *); -#endif /* HAVE_GETPEEREID */ - -#ifdef __cplusplus -} -#endif - -#endif /* _BSD_GETPEEREID_H */ diff --git a/usr/src/cmd/ssh/include/bsd-misc.h b/usr/src/cmd/ssh/include/bsd-misc.h deleted file mode 100644 index 9990c87f3d..0000000000 --- a/usr/src/cmd/ssh/include/bsd-misc.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 1999-2000 Damien Miller. 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 _BSD_MISC_H -#define _BSD_MISC_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* $Id: bsd-misc.h,v 1.6 2002/06/13 21:34:58 mouring Exp $ */ - -#include "config.h" - -char *get_progname(char *argv0); - -#ifndef HAVE_SETSID -#define setsid() setpgrp(0, getpid()) -#endif /* !HAVE_SETSID */ - -#ifndef HAVE_SETENV -int setenv(const char *name, const char *value, int overwrite); -#endif /* !HAVE_SETENV */ - -#ifndef HAVE_SETLOGIN -int setlogin(const char *name); -#endif /* !HAVE_SETLOGIN */ - -#ifndef HAVE_INNETGR -int innetgr(const char *netgroup, const char *host, - const char *user, const char *domain); -#endif /* HAVE_INNETGR */ - -#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) -int seteuid(uid_t euid); -#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ - -#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) -int setegid(uid_t egid); -#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ - -#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) -const char *strerror(int e); -#endif - - -#ifndef HAVE_UTIMES -#ifndef HAVE_STRUCT_TIMEVAL -struct timeval { - long tv_sec; - long tv_usec; -} -#endif /* HAVE_STRUCT_TIMEVAL */ - -int utimes(char *filename, struct timeval *tvp); -#endif /* HAVE_UTIMES */ - -#ifndef HAVE_TRUNCATE -int truncate (const char *path, off_t length); -#endif /* HAVE_TRUNCATE */ - -#if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) -int setgroups(size_t size, const gid_t *list); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _BSD_MISC_H */ diff --git a/usr/src/cmd/ssh/include/bsd-snprintf.h b/usr/src/cmd/ssh/include/bsd-snprintf.h deleted file mode 100644 index 71691a01d3..0000000000 --- a/usr/src/cmd/ssh/include/bsd-snprintf.h +++ /dev/null @@ -1,28 +0,0 @@ -/* $Id: bsd-snprintf.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _BSD_SNPRINTF_H -#define _BSD_SNPRINTF_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#include <sys/types.h> /* For size_t */ - -#ifndef HAVE_SNPRINTF -int snprintf(char *str, size_t count, const char *fmt, ...); -#endif /* !HAVE_SNPRINTF */ - -#ifndef HAVE_VSNPRINTF -int vsnprintf(char *str, size_t count, const char *fmt, va_list args); -#endif /* !HAVE_SNPRINTF */ - -#ifdef __cplusplus -} -#endif - -#endif /* _BSD_SNPRINTF_H */ diff --git a/usr/src/cmd/ssh/include/bsd-waitpid.h b/usr/src/cmd/ssh/include/bsd-waitpid.h deleted file mode 100644 index 9c6385fdb8..0000000000 --- a/usr/src/cmd/ssh/include/bsd-waitpid.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 _BSD_WAITPID_H -#define _BSD_WAITPID_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* $Id: bsd-waitpid.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef HAVE_WAITPID -/* Clean out any potental issues */ -#undef WIFEXITED -#undef WIFSTOPPED -#undef WIFSIGNALED - -/* Define required functions to mimic a POSIX look and feel */ -#define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */ -#define WIFEXITED(w) (!((_W_INT(w)) & 0377)) -#define WIFSTOPPED(w) ((_W_INT(w)) & 0100) -#define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w)) -#define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1) -#define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1) -#define WCOREFLAG 0x80 -#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) - -/* Prototype */ -pid_t waitpid(int pid, int *stat_loc, int options); - -#endif /* !HAVE_WAITPID */ - -#ifdef __cplusplus -} -#endif - -#endif /* _BSD_WAITPID_H */ diff --git a/usr/src/cmd/ssh/include/bufaux.h b/usr/src/cmd/ssh/include/bufaux.h deleted file mode 100644 index aa673cccb1..0000000000 --- a/usr/src/cmd/ssh/include/bufaux.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* $OpenBSD: bufaux.h,v 1.18 2002/04/20 09:14:58 markus Exp $ */ - -#ifndef _BUFAUX_H -#define _BUFAUX_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -#include "buffer.h" -#include <openssl/bn.h> - -void buffer_put_bignum(Buffer *, const BIGNUM *); -void buffer_put_bignum2(Buffer *, const BIGNUM *); -void buffer_get_bignum(Buffer *, BIGNUM *); -void buffer_get_bignum2(Buffer *, BIGNUM *); - -u_short buffer_get_short(Buffer *); -void buffer_put_short(Buffer *, u_short); - -u_int buffer_get_int(Buffer *); -void buffer_put_int(Buffer *, u_int); - -#ifdef HAVE_U_INT64_T -u_int64_t buffer_get_int64(Buffer *); -void buffer_put_int64(Buffer *, u_int64_t); -#endif - -int buffer_get_char(Buffer *); -void buffer_put_char(Buffer *, int); - -void *buffer_get_string(Buffer *, u_int *); -char *buffer_get_utf8_string(Buffer *, uint_t *); -void buffer_put_string(Buffer *, const void *, u_int); -void buffer_put_cstring(Buffer *, const char *); -void buffer_put_utf8_string(Buffer *, const char *, uint_t len); -void buffer_put_utf8_cstring(Buffer *, const char *); - -#define buffer_skip_string(b) \ - do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while(0) - -int buffer_put_bignum_ret(Buffer *, const BIGNUM *); -int buffer_get_bignum_ret(Buffer *, BIGNUM *); -int buffer_put_bignum2_ret(Buffer *, const BIGNUM *); -int buffer_get_bignum2_ret(Buffer *, BIGNUM *); -int buffer_get_short_ret(u_short *, Buffer *); -int buffer_get_int_ret(u_int *, Buffer *); -#ifdef HAVE_U_INT64_T -int buffer_get_int64_ret(u_int64_t *, Buffer *); -#endif -void *buffer_get_string_ret(Buffer *, u_int *); -int buffer_get_char_ret(char *, Buffer *); - -#ifdef __cplusplus -} -#endif - -#endif /* _BUFAUX_H */ diff --git a/usr/src/cmd/ssh/include/buffer.h b/usr/src/cmd/ssh/include/buffer.h deleted file mode 100644 index 4a6c7ad5e1..0000000000 --- a/usr/src/cmd/ssh/include/buffer.h +++ /dev/null @@ -1,60 +0,0 @@ -/* $OpenBSD: buffer.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _BUFFER_H -#define _BUFFER_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ - -typedef struct { - u_char *buf; /* Buffer for data. */ - u_int alloc; /* Number of bytes allocated for data. */ - u_int offset; /* Offset of first byte containing data. */ - u_int end; /* Offset of last byte containing data. */ -} Buffer; - -void buffer_init(Buffer *); -void buffer_clear(Buffer *); -void buffer_free(Buffer *); - -u_int buffer_len(Buffer *); -void *buffer_ptr(Buffer *); - -void buffer_append(Buffer *, const void *, u_int); -void *buffer_append_space(Buffer *, u_int); - -int buffer_check_alloc(Buffer *, u_int); - -void buffer_get(Buffer *, void *, u_int); - -void buffer_consume(Buffer *, u_int); -void buffer_consume_end(Buffer *, u_int); - -void buffer_dump(Buffer *); - -int buffer_get_ret(Buffer *, void *, u_int); -int buffer_consume_ret(Buffer *, u_int); -int buffer_consume_end_ret(Buffer *, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _BUFFER_H */ diff --git a/usr/src/cmd/ssh/include/canohost.h b/usr/src/cmd/ssh/include/canohost.h deleted file mode 100644 index a60c0ef7e9..0000000000 --- a/usr/src/cmd/ssh/include/canohost.h +++ /dev/null @@ -1,41 +0,0 @@ -/* $OpenBSD: canohost.h,v 1.8 2001/06/26 17:27:23 markus Exp $ */ - -#ifndef _CANOHOST_H -#define _CANOHOST_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -const char *get_canonical_hostname(int); -const char *get_remote_ipaddr(void); -const char *get_remote_name_or_ip(u_int, int); - -char *get_peer_ipaddr(int); -int get_peer_port(int); -char *get_local_ipaddr(int); -char *get_local_name(int); - -int get_remote_port(void); -int get_local_port(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _CANOHOST_H */ diff --git a/usr/src/cmd/ssh/include/channels.h b/usr/src/cmd/ssh/include/channels.h deleted file mode 100644 index 4440f1996a..0000000000 --- a/usr/src/cmd/ssh/include/channels.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * 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) 1999, 2000, 2001, 2002 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. - */ -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ -/* $OpenBSD: channels.h,v 1.70 2002/06/24 14:33:27 markus Exp $ */ - - -#ifndef _CHANNELS_H -#define _CHANNELS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "buffer.h" - -/* Definitions for channel types. */ -#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */ -#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */ -#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ -#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */ -#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */ -#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */ -#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */ -#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */ -#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */ -#define SSH_CHANNEL_LARVAL 10 /* larval session */ -#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */ -#define SSH_CHANNEL_CONNECTING 12 -#define SSH_CHANNEL_DYNAMIC 13 -#define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */ -#define SSH_CHANNEL_MAX_TYPE 15 - -#define SSH_CHANNEL_PATH_LEN 256 - -struct Channel; -typedef struct Channel Channel; - -typedef void channel_callback_fn(int, void *); -typedef int channel_filter_fn(struct Channel *, char *, int); - -struct Channel { - int type; /* channel type/state */ - int self; /* my own channel identifier */ - int remote_id; /* channel identifier for remote peer */ - u_int istate; /* input from channel (state of receive half) */ - u_int ostate; /* output to channel (state of transmit half) */ - int wait_for_exit; /* no close till after exit-status is sent */ - int flags; /* close sent/rcvd */ - int rfd; /* read fd */ - int wfd; /* write fd */ - int efd; /* extended fd */ - int sock; /* sock fd */ - int isatty; /* rfd is a tty */ - int wfd_isatty; /* wfd is a tty */ - int force_drain; /* force close on iEOF */ - int delayed; /* post-select handlers for newly created - * channels are delayed until the first call - * to a matching pre-select handler. - * this way post-select handlers are not - * accidenly called if a FD gets reused */ - Buffer input; /* data read from socket, to be sent over - * encrypted connection */ - Buffer output; /* data received over encrypted connection for - * send on socket */ - Buffer extended; - char path[SSH_CHANNEL_PATH_LEN]; - /* path for unix domain sockets, or host name for forwards */ - int listening_port; /* port being listened for forwards */ - int host_port; /* remote port to connect for forwards */ - char *remote_name; /* remote hostname */ - - u_int remote_window; - u_int remote_maxpacket; - u_int local_window; - u_int local_window_max; - u_int local_consumed; - u_int local_maxpacket; - int extended_usage; - int single_connection; - - char *ctype; /* type */ - - /* callback */ - channel_callback_fn *confirm; - channel_callback_fn *detach_user; - - /* 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_PACKET_DEFAULT (32*1024) -#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT) -#define CHAN_TCP_PACKET_DEFAULT (32*1024) -#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT) -#define CHAN_X11_PACKET_DEFAULT (16*1024) -#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) - -/* possible input states */ -#define CHAN_INPUT_OPEN 0 -#define CHAN_INPUT_WAIT_DRAIN 1 -#define CHAN_INPUT_WAIT_OCLOSE 2 -#define CHAN_INPUT_CLOSED 3 - -/* possible output states */ -#define CHAN_OUTPUT_OPEN 0 -#define CHAN_OUTPUT_WAIT_DRAIN 1 -#define CHAN_OUTPUT_WAIT_IEOF 2 -#define CHAN_OUTPUT_CLOSED 3 - -/* - * Other channel flag bits are specific to each type of channel and are - * defined locally with the code that uses them. - */ -#define CHAN_CLOSE_SENT 0x01 -#define CHAN_CLOSE_RCVD 0x02 -#define CHAN_EOF_SENT 0x04 -#define CHAN_EOF_RCVD 0x08 - -#define CHAN_RBUF 16*1024 - -/* check whether 'efd' is still in use */ -#define CHANNEL_EFD_INPUT_ACTIVE(c) \ - (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \ - (c->efd != -1 || \ - buffer_len(&c->extended) > 0)) -#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \ - (compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \ - ((c->efd != -1 && !(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD))) || \ - buffer_len(&c->extended) > 0)) - -/* channel management */ - -Channel *channel_lookup(int); -Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); -void channel_set_fds(int, int, int, int, int, int, u_int); -void channel_set_wait_for_exit(int, int); -void channel_free(Channel *); -void channel_free_all(void); -void channel_stop_listening(void); - -void channel_send_open(int); -void channel_request_start(int, char *, int); -void channel_register_cleanup(int, channel_callback_fn *); -void channel_register_confirm(int, channel_callback_fn *); -void channel_register_filter(int, channel_filter_fn *); -void channel_cancel_cleanup(int); -int channel_close_fd(int *); - -/* protocol handler */ - -void channel_input_close(int, u_int32_t, void *); -void channel_input_close_confirmation(int, u_int32_t, void *); -void channel_input_data(int, u_int32_t, void *); -void channel_input_extended_data(int, u_int32_t, void *); -void channel_input_ieof(int, u_int32_t, void *); -void channel_input_oclose(int, u_int32_t, void *); -void channel_input_open_confirmation(int, u_int32_t, void *); -void channel_input_open_failure(int, u_int32_t, void *); -void channel_input_port_open(int, u_int32_t, void *); -void channel_input_window_adjust(int, u_int32_t, void *); - -/* file descriptor handling (read/write) */ - -void channel_prepare_select(fd_set **, fd_set **, int *, int*, int); -void channel_after_select(fd_set *, fd_set *); -void channel_output_poll(void); - -int channel_not_very_much_buffered_data(void); -void channel_close_all(void); -int channel_still_open(void); -char *channel_open_message(void); -int channel_find_open(void); - -/* tcp forwarding */ -void channel_set_af(int af); -void channel_permit_all_opens(void); -void channel_add_permitted_opens(char *, int); -void channel_clear_permitted_opens(void); -void channel_input_port_forward_request(int, int); -int channel_connect_to(const char *, u_short); -int channel_connect_by_listen_address(u_short); -int channel_request_remote_forwarding(const char *, u_short, - const char *, u_short); -int channel_setup_local_fwd_listener(const char *, u_short, - const char *, u_short, int); -void channel_request_rforward_cancel(const char *host, u_short port); -int channel_setup_remote_fwd_listener(const char *, u_short, int); -int channel_cancel_rport_listener(const char *, u_short); - -/* x11 forwarding */ - -int x11_connect_display(void); -int x11_create_display_inet(int, int, int, u_int *); -void x11_input_open(int, u_int32_t, void *); -void x11_request_forwarding_with_spoofing(int, const char *, const char *, - const char *); -void deny_input_open(int, u_int32_t, void *); - -/* agent forwarding */ - -void auth_request_forwarding(void); -void auth_input_open_request(int, u_int32_t, void *); - -/* channel close */ - -int chan_is_dead(Channel *, int); -void chan_mark_dead(Channel *); - -/* channel events */ - -void chan_rcvd_oclose(Channel *); -void chan_rcvd_eow(Channel *); /* SSH2-only */ -void chan_read_failed(Channel *); -void chan_ibuf_empty(Channel *); - -void chan_rcvd_ieof(Channel *); -void chan_write_failed(Channel *); -void chan_obuf_empty(Channel *); - -#ifdef __cplusplus -} -#endif - -#endif /* _CHANNELS_H */ diff --git a/usr/src/cmd/ssh/include/cipher.h b/usr/src/cmd/ssh/include/cipher.h deleted file mode 100644 index e9362fedc4..0000000000 --- a/usr/src/cmd/ssh/include/cipher.h +++ /dev/null @@ -1,103 +0,0 @@ -/* $OpenBSD: cipher.h,v 1.33 2002/03/18 17:13:15 markus Exp $ */ - -#ifndef _CIPHER_H -#define _CIPHER_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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. - */ - -#include <openssl/evp.h> -/* - * Cipher types for SSH-1. New types can be added, but old types should not - * be removed for compatibility. The maximum allowed value is 31. - */ -#define SSH_CIPHER_SSH2 -3 -#define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */ -#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */ -#define SSH_CIPHER_NONE 0 /* no encryption */ -#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ -#define SSH_CIPHER_DES 2 /* DES CBC */ -#define SSH_CIPHER_3DES 3 /* 3DES CBC */ -#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ -#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ -#define SSH_CIPHER_BLOWFISH 6 -#define SSH_CIPHER_RESERVED 7 -#define SSH_CIPHER_MAX 31 - -#define CIPHER_ENCRYPT 1 -#define CIPHER_DECRYPT 0 - -typedef struct Cipher Cipher; -typedef struct CipherContext CipherContext; - -struct Cipher; -struct CipherContext { - int plaintext; - EVP_CIPHER_CTX evp; - Cipher *cipher; -}; - -u_int cipher_mask_ssh1(int); -Cipher *cipher_by_name(const char *); -Cipher *cipher_by_number(int); -int cipher_number(const char *); -char *cipher_name(int); -int ciphers_valid(const char *); -void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, - const u_char *, u_int, int); -void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int); -void cipher_cleanup(CipherContext *); -void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); -u_int cipher_blocksize(Cipher *); -u_int cipher_keylen(Cipher *); - -u_int cipher_get_number(Cipher *); -void cipher_get_keyiv(CipherContext *, u_char *, u_int); -void cipher_set_keyiv(CipherContext *, u_char *); -int cipher_get_keyiv_len(CipherContext *); -int cipher_get_keycontext(CipherContext *, u_char *); -void cipher_set_keycontext(CipherContext *, u_char *); - -#ifdef __cplusplus -} -#endif - -#endif /* _CIPHER_H */ diff --git a/usr/src/cmd/ssh/include/clientloop.h b/usr/src/cmd/ssh/include/clientloop.h deleted file mode 100644 index 46c801e405..0000000000 --- a/usr/src/cmd/ssh/include/clientloop.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _CLIENTLOOP_H -#define _CLIENTLOOP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* $OpenBSD: clientloop.h,v 1.7 2002/04/22 21:04:52 markus Exp $ */ - -/* Client side main loop for the interactive session. */ -int client_loop(int, int, int); -void client_x11_get_proto(const char *, const char *, uint_t, - char **, char **); -void client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt); -void client_daemonize(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _CLIENTLOOP_H */ diff --git a/usr/src/cmd/ssh/include/compat.h b/usr/src/cmd/ssh/include/compat.h deleted file mode 100644 index 63b845017a..0000000000 --- a/usr/src/cmd/ssh/include/compat.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _COMPAT_H -#define _COMPAT_H - -/* $OpenBSD: compat.h,v 1.33 2002/09/27 10:42:09 mickey Exp $ */ - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SSH_PROTO_UNKNOWN 0x00 -#define SSH_PROTO_1 0x01 -#define SSH_PROTO_1_PREFERRED 0x02 -#define SSH_PROTO_2 0x04 - -#define SSH_BUG_SIGBLOB 0x00000001 -#define SSH_BUG_PKSERVICE 0x00000002 -#define SSH_BUG_HMAC 0x00000004 -#define SSH_BUG_X11FWD 0x00000008 -#define SSH_OLD_SESSIONID 0x00000010 -#define SSH_BUG_PKAUTH 0x00000020 -#define SSH_BUG_DEBUG 0x00000040 -#define SSH_BUG_BANNER 0x00000080 -#define SSH_BUG_IGNOREMSG 0x00000100 -#define SSH_BUG_PKOK 0x00000200 -#define SSH_BUG_PASSWORDPAD 0x00000400 -#define SSH_BUG_SCANNER 0x00000800 -#define SSH_BUG_BIGENDIANAES 0x00001000 -#define SSH_BUG_RSASIGMD5 0x00002000 -#define SSH_OLD_DHGEX 0x00004000 -#define SSH_BUG_NOREKEY 0x00008000 -#define SSH_BUG_HBSERVICE 0x00010000 -#define SSH_BUG_OPENFAILURE 0x00020000 -#define SSH_BUG_DERIVEKEY 0x00040000 -/*#define this is free slot 0x00080000 */ -#define SSH_BUG_DUMMYCHAN 0x00100000 -#define SSH_BUG_EXTEOF 0x00200000 -#define SSH_BUG_K5USER 0x00400000 -#define SSH_BUG_PROBE 0x00800000 -#define SSH_BUG_LOCALES_NOT_LANGTAGS 0x01000000 -#define SSH_OLD_GSSAPI 0x02000000 -#define SSH_BUG_GSSAPI_BER 0x04000000 -#define SSH_BUG_FIRSTKEX 0x08000000 -#define SSH_BUG_RFWD_ADDR 0x10000000 -#define SSH_BUG_GSSKEX_HOSTKEY 0x20000000 -/* SSH_OLD_FORWARD_ADDR flag bumped up the SunSSH version to 1.2 */ -#define SSH_OLD_FORWARD_ADDR 0x40000000 -/* SSH_BUG_STRING_ENCODING flag bumped up the SunSSH version to 1.4 */ -#define SSH_BUG_STRING_ENCODING 0x80000000 - -void enable_compat13(void); -void enable_compat20(void); -void compat_datafellows(const char *); -int proto_spec(const char *); -char *compat_cipher_proposal(char *); - -extern int compat13; -extern int compat20; -extern uint32_t datafellows; - -#ifdef __cplusplus -} -#endif - -#endif /* _COMPAT_H */ diff --git a/usr/src/cmd/ssh/include/compress.h b/usr/src/cmd/ssh/include/compress.h deleted file mode 100644 index ad87892227..0000000000 --- a/usr/src/cmd/ssh/include/compress.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $OpenBSD: compress.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _COMPRESS_H -#define _COMPRESS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ - -void buffer_compress_init_send(int); -void buffer_compress_init_recv(void); -void buffer_compress_uninit(void); -void buffer_compress(Buffer *, Buffer *); -void buffer_uncompress(Buffer *, Buffer *); - -#ifdef __cplusplus -} -#endif - -#endif /* _COMPRESS_H */ diff --git a/usr/src/cmd/ssh/include/config.h b/usr/src/cmd/ssh/include/config.h deleted file mode 100644 index 437b120029..0000000000 --- a/usr/src/cmd/ssh/include/config.h +++ /dev/null @@ -1,983 +0,0 @@ -/* config.h. Generated by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ -/* $Id: acconfig.h,v 1.145 2002/09/26 00:38:48 tim Exp $ */ - -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 Gary Mills - */ - -#ifndef _CONFIG_H -#define _CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Generated automatically from acconfig.h by autoheader. */ -/* Please make your changes there */ - - -/* Define to a Set Process Title type if your system is */ -/* supported by bsd-setproctitle.c */ -/* #undef SPT_TYPE */ - -/* setgroups() NOOP allowed */ -/* #undef SETGROUPS_NOOP */ - -/* SCO workaround */ -/* #undef BROKEN_SYS_TERMIO_H */ - -/* If your header files don't define LOGIN_PROGRAM, then use this (detected) */ -/* from environment and PATH */ -#define LOGIN_PROGRAM_FALLBACK "/usr/bin/login" - -/* Define if your password has a pw_class field */ -/* #undef HAVE_PW_CLASS_IN_PASSWD */ - -/* Define if your password has a pw_expire field */ -/* #undef HAVE_PW_EXPIRE_IN_PASSWD */ - -/* Define if your password has a pw_change field */ -/* #undef HAVE_PW_CHANGE_IN_PASSWD */ - -/* Define if your system uses access rights style file descriptor passing */ -#define HAVE_ACCRIGHTS_IN_MSGHDR 1 - -/* Define if your system uses ancillary data style file descriptor passing */ -/* #undef HAVE_CONTROL_IN_MSGHDR */ - -/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ -/* #undef BROKEN_INET_NTOA */ - -/* Define if your system defines sys_errlist[] */ -#define HAVE_SYS_ERRLIST 1 - -/* Define if your system defines sys_nerr */ -#define HAVE_SYS_NERR 1 - -/* Define if your system choked on IP TOS setting */ -#define IP_TOS_IS_BROKEN 1 - -/* Define if you have the getuserattr function. */ -/* #undef HAVE_GETUSERATTR */ - -/* Work around problematic Linux PAM modules handling of PAM_TTY */ -#define PAM_TTY_KLUDGE 1 - -/* Define if your snprintf is busted */ -/* #undef BROKEN_SNPRINTF */ - -/* Define if you are on Cygwin */ -/* #undef HAVE_CYGWIN */ - -/* Define if you have a broken realpath. */ -/* #undef BROKEN_REALPATH */ - -/* Define if you are on NEWS-OS */ -/* #undef HAVE_NEWS4 */ - -/* Define if you want to enable PAM support */ -#define USE_PAM 1 - -/* Define if you want to enable AIX4's authenticate function */ -/* #undef WITH_AIXAUTHENTICATE */ - -/* - * Define if you have/want arrays (cluster-wide session managment, not C - * arrays) - */ -/* #undef WITH_IRIX_ARRAY */ - -/* Define if you want IRIX project management */ -/* #undef WITH_IRIX_PROJECT */ - -/* Define if you want IRIX audit trails */ -/* #undef WITH_IRIX_AUDIT */ - -/* Define if you want IRIX kernel jobs */ -/* #undef WITH_IRIX_JOBS */ - -/* Location of PRNGD/EGD random number socket */ -/* #undef PRNGD_SOCKET */ - -/* Port number of PRNGD/EGD random number socket */ -/* #undef PRNGD_PORT */ - -/* Builtin PRNG command timeout */ -#define ENTROPY_TIMEOUT_MSEC 200 - -/* non-privileged user for privilege separation */ -#define SSH_PRIVSEP_USER "sshd" - -/* Define if you want to install preformatted manpages. */ -/* #undef MANTYPE */ - -/* Define if your ssl headers are included with #include <openssl/header.h> */ -#define HAVE_OPENSSL 1 - -/* Define if Solaris' OpenSSL lacks AES support */ -#define SOLARIS_OPENSSL_NO_AES 1 - -/* Define if Solaris-style Least Privilege is available */ -#define HAVE_SOLARIS_PRIVILEGE 1 - -/* Define if you want Sun's alternative privilege separation */ -#define ALTPRIVSEP - -/* Define if you have Solaris-style Contracts */ -#define HAVE_SOLARIS_CONTRACTS 1 - -/* Define if SVR4-style libcmd (for accessing /etc/default/ files) */ -#define HAVE_DEFOPEN 1 - -/* - * Define if you are linking against RSAref. Used only to print the right - * message at run-time. - */ -/* #undef RSAREF */ - -/* struct timeval */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* struct utmp and struct utmpx fields */ -/* #undef HAVE_HOST_IN_UTMP */ -#define HAVE_HOST_IN_UTMPX 1 -/* #undef HAVE_ADDR_IN_UTMP */ -/* #undef HAVE_ADDR_IN_UTMPX */ -/* #undef HAVE_ADDR_V6_IN_UTMP */ -/* #undef HAVE_ADDR_V6_IN_UTMPX */ -#define HAVE_SYSLEN_IN_UTMPX 1 -#define HAVE_PID_IN_UTMP 1 -#define HAVE_TYPE_IN_UTMP 1 -#define HAVE_TYPE_IN_UTMPX 1 -/* #undef HAVE_TV_IN_UTMP */ -#define HAVE_TV_IN_UTMPX 1 -#define HAVE_ID_IN_UTMP 1 -#define HAVE_ID_IN_UTMPX 1 -#define HAVE_EXIT_IN_UTMP 1 -#define HAVE_TIME_IN_UTMP 1 -#define HAVE_TIME_IN_UTMPX 1 - -/* Define if you don't want to use your system's login() call */ -/* #undef DISABLE_LOGIN */ - -/* Define if you don't want to use pututline() etc. to write [uw]tmp */ -/* #undef DISABLE_PUTUTLINE */ - -/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ -/* #undef DISABLE_PUTUTXLINE */ - -/* Define if you don't want to use lastlog */ -/* #undef DISABLE_LASTLOG */ - -/* Define if you don't want to use lastlog in session.c */ -/* #undef NO_SSH_LASTLOG */ - -/* Define if you don't want to use utmp */ -#define DISABLE_UTMP 1 - -/* Define if you don't want to use utmpx */ -/* #undef DISABLE_UTMPX */ - -/* Define if you don't want to use wtmp */ -#define DISABLE_WTMP 1 - -/* Define if you don't want to use wtmpx */ -/* #undef DISABLE_WTMPX */ - -/* Some systems need a utmpx entry for /bin/login to work */ -#define LOGIN_NEEDS_UTMPX 1 - -/* Some versions of /bin/login need the TERM supplied on the commandline */ -#define LOGIN_NEEDS_TERM 1 - -/* Define if your login program cannot handle end of options ("--") */ -/* #undef LOGIN_NO_ENDOPT */ - -/* Define if you want to specify the path to your lastlog file */ -#define CONF_LASTLOG_FILE "/var/adm/lastlog" - -/* Define if you want to specify the path to your utmp file */ -/* #undef CONF_UTMP_FILE */ - -/* Define if you want to specify the path to your wtmp file */ -/* #undef CONF_WTMP_FILE */ - -/* Define if you want to specify the path to your utmpx file */ -/* #undef CONF_UTMPX_FILE */ - -/* Define if you want to specify the path to your wtmpx file */ -/* #undef CONF_WTMPX_FILE */ - -/* Define if you want external askpass support */ -/* #undef USE_EXTERNAL_ASKPASS */ - -/* Define if libc defines __progname */ -#define HAVE___PROGNAME 1 - -/* Define if compiler implements __FUNCTION__ */ -#define HAVE___FUNCTION__ 1 - -/* Define if compiler implements __func__ */ -#define HAVE___func__ 1 - -/* Define if you want GSS-API support */ -#define GSSAPI 1 - -/* Define if you have <gssapi/gssapi.h> */ -#define SUNW_GSSAPI 1 - -/* Define if you have GSS_Store_cred() */ -#define HAVE_GSS_STORE_CRED 1 - -/* Define if you have __gss_userok() */ -#define HAVE___GSS_USEROK 1 - -/* Define for simple authorization of GSS-API principals */ -/* #undef GSSAPI_SIMPLE_USEROK */ - -/* Define if you have gsscred_name_to_unix_cred() (Solaris) */ -#define HAVE_GSSCRED_API 1 - -/* Define if you have __gss_oid_to_mech() */ -#define HAVE_GSS_OID_TO_MECH 1 - -/* Define if you have gss_oid_to_str() */ -#define HAVE_GSS_OID_TO_STR 1 - -/* Define if you want support for MIT krb5 GSS internals */ -/* #undef KRB5_GSS */ - -/* Define if you want support for GSI GSS internals */ -/* #undef GSI_GSS */ - -/* Define if you want raw Kerberos 5 support */ -/* #undef KRB5 */ - -/* Define if you want GSI/Globus authentication support */ -/* #undef GSI */ - -/* Define this if you are using the Heimdal version of Kerberos V5 */ -/* #undef HEIMDAL */ - -/* Define if you want Kerberos 4 support */ -/* #undef KRB4 */ - -/* Define if you want AFS support */ -/* #undef AFS */ - -/* Define if you want S/Key support */ -/* #undef SKEY */ - -/* Define if you want TCP Wrappers support */ -#define LIBWRAP 1 - -/* Define if your libraries define login() */ -/* #undef HAVE_LOGIN */ - -/* Define if your libraries define getpagesize() */ -#define HAVE_GETPAGESIZE 1 - -/* Define if xauth is found in your path */ -#define XAUTH_PATH "/usr/X11/bin/xauth" - -/* Define if rsh is found in your path */ -#define RSH_PATH "/usr/bin/rsh" - -/* Define if you want to allow MD5 passwords */ -/* #undef HAVE_MD5_PASSWORDS */ - -/* Define if you want to disable shadow passwords */ -/* #undef DISABLE_SHADOW */ - -/* Define if you want to use shadow password expire field */ -/* #undef HAS_SHADOW_EXPIRE */ - -/* Define if you have Digital Unix Security Integration Architecture */ -/* #undef HAVE_OSF_SIA */ - -/* Define if you have getpwanam(3) [SunOS 4.x] */ -/* #undef HAVE_GETPWANAM */ - -/* Define if you have an old version of PAM which takes only one argument */ -/* to pam_strerror */ -/* #undef HAVE_OLD_PAM */ - -/* Define if you are using Solaris-derived PAM which passes pam_messages */ -/* to the conversation function with an extra level of indirection */ -#define PAM_SUN_CODEBASE 1 - -/* Set this to your mail directory if you don't have maillock.h */ -/* #undef MAIL_DIRECTORY */ - -/* Data types */ -#define HAVE_U_INT 1 -#define HAVE_INTXX_T 1 -/* #undef HAVE_U_INTXX_T */ -#define HAVE_UINTXX_T 1 -#define HAVE_INT64_T 1 -/* #undef HAVE_U_INT64_T */ -#define HAVE_U_CHAR 1 -#define HAVE_SIZE_T 1 -#define HAVE_SSIZE_T 1 -#define HAVE_CLOCK_T 1 -#define HAVE_MODE_T 1 -#define HAVE_PID_T 1 -#define HAVE_SA_FAMILY_T 1 -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 -#define HAVE_STRUCT_ADDRINFO 1 -#define HAVE_STRUCT_IN6_ADDR 1 -#define HAVE_STRUCT_SOCKADDR_IN6 1 - -/* Fields in struct sockaddr_storage */ -#define HAVE_SS_FAMILY_IN_SS 1 -/* #undef HAVE___SS_FAMILY_IN_SS */ - -/* Define if you have /dev/ptmx */ -#define HAVE_DEV_PTMX 1 - -/* Define if you have /dev/ptc */ -/* #undef HAVE_DEV_PTS_AND_PTC */ - -/* Define if you need to use IP address instead of hostname in $DISPLAY */ -/* #undef IPADDR_IN_DISPLAY */ - -/* - * Specify the default $PATH. While /bin is a symbolic link to /usr/bin in - * Solaris, to include both of them there may help when users use - * ChrootDirectory options with plain SSH connections, without their own shell - * profiles. - */ -#define USER_PATH "/usr/bin:/bin" - -/* Specify location of ssh.pid */ -#define _PATH_SSH_PIDDIR "/var/run" - -/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ -/* #undef IPV4_DEFAULT */ - -/* getaddrinfo is broken (if present) */ -/* #undef BROKEN_GETADDRINFO */ - -/* Workaround more Linux IPv6 quirks */ -/* #undef DONT_TRY_OTHER_AF */ - -/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ -#define IPV4_IN_IPV6 1 - -/* Define if you have BSD auth support */ -/* #undef BSD_AUTH */ - -/* Define if X11 doesn't support AF_UNIX sockets on that system */ -/* #undef NO_X11_UNIX_SOCKETS */ - -/* Define if the concept of ports only accessible to superusers isn't known */ -/* #undef NO_IPPORT_RESERVED_CONCEPT */ - -/* Needed for SCO and NeXT */ -/* #undef BROKEN_SAVED_UIDS */ - -/* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */ -#define GLOB_HAS_ALTDIRFUNC 1 - -/* Define if your system glob() function has gl_matchc options in glob_t */ -#define GLOB_HAS_GL_MATCHC 1 - -/* - * Define in your struct dirent expects you to allocate extra space for - * d_name - */ -#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1 - -/* Define if your getopt(3) defines and uses optreset */ -/* #undef HAVE_GETOPT_OPTRESET */ - -/* Define on *nto-qnx systems */ -/* #undef MISSING_NFDBITS */ - -/* Define on *nto-qnx systems */ -/* #undef MISSING_HOWMANY */ - -/* Define on *nto-qnx systems */ -/* #undef MISSING_FD_MASK */ - -/* - * Use libedit or libtecla for sftp - * If both USE_LIBEDIT and USE_LIBTECLA are defined, then USE_LIBEDIT will - * have higher precedence. - */ -#undef USE_LIBEDIT -#define USE_LIBTECLA 1 - -/* Define if you want to use OpenSSL's internally seeded PRNG only */ -#define OPENSSL_PRNG_ONLY 1 - -/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */ -/* #undef WITH_ABBREV_NO_TTY */ - -/* Define if you want a different $PATH for the superuser */ -#define SUPERUSER_PATH "/usr/sbin:/usr/bin" - -/* Path that unprivileged child will chroot() to in privep mode */ -/* #undef PRIVSEP_PATH */ - -/* Define if your platform needs to skip post auth file descriptor passing */ -/* #undef DISABLE_FD_PASSING */ - - -/* Define to 1 if the `getpgrp' function requires zero arguments. */ -#define GETPGRP_VOID 1 - -/* Define to 1 if you have the `arc4random' function. */ -/* #undef HAVE_ARC4RANDOM */ - -/* Define to 1 if you have the `asprintf' function. */ -#define HAVE_ASPRINTF 1 - -/* Define to 1 if you have the `b64_ntop' function. */ -/* #undef HAVE_B64_NTOP */ - -/* Define to 1 if you have the `bcopy' function. */ -#define HAVE_BCOPY 1 - -/* Define to 1 if you have the `bindresvport_sa' function. */ -/* #undef HAVE_BINDRESVPORT_SA */ - -/* Define to 1 if you have the <bstring.h> header file. */ -/* #undef HAVE_BSTRING_H */ - -/* Define to 1 if you have the `clock' function. */ -#define HAVE_CLOCK 1 - -/* Define to 1 if you have the <crypt.h> header file. */ -#define HAVE_CRYPT_H 1 - -/* Define to 1 if you have the `dirname' function. */ -#define HAVE_DIRNAME 1 - -/* Define to 1 if you have the <endian.h> header file. */ -/* #undef HAVE_ENDIAN_H */ - -/* Define to 1 if you have the `endutent' function. */ -#define HAVE_ENDUTENT 1 - -/* Define to 1 if you have the `endutxent' function. */ -#define HAVE_ENDUTXENT 1 - -/* Define to 1 if you have the `fchmod' function. */ -#define HAVE_FCHMOD 1 - -/* Define to 1 if you have the `fchown' function. */ -#define HAVE_FCHOWN 1 - -/* Define to 1 if you have the <floatingpoint.h> header file. */ -#define HAVE_FLOATINGPOINT_H 1 - -/* Define to 1 if you have the `freeaddrinfo' function. */ -#define HAVE_FREEADDRINFO 1 - -/* Define to 1 if you have the `futimes' function. */ -/* #undef HAVE_FUTIMES */ - -/* Define to 1 if you have the `gai_strerror' function. */ -#define HAVE_GAI_STRERROR 1 - -/* Define to 1 if you have the `getaddrinfo' function. */ -#define HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `getcwd' function. */ -#define HAVE_GETCWD 1 - -/* Define to 1 if you have the `getgrouplist' function. */ -/* #undef HAVE_GETGROUPLIST */ - -/* Define to 1 if you have the `getluid' function. */ -/* #undef HAVE_GETLUID */ - -/* Define to 1 if you have the `getnameinfo' function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to 1 if you have the `getopt' function. */ -#define HAVE_GETOPT 1 - -/* Define to 1 if you have the <getopt.h> header file. */ -/* #undef HAVE_GETOPT_H */ - -/* Define to 1 if you have the `getpeereid' function. */ -/* #undef HAVE_GETPEEREID */ - -/* Define to 1 if you have the `getpeerucred' function. */ -#define HAVE_GETPEERUCRED 1 - -/* Define to 1 if you have the `getpwanam' function. */ -/* #undef HAVE_GETPWANAM */ - -/* Define to 1 if you have the `getrlimit' function. */ -#define HAVE_GETRLIMIT 1 - -/* Define to 1 if you have the `getrusage' function. */ -#define HAVE_GETRUSAGE 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the `getttyent' function. */ -/* #undef HAVE_GETTTYENT */ - -/* Define to 1 if you have the `getutent' function. */ -#define HAVE_GETUTENT 1 - -/* Define to 1 if you have the `getutid' function. */ -#define HAVE_GETUTID 1 - -/* Define to 1 if you have the `getutline' function. */ -#define HAVE_GETUTLINE 1 - -/* Define to 1 if you have the `getutxent' function. */ -#define HAVE_GETUTXENT 1 - -/* Define to 1 if you have the `getutxid' function. */ -#define HAVE_GETUTXID 1 - -/* Define to 1 if you have the `getutxline' function. */ -#define HAVE_GETUTXLINE 1 - -/* Define to 1 if you have the `glob' function. */ -#define HAVE_GLOB 1 - -/* Define to 1 if you have the <glob.h> header file. */ -#define HAVE_GLOB_H 1 - -/* Define to 1 if you have the <ia.h> header file. */ -/* #undef HAVE_IA_H */ - -/* Define to 1 if you have the `inet_aton' function. */ -/* #undef HAVE_INET_ATON */ - -/* Define to 1 if you have the `inet_ntoa' function. */ -#define HAVE_INET_NTOA 1 - -/* Define to 1 if you have the `inet_ntop' function. */ -#define HAVE_INET_NTOP 1 - -/* Define to 1 if you have the `innetgr' function. */ -#define HAVE_INNETGR 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <krb.h> header file. */ -/* #undef HAVE_KRB_H */ - -/* Define to 1 if you have the <lastlog.h> header file. */ -#define HAVE_LASTLOG_H 1 - -/* Define to 1 if you have the `crypt' library (-lcrypt). */ -/* #undef HAVE_LIBCRYPT */ - -/* Define to 1 if you have the `des' library (-ldes). */ -/* #undef HAVE_LIBDES */ - -/* Define to 1 if you have the `des425' library (-ldes425). */ -/* #undef HAVE_LIBDES425 */ - -/* Define to 1 if you have the `dl' library (-ldl). */ -#define HAVE_LIBDL 1 - -/* Define to 1 if you have the <libgen.h> header file. */ -#define HAVE_LIBGEN_H 1 - -/* Define to 1 if you have the `krb' library (-lkrb). */ -/* #undef HAVE_LIBKRB */ - -/* Define to 1 if you have the `krb4' library (-lkrb4). */ -/* #undef HAVE_LIBKRB4 */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -#define HAVE_LIBNSL 1 - -/* Define to 1 if you have the `pam' library (-lpam). */ -#define HAVE_LIBPAM 1 - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -/* #undef HAVE_LIBRESOLV */ - -/* Define to 1 if you have the `sectok' library (-lsectok). */ -/* #undef HAVE_LIBSECTOK */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -#define HAVE_LIBSOCKET 1 - -/* Define to 1 if you have the <libutil.h> header file. */ -/* #undef HAVE_LIBUTIL_H */ - -/* Define to 1 if you have the `xnet' library (-lxnet). */ -/* #undef HAVE_LIBXNET */ - -/* Define to 1 if you have the `z' library (-lz). */ -#define HAVE_LIBZ 1 - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the <login.h> header file. */ -/* #undef HAVE_LOGIN_H */ - -/* Define to 1 if you have the `logout' function. */ -/* #undef HAVE_LOGOUT */ - -/* Define to 1 if you have the `logwtmp' function. */ -/* #undef HAVE_LOGWTMP */ - -/* Define to 1 if you have the <maillock.h> header file. */ -#define HAVE_MAILLOCK_H 1 - -/* Define to 1 if you have the `md5_crypt' function. */ -/* #undef HAVE_MD5_CRYPT */ - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have mkstemp, mkstemps and mkdtemp */ -#define HAVE_MKDTEMP 1 - -/* Define to 1 if you have the `mmap' function. */ -#define HAVE_MMAP 1 - -/* Define to 1 if you have the <netdb.h> header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the <netgroup.h> header file. */ -/* #undef HAVE_NETGROUP_H */ - -/* Define to 1 if you have the <netinet/in_systm.h> header file. */ -#define HAVE_NETINET_IN_SYSTM_H 1 - -/* Define to 1 if you have the `ngetaddrinfo' function. */ -/* #undef HAVE_NGETADDRINFO */ - -/* Define to 1 if you have the `ogetaddrinfo' function. */ -/* #undef HAVE_OGETADDRINFO */ - -/* Define to 1 if you have the `openpty' function. */ -/* #undef HAVE_OPENPTY */ - -/* Define to 1 if you have the `pam_getenvlist' function. */ -#define HAVE_PAM_GETENVLIST 1 - -/* Define to 1 if you have the <paths.h> header file. */ -/* #undef HAVE_PATHS_H */ - -/* Define to 1 if you have the <pty.h> header file. */ -/* #undef HAVE_PTY_H */ - -/* Define to 1 if you have the `pututline' function. */ -#define HAVE_PUTUTLINE 1 - -/* Define to 1 if you have the `pututxline' function. */ -#define HAVE_PUTUTXLINE 1 - -/* Define to 1 if you have the `readpassphrase' function. */ -/* #undef HAVE_READPASSPHRASE */ - -/* Define to 1 if you have the <readpassphrase.h> header file. */ -/* #undef HAVE_READPASSPHRASE_H */ - -/* Define to 1 if you have the `realpath' function. */ -#define HAVE_REALPATH 1 - -/* Define to 1 if you have the `recvmsg' function. */ -#define HAVE_RECVMSG 1 - -/* Define to 1 if you have the <rpc/types.h> header file. */ -#define HAVE_RPC_TYPES_H 1 - -/* Define to 1 if you have the `rresvport_af' function. */ -#define HAVE_RRESVPORT_AF 1 - -/* Define to 1 if you have the <sectok.h> header file. */ -/* #undef HAVE_SECTOK_H */ - -/* Define to 1 if you have the <security/pam_appl.h> header file. */ -#define HAVE_SECURITY_PAM_APPL_H 1 - -/* Define to 1 if you have the `sendmsg' function. */ -#define HAVE_SENDMSG 1 - -/* Define to 1 if you have the `setdtablesize' function. */ -/* #undef HAVE_SETDTABLESIZE */ - -/* Define to 1 if you have the `setegid' function. */ -#define HAVE_SETEGID 1 - -/* Define to 1 if you have the `setenv' function. */ -#define HAVE_SETENV 1 - -/* Define to 1 if you have the `seteuid' function. */ -#define HAVE_SETEUID 1 - -/* Define to 1 if you have the `setgroups' function. */ -#define HAVE_SETGROUPS 1 - -/* Define to 1 if you have the `setlogin' function. */ -/* #undef HAVE_SETLOGIN */ - -/* Define to 1 if you have the `setluid' function. */ -/* #undef HAVE_SETLUID */ - -/* Define to 1 if you have the `setpcred' function. */ -/* #undef HAVE_SETPCRED */ - -/* Define to 1 if you have the `setproctitle' function. */ -/* #undef HAVE_SETPROCTITLE */ - -/* Define to 1 if you have the `setresgid' function. */ -/* #undef HAVE_SETRESGID */ - -/* Define to 1 if you have the `setreuid' function. */ -#define HAVE_SETREUID 1 - -/* Define to 1 if you have the `setrlimit' function. */ -#define HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the `setsid' function. */ -#define HAVE_SETSID 1 - -/* Define to 1 if you have the `setutent' function. */ -#define HAVE_SETUTENT 1 - -/* Define to 1 if you have the `setutxent' function. */ -#define HAVE_SETUTXENT 1 - -/* Define to 1 if you have the `setvbuf' function. */ -#define HAVE_SETVBUF 1 - -/* Define to 1 if you have the <shadow.h> header file. */ -#define HAVE_SHADOW_H 1 - -/* Define to 1 if you have the `sigaction' function. */ -#define HAVE_SIGACTION 1 - -/* Define to 1 if you have the `sigvec' function. */ -/* #undef HAVE_SIGVEC */ - -/* Define to 1 if the system has the type `sig_atomic_t'. */ -#define HAVE_SIG_ATOMIC_T 1 - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the `socketpair' function. */ -#define HAVE_SOCKETPAIR 1 - -/* Define to 1 if you have the <stddef.h> header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the `strftime' function. */ -#define HAVE_STRFTIME 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcat' function. */ -#define HAVE_STRLCAT 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define HAVE_STRLCPY 1 - -/* Define to 1 if you have the `strmode' function. */ -/* #undef HAVE_STRMODE */ - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 - -/* Define to 1 if you have the `sysconf' function. */ -#define HAVE_SYSCONF 1 - -/* Define to 1 if you have the <sys/bitypes.h> header file. */ -/* #undef HAVE_SYS_BITYPES_H */ - -/* Define to 1 if you have the <sys/bsdtty.h> header file. */ -/* #undef HAVE_SYS_BSDTTY_H */ - -/* Define to 1 if you have the <sys/cdefs.h> header file. */ -/* #undef HAVE_SYS_CDEFS_H */ - - -/* Define to 1 if you have the <sys/mman.h> header file. */ -#define HAVE_SYS_MMAN_H 1 - -/* Define to 1 if you have the <sys/select.h> header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/stropts.h> header file. */ -#define HAVE_SYS_STROPTS_H 1 - -/* Define to 1 if you have the <sys/sysmacros.h> header file. */ -#define HAVE_SYS_SYSMACROS_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/un.h> header file. */ -#define HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the `tcgetpgrp' function. */ -#define HAVE_TCGETPGRP 1 - -/* Define to 1 if you have the `time' function. */ -#define HAVE_TIME 1 - -/* Define to 1 if you have the <time.h> header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the <tmpdir.h> header file. */ -/* #undef HAVE_TMPDIR_H */ - -/* Define to 1 if you have the `truncate' function. */ -#define HAVE_TRUNCATE 1 - -/* Define to 1 if you have the <ttyent.h> header file. */ -/* #undef HAVE_TTYENT_H */ - -/* Define to 1 if you have the <ucred.h> header file. */ -#define HAVE_UCRED_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `updwtmp' function. */ -#define HAVE_UPDWTMP 1 - -/* Define to 1 if you have the <usersec.h> header file. */ -/* #undef HAVE_USERSEC_H */ - -/* Define to 1 if you have the <util.h> header file. */ -/* #undef HAVE_UTIL_H */ - -/* Define to 1 if you have the `utimes' function. */ -#define HAVE_UTIMES 1 - -/* Define to 1 if you have the <utime.h> header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if you have the `utmpname' function. */ -#define HAVE_UTMPNAME 1 - -/* Define to 1 if you have the `utmpxname' function. */ -#define HAVE_UTMPXNAME 1 - -/* Define to 1 if you have the <utmpx.h> header file. */ -#define HAVE_UTMPX_H 1 - -/* Define to 1 if you have the <utmp.h> header file. */ -#define HAVE_UTMP_H 1 - -/* Define to 1 if you have the `vasprintf' function. */ -#define HAVE_VASPRINTF 1 - -/* Define to 1 if you have the `vhangup' function. */ -#define HAVE_VHANGUP 1 - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if you have the `waitpid' function. */ -#define HAVE_WAITPID 1 - -/* Define to 1 if you have the `_getpty' function. */ -/* #undef HAVE__GETPTY */ - -/* Define to 1 if you have the `__b64_ntop' function. */ -/* #undef HAVE___B64_NTOP */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* The size of a `char', as computed by sizeof. */ -#define SIZEOF_CHAR 1 - -/* The size of a `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of a `long int', as computed by sizeof. */ -#define SIZEOF_LONG_INT 4 - -/* The size of a `long long int', as computed by sizeof. */ -#define SIZEOF_LONG_LONG_INT 8 - -/* The size of a `short int', as computed by sizeof. */ -#define SIZEOF_SHORT_INT 2 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* - * Define to 1 if your processor stores words with the most significant byte - * first (like Motorola and SPARC, unlike Intel and VAX). - */ -#define WORDS_BIGENDIAN 1 - -/* Number of bits in a file offset, on hosts where this is settable. */ -#define _FILE_OFFSET_BITS 64 - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* - * Define as `__inline' if that's what the C compiler calls it, or to nothing if - * it is not supported. - */ -/* #undef inline */ - -/* type to use in place of socklen_t if not defined */ -/* #undef socklen_t */ - -/* Define for BSM auditing (Solaris) support */ -#define HAVE_BSM 1 - -/* Define if compiling in ON */ -#define SUNW_SSH 1 - -/* ******************* Shouldn't need to edit below this line ************** */ - -#ifdef __cplusplus -} -#endif - -#endif /* _CONFIG_H */ diff --git a/usr/src/cmd/ssh/include/crc32.h b/usr/src/cmd/ssh/include/crc32.h deleted file mode 100644 index 3218cc925c..0000000000 --- a/usr/src/cmd/ssh/include/crc32.h +++ /dev/null @@ -1,32 +0,0 @@ -/* $OpenBSD: crc32.h,v 1.13 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _CRC32_H -#define _CRC32_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1992 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ - -u_int ssh_crc32(const u_char *, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _CRC32_H */ diff --git a/usr/src/cmd/ssh/include/deattack.h b/usr/src/cmd/ssh/include/deattack.h deleted file mode 100644 index fa7fc82312..0000000000 --- a/usr/src/cmd/ssh/include/deattack.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $OpenBSD: deattack.h,v 1.7 2001/06/26 17:27:23 markus Exp $ */ - -#ifndef _DEATTACK_H -#define _DEATTACK_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Cryptographic attack detector for ssh - Header file - * - * 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> - */ - -/* Return codes */ -#define DEATTACK_OK 0 -#define DEATTACK_DETECTED 1 -#define DEATTACK_DOS_DETECTED 2 - -int detect_attack(u_char *, u_int32_t, u_char[8]); - -#ifdef __cplusplus -} -#endif - -#endif /* _DEATTACK_H */ diff --git a/usr/src/cmd/ssh/include/defines.h b/usr/src/cmd/ssh/include/defines.h deleted file mode 100644 index 13eb012162..0000000000 --- a/usr/src/cmd/ssh/include/defines.h +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c) 1999-2003 Damien Miller. 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 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _DEFINES_H -#define _DEFINES_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* $Id: defines.h,v 1.96 2002/09/26 00:38:48 tim Exp $ */ - - -/* Constants */ -#ifndef SHUT_RDWR -enum -{ - SHUT_RD = 0, /* No more receptions. */ - SHUT_WR, /* No more transmissions. */ - SHUT_RDWR /* No more receptions or transmissions. */ -}; -#define SHUT_RD SHUT_RD -#define SHUT_WR SHUT_WR -#define SHUT_RDWR SHUT_RDWR -#endif - -#ifndef IPTOS_LOWDELAY -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_LOWCOST 0x02 -#define IPTOS_MINCOST IPTOS_LOWCOST -#endif /* IPTOS_LOWDELAY */ - -#ifndef MAXPATHLEN -#ifdef PATH_MAX -#define MAXPATHLEN PATH_MAX -#else /* PATH_MAX */ -#define MAXPATHLEN 64 /* Should be safe */ -#endif /* PATH_MAX */ -#endif /* MAXPATHLEN */ - -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif - -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif - -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif - -/* Disable groupaccess if NGROUPS_UMAX, NGROUPS_MAX and NGROUPS are not set */ -#ifndef NGROUPS_UMAX -#ifdef NGROUPS_MAX -#define NGROUPS_UMAX NGROUPS_MAX -#elif defined(NGROUPS) -#define NGROUPS_UMAX NGROUPS -#else -#define NGROUPS_UMAX 0 -#endif -#endif - -#ifndef O_NONBLOCK /* Non Blocking Open */ -#define O_NONBLOCK 00004 -#endif - -#ifndef S_ISDIR -#define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) -#endif /* S_ISDIR */ - -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) -#endif /* S_ISREG */ - -#ifndef S_ISLNK -#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -#endif /* S_ISLNK */ - -#ifndef S_IXUSR -#define S_IXUSR 0000100 /* execute/search permission, */ -#define S_IXGRP 0000010 /* execute/search permission, */ -#define S_IXOTH 0000001 /* execute/search permission, */ -#define _S_IWUSR 0000200 /* write permission, */ -#define S_IWUSR _S_IWUSR /* write permission, owner */ -#define S_IWGRP 0000020 /* write permission, group */ -#define S_IWOTH 0000002 /* write permission, other */ -#define S_IRUSR 0000400 /* read permission, owner */ -#define S_IRGRP 0000040 /* read permission, group */ -#define S_IROTH 0000004 /* read permission, other */ -#define S_IRWXU 0000700 /* read, write, execute */ -#define S_IRWXG 0000070 /* read, write, execute */ -#define S_IRWXO 0000007 /* read, write, execute */ -#endif /* S_IXUSR */ - -#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) -#define MAP_ANON MAP_ANONYMOUS -#endif - -#ifndef MAP_FAILED -#define MAP_FAILED ((void *)-1) -#endif - -/* *-*-nto-qnx doesn't define this constant in the system headers */ -#ifdef MISSING_NFDBITS -#define NFDBITS (8 * sizeof (unsigned long)) -#endif - -/* - * SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but including - * rpc/rpc.h breaks Solaris 6 - */ -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK ((ulong_t)0x7f000001) -#endif - -/* Types */ - -/* - * If sys/types.h does not supply intXX_t, supply them ourselves (or die trying) - */ -#ifndef HAVE_U_INT -/* for now, we can't remove u_int without changing almost all other files */ -/* CSTYLED */ -typedef unsigned int u_int; -#endif - -#ifndef HAVE_INTXX_T -#if (SIZEOF_CHAR == 1) -typedef char int8_t; -#else -#error "8 bit int type not found." -#endif -#if (SIZEOF_SHORT_INT == 2) -typedef short int int16_t; -#else -#ifdef _UNICOS -#if (SIZEOF_SHORT_INT == 4) -typedef short int16_t; -#else -typedef long int16_t; -#endif -#else -#error "16 bit int type not found." -#endif /* _UNICOS */ -#endif -#if (SIZEOF_INT == 4) -typedef int int32_t; -#else -#ifdef _UNICOS -typedef long int32_t; -#else -#error "32 bit int type not found." -#endif /* _UNICOS */ -#endif -#endif - -/* If sys/types.h does not supply u_intXX_t, supply them ourselves */ -#ifndef HAVE_U_INTXX_T -#ifdef HAVE_UINTXX_T -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; -#define HAVE_U_INTXX_T 1 -#else -#if (SIZEOF_CHAR == 1) -typedef unsigned char u_int8_t; -#else -#error "8 bit int type not found." -#endif -#if (SIZEOF_SHORT_INT == 2) -typedef unsigned short int u_int16_t; -#else -#ifdef _UNICOS -#if (SIZEOF_SHORT_INT == 4) -typedef unsigned short u_int16_t; -#else -typedef unsigned long u_int16_t; -#endif -#else -#error "16 bit int type not found." -#endif -#endif -#if (SIZEOF_INT == 4) -typedef unsigned int u_int32_t; -#else -#ifdef _UNICOS -typedef unsigned long u_int32_t; -#else -#error "32 bit int type not found." -#endif -#endif -#endif -#define __BIT_TYPES_DEFINED__ -#endif - -/* 64-bit types */ -#ifndef HAVE_INT64_T -#if (SIZEOF_LONG_INT == 8) -typedef long int int64_t; -#define HAVE_INT64_T 1 -#else -#if (SIZEOF_LONG_LONG_INT == 8) -typedef long long int int64_t; -#define HAVE_INT64_T 1 -#endif -#endif -#endif - -#ifndef HAVE_U_INT64_T -#if (SIZEOF_LONG_INT == 8) -typedef unsigned long int u_int64_t; -#define HAVE_U_INT64_T 1 -#else -#if (SIZEOF_LONG_LONG_INT == 8) -typedef unsigned long long int u_int64_t; -#define HAVE_U_INT64_T 1 -#endif -#endif -#endif - -#if !defined(HAVE_LONG_LONG_INT) && (SIZEOF_LONG_LONG_INT == 8) -#define HAVE_LONG_LONG_INT 1 -#endif - -#ifndef HAVE_U_CHAR -/* for now, we can't remove u_char without changing almost all other files */ -/* CSTYLED */ -typedef unsigned char u_char; -#define HAVE_U_CHAR -#endif /* HAVE_U_CHAR */ - -#ifndef SIZE_T_MAX -#define SIZE_T_MAX ULONG_MAX -#endif /* SIZE_T_MAX */ - -#ifndef HAVE_SIZE_T -typedef unsigned int size_t; -#define HAVE_SIZE_T -#endif /* HAVE_SIZE_T */ - -#ifndef HAVE_SSIZE_T -typedef int ssize_t; -#define HAVE_SSIZE_T -#endif /* HAVE_SSIZE_T */ - -#ifndef HAVE_CLOCK_T -typedef long clock_t; -#define HAVE_CLOCK_T -#endif /* HAVE_CLOCK_T */ - -#ifndef HAVE_SA_FAMILY_T -typedef int sa_family_t; -#define HAVE_SA_FAMILY_T -#endif /* HAVE_SA_FAMILY_T */ - -#ifndef HAVE_PID_T -typedef int pid_t; -#define HAVE_PID_T -#endif /* HAVE_PID_T */ - -#ifndef HAVE_SIG_ATOMIC_T -typedef int sig_atomic_t; -#define HAVE_SIG_ATOMIC_T -#endif /* HAVE_SIG_ATOMIC_T */ - -#ifndef HAVE_MODE_T -typedef int mode_t; -#define HAVE_MODE_T -#endif /* HAVE_MODE_T */ - -#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS) -#define ss_family __ss_family -#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */ - -#ifndef HAVE_SYS_UN_H -struct sockaddr_un { - short sun_family; /* AF_UNIX */ - char sun_path[108]; /* path name (gag) */ -}; -#endif /* HAVE_SYS_UN_H */ - -#if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE) -#define _STRUCT_WINSIZE -struct winsize { - unsigned short ws_row; /* rows, in characters */ - unsigned short ws_col; /* columns, in character */ - unsigned short ws_xpixel; /* horizontal size, pixels */ - unsigned short ws_ypixel; /* vertical size, pixels */ -}; -#endif - -/* *-*-nto-qnx does not define this type in the system headers */ -#ifdef MISSING_FD_MASK -typedef unsigned long int fd_mask; -#endif - -/* Paths */ - -#ifndef _PATH_BSHELL -#define _PATH_BSHELL "/bin/sh" -#endif - -#ifndef _PATH_CSHELL -#define _PATH_CSHELL "/bin/csh" -#endif - -#ifndef _PATH_SHELLS -#define _PATH_SHELLS "/etc/shells" -#endif - -#ifdef USER_PATH -#ifdef _PATH_STDPATH -#undef _PATH_STDPATH -#endif -#define _PATH_STDPATH USER_PATH -#endif - -#ifndef _PATH_STDPATH -#define _PATH_STDPATH "/usr/bin" -#endif - -#ifndef _PATH_DEVNULL -#define _PATH_DEVNULL "/dev/null" -#endif - -#ifndef MAIL_DIRECTORY -#define MAIL_DIRECTORY "/var/spool/mail" -#endif - -#ifndef MAILDIR -#define MAILDIR MAIL_DIRECTORY -#endif - -#if !defined(_PATH_MAILDIR) && defined(MAILDIR) -#define _PATH_MAILDIR MAILDIR -#endif /* !defined(_PATH_MAILDIR) && defined(MAILDIR) */ - -#ifndef _PATH_RSH -#ifdef RSH_PATH -#define _PATH_RSH RSH_PATH -#else /* RSH_PATH */ -#define _PATH_RSH "/usr/bin/rsh" -#endif /* RSH_PATH */ -#endif /* _PATH_RSH */ - -#ifndef _PATH_NOLOGIN -#define _PATH_NOLOGIN "/etc/nologin" -#endif - -/* Define this to be the path of the xauth program. */ -#ifdef XAUTH_PATH -#define _PATH_XAUTH XAUTH_PATH -#endif /* XAUTH_PATH */ - -/* derived from XF4/xc/lib/dps/Xlibnet.h */ -#ifndef X_UNIX_PATH -#ifdef __hpux -#define X_UNIX_PATH "/var/spool/sockets/X11/%u" -#else -#define X_UNIX_PATH "/tmp/.X11-unix/X%u" -#endif -#endif /* X_UNIX_PATH */ - -#define _PATH_UNIX_X X_UNIX_PATH - -#ifndef _PATH_TTY -#define _PATH_TTY "/dev/tty" -#endif - -/* Macros */ - -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef roundup -#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -#endif - -#ifndef timersub -#define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) -#endif - -#ifndef __P -#define __P(x) x -#endif - -#if !defined(IN6_IS_ADDR_V4MAPPED) -#define IN6_IS_ADDR_V4MAPPED(a) \ - ((((u_int32_t *)(a))[0] == 0) && (((u_int32_t *)(a))[1] == 0) && \ - (((u_int32_t *)(a))[2] == htonl(0xffff))) -#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */ - -#if !defined(__GNUC__) || (__GNUC__ < 2) -#define __attribute__(x) -#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ - -#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__bounded__) -#define __bounded__(x, y, z) -#endif - -/* *-*-nto-qnx doesn't define this macro in the system headers */ -#ifdef MISSING_HOWMANY -#define howmany(x, y) (((x) + ((y) - 1)) / (y)) -#endif - -#ifndef OSSH_ALIGNBYTES -#define OSSH_ALIGNBYTES (sizeof (int) - 1) -#endif - -#ifndef __CMSG_ALIGN -#define __CMSG_ALIGN(p) (((uint_t)(p) + OSSH_ALIGNBYTES) &~ OSSH_ALIGNBYTES) -#endif - -/* Length of the contents of a control message of length len */ -#ifndef CMSG_LEN -#define CMSG_LEN(len) (__CMSG_ALIGN(sizeof (struct cmsghdr)) + (len)) -#endif - -/* Length of the space taken up by a padded control message of length len */ -#ifndef CMSG_SPACE -#define CMSG_SPACE(len) \ - (__CMSG_ALIGN(sizeof (struct cmsghdr)) + __CMSG_ALIGN(len)) -#endif - -/* Function replacement / compatibility hacks */ - -#if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || \ - defined(HAVE_NGETADDRINFO)) -#define HAVE_GETADDRINFO -#endif - -#ifndef HAVE_GETOPT_OPTRESET -#undef getopt -#undef opterr -#undef optind -#undef optopt -#undef optreset -#undef optarg -#define getopt(ac, av, o) BSDgetopt(ac, av, o) -#define opterr BSDopterr -#define optind BSDoptind -#define optopt BSDoptopt -#define optreset BSDoptreset -#define optarg BSDoptarg -#endif - -/* In older versions of libpam, pam_strerror takes a single argument */ -#ifdef HAVE_OLD_PAM -#define PAM_STRERROR(a, b) pam_strerror((b)) -#else -#define PAM_STRERROR(a, b) pam_strerror((a), (b)) -#endif - -#ifdef PAM_SUN_CODEBASE -#define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member) -#else -#define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member) -#endif - -#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) -#undef HAVE_GETADDRINFO -#endif - -#if defined(BROKEN_GETADDRINFO) && defined(HAVE_FREEADDRINFO) -#undef HAVE_FREEADDRINFO -#endif - -#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GAI_STRERROR) -#undef HAVE_GAI_STRERROR -#endif - -#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) -#define memmove(s1, s2, n) bcopy((s2), (s1), (n)) -#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */ - -#if defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) -#define USE_VHANGUP -#endif /* defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) */ - -#ifndef GETPGRP_VOID -#define getpgrp() getpgrp(0) -#endif - -/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */ -#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f) -#define OPENSSL_free(x) Free(x) -#endif - -#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) -#define __func__ __FUNCTION__ -#elif !defined(HAVE___func__) -#define __func__ "" -#endif - -/* - * login recorder definitions - */ - -/* FIXME: put default paths back in */ -#ifndef UTMP_FILE -#ifdef _PATH_UTMP -#define UTMP_FILE _PATH_UTMP -#else -#ifdef CONF_UTMP_FILE -#define UTMP_FILE CONF_UTMP_FILE -#endif -#endif -#endif - -#ifndef WTMP_FILE -#ifdef _PATH_WTMP -#define WTMP_FILE _PATH_WTMP -#else -#ifdef CONF_WTMP_FILE -#define WTMP_FILE CONF_WTMP_FILE -#endif -#endif -#endif - -/* pick up the user's location for lastlog if given */ -#ifndef LASTLOG_FILE -#ifdef _PATH_LASTLOG -#define LASTLOG_FILE _PATH_LASTLOG -#else -#ifdef CONF_LASTLOG_FILE -#define LASTLOG_FILE CONF_LASTLOG_FILE -#endif -#endif -#endif - -/* The login() library function in libutil is first choice */ -#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN) -#define USE_LOGIN -#else -/* Simply select your favourite login types. */ -/* Can't do if-else because some systems use several... <sigh> */ -#if defined(UTMPX_FILE) && !defined(DISABLE_UTMPX) -#define USE_UTMPX -#endif -#if defined(UTMP_FILE) && !defined(DISABLE_UTMP) -#define USE_UTMP -#endif -#if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX) -#define USE_WTMPX -#endif -#if defined(WTMP_FILE) && !defined(DISABLE_WTMP) -#define USE_WTMP -#endif -#endif - -/* I hope that the presence of LASTLOG_FILE is enough to detect this */ -#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG) -#define USE_LASTLOG -#endif - -/* end of login recorder definitions */ - -#ifdef __cplusplus -} -#endif - -#endif /* _DEFINES_H */ diff --git a/usr/src/cmd/ssh/include/dh.h b/usr/src/cmd/ssh/include/dh.h deleted file mode 100644 index e977847119..0000000000 --- a/usr/src/cmd/ssh/include/dh.h +++ /dev/null @@ -1,60 +0,0 @@ -/* $OpenBSD: dh.h,v 1.7 2001/06/26 17:27:23 markus Exp $ */ - -#ifndef _DH_H -#define _DH_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Copyright (c) 2000 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. - */ - -struct dhgroup { - int size; - BIGNUM *g; - BIGNUM *p; -}; - -DH *choose_dh(int, int, int); -DH *dh_new_group_asc(const char *, const char *); -DH *dh_new_group(BIGNUM *, BIGNUM *); -DH *dh_new_group1(void); - -void dh_gen_key(DH *, int); -int dh_pub_is_valid(DH *, BIGNUM *); - -int dh_estimate(int); - -#define DH_GRP_MIN 1024 -#define DH_GRP_MAX 8192 - -#ifdef __cplusplus -} -#endif - -#endif /* _DH_H */ diff --git a/usr/src/cmd/ssh/include/dirname.h b/usr/src/cmd/ssh/include/dirname.h deleted file mode 100644 index 4201e3399d..0000000000 --- a/usr/src/cmd/ssh/include/dirname.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * XXX - Add OpenSSH copyright... - */ - -#ifndef _DIRNAME_H -#define _DIRNAME_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef HAVE_DIRNAME - -char *dirname(const char *path); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _DIRNAME_H */ diff --git a/usr/src/cmd/ssh/include/dispatch.h b/usr/src/cmd/ssh/include/dispatch.h deleted file mode 100644 index 9262c9a034..0000000000 --- a/usr/src/cmd/ssh/include/dispatch.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $OpenBSD: dispatch.h,v 1.9 2002/01/11 13:39:36 markus Exp $ */ - -#ifndef _DISPATCH_H -#define _DISPATCH_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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 -}; - -typedef void dispatch_fn(int, u_int32_t, void *); - -void dispatch_init(dispatch_fn *); -void dispatch_set(int, dispatch_fn *); -void dispatch_range(u_int, u_int, dispatch_fn *); -void dispatch_run(int, int *, void *); -void dispatch_protocol_error(int, u_int32_t, void *); -void dispatch_protocol_ignore(int, u_int32_t, void *); - -#ifdef __cplusplus -} -#endif - -#endif /* _DISPATCH_H */ diff --git a/usr/src/cmd/ssh/include/engine.h b/usr/src/cmd/ssh/include/engine.h deleted file mode 100644 index 74ee80db01..0000000000 --- a/usr/src/cmd/ssh/include/engine.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _ENGINE_H -#define _ENGINE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "includes.h" -#include <openssl/engine.h> - -ENGINE *pkcs11_engine_load(int use_engine); -void pkcs11_engine_finish(void *engine); - -#ifdef __cplusplus -} -#endif - -#endif /* _ENGINE_H */ diff --git a/usr/src/cmd/ssh/include/entropy.h b/usr/src/cmd/ssh/include/entropy.h deleted file mode 100644 index 79a2884eca..0000000000 --- a/usr/src/cmd/ssh/include/entropy.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 1999-2000 Damien Miller. 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 _ENTROPY_H -#define _ENTROPY_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* $Id: entropy.h,v 1.4 2001/02/09 01:55:36 djm Exp $ */ - -void seed_rng(void); -void init_rng(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _ENTROPY_H */ diff --git a/usr/src/cmd/ssh/include/fake-gai-errnos.h b/usr/src/cmd/ssh/include/fake-gai-errnos.h deleted file mode 100644 index 8df9159f18..0000000000 --- a/usr/src/cmd/ssh/include/fake-gai-errnos.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * fake library for ssh - * - * This file is included in getaddrinfo.c and getnameinfo.c. - * See getaddrinfo.c and getnameinfo.c. - */ - -#ifndef _FAKE_GAI_ERRNOS_H -#define _FAKE_GAI_ERRNOS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* $Id: fake-gai-errnos.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -/* for old netdb.h */ -#ifndef EAI_NODATA -#define EAI_NODATA 1 -#define EAI_MEMORY 2 -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _FAKE_GAI_ERRNOS_H */ diff --git a/usr/src/cmd/ssh/include/fake-getaddrinfo.h b/usr/src/cmd/ssh/include/fake-getaddrinfo.h deleted file mode 100644 index b5a1a6441e..0000000000 --- a/usr/src/cmd/ssh/include/fake-getaddrinfo.h +++ /dev/null @@ -1,57 +0,0 @@ -/* $Id: fake-getaddrinfo.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _FAKE_GETADDRINFO_H -#define _FAKE_GETADDRINFO_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#include "fake-gai-errnos.h" - -#ifndef AI_PASSIVE -# define AI_PASSIVE 1 -# define AI_CANONNAME 2 -#endif - -#ifndef NI_NUMERICHOST -# define NI_NUMERICHOST 2 -# define NI_NAMEREQD 4 -# define NI_NUMERICSERV 8 -#endif - -#ifndef HAVE_STRUCT_ADDRINFO -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif /* !HAVE_STRUCT_ADDRINFO */ - -#ifndef HAVE_GETADDRINFO -int getaddrinfo(const char *hostname, const char *servname, - const struct addrinfo *hints, struct addrinfo **res); -#endif /* !HAVE_GETADDRINFO */ - -#ifndef HAVE_GAI_STRERROR -char *gai_strerror(int ecode); -#endif /* !HAVE_GAI_STRERROR */ - -#ifndef HAVE_FREEADDRINFO -void freeaddrinfo(struct addrinfo *ai); -#endif /* !HAVE_FREEADDRINFO */ - -#ifdef __cplusplus -} -#endif - -#endif /* _FAKE_GETADDRINFO_H */ diff --git a/usr/src/cmd/ssh/include/fake-getnameinfo.h b/usr/src/cmd/ssh/include/fake-getnameinfo.h deleted file mode 100644 index 2527882ad0..0000000000 --- a/usr/src/cmd/ssh/include/fake-getnameinfo.h +++ /dev/null @@ -1,30 +0,0 @@ -/* $Id: fake-getnameinfo.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _FAKE_GETNAMEINFO_H -#define _FAKE_GETNAMEINFO_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#ifndef HAVE_GETNAMEINFO -int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, - size_t hostlen, char *serv, size_t servlen, int flags); -#endif /* !HAVE_GETNAMEINFO */ - -#ifndef NI_MAXSERV -# define NI_MAXSERV 32 -#endif /* !NI_MAXSERV */ -#ifndef NI_MAXHOST -# define NI_MAXHOST 1025 -#endif /* !NI_MAXHOST */ - -#ifdef __cplusplus -} -#endif - -#endif /* _FAKE_GETNAMEINFO_H */ diff --git a/usr/src/cmd/ssh/include/fake-socket.h b/usr/src/cmd/ssh/include/fake-socket.h deleted file mode 100644 index 30444dd91c..0000000000 --- a/usr/src/cmd/ssh/include/fake-socket.h +++ /dev/null @@ -1,56 +0,0 @@ -/* $Id: fake-socket.h,v 1.3 2002/04/12 03:35:40 tim Exp $ */ - -#ifndef _FAKE_SOCKET_H -#define _FAKE_SOCKET_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "includes.h" -#include "sys/types.h" - -#ifndef HAVE_STRUCT_SOCKADDR_STORAGE -# define _SS_MAXSIZE 128 /* Implementation specific max size */ -# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) - -struct sockaddr_storage { - struct sockaddr ss_sa; - char __ss_pad2[_SS_PADSIZE]; -}; -# define ss_family ss_sa.sa_family -#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ - -#ifndef IN6_IS_ADDR_LOOPBACK -# define IN6_IS_ADDR_LOOPBACK(a) \ - (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ - ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) -#endif /* !IN6_IS_ADDR_LOOPBACK */ - -#ifndef HAVE_STRUCT_IN6_ADDR -struct in6_addr { - u_int8_t s6_addr[16]; -}; -#endif /* !HAVE_STRUCT_IN6_ADDR */ - -#ifndef HAVE_STRUCT_SOCKADDR_IN6 -struct sockaddr_in6 { - unsigned short sin6_family; - u_int16_t sin6_port; - u_int32_t sin6_flowinfo; - struct in6_addr sin6_addr; -}; -#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ - -#ifndef AF_INET6 -/* Define it to something that should never appear */ -#define AF_INET6 AF_MAX -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _FAKE_SOCKET_H */ diff --git a/usr/src/cmd/ssh/include/g11n.h b/usr/src/cmd/ssh/include/g11n.h deleted file mode 100644 index 64acf8e630..0000000000 --- a/usr/src/cmd/ssh/include/g11n.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _G11N_H -#define _G11N_H - -#ifdef __cplusplus -extern "C" { -#endif - - -#include "includes.h" -#include <sys/types.h> - -/* - * Functions for language tag negotiation - */ - -/* boolean */ -uint_t g11n_langtag_is_default(char *langtag); - -/* return 0 if not, 1 if yes, 2 if the country is matched too */ -uint_t g11n_langtag_matches_locale(char *langtag, char *locale); - -/* get current locale */ -char *g11n_getlocale(); - -/* get current locale */ -void g11n_setlocale(int category, const char *locale); - -/* get list of locales - returns pointer to array of pointers to char */ -char **g11n_getlocales(); - -/* get list of langs spoken by the user, from SSH_LANGS env var */ -char *g11n_getlangs(); - -/* make a comma-separated list of language tags from list of locales */ -char *g11n_locales2langs(char **locale_set); - -int g11n_langtag_match(char *langtag1, char *langtag2); - -/* intersect comma-separated lists of IETF language tags */ -char *g11n_langtag_set_intersect(char *set1, char *set2); - -char *g11n_clnt_langtag_negotiate(char *clnt_langtags, char *srvr_langtags); - -char **g11n_langtag_set_locale_set_intersect(char *langtag_set, - char **locale_set); - -char *g11n_srvr_locale_negotiate(char *clnt_langtags, char **srvr_locales); - -/* auxiliary functions */ -void g11n_freelist(char **list); - -/* - * Functions for converting to ASCII or UTF-8 from the local codeset - * Functions for converting from ASCII or UTF-8 to the local codeset - * - * The error_str parameter is an optional pointer to a char variable - * where to store a string suitable for use with error() or fatal() or - * friends. - * - */ -extern char *g11n_convert_from_utf8(const char *str, uint_t *lenp, - char **error_str); - -extern char *g11n_convert_to_utf8(const char *str, uint_t *lenp, int native, - char **error_str); - -extern char *g11n_filter_string(char *); -extern void g11n_test_langtag(const char *, int); - -#ifdef __cplusplus -} -#endif - -#endif /* _G11N_H */ diff --git a/usr/src/cmd/ssh/include/getcwd.h b/usr/src/cmd/ssh/include/getcwd.h deleted file mode 100644 index 2d9069e6e4..0000000000 --- a/usr/src/cmd/ssh/include/getcwd.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Id: getcwd.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _GETCWD_H -#define _GETCWD_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#if !defined(HAVE_GETCWD) - -char *getcwd(char *pt, size_t size); - -#endif /* !defined(HAVE_GETCWD) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETCWD_H */ diff --git a/usr/src/cmd/ssh/include/getgrouplist.h b/usr/src/cmd/ssh/include/getgrouplist.h deleted file mode 100644 index 587402800f..0000000000 --- a/usr/src/cmd/ssh/include/getgrouplist.h +++ /dev/null @@ -1,26 +0,0 @@ -/* $Id: getgrouplist.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _GETGROUPLIST_H -#define _GETGROUPLIST_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#ifndef HAVE_GETGROUPLIST - -#include <grp.h> - -int getgrouplist(const char *, gid_t, gid_t *, int *); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _GETGROUPLIST_H */ diff --git a/usr/src/cmd/ssh/include/getopt.h b/usr/src/cmd/ssh/include/getopt.h deleted file mode 100644 index 7ae4576d0c..0000000000 --- a/usr/src/cmd/ssh/include/getopt.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Id: getopt.h,v 1.4 2001/09/18 05:05:21 djm Exp $ */ - -#ifndef _GETOPT_H -#define _GETOPT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) - -int BSDgetopt(int argc, char * const *argv, const char *opts); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/usr/src/cmd/ssh/include/getput.h b/usr/src/cmd/ssh/include/getput.h deleted file mode 100644 index 1a33883507..0000000000 --- a/usr/src/cmd/ssh/include/getput.h +++ /dev/null @@ -1,69 +0,0 @@ -/* $OpenBSD: getput.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _GETPUT_H -#define _GETPUT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ - -/*------------ macros for storing/extracting msb first words -------------*/ - -#define GET_64BIT(cp) (((u_int64_t)(u_char)(cp)[0] << 56) | \ - ((u_int64_t)(u_char)(cp)[1] << 48) | \ - ((u_int64_t)(u_char)(cp)[2] << 40) | \ - ((u_int64_t)(u_char)(cp)[3] << 32) | \ - ((u_int64_t)(u_char)(cp)[4] << 24) | \ - ((u_int64_t)(u_char)(cp)[5] << 16) | \ - ((u_int64_t)(u_char)(cp)[6] << 8) | \ - ((u_int64_t)(u_char)(cp)[7])) - -#define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \ - ((u_long)(u_char)(cp)[1] << 16) | \ - ((u_long)(u_char)(cp)[2] << 8) | \ - ((u_long)(u_char)(cp)[3])) - -#define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \ - ((u_long)(u_char)(cp)[1])) - -#define PUT_64BIT(cp, value) do { \ - (cp)[0] = (value) >> 56; \ - (cp)[1] = (value) >> 48; \ - (cp)[2] = (value) >> 40; \ - (cp)[3] = (value) >> 32; \ - (cp)[4] = (value) >> 24; \ - (cp)[5] = (value) >> 16; \ - (cp)[6] = (value) >> 8; \ - (cp)[7] = (value); } while (0) - -#define PUT_32BIT(cp, value) do { \ - (cp)[0] = (value) >> 24; \ - (cp)[1] = (value) >> 16; \ - (cp)[2] = (value) >> 8; \ - (cp)[3] = (value); } while (0) - -#define PUT_16BIT(cp, value) do { \ - (cp)[0] = (value) >> 8; \ - (cp)[1] = (value); } while (0) - -#ifdef __cplusplus -} -#endif - -#endif /* _GETPUT_H */ diff --git a/usr/src/cmd/ssh/include/groupaccess.h b/usr/src/cmd/ssh/include/groupaccess.h deleted file mode 100644 index bc40898888..0000000000 --- a/usr/src/cmd/ssh/include/groupaccess.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $OpenBSD: groupaccess.h,v 1.4 2001/06/26 17:27:23 markus Exp $ */ - -#ifndef _GROUPACCESS_H -#define _GROUPACCESS_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Copyright (c) 2001 Kevin Steves. 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 <grp.h> - -int ga_init(const char *, gid_t); -int ga_match(char * const *, int); -int ga_match_pattern_list(const char *); -void ga_free(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _GROUPACCESS_H */ diff --git a/usr/src/cmd/ssh/include/hostfile.h b/usr/src/cmd/ssh/include/hostfile.h deleted file mode 100644 index 3a2c7e6a06..0000000000 --- a/usr/src/cmd/ssh/include/hostfile.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 - -/* $OpenBSD: hostfile.h,v 1.12 2002/09/08 20:24:08 markus Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - HOST_OK, HOST_NEW, HOST_CHANGED, HOST_FOUND -} HostStatus; - -int hostfile_read_key(char **, u_int *, Key *); -HostStatus -check_host_in_hostfile(const char *, const char *, const Key *, Key *, int *); -int add_host_to_hostfile(const char *, const char *, const Key *, int); -int -lookup_key_in_hostfile_by_type(const char *, const char *, int , Key *, int *); - -#define HASH_MAGIC "|1|" -#define HASH_DELIM '|' - -char *host_hash(const char *, const char *, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _HOSTFILE_H */ diff --git a/usr/src/cmd/ssh/include/includes.h b/usr/src/cmd/ssh/include/includes.h deleted file mode 100644 index ecd55ea737..0000000000 --- a/usr/src/cmd/ssh/include/includes.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _INCLUDES_H -#define _INCLUDES_H - -/* $OpenBSD: includes.h,v 1.17 2002/01/26 16:44:22 stevesk Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RCSID(msg) \ -static const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } - -#include "config.h" - -#include <stdio.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> /* For O_NONBLOCK */ -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <pwd.h> -#include <grp.h> -#include <time.h> -#include <dirent.h> -#include <libintl.h> -#include <locale.h> - -#ifdef HAVE_LIMITS_H -#include <limits.h> /* For PATH_MAX */ -#endif - -#ifdef HAVE_GETOPT_H -#include <getopt.h> -#endif - -#ifdef HAVE_BSTRING_H -#include <bstring.h> -#endif - -#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ - defined(GLOB_HAS_GL_MATCHC) -#include <glob.h> -#endif - -#ifdef HAVE_NETGROUP_H -#include <netgroup.h> -#endif - -#if defined(HAVE_NETDB_H) -#include <netdb.h> -#endif - -#ifdef HAVE_ENDIAN_H -#include <endian.h> -#endif - -#ifdef HAVE_TTYENT_H -#include <ttyent.h> -#endif - -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif - -#ifdef HAVE_MAILLOCK_H -#include <maillock.h> /* For _PATH_MAILDIR */ -#endif - -#include <unistd.h> /* For STDIN_FILENO, etc */ -#include <termios.h> /* Struct winsize */ - -/* - * *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE - * respectively - */ -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif - -#ifdef HAVE_LOGIN_H -#include <login.h> -#endif - -#ifdef HAVE_UCRED_H -#include <ucred.h> -#endif - -#ifdef HAVE_UTMP_H -#include <utmp.h> -#endif - -#ifdef HAVE_UTMPX_H -#ifdef HAVE_TV_IN_UTMPX -#include <sys/time.h> -#endif -#include <utmpx.h> -#endif - -#ifdef HAVE_LASTLOG_H -#include <lastlog.h> -#endif - -#ifdef HAVE_PATHS_H -#include <paths.h> /* For _PATH_XXX */ -#endif - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/wait.h> - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> /* For timersub */ -#endif - -#include <sys/resource.h> -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#ifdef HAVE_SYS_BSDTTY_H -#include <sys/bsdtty.h> -#endif - -#include <sys/param.h> /* For MAXPATHLEN and roundup() */ -#ifdef HAVE_SYS_UN_H -#include <sys/un.h> /* For sockaddr_un */ -#endif - -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif - -#ifdef HAVE_SYS_BITYPES_H -#include <sys/bitypes.h> /* For u_intXX_t */ -#endif - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> /* For __P() */ -#endif - -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> /* For S_* constants and macros */ -#endif - -#ifdef HAVE_SYS_SYSMACROS_H -#include <sys/sysmacros.h> /* For MIN, MAX, etc */ -#endif - -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> /* for MAP_ANONYMOUS */ -#endif - -#include <netinet/in_systm.h> /* For typedefs */ -#include <netinet/in.h> /* For IPv6 macros */ -#include <netinet/ip.h> /* For IPTOS macros */ -#include <netinet/tcp.h> -#include <arpa/inet.h> - -#ifdef HAVE_RPC_TYPES_H -#include <rpc/types.h> /* For INADDR_LOOPBACK */ -#endif - -#ifdef USE_PAM -#include <security/pam_appl.h> -#endif - -#ifdef HAVE_READPASSPHRASE_H -#include <readpassphrase.h> -#endif - -#ifdef HAVE_IA_H -#include <ia.h> -#endif - -#ifdef HAVE_TMPDIR_H -#include <tmpdir.h> -#endif - -#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */ - -#include "defines.h" - -#include "version.h" -#include "openbsd-compat.h" -#include "bsd-cygwin_util.h" - -#include "entropy.h" -#include "g11n.h" - -#ifdef __cplusplus -} -#endif - -#endif /* _INCLUDES_H */ diff --git a/usr/src/cmd/ssh/include/inet_ntoa.h b/usr/src/cmd/ssh/include/inet_ntoa.h deleted file mode 100644 index b491398f7f..0000000000 --- a/usr/src/cmd/ssh/include/inet_ntoa.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Id: inet_ntoa.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _INET_NTOA_H -#define _INET_NTOA_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) -char *inet_ntoa(struct in_addr in); -#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _INET_NTOA_H */ diff --git a/usr/src/cmd/ssh/include/inet_ntop.h b/usr/src/cmd/ssh/include/inet_ntop.h deleted file mode 100644 index 91005955f8..0000000000 --- a/usr/src/cmd/ssh/include/inet_ntop.h +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: inet_ntop.h,v 1.4 2001/08/09 00:56:53 mouring Exp $ */ - -#ifndef _INET_NTOP_H -#define _INET_NTOP_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#ifndef HAVE_INET_NTOP -const char * -inet_ntop(int af, const void *src, char *dst, size_t size); -#endif /* !HAVE_INET_NTOP */ - -#ifdef __cplusplus -} -#endif - -#endif /* _INET_NTOP_H */ diff --git a/usr/src/cmd/ssh/include/kex.h b/usr/src/cmd/ssh/include/kex.h deleted file mode 100644 index 30a6cdb4a5..0000000000 --- a/usr/src/cmd/ssh/include/kex.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* $OpenBSD: kex.h,v 1.32 2002/09/09 14:54:14 markus Exp $ */ - -#ifndef _KEX_H -#define _KEX_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <openssl/evp.h> -#include <openssl/hmac.h> -#include "buffer.h" -#include "cipher.h" -#include "key.h" - -#ifdef GSSAPI -#ifdef SUNW_GSSAPI -#include <gssapi/gssapi.h> -#include <gssapi/gssapi_ext.h> -#else -#ifdef GSS_KRB5 -#ifdef HEIMDAL -#include <gssapi.h> -#else -#include <gssapi_generic.h> -#endif /* HEIMDAL */ -#endif /* GSS_KRB5 */ -#endif /* SUNW_GSSAPI */ -#endif /* GSSAPI */ - -#define KEX_DH1 "diffie-hellman-group1-sha1" -#define KEX_DHGEX "diffie-hellman-group-exchange-sha1" - -enum kex_init_proposals { - PROPOSAL_KEX_ALGS, - PROPOSAL_SERVER_HOST_KEY_ALGS, - PROPOSAL_ENC_ALGS_CTOS, - PROPOSAL_ENC_ALGS_STOC, - PROPOSAL_MAC_ALGS_CTOS, - PROPOSAL_MAC_ALGS_STOC, - PROPOSAL_COMP_ALGS_CTOS, - PROPOSAL_COMP_ALGS_STOC, - PROPOSAL_LANG_CTOS, - PROPOSAL_LANG_STOC, - PROPOSAL_MAX -}; - -enum kex_modes { - MODE_IN, - MODE_OUT, - MODE_MAX -}; - -enum kex_exchange { - KEX_DH_GRP1_SHA1, - KEX_DH_GEX_SHA1, -#ifdef GSSAPI - KEX_GSS_GRP1_SHA1, -#endif /* GSSAPI */ - KEX_MAX -}; - - -#define KEX_INIT_SENT 0x0001 - -typedef struct Kex Kex; -typedef struct Mac Mac; -typedef struct Comp Comp; -typedef struct Enc Enc; -typedef struct Newkeys Newkeys; - -struct Enc { - char *name; - Cipher *cipher; - int enabled; - u_int key_len; - u_int block_size; - u_char *key; - u_char *iv; -}; -struct Mac { - char *name; - int enabled; - u_int mac_len; - u_char *key; - u_int key_len; - int type; - const EVP_MD *evp_md; - HMAC_CTX evp_ctx; -}; -struct Comp { - int type; - int enabled; - char *name; -}; -struct Newkeys { - Enc enc; - Mac mac; - Comp comp; -}; - -struct KexOptions { - int gss_deleg_creds; -}; - -struct Kex { - u_char *session_id; - u_int session_id_len; - Newkeys *newkeys[MODE_MAX]; - int we_need; - int server; - char *serverhost; - char *name; - int hostkey_type; - int kex_type; - Buffer my; - Buffer peer; - int initial_kex_done; - int done; - int flags; - char *client_version_string; - char *server_version_string; - struct KexOptions options; - int (*verify_host_key)(Key *); - int (*accept_host_key)(Key *); /* for GSS keyex */ - Key *(*load_host_key)(int); - int (*host_key_index)(Key *); - void (*kex[KEX_MAX])(Kex *); - void (*kex_hook)(Kex *, char **); /* for GSS keyex rekeying */ -#ifdef GSSAPI - gss_OID_set mechs; /* mechs in my proposal */ -#endif /* GSSAPI */ -}; - -typedef void (*Kex_hook_func)(Kex *, char **); /* for GSS-API rekeying */ - -Kex *kex_setup(const char *host, - char *proposal[PROPOSAL_MAX], - Kex_hook_func hook); -void kex_start(Kex *); -void kex_finish(Kex *); - -void kex_send_kexinit(Kex *); -void kex_input_kexinit(int, u_int32_t, void *); -void kex_derive_keys(Kex *, u_char *, BIGNUM *); - -Newkeys *kex_get_newkeys(int); - -void kexdh_client(Kex *); -void kexdh_server(Kex *); -void kexgex_client(Kex *); -void kexgex_server(Kex *); - -u_char * -kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, - BIGNUM *, BIGNUM *, BIGNUM *); -u_char * -kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int, - int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *); - -#ifdef GSSAPI -void kexgss_client(Kex *); -void kexgss_server(Kex *); -#endif - -#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) -void dump_digest(char *, u_char *, int); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _KEX_H */ diff --git a/usr/src/cmd/ssh/include/key.h b/usr/src/cmd/ssh/include/key.h deleted file mode 100644 index ec4993a9c1..0000000000 --- a/usr/src/cmd/ssh/include/key.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _KEY_H -#define _KEY_H - -/* $OpenBSD: key.h,v 1.19 2002/03/18 17:23:31 markus Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -#include <openssl/rsa.h> -#include <openssl/dsa.h> - -typedef struct Key Key; -enum types { - KEY_RSA1, - KEY_RSA, - KEY_DSA, - KEY_ECDSA, - KEY_RSA_CERT, - KEY_DSA_CERT, - KEY_ECDSA_CERT, - KEY_RSA_CERT_V00, - KEY_DSA_CERT_V00, - KEY_NULL, - KEY_UNSPEC -}; -enum fp_type { - SSH_FP_SHA1, - SSH_FP_MD5 -}; -enum fp_rep { - SSH_FP_HEX, - SSH_FP_BUBBLEBABBLE -}; - -/* key is stored in external hardware */ -#define KEY_FLAG_EXT 0x0001 - -struct Key { - int type; - int flags; - RSA *rsa; - DSA *dsa; -}; - -Key *key_new(int); -Key *key_new_private(int); -void key_free(Key *); -Key *key_demote(Key *); -int key_equal(const Key *, const Key *); -char *key_fingerprint(Key *, enum fp_type, enum fp_rep); -char *key_type(Key *); -int key_write(const Key *, FILE *); -int key_read(Key *, char **); -u_int key_size(Key *); - -Key *key_generate(int, u_int); -Key *key_from_private(Key *); -int key_type_from_name(char *); - -Key *key_from_blob(u_char *, int); -int key_to_blob(const Key *, u_char **, u_int *); -char *key_ssh_name(const Key *); -int key_names_valid2(const char *); - -int key_sign(Key *, u_char **, u_int *, u_char *, u_int); -int key_verify(Key *, u_char *, u_int, u_char *, u_int); - -int key_type_plain(int type); -#ifdef __cplusplus -} -#endif - -#endif /* _KEY_H */ diff --git a/usr/src/cmd/ssh/include/log.h b/usr/src/cmd/ssh/include/log.h deleted file mode 100644 index 34bc82f5e3..0000000000 --- a/usr/src/cmd/ssh/include/log.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* $OpenBSD: log.h,v 1.8 2002/07/19 15:43:33 markus Exp $ */ - -#ifndef _LOG_H -#define _LOG_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* $OpenBSD: log.h,v 1.8 2002/07/19 15:43:33 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". - */ - -#include <syslog.h> /* Needed for LOG_AUTHPRIV (if present) */ - -/* Supported syslog facilities and levels. */ -typedef enum { - SYSLOG_FACILITY_DAEMON, - SYSLOG_FACILITY_USER, - SYSLOG_FACILITY_AUTH, -#ifdef LOG_AUTHPRIV - SYSLOG_FACILITY_AUTHPRIV, -#endif - SYSLOG_FACILITY_LOCAL0, - SYSLOG_FACILITY_LOCAL1, - SYSLOG_FACILITY_LOCAL2, - SYSLOG_FACILITY_LOCAL3, - SYSLOG_FACILITY_LOCAL4, - SYSLOG_FACILITY_LOCAL5, - SYSLOG_FACILITY_LOCAL6, - SYSLOG_FACILITY_LOCAL7, - SYSLOG_FACILITY_NOT_SET = -1 -} SyslogFacility; - -typedef enum { - SYSLOG_LEVEL_QUIET, - SYSLOG_LEVEL_FATAL, - SYSLOG_LEVEL_ERROR, - SYSLOG_LEVEL_NOTICE, - SYSLOG_LEVEL_INFO, - SYSLOG_LEVEL_VERBOSE, - SYSLOG_LEVEL_DEBUG1, - SYSLOG_LEVEL_DEBUG2, - SYSLOG_LEVEL_DEBUG3, - SYSLOG_LEVEL_NOT_SET = -1 -} LogLevel; - -void log_init(char *, LogLevel, SyslogFacility, int); - -SyslogFacility log_facility_number(char *); -LogLevel log_level_number(char *); - -void set_log_txt_prefix(const char *); -void fatal(const char *, ...) __attribute__((format(printf, 1, 2))); -void error(const char *, ...) __attribute__((format(printf, 1, 2))); -void notice(const char *, ...) __attribute__((format(printf, 1, 2))); -void log(const char *, ...) __attribute__((format(printf, 1, 2))); -void verbose(const char *, ...) __attribute__((format(printf, 1, 2))); -void debug(const char *, ...) __attribute__((format(printf, 1, 2))); -void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); -void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); - -void fatal_cleanup(void); -void fatal_add_cleanup(void (*) (void *), void *); -void fatal_remove_cleanup(void (*) (void *), void *); -void fatal_remove_all_cleanups(void); - -void do_log(LogLevel, const char *, va_list); - -#ifdef __cplusplus -} -#endif - -#endif /* _LOG_H */ diff --git a/usr/src/cmd/ssh/include/loginrec.h b/usr/src/cmd/ssh/include/loginrec.h deleted file mode 100644 index 8086d96686..0000000000 --- a/usr/src/cmd/ssh/include/loginrec.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Copyright (c) 2000 Andre Lucas. 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 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 - * 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. - */ -/* - * loginrec.h: platform-independent login recording and lastlog retrieval - */ - -#ifndef _LOGINREC_H -#define _LOGINREC_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "includes.h" - -#include <sys/types.h> -#include <netinet/in.h> -#include <sys/socket.h> - -/* RCSID("$Id: loginrec.h,v 1.6 2001/05/08 20:33:06 mouring Exp $"); */ - -/** - ** you should use the login_* calls to work around platform dependencies - **/ - -/* - * login_netinfo structure - */ - -union login_netinfo { - struct sockaddr sa; - struct sockaddr_in sa_in; - struct sockaddr_storage sa_storage; -}; - -/* - * * logininfo structure * - */ -/* types - different to utmp.h 'type' macros */ -/* (though set to the same value as linux, openbsd and others...) */ -#define LTYPE_LOGIN 7 -#define LTYPE_LOGOUT 8 - -/* string lengths - set very long */ -#define LINFO_PROGSIZE 64 -#define LINFO_LINESIZE 64 -#define LINFO_NAMESIZE 64 -#define LINFO_HOSTSIZE 256 - -struct logininfo { - int progname_null; - char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */ - short int type; /* type of login (LTYPE_*) */ - int pid; /* PID of login process */ - int uid; /* UID of this user */ - int line_null; - char line[LINFO_LINESIZE]; /* tty/pty name */ - char username[LINFO_NAMESIZE]; /* login username */ - char hostname[LINFO_HOSTSIZE]; /* remote hostname */ - /* 'exit_status' structure components */ - int exit; /* process exit status */ - int termination; /* process termination status */ - /* struct timeval (sys/time.h) isn't always available, if it isn't we'll - * use time_t's value as tv_sec and set tv_usec to 0 - */ - unsigned int tv_sec; - unsigned int tv_usec; - union login_netinfo hostaddr; /* caller's host address(es) */ -}; /* struct logininfo */ - -/* - * login recording functions - */ - -/** 'public' functions */ - -/* construct a new login entry */ -struct logininfo *login_alloc_entry(int pid, const char *username, - const char *hostname, const char *line, - const char *progname); -/* free a structure */ -void login_free_entry(struct logininfo *li); -/* fill out a pre-allocated structure with useful information */ -int login_init_entry(struct logininfo *li, int pid, const char *username, - const char *hostname, const char *line, - const char *progname); -/* place the current time in a logininfo struct */ -void login_set_current_time(struct logininfo *li); - -/* record the entry */ -int login_login (struct logininfo *li); -int login_logout(struct logininfo *li); -#ifdef LOGIN_NEEDS_UTMPX -int login_utmp_only(struct logininfo *li); -#endif - -/** End of public functions */ - -/* record the entry */ -int login_write (struct logininfo *li); -int login_log_entry(struct logininfo *li); - -/* set the network address based on network address type */ -void login_set_addr(struct logininfo *li, const struct sockaddr *sa, - const unsigned int sa_size); - -/* - * lastlog retrieval functions - */ -/* lastlog *entry* functions fill out a logininfo */ -struct logininfo *login_get_lastlog(struct logininfo *li, const int uid); -/* lastlog *time* functions return time_t equivalent (uint) */ -unsigned int login_get_lastlog_time(const int uid); - -/* produce various forms of the line filename */ -char *line_fullname(char *dst, const char *src, int dstsize); -char *line_stripname(char *dst, const char *src, int dstsize); -char *line_abbrevname(char *dst, const char *src, int dstsize); - -#ifdef __cplusplus -} -#endif - -#endif /* _LOGINREC_H */ diff --git a/usr/src/cmd/ssh/include/mac.h b/usr/src/cmd/ssh/include/mac.h deleted file mode 100644 index cc05d332ae..0000000000 --- a/usr/src/cmd/ssh/include/mac.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* $OpenBSD: mac.h,v 1.3 2001/06/26 17:27:24 markus Exp $ */ - -#ifndef _MAC_H -#define _MAC_H - -#ifdef __cplusplus -extern "C" { -#endif - -int mac_valid(const char *); -int mac_setup(Mac *, char *); -int mac_init(Mac *); -u_char *mac_compute(Mac *, u_int32_t, u_char *, int); -void mac_clear(Mac *); - -#ifdef __cplusplus -} -#endif - -#endif /* _MAC_H */ diff --git a/usr/src/cmd/ssh/include/match.h b/usr/src/cmd/ssh/include/match.h deleted file mode 100644 index 81729c33da..0000000000 --- a/usr/src/cmd/ssh/include/match.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: match.h,v 1.12 2002/03/01 13:12:10 markus Exp $ */ - -#ifndef _MATCH_H -#define _MATCH_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -int match_pattern(const char *, const char *); -int match_pattern_list(const char *, const char *, u_int, int); -int match_hostname(const char *, const char *, u_int); -int match_host_and_ip(const char *, const char *, const char *); -int match_user(const char *, const char *, const char *, const char *); -char *match_list(const char *, const char *, u_int *); - -/* addrmatch.c */ -int addr_match_list(const char *, const char *); - -#ifdef __cplusplus -} -#endif - -#endif /* _MATCH_H */ diff --git a/usr/src/cmd/ssh/include/misc.h b/usr/src/cmd/ssh/include/misc.h deleted file mode 100644 index c626301f84..0000000000 --- a/usr/src/cmd/ssh/include/misc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _MISC_H -#define _MISC_H - -/* $OpenBSD: misc.h,v 1.12 2002/03/19 10:49:35 markus Exp $ */ - -#ifdef __cplusplus -extern "C" { -#endif - -char *chop(char *); -char *strdelim(char **); -void set_nonblock(int); -void unset_nonblock(int); -void set_nodelay(int); -int a2port(const char *); -char *cleanhostname(char *); -char *hpdelim(char **); -char *colon(char *); -long convtime(const char *); -char *percent_expand(const char *, ...); -char *tohex(const void *, size_t); -void sanitise_stdfd(void); -int get_yes_no_flag(int *option, const char *arg, const char *filename, - int linenum, int active); -char *tolowercase(const char *s); - -struct passwd *pwcopy(struct passwd *); -void pwfree(struct passwd **); - -typedef struct arglist arglist; -struct arglist { - char **list; - int num; - int nalloc; -}; -void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3))); -void replacearg(arglist *, u_int, char *, ...) - __attribute__((format(printf, 3, 4))); -void freeargs(arglist *); - -/* wrapper for signal interface */ -typedef void (*mysig_t)(int); -mysig_t mysignal(int sig, mysig_t act); - -/* Functions to extract or store big-endian words of various sizes */ -u_int64_t get_u64(const void *) - __attribute__((__bounded__( __minbytes__, 1, 8))); -u_int32_t get_u32(const void *) - __attribute__((__bounded__( __minbytes__, 1, 4))); -u_int16_t get_u16(const void *) - __attribute__((__bounded__( __minbytes__, 1, 2))); -void put_u64(void *, u_int64_t) - __attribute__((__bounded__( __minbytes__, 1, 8))); -void put_u32(void *, u_int32_t) - __attribute__((__bounded__( __minbytes__, 1, 4))); -void put_u16(void *, u_int16_t) - __attribute__((__bounded__( __minbytes__, 1, 2))); - -#ifdef __cplusplus -} -#endif - -#endif /* _MISC_H */ diff --git a/usr/src/cmd/ssh/include/mktemp.h b/usr/src/cmd/ssh/include/mktemp.h deleted file mode 100644 index b93f2b5c10..0000000000 --- a/usr/src/cmd/ssh/include/mktemp.h +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: mktemp.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _MKTEMP_H -#define _MKTEMP_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" -#ifndef HAVE_MKDTEMP -int mkstemps(char *path, int slen); -int mkstemp(char *path); -char *mkdtemp(char *path); -#endif /* !HAVE_MKDTEMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* _MKTEMP_H */ diff --git a/usr/src/cmd/ssh/include/mpaux.h b/usr/src/cmd/ssh/include/mpaux.h deleted file mode 100644 index 6577a9b05d..0000000000 --- a/usr/src/cmd/ssh/include/mpaux.h +++ /dev/null @@ -1,33 +0,0 @@ -/* $OpenBSD: mpaux.h,v 1.12 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _MPAUX_H -#define _MPAUX_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -void compute_session_id(u_char[16], u_char[8], BIGNUM *, BIGNUM *); - -#ifdef __cplusplus -} -#endif - -#endif /* _MPAUX_H */ diff --git a/usr/src/cmd/ssh/include/msg.h b/usr/src/cmd/ssh/include/msg.h deleted file mode 100644 index c04f7d48b2..0000000000 --- a/usr/src/cmd/ssh/include/msg.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $OpenBSD: msg.h,v 1.1 2002/05/23 19:24:30 markus Exp $ */ -/* - * Copyright (c) 2002 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 _MSG_H -#define _MSG_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -void ssh_msg_send(int, u_char, Buffer *); -int ssh_msg_recv(int, Buffer *); - -#ifdef __cplusplus -} -#endif - -#endif /* _MSG_H */ diff --git a/usr/src/cmd/ssh/include/myproposal.h b/usr/src/cmd/ssh/include/myproposal.h deleted file mode 100644 index dc0043e49a..0000000000 --- a/usr/src/cmd/ssh/include/myproposal.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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. - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* $OpenBSD: myproposal.h,v 1.14 2002/04/03 09:26:11 markus Exp $ */ - -#ifndef _MYPROPOSAL_H -#define _MYPROPOSAL_H - -#ifdef __cplusplus -extern "C" { -#endif - - -#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1," \ - "diffie-hellman-group1-sha1" - -#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" - -/* - * Keep CBC modes in the back of the client default cipher list for backward - * compatibility but remove them from the server side because there are some - * potential security issues with those modes regarding SSH protocol version 2. - * Since the client is the one who picks the cipher from the list offered by the - * server the only way to force the client not to use CBC modes is not to - * advertise those at all. Note that we still support all such CBC modes in the - * server code, this is about the default server cipher list only. The list can - * be changed in the Ciphers option in the sshd_config(4) file. - * - * Note that the ordering of ciphers on the server side is not relevant but we - * must do it properly even here so that we can use the macro for the client - * list as well. - */ -#define KEX_DEFAULT_SERVER_ENCRYPT "aes128-ctr,aes192-ctr,aes256-ctr," \ - "arcfour128,arcfour256,arcfour" - -#define KEX_DEFAULT_CLIENT_ENCRYPT KEX_DEFAULT_SERVER_ENCRYPT \ - ",aes128-cbc,aes192-cbc,aes256-cbc," \ - "blowfish-cbc,3des-cbc" - -#define KEX_DEFAULT_MAC "hmac-md5,hmac-sha1,hmac-sha1-96," \ - "hmac-md5-96" - -#define KEX_DEFAULT_COMP "none,zlib" -#define KEX_DEFAULT_LANG "" - - -static char *my_srv_proposal[PROPOSAL_MAX] = { - KEX_DEFAULT_KEX, - KEX_DEFAULT_PK_ALG, - KEX_DEFAULT_SERVER_ENCRYPT, - KEX_DEFAULT_SERVER_ENCRYPT, - KEX_DEFAULT_MAC, - KEX_DEFAULT_MAC, - KEX_DEFAULT_COMP, - KEX_DEFAULT_COMP, - KEX_DEFAULT_LANG, - KEX_DEFAULT_LANG -}; - -static char *my_clnt_proposal[PROPOSAL_MAX] = { - KEX_DEFAULT_KEX, - KEX_DEFAULT_PK_ALG, - KEX_DEFAULT_CLIENT_ENCRYPT, - KEX_DEFAULT_CLIENT_ENCRYPT, - KEX_DEFAULT_MAC, - KEX_DEFAULT_MAC, - KEX_DEFAULT_COMP, - KEX_DEFAULT_COMP, - KEX_DEFAULT_LANG, - KEX_DEFAULT_LANG -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _MYPROPOSAL_H */ diff --git a/usr/src/cmd/ssh/include/openbsd-compat.h b/usr/src/cmd/ssh/include/openbsd-compat.h deleted file mode 100644 index aab8e36c62..0000000000 --- a/usr/src/cmd/ssh/include/openbsd-compat.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 1999-2003 Damien Miller. All rights reserved. - * Copyright (c) 2003 Ben Lindstrom. All rights reserved. - * Copyright (c) 2002 Tim Rice. 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 _OPENBSD_COMPAT_H -#define _OPENBSD_COMPAT_H - -/* $Id: openbsd-compat.h,v 1.17 2002/09/12 00:33:02 djm Exp $ */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -/* OpenBSD function replacements */ -#include "bindresvport.h" -#include "getcwd.h" -#include "realpath.h" -#include "rresvport.h" -#include "strlcpy.h" -#include "strlcat.h" -#include "strmode.h" -#include "mktemp.h" -#include "dirname.h" -#include "base64.h" -#include "sigact.h" -#include "inet_ntoa.h" -#include "inet_ntop.h" -#include "setproctitle.h" -#include "getgrouplist.h" -#include "glob.h" -#include "readpassphrase.h" -#include "getopt.h" - -/* Home grown routines */ -#include "bsd-arc4random.h" -#include "bsd-getpeereid.h" -#include "bsd-misc.h" -#include "bsd-snprintf.h" -#include "bsd-waitpid.h" - -/* rfc2553 socket API replacements */ -#include "fake-getaddrinfo.h" -#include "fake-getnameinfo.h" -#include "fake-socket.h" - -/* Routines for a single OS platform */ -#include "bsd-cray.h" -#include "port-irix.h" -#include "port-aix.h" - -#ifndef HAVE_VASPRINTF -int vasprintf(char **, const char *, va_list); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _OPENBSD_COMPAT_H */ diff --git a/usr/src/cmd/ssh/include/packet.h b/usr/src/cmd/ssh/include/packet.h deleted file mode 100644 index 26c3f8843e..0000000000 --- a/usr/src/cmd/ssh/include/packet.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PACKET_H -#define _PACKET_H - -/* $OpenBSD: packet.h,v 1.35 2002/06/19 18:01:00 markus Exp $ */ - -#ifdef __cplusplus -extern "C" { -#endif - - -#include <openssl/bn.h> -#include "kex.h" - -#ifdef ALTPRIVSEP -/* Monitor-side functions */ -void packet_set_server(void); -void packet_set_no_monitor(void); -void packet_set_monitor(int pip_fd); -int packet_is_server(void); -int packet_is_monitor(void); -void packet_set_packet(const void *buf, u_int len); -void packet_set_fds(int fd, int restore); -#endif /* ALTPRIVSEP */ - -void packet_set_connection(int, int); -void packet_set_nonblocking(void); -int packet_get_connection_in(void); -int packet_get_connection_out(void); -void packet_close(void); -void packet_set_encryption_key(const u_char *, u_int, int); -u_int packet_get_encryption_key(u_char *); -void packet_set_protocol_flags(u_int); -u_int packet_get_protocol_flags(void); -void packet_start_compression(int); -void packet_set_interactive(int); -int packet_is_interactive(void); - -void packet_start(u_char); -void packet_put_char(int ch); -void packet_put_int(u_int value); -void packet_put_bignum(BIGNUM * value); -void packet_put_bignum2(BIGNUM * value); -void packet_put_string(const void *buf, u_int len); -void packet_put_cstring(const char *str); -void packet_put_raw(const void *buf, u_int len); -void packet_send(void); - -void packet_put_utf8_string(const char *str, uint_t len); -void packet_put_utf8_cstring(const char *str); - -int packet_read(void); -void packet_read_expect(int type); -int packet_read_poll(void); -void packet_process_incoming(const char *buf, u_int len); -int packet_read_seqnr(u_int32_t *seqnr_p); -int packet_read_poll_seqnr(u_int32_t *seqnr_p); - -u_int packet_get_char(void); -u_int packet_get_int(void); -void packet_get_bignum(BIGNUM * value); -void packet_get_bignum2(BIGNUM * value); -void *packet_get_raw(u_int *length_ptr); -void *packet_get_string(u_int *length_ptr); -char *packet_get_utf8_string(uint_t *length_ptr); -void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); -void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); - -void set_newkeys(int mode); -void free_keys(Newkeys *keys); - -void packet_write_poll(void); -void packet_write_wait(void); -int packet_have_data_to_write(void); -int packet_not_very_much_data_to_write(void); - -int packet_connection_is_on_socket(void); -int packet_connection_is_ipv4(void); -int packet_remaining(void); -void packet_send_ignore(int); -void packet_add_padding(u_char); - -void tty_make_modes(int, struct termios *); -void tty_parse_modes(int, int *); - -extern int max_packet_size; -int packet_set_maxsize(int); -#define packet_get_maxsize() max_packet_size - -/* don't allow remaining bytes after the end of the message */ -#define packet_check_eom() \ -do { \ - int _len = packet_remaining(); \ - if (_len > 0) { \ - log("Packet integrity error (%d bytes remaining) at %s:%d", \ - _len ,__FILE__, __LINE__); \ - packet_disconnect("Packet integrity error."); \ - } \ -} while (0) - -int packet_need_rekeying(void); -void packet_set_rekey_limit(u_int32_t); - -/* see a comment attached to will_daemonize in packet.c for more information */ -#define NOT_DAEMONIZING 0 -#define DAEMONIZING_REQUESTED 1 -#define FIRST_NEWKEYS_PROCESSED 2 -#define SECOND_NEWKEYS_PROCESSED 3 - -#ifdef __cplusplus -} -#endif - -#endif /* _PACKET_H */ diff --git a/usr/src/cmd/ssh/include/pathnames.h b/usr/src/cmd/ssh/include/pathnames.h deleted file mode 100644 index 4c6638387d..0000000000 --- a/usr/src/cmd/ssh/include/pathnames.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* $OpenBSD: pathnames.h,v 1.13 2002/05/23 19:24:30 markus Exp $ */ - -#ifndef _PATHNAMES_H -#define _PATHNAMES_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -#define ETCDIR "/etc" - -#ifndef SSHDIR -#define SSHDIR ETCDIR "/ssh" -#endif - -#ifndef _PATH_SSH_PIDDIR -#define _PATH_SSH_PIDDIR "/var/run" -#endif - -/* - * System-wide file containing host keys of known hosts. This file should be - * world-readable. - */ -#define _PATH_SSH_SYSTEM_HOSTFILE SSHDIR "/ssh_known_hosts" -/* backward compat for protocol 2 */ -#define _PATH_SSH_SYSTEM_HOSTFILE2 SSHDIR "/ssh_known_hosts2" - -/* - * Of these, ssh_host_key must be readable only by root, whereas ssh_config - * should be world-readable. - */ -#define _PATH_SERVER_CONFIG_FILE SSHDIR "/sshd_config" -#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config" -#define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key" -#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" -#define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" -#define _PATH_DH_MODULI SSHDIR "/moduli" -/* Backwards compatibility */ -#define _PATH_DH_PRIMES SSHDIR "/primes" - -#ifndef _PATH_SSH_PROGRAM -#define _PATH_SSH_PROGRAM "/usr/bin/ssh" -#endif - -/* - * The process id of the daemon listening for connections is saved here to - * make it easier to kill the correct daemon when necessary. - */ -#define _PATH_SSH_DAEMON_PID_FILE _PATH_SSH_PIDDIR "/sshd.pid" - -/* - * The directory in user\'s home directory in which the files reside. The - * directory should be world-readable (though not all files are). - */ -#define _PATH_SSH_USER_DIR ".ssh" - -/* - * Per-user file containing host keys of known hosts. This file need not be - * readable by anyone except the user him/herself, though this does not - * contain anything particularly secret. - */ -#define _PATH_SSH_USER_HOSTFILE "~/.ssh/known_hosts" -/* backward compat for protocol 2 */ -#define _PATH_SSH_USER_HOSTFILE2 "~/.ssh/known_hosts2" - -/* - * Name of the default file containing client-side authentication key. This - * file should only be readable by the user him/herself. - */ -#define _PATH_SSH_CLIENT_IDENTITY ".ssh/identity" -#define _PATH_SSH_CLIENT_ID_DSA ".ssh/id_dsa" -#define _PATH_SSH_CLIENT_ID_RSA ".ssh/id_rsa" - -/* - * Configuration file in user\'s home directory. This file need not be - * readable by anyone but the user him/herself, but does not contain anything - * particularly secret. If the user\'s home directory resides on an NFS - * volume where root is mapped to nobody, this may need to be world-readable. - */ -#define _PATH_SSH_USER_CONFFILE ".ssh/config" - -/* - * File containing a list of those rsa keys that permit logging in as this - * user. This file need not be readable by anyone but the user him/herself, - * but does not contain anything particularly secret. If the user\'s home - * directory resides on an NFS volume where root is mapped to nobody, this - * may need to be world-readable. (This file is read by the daemon which is - * running as root.) - */ -#define _PATH_SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" - -/* backward compat for protocol v2 */ -#define _PATH_SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2" - -/* - * Per-user and system-wide ssh "rc" files. These files are executed with - * /bin/sh before starting the shell or command if they exist. They will be - * passed "proto cookie" as arguments if X11 forwarding with spoofing is in - * use. xauth will be run if neither of these exists. - */ -#define _PATH_SSH_USER_RC ".ssh/rc" -#define _PATH_SSH_SYSTEM_RC SSHDIR "/sshrc" - -/* - * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use - * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled. - */ -#define _PATH_SSH_HOSTS_EQUIV SSHDIR "/shosts.equiv" -#define _PATH_RHOSTS_EQUIV "/etc/hosts.equiv" - -/* - * /etc/default/login - */ -#define _PATH_DEFAULT_LOGIN "/etc/default/login" - -/* - * Default location of askpass - */ -#ifndef _PATH_SSH_ASKPASS_DEFAULT -#define _PATH_SSH_ASKPASS_DEFAULT "/usr/lib/ssh/ssh-askpass" -#endif - -/* Location of ssh-keysign for hostbased authentication */ -#ifndef _PATH_SSH_KEY_SIGN -#define _PATH_SSH_KEY_SIGN "/usr/lib/ssh/ssh-keysign" -#endif - -/* xauth for X11 forwarding */ -#ifndef _PATH_XAUTH -#define _PATH_XAUTH "/usr/openwin/bin/xauth" -#endif - -/* UNIX domain socket for X11 server; displaynum will replace %u */ -#ifndef _PATH_UNIX_X -#define _PATH_UNIX_X "/tmp/.X11-unix/X%u" -#endif - -/* for scp */ -#ifndef _PATH_CP -#define _PATH_CP "cp" -#endif - -/* for sftp */ -#ifndef _PATH_SFTP_SERVER -#define _PATH_SFTP_SERVER "/usr/lib/ssh/sftp-server" -#endif - -/* chroot directory for unprivileged user when UsePrivilegeSeparation=yes */ -#ifndef _PATH_PRIVSEP_CHROOT_DIR -#define _PATH_PRIVSEP_CHROOT_DIR "/var/empty" -#endif - -#ifndef _PATH_LS -#define _PATH_LS "ls" -#endif - -/* path to login program */ -#ifndef LOGIN_PROGRAM -# ifdef LOGIN_PROGRAM_FALLBACK -# define LOGIN_PROGRAM LOGIN_PROGRAM_FALLBACK -# else -# define LOGIN_PROGRAM "/usr/bin/login" -# endif -#endif /* LOGIN_PROGRAM */ - -/* Askpass program define */ -#ifndef ASKPASS_PROGRAM -#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" -#endif /* ASKPASS_PROGRAM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _PATHNAMES_H */ diff --git a/usr/src/cmd/ssh/include/port-aix.h b/usr/src/cmd/ssh/include/port-aix.h deleted file mode 100644 index e14fb811b8..0000000000 --- a/usr/src/cmd/ssh/include/port-aix.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright (c) 2001 Gert Doering. 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 _PORT_AIX_H -#define _PORT_AIX_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifdef _AIX -void aix_usrinfo(struct passwd *pw); -#endif /* _AIX */ - -#ifdef __cplusplus -} -#endif - -#endif /* _PORT_AIX_H */ diff --git a/usr/src/cmd/ssh/include/port-irix.h b/usr/src/cmd/ssh/include/port-irix.h deleted file mode 100644 index 79397e0674..0000000000 --- a/usr/src/cmd/ssh/include/port-irix.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * XXX - Add OpenSSH copyright - */ - -#ifndef _PORT_IRIX_H -#define _PORT_IRIX_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) - -void irix_setusercontext(struct passwd *pw); - -#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _PORT_IRIX_H */ diff --git a/usr/src/cmd/ssh/include/progressmeter.h b/usr/src/cmd/ssh/include/progressmeter.h deleted file mode 100644 index d8a3bc6737..0000000000 --- a/usr/src/cmd/ssh/include/progressmeter.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2002 Nils Nordman. 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 _PROGRESSMETER_H -#define _PROGRESSMETER_H - -/* $OpenBSD: progressmeter.h,v 1.2 2006/03/25 22:22:43 djm Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -void start_progress_meter(char *, off_t, off_t *); -void stop_progress_meter(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _PROGRESSMETER_H */ diff --git a/usr/src/cmd/ssh/include/proxy-io.h b/usr/src/cmd/ssh/include/proxy-io.h deleted file mode 100644 index e240118c8d..0000000000 --- a/usr/src/cmd/ssh/include/proxy-io.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PROXY_IO_H -#define _PROXY_IO_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Read/write loop for ssh proxies. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define BUFFER_SIZ 8192 - -int proxy_read_write_loop(int readfd, int writefd); - -#ifdef __cplusplus -} -#endif - -#endif /* _PROXY_IO_H */ diff --git a/usr/src/cmd/ssh/include/readconf.h b/usr/src/cmd/ssh/include/readconf.h deleted file mode 100644 index 1aceb9cb7c..0000000000 --- a/usr/src/cmd/ssh/include/readconf.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _READCONF_H -#define _READCONF_H - -/* $OpenBSD: readconf.h,v 1.43 2002/06/08 05:17:01 markus Exp $ */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "key.h" - -/* - * We accept only fixed amount of unknown options. Note that we must treat all - * options in different Host sections separately since we need to remember the - * line number. See IgnoreIfUnknown for more information. - */ -#define MAX_UNKNOWN_OPTIONS 64 - -/* Data structure for representing a forwarding request. */ - -typedef struct { - char *listen_host; /* Host (address) to listen on. */ - u_short listen_port; /* Port to forward. */ - char *connect_host; /* Host to connect. */ - u_short connect_port; /* Port to connect on connect_host. */ -} Forward; -/* Data structure for representing option data. */ - -/* For postponed processing of option keywords. */ -typedef struct { - char *keyword; /* option keyword name */ - char *filename; /* config file it was found in */ - int linenum; /* line number in the config file */ -} StoredOption; - -typedef struct { - int forward_agent; /* Forward authentication agent. */ - int forward_x11; /* Forward X11 display. */ - int forward_x11_trusted; /* Trust 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. */ - int rhosts_rsa_authentication; /* Try rhosts with RSA - * authentication. */ - int rsa_authentication; /* Try RSA authentication. */ - int pubkey_authentication; /* Try ssh2 pubkey authentication. */ - int hostbased_authentication; /* ssh2's rhosts_rsa */ - int challenge_response_authentication; - int fallback_to_rsh; /* Use rsh if cannot connect with ssh. */ - int use_rsh; /* Always use rsh(don\'t try ssh). */ - /* Try S/Key or TIS, authentication. */ -#if defined(KRB4) || defined(KRB5) - int kerberos_authentication; /* Try Kerberos authentication. */ -#endif -#if defined(AFS) || defined(KRB5) - int kerberos_tgt_passing; /* Try Kerberos TGT passing. */ -#endif - -#ifdef GSSAPI - int gss_keyex; - int gss_authentication; - int gss_deleg_creds; -#ifdef GSI - int gss_globus_deleg_limited_proxy; -#endif /* GSI */ -#endif /* GSSAPI */ - -#ifdef AFS - int afs_token_passing; /* Try AFS token passing. */ -#endif - int password_authentication; /* Try password - * authentication. */ - int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ - char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ - int batch_mode; /* Batch mode: do not ask for passwords. */ - int check_host_ip; /* Also keep track of keys for IP address */ - int strict_host_key_checking; /* Strict host key checking. */ - int compression; /* Compress packets in both directions. */ - int compression_level; /* Compression level 1 (fast) to 9 - * (best). */ - int keepalives; /* Set SO_KEEPALIVE. */ - LogLevel log_level; /* Level for logging. */ - - int port; /* Port to connect. */ - int connection_attempts; /* Max attempts (seconds) before - * giving up */ - int connection_timeout; /* Max time (seconds) before - * aborting connection attempt */ - int number_of_password_prompts; /* Max number of password - * prompts. */ - int cipher; /* Cipher to use. */ - char *ciphers; /* SSH2 ciphers in order of preference. */ - char *macs; /* SSH2 macs in order of preference. */ - char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ - int protocol; /* Protocol in order of preference. */ - char *hostname; /* Real host to connect. */ - char *host_key_alias; /* hostname alias for .ssh/known_hosts */ - char *proxy_command; /* Proxy command for connecting the host. */ - char *user; /* User to log in as. */ - int escape_char; /* Escape character; -2 = none */ - - char *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */ - char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */ - char *system_hostfile2; - char *user_hostfile2; - char *preferred_authentications; - char *bind_address; /* local socket address for connection to sshd */ - char *smartcard_device; /* Smartcard reader device */ - int disable_banner; /* Disable display of banner */ - - /* - * Unknown options listed in IgnoreIfUnknown will not cause ssh to - * exit. So, we must store all unknown options here and can't process - * them before the command line options and all config files are read - * and IgnoreIfUnknown is properly set. - */ - char *ignore_if_unknown; - int unknown_opts_num; - StoredOption unknown_opts[MAX_UNKNOWN_OPTIONS]; - - int num_identity_files; /* Number of files for RSA/DSA identities. */ - char *identity_files[SSH_MAX_IDENTITY_FILES]; - Key *identity_keys[SSH_MAX_IDENTITY_FILES]; - - /* Local TCP/IP forward requests. */ - int num_local_forwards; - Forward local_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; - - /* Remote TCP/IP forward requests. */ - int num_remote_forwards; - Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; - int clear_forwardings; - - int64_t rekey_limit; - int no_host_authentication_for_localhost; - int server_alive_interval; - int server_alive_count_max; - - int hash_known_hosts; - int use_openssl_engine; -} Options; - - -void initialize_options(Options *); -void fill_default_options(Options *); -int read_config_file(const char *, const char *, Options *); -int parse_forward(int, Forward *, const char *); - -int -process_config_line(Options *, const char *, char *, const char *, int, int *); - -void add_local_forward(Options *, const Forward *); -void add_remote_forward(Options *, const Forward *); - -void process_unknown_options(Options *); - -#ifdef __cplusplus -} -#endif - -#endif /* _READCONF_H */ diff --git a/usr/src/cmd/ssh/include/readpass.h b/usr/src/cmd/ssh/include/readpass.h deleted file mode 100644 index 1917f08e30..0000000000 --- a/usr/src/cmd/ssh/include/readpass.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: readpass.h,v 1.7 2002/03/26 15:58:46 markus Exp $ */ - -#ifndef _READPASS_H -#define _READPASS_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -#define RP_ECHO 0x0001 -#define RP_ALLOW_STDIN 0x0002 -#define RP_ALLOW_EOF 0x0004 -#define RP_USE_ASKPASS 0x0008 - -char *read_passphrase(const char *, int); -int ask_permission(const char *, ...) - __attribute__((format(printf, 1, 2))); -int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); - -#ifdef __cplusplus -} -#endif - -#endif /* _READPASS_H */ diff --git a/usr/src/cmd/ssh/include/readpassphrase.h b/usr/src/cmd/ssh/include/readpassphrase.h deleted file mode 100644 index 3dd7b367d0..0000000000 --- a/usr/src/cmd/ssh/include/readpassphrase.h +++ /dev/null @@ -1,60 +0,0 @@ -/* $OpenBSD: readpassphrase.h,v 1.3 2002/06/28 12:32:22 millert Exp $ */ - -#ifndef _READPASSPHRASE_H -#define _READPASSPHRASE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com> - * 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. 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 ``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" - -#ifndef HAVE_READPASSPHRASE - -#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ -#define RPP_ECHO_ON 0x01 /* Leave echo on. */ -#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ -#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ -#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ -#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ -#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ - -char * readpassphrase(const char *, char *, size_t, int); - -#endif /* HAVE_READPASSPHRASE */ - -#ifdef __cplusplus -} -#endif - -#endif /* _READPASSPHRASE_H */ diff --git a/usr/src/cmd/ssh/include/realpath.h b/usr/src/cmd/ssh/include/realpath.h deleted file mode 100644 index 1bd00053ac..0000000000 --- a/usr/src/cmd/ssh/include/realpath.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Id: realpath.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _REALPATH_H -#define _REALPATH_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) - -char *realpath(const char *path, char *resolved); - -#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _REALPATH_H */ diff --git a/usr/src/cmd/ssh/include/rresvport.h b/usr/src/cmd/ssh/include/rresvport.h deleted file mode 100644 index 33c47d84cf..0000000000 --- a/usr/src/cmd/ssh/include/rresvport.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Id: rresvport.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _RRESVPORT_H -#define _RRESVPORT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#ifndef HAVE_RRESVPORT_AF -int rresvport_af(int *alport, sa_family_t af); -#endif /* !HAVE_RRESVPORT_AF */ - -#ifdef __cplusplus -} -#endif - -#endif /* _RRESVPORT_H */ diff --git a/usr/src/cmd/ssh/include/rsa.h b/usr/src/cmd/ssh/include/rsa.h deleted file mode 100644 index f0fcc49ba0..0000000000 --- a/usr/src/cmd/ssh/include/rsa.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: rsa.h,v 1.15 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _RSA_H -#define _RSA_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ - -#include <openssl/bn.h> -#include <openssl/rsa.h> - -void rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); -int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *); -void rsa_generate_additional_parameters(RSA *); - -#ifdef __cplusplus -} -#endif - -#endif /* _RSA_H */ diff --git a/usr/src/cmd/ssh/include/servconf.h b/usr/src/cmd/ssh/include/servconf.h deleted file mode 100644 index 9a32544c2a..0000000000 --- a/usr/src/cmd/ssh/include/servconf.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* $OpenBSD: servconf.h,v 1.59 2002/07/30 17:03:55 markus Exp $ */ - -#ifndef _SERVCONF_H -#define _SERVCONF_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_PORTS 256 /* Max # ports. */ - -#define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ -#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. */ -#define MAX_HOSTKEYS 256 /* Max # hostkeys. */ - -/* permit_root_login */ -#define PERMIT_NOT_SET -1 -#define PERMIT_NO 0 -#define PERMIT_FORCED_ONLY 1 -#define PERMIT_NO_PASSWD 2 -#define PERMIT_YES 3 - -/* Magic name for internal sftp-server */ -#define INTERNAL_SFTP_NAME "internal-sftp" -#define _SSH_PAM_SERVICE_PREFIX "sshd" - -typedef struct { - u_int num_ports; - u_int ports_from_cmdline; - u_short ports[MAX_PORTS]; /* Port number to listen on. */ - char *listen_addr; /* Address on which the server listens. */ - struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ - char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */ - int num_host_key_files; /* Number of files for host keys. */ - char *pid_file; /* Where to put our pid */ - int server_key_bits;/* Size of the server key. */ - int login_grace_time; /* Disconnect if no auth in this time - * (sec). */ - int key_regeneration_time; /* Server key lifetime (seconds). */ - int permit_root_login; /* PERMIT_*, see above */ - int ignore_rhosts; /* Ignore .rhosts and .shosts. */ - int ignore_user_known_hosts; /* Ignore ~/.ssh/known_hosts - * for RhostsRsaAuth */ - int print_motd; /* If true, print /etc/motd. */ - int print_lastlog; /* If true, print lastlog */ - int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ - int x11_display_offset; /* What DISPLAY number to start - * searching at */ - int x11_use_localhost; /* If true, use localhost for fake X11 server. */ - 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; /* Supported SSH2 ciphers. */ - char *macs; /* Supported SSH2 macs. */ - int protocol; /* Supported protocol versions. */ - int gateway_ports; /* If true, allow remote connects to forwarded ports. */ - SyslogFacility log_facility; /* Facility for system logging. */ - LogLevel log_level; /* Level for system logging. */ - int rhosts_authentication; /* If true, permit rhosts - * authentication. */ - int rhosts_rsa_authentication; /* If true, permit rhosts RSA - * authentication. */ - int hostbased_authentication; /* If true, permit ssh2 hostbased auth */ - int hostbased_uses_name_from_packet_only; /* experimental */ - int rsa_authentication; /* If true, permit RSA authentication. */ - int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ -#ifdef GSSAPI - int gss_authentication; - int gss_keyex; - int gss_store_creds; - int gss_use_session_ccache; /* If true, delegated credentials are - * stored in a session specific cache */ - int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -#endif /* GSSAPI */ -#if defined(KRB4) || defined(KRB5) - int kerberos_authentication; /* If true, permit Kerberos - * authentication. */ - int kerberos_or_local_passwd; /* If true, permit kerberos - * and any other password - * authentication mechanism, - * such as SecurID or - * /etc/passwd */ - int kerberos_ticket_cleanup; /* If true, destroy ticket - * file on logout. */ -#endif -#if defined(AFS) || defined(KRB5) - int kerberos_tgt_passing; /* If true, permit Kerberos TGT - * passing. */ -#endif -#ifdef AFS - int afs_token_passing; /* If true, permit AFS token passing. */ -#endif - int password_authentication; /* If true, permit password - * authentication. */ - - int kbd_interactive_authentication; - int challenge_response_authentication; - int pam_authentication_via_kbd_int; - - int permit_empty_passwd; /* If false, do not permit empty - * passwords. */ - int permit_user_env; /* If true, read ~/.ssh/environment */ - int use_login; /* If true, login(1) is used */ - int compression; /* If true, compression is allowed */ - int allow_tcp_forwarding; - - u_int num_allow_users; - char *allow_users[MAX_ALLOW_USERS]; - u_int num_deny_users; - char *deny_users[MAX_DENY_USERS]; - u_int num_allow_groups; - char *allow_groups[MAX_ALLOW_GROUPS]; - u_int num_deny_groups; - char *deny_groups[MAX_DENY_GROUPS]; - - u_int num_subsystems; - char *subsystem_name[MAX_SUBSYSTEMS]; - char *subsystem_command[MAX_SUBSYSTEMS]; - char *subsystem_args[MAX_SUBSYSTEMS]; - - int max_startups_begin; - int max_startups_rate; - int max_startups; - char *banner; /* SSH-2 banner message */ - int verify_reverse_mapping; /* cross-check ip and dns */ - int client_alive_interval; /* - * poke the client this often to - * see if it's still there - */ - int client_alive_count_max; /* - * If the client is unresponsive - * for this many intervals above, - * disconnect the session - */ - - char *authorized_keys_file; /* File containing public keys */ - char *authorized_keys_file2; - - int max_auth_tries; - int max_auth_tries_log; - - int max_init_auth_tries; /* SUNW: /etc/default/login */ - int max_init_auth_tries_log; /* SUNW: /etc/default/login */ - - int lookup_client_hostnames; - int use_openssl_engine; - char *chroot_directory; - char *pre_userauth_hook; - char *pam_service_prefix; - char *pam_service_name; - char *pubkey_plugin; - -} ServerOptions; - -void initialize_server_options(ServerOptions *); -void fill_default_server_options(ServerOptions *); -int process_server_config_line(ServerOptions *, char *, const char *, int, - int *, const char *, const char *, const char *); -void load_server_config(const char *, Buffer *); -void parse_server_config(ServerOptions *, const char *, Buffer *, - const char *, const char *, const char *); -void parse_server_match_config(ServerOptions *, const char *, const char *, - const char *); -void copy_set_server_options(ServerOptions *, ServerOptions *, int); -int chroot_requested(char *chroot_directory); - -#ifdef __cplusplus -} -#endif - - -#endif /* _SERVCONF_H */ diff --git a/usr/src/cmd/ssh/include/serverloop.h b/usr/src/cmd/ssh/include/serverloop.h deleted file mode 100644 index ec5b34a6b2..0000000000 --- a/usr/src/cmd/ssh/include/serverloop.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $OpenBSD: serverloop.h,v 1.5 2001/06/27 02:12:53 markus Exp $ */ - -#ifndef _SERVERLOOP_H -#define _SERVERLOOP_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ -/* - * Performs the interactive session. This handles data transmission between - * the client and the program. Note that the notion of stdin, stdout, and - * stderr in this function is sort of reversed: this function writes to stdin - * (of the child program), and reads from stdout and stderr (of the child - * program). - */ - -void server_loop(pid_t, int, int, int); -void server_loop2(Authctxt *); - -#ifdef __cplusplus -} -#endif - -#endif /* _SERVERLOOP_H */ diff --git a/usr/src/cmd/ssh/include/session.h b/usr/src/cmd/ssh/include/session.h deleted file mode 100644 index 0d81189842..0000000000 --- a/usr/src/cmd/ssh/include/session.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SESSION_H -#define _SESSION_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* $OpenBSD: session.h,v 1.19 2002/06/30 21:59:45 deraadt Exp $ */ -#define TTYSZ 64 -typedef struct Session Session; -struct Session { - int used; - int self; - struct passwd *pw; - Authctxt *authctxt; - pid_t pid; - /* tty */ - char *term; - int ptyfd, ttyfd, ptymaster; - u_int row, col, xpixel, ypixel; - char tty[TTYSZ]; - /* last login */ - char hostname[MAXHOSTNAMELEN]; - time_t last_login_time; - /* X11 */ - u_int display_number; - char *display; - u_int screen; - char *auth_display; - char *auth_proto; - char *auth_data; - char *auth_file; /* xauth(1) authority file */ - int single_connection; - /* proto 2 */ - int chanid; - int is_subsystem; - char *command; - char **env; -}; - -void do_authenticated(Authctxt *); - -int session_open(Authctxt *, int); -int session_input_channel_req(Channel *, const char *); -void session_close_by_pid(pid_t, int); -void session_close_by_channel(int, void *); -void session_destroy_all(void (*)(Session *)); -void session_pty_cleanup2(void *); - -Session *session_new(void); -Session *session_by_tty(char *); -void session_close(Session *); -void do_setusercontext(struct passwd *); -void child_set_env(char ***envp, u_int *envsizep, const char *name, - const char *value); -void child_set_env_silent(char ***envp, u_int *envsizep, const char *name, - const char *value); - - -#ifdef __cplusplus -} -#endif - -#endif /* _SESSION_H */ diff --git a/usr/src/cmd/ssh/include/setproctitle.h b/usr/src/cmd/ssh/include/setproctitle.h deleted file mode 100644 index 9488be3cf7..0000000000 --- a/usr/src/cmd/ssh/include/setproctitle.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Id: setproctitle.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _SETPROCTITLE_H -#define _SETPROCTITLE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" - -#ifndef HAVE_SETPROCTITLE -void setproctitle(const char *fmt, ...); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _SETPROCTITLE_H */ diff --git a/usr/src/cmd/ssh/include/sftp-client.h b/usr/src/cmd/ssh/include/sftp-client.h deleted file mode 100644 index 1927e3df16..0000000000 --- a/usr/src/cmd/ssh/include/sftp-client.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SFTP_CLIENT_H -#define _SFTP_CLIENT_H - -/* $OpenBSD: sftp-client.h,v 1.14 2005/04/26 12:59:02 jmc Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Client side of SSH2 filexfer protocol */ - -typedef struct SFTP_DIRENT SFTP_DIRENT; - -struct SFTP_DIRENT { - char *filename; - char *longname; - Attrib a; -}; - -/* - * Initialise a SSH filexfer connection. Returns NULL on error or - * a pointer to a initialized sftp_conn struct on success. - */ -struct sftp_conn *do_init(int, int, u_int, u_int); - -u_int sftp_proto_version(struct sftp_conn *); - -/* Close file referred to by 'handle' */ -int do_close(struct sftp_conn *, char *, u_int); - -/* Read contents of 'path' to NULL-terminated array 'dir' */ -int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***); - -/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ -void free_sftp_dirents(SFTP_DIRENT **); - -/* Delete file 'path' */ -int do_rm(struct sftp_conn *, char *); - -/* Create directory 'path' */ -int do_mkdir(struct sftp_conn *, char *, Attrib *); - -/* Remove directory 'path' */ -int do_rmdir(struct sftp_conn *, char *); - -/* Get file attributes of 'path' (follows symlinks) */ -Attrib *do_stat(struct sftp_conn *, char *, int); - -/* Get file attributes of 'path' (does not follow symlinks) */ -Attrib *do_lstat(struct sftp_conn *, char *, int); - -/* Get file attributes of open file 'handle' */ -Attrib *do_fstat(struct sftp_conn *, char *, u_int, int); - -/* Set file attributes of 'path' */ -int do_setstat(struct sftp_conn *, char *, Attrib *); - -/* Set file attributes of open file 'handle' */ -int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); - -/* Canonicalise 'path' - caller must free result */ -char *do_realpath(struct sftp_conn *, char *); - -/* Rename 'oldpath' to 'newpath' */ -int do_rename(struct sftp_conn *, char *, char *); - -/* Rename 'oldpath' to 'newpath' */ -int do_symlink(struct sftp_conn *, char *, char *); - -/* Return target of symlink 'path' - caller must free result */ -char *do_readlink(struct sftp_conn *, char *); - -/* XXX: add callbacks to do_download/do_upload so we can do progress meter */ - -/* - * Download 'remote_path' to 'local_path'. Preserve permissions and times - * if 'pflag' is set - */ -int do_download(struct sftp_conn *, char *, char *, int); - -/* - * Upload 'local_path' to 'remote_path'. Preserve permissions and times - * if 'pflag' is set - */ -int do_upload(struct sftp_conn *, char *, char *, int); - -#ifdef __cplusplus -} -#endif - -#endif /* _SFTP_CLIENT_H */ diff --git a/usr/src/cmd/ssh/include/sftp-common.h b/usr/src/cmd/ssh/include/sftp-common.h deleted file mode 100644 index 86225bc175..0000000000 --- a/usr/src/cmd/ssh/include/sftp-common.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * Copyright (c) 2001 Damien Miller. 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 _SFTP_COMMON_H -#define _SFTP_COMMON_H - -/* $OpenBSD: sftp-common.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Maximum packet that we are willing to send/accept */ -#define SFTP_MAX_MSG_LENGTH (256 * 1024) - -typedef struct Attrib Attrib; - -/* File attributes */ -struct Attrib { - u_int32_t flags; - u_int64_t size; - u_int32_t uid; - u_int32_t gid; - u_int32_t perm; - u_int32_t atime; - u_int32_t mtime; -}; - -void attrib_clear(Attrib *); -void stat_to_attrib(const struct stat *, Attrib *); -void attrib_to_stat(const Attrib *, struct stat *); -Attrib *decode_attrib(Buffer *); -void encode_attrib(Buffer *, const Attrib *); -char *ls_file(const char *, const struct stat *, int); - -const char *fx2txt(int); - -#ifdef __cplusplus -} -#endif - -#endif /* _SFTP_COMMON_H */ diff --git a/usr/src/cmd/ssh/include/sftp.h b/usr/src/cmd/ssh/include/sftp.h deleted file mode 100644 index e35cbdedf1..0000000000 --- a/usr/src/cmd/ssh/include/sftp.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* $OpenBSD: sftp.h,v 1.4 2002/02/13 00:59:23 djm Exp $ */ - -/* - * draft-ietf-secsh-filexfer-01.txt - */ - -#ifndef _SFTP_H -#define _SFTP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* version */ -#define SSH2_FILEXFER_VERSION 3 - -/* client to server */ -#define SSH2_FXP_INIT 1 -#define SSH2_FXP_OPEN 3 -#define SSH2_FXP_CLOSE 4 -#define SSH2_FXP_READ 5 -#define SSH2_FXP_WRITE 6 -#define SSH2_FXP_LSTAT 7 -#define SSH2_FXP_STAT_VERSION_0 7 -#define SSH2_FXP_FSTAT 8 -#define SSH2_FXP_SETSTAT 9 -#define SSH2_FXP_FSETSTAT 10 -#define SSH2_FXP_OPENDIR 11 -#define SSH2_FXP_READDIR 12 -#define SSH2_FXP_REMOVE 13 -#define SSH2_FXP_MKDIR 14 -#define SSH2_FXP_RMDIR 15 -#define SSH2_FXP_REALPATH 16 -#define SSH2_FXP_STAT 17 -#define SSH2_FXP_RENAME 18 -#define SSH2_FXP_READLINK 19 -#define SSH2_FXP_SYMLINK 20 - -/* server to client */ -#define SSH2_FXP_VERSION 2 -#define SSH2_FXP_STATUS 101 -#define SSH2_FXP_HANDLE 102 -#define SSH2_FXP_DATA 103 -#define SSH2_FXP_NAME 104 -#define SSH2_FXP_ATTRS 105 - -#define SSH2_FXP_EXTENDED 200 -#define SSH2_FXP_EXTENDED_REPLY 201 - -/* attributes */ -#define SSH2_FILEXFER_ATTR_SIZE 0x00000001 -#define SSH2_FILEXFER_ATTR_UIDGID 0x00000002 -#define SSH2_FILEXFER_ATTR_PERMISSIONS 0x00000004 -#define SSH2_FILEXFER_ATTR_ACMODTIME 0x00000008 -#define SSH2_FILEXFER_ATTR_EXTENDED 0x80000000 - -/* portable open modes */ -#define SSH2_FXF_READ 0x00000001 -#define SSH2_FXF_WRITE 0x00000002 -#define SSH2_FXF_APPEND 0x00000004 -#define SSH2_FXF_CREAT 0x00000008 -#define SSH2_FXF_TRUNC 0x00000010 -#define SSH2_FXF_EXCL 0x00000020 - -/* status messages */ -#define SSH2_FX_OK 0 -#define SSH2_FX_EOF 1 -#define SSH2_FX_NO_SUCH_FILE 2 -#define SSH2_FX_PERMISSION_DENIED 3 -#define SSH2_FX_FAILURE 4 -#define SSH2_FX_BAD_MESSAGE 5 -#define SSH2_FX_NO_CONNECTION 6 -#define SSH2_FX_CONNECTION_LOST 7 -#define SSH2_FX_OP_UNSUPPORTED 8 -#define SSH2_FX_MAX 8 - -struct passwd; - -int sftp_server_main(int, char **, struct passwd *); - -#ifdef __cplusplus -} -#endif - -#endif /* _SFTP_H */ diff --git a/usr/src/cmd/ssh/include/sigact.h b/usr/src/cmd/ssh/include/sigact.h deleted file mode 100644 index fc5b3b6427..0000000000 --- a/usr/src/cmd/ssh/include/sigact.h +++ /dev/null @@ -1,99 +0,0 @@ -/* $OpenBSD: SigAction.h,v 1.2 1999/06/27 08:15:19 millert Exp $ */ - -#ifndef _SIGACT_H -#define _SIGACT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/**************************************************************************** - * Copyright (c) 1998 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - ****************************************************************************/ - -/* - * $From: SigAction.h,v 1.5 1999/06/19 23:00:54 tom Exp $ - * - * This file exists to handle non-POSIX systems which don't have <unistd.h>, - * and usually no sigaction() nor <termios.h> - */ - -#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) - -#undef SIG_BLOCK -#define SIG_BLOCK 00 - -#undef SIG_UNBLOCK -#define SIG_UNBLOCK 01 - -#undef SIG_SETMASK -#define SIG_SETMASK 02 - -/* - * <bsd/signal.h> is in the Linux 1.2.8 + gcc 2.7.0 configuration, - * and is useful for testing this header file. - */ -#if HAVE_BSD_SIGNAL_H -# include <bsd/signal.h> -#endif - -struct sigaction -{ - struct sigvec sv; -}; - -typedef unsigned long sigset_t; - -#undef sa_mask -#define sa_mask sv.sv_mask -#undef sa_handler -#define sa_handler sv.sv_handler -#undef sa_flags -#define sa_flags sv.sv_flags - -int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact); -int sigprocmask (int how, sigset_t *mask, sigset_t *omask); -int sigemptyset (sigset_t *mask); -int sigsuspend (sigset_t *mask); -int sigdelset (sigset_t *mask, int sig); -int sigaddset (sigset_t *mask, int sig); - -#endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SIGACT_H */ diff --git a/usr/src/cmd/ssh/include/ssh-dss.h b/usr/src/cmd/ssh/include/ssh-dss.h deleted file mode 100644 index 7f4e6d19fe..0000000000 --- a/usr/src/cmd/ssh/include/ssh-dss.h +++ /dev/null @@ -1,44 +0,0 @@ -/* $OpenBSD: ssh-dss.h,v 1.6 2002/02/24 19:14:59 markus Exp $ */ - -#ifndef _SSH_DSS_H -#define _SSH_DSS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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. - */ - -int ssh_dss_sign(Key *, u_char **, u_int *, u_char *, u_int); -int ssh_dss_verify(Key *, u_char *, u_int, u_char *, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSH_DSS_H */ diff --git a/usr/src/cmd/ssh/include/ssh-gss.h b/usr/src/cmd/ssh/include/ssh-gss.h deleted file mode 100644 index 6e35d9ed61..0000000000 --- a/usr/src/cmd/ssh/include/ssh-gss.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SSH_GSS_H -#define _SSH_GSS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef GSSAPI - -#include "kex.h" -#include "buffer.h" - -#ifdef SUNW_GSSAPI -#include <gssapi/gssapi.h> -#include <gssapi/gssapi_ext.h> -#else -#ifdef GSS_KRB5 -#ifndef HEIMDAL -#include <gssapi_generic.h> - -/* MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */ -#ifndef GSS_C_NT_HOSTBASED_SERVICE -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name -#endif /* GSS_C_NT_... */ -#endif /* !HEIMDAL */ -#endif /* GSS_KRB5 */ -#endif /* SUNW_GSSAPI */ - -/* draft-ietf-secsh-gsskeyex-03 */ -#define SSH2_MSG_KEXGSS_INIT 30 -#define SSH2_MSG_KEXGSS_CONTINUE 31 -#define SSH2_MSG_KEXGSS_COMPLETE 32 -#define SSH2_MSG_KEXGSS_HOSTKEY 33 -#define SSH2_MSG_KEXGSS_ERROR 34 -#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 -#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 -#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 -#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 -#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 -#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66 - -#define KEX_GSS_SHA1 "gss-group1-sha1-" -#define SSH_GSS_HOSTBASED_SERVICE "host" - -#ifndef HAVE_GSS_STORE_CRED -typedef struct ssh_gssapi_cred_store ssh_gssapi_cred_store; /* server-only */ -#endif /* !HAVE_GSS_STORE_CRED */ - -typedef struct { - OM_uint32 major; - OM_uint32 minor; - int local; /* true on client, false on server */ - int established; - OM_uint32 flags; - gss_ctx_id_t context; - gss_OID desired_mech; /* client-side only */ - gss_OID actual_mech; - gss_name_t desired_name; /* targ on both */ - gss_name_t src_name; - gss_name_t dst_name; - gss_cred_id_t creds; /* server-side only */ - gss_cred_id_t deleg_creds; /* server-side only */ - int default_creds; /* server-side only */ -#ifndef HAVE_GSS_STORE_CRED - ssh_gssapi_cred_store *cred_store; /* server-side only */ -#endif /* !HAVE_GSS_STORE_CRED */ -} Gssctxt; - -/* Functions to get supported mech lists */ -void ssh_gssapi_server_mechs(gss_OID_set *mechs); -void ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs); - -/* Functions to get fix KEX proposals (needed for rekey cases) */ -void ssh_gssapi_modify_kex(Kex *kex, gss_OID_set mechs, char **proposal); -void ssh_gssapi_server_kex_hook(Kex *kex, char **proposal); -void ssh_gssapi_client_kex_hook(Kex *kex, char **proposal); - -/* Map an encoded mechanism keyex name to a mechanism OID */ -void ssh_gssapi_mech_oid_to_kexname(const gss_OID mech, char **kexname); -void ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, - char **kexname_list); -/* dup oid? */ -void ssh_gssapi_oid_of_kexname(const char *kexname, gss_OID *mech); - -/* - * Unfortunately, the GSS-API is not generic enough for some things -- - * see gss-serv.c and ssh-gss.c - */ -int ssh_gssapi_is_spnego(gss_OID oid); -int ssh_gssapi_is_krb5(gss_OID oid); -int ssh_gssapi_is_gsi(gss_OID oid); -int ssh_gssapi_is_dh(gss_OID oid); - -/* GSS_Init/Accept_sec_context() and GSS_Acquire_cred() wrappers */ -/* client-only */ -OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, const char *server_host, - int deleg_creds, gss_buffer_t recv_tok, gss_buffer_t send_tok); -/* server-only */ -OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok, - gss_buffer_t send_tok); -/* server-only */ -OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx); - -/* MIC wrappers */ -OM_uint32 ssh_gssapi_get_mic(Gssctxt *ctx, gss_buffer_t buffer, - gss_buffer_t hash); -OM_uint32 ssh_gssapi_verify_mic(Gssctxt *ctx, gss_buffer_t buffer, - gss_buffer_t hash); - -/* Gssctxt functions */ -void ssh_gssapi_build_ctx(Gssctxt **ctx, int client, gss_OID mech); -void ssh_gssapi_delete_ctx(Gssctxt **ctx); -int ssh_gssapi_check_mech_oid(Gssctxt *ctx, void *data, size_t len); -void ssh_gssapi_error(Gssctxt *ctx, const char *where); -char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min); - -/* Server-side */ -int ssh_gssapi_userok(Gssctxt *ctx, char *name); -char *ssh_gssapi_localname(Gssctxt *ctx); - -/* Server-side, if PAM and gss_store_cred() are available, ... */ -struct Authctxt; /* needed to avoid conflicts between auth.h, sshconnect2.c */ -void ssh_gssapi_storecreds(Gssctxt *ctx, struct Authctxt *authctxt); - -/* ... else, if other interfaces are available for GSS-API cred storing */ -void ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, uint_t *envsizep); -void ssh_gssapi_cleanup_creds(Gssctxt *ctx); - -/* Misc */ -int ssh_gssapi_import_name(Gssctxt *ctx, const char *server_host); -const char *ssh_gssapi_oid_to_name(gss_OID oid); -char *ssh_gssapi_oid_to_str(gss_OID oid); -gss_OID ssh_gssapi_dup_oid(gss_OID oid); -gss_OID ssh_gssapi_make_oid(size_t length, void *elements); -gss_OID ssh_gssapi_make_oid_ext(size_t length, void *elements, - int der_wrapped); -void *ssh_gssapi_der_wrap(size_t, size_t *length); -size_t ssh_gssapi_der_wrap_size(size_t, size_t *length); -void ssh_gssapi_release_oid(gss_OID *oid); -#endif /* GSSAPI */ - -#endif /* _SSH_GSS_H */ diff --git a/usr/src/cmd/ssh/include/ssh-rsa.h b/usr/src/cmd/ssh/include/ssh-rsa.h deleted file mode 100644 index 2d883fa774..0000000000 --- a/usr/src/cmd/ssh/include/ssh-rsa.h +++ /dev/null @@ -1,44 +0,0 @@ -/* $OpenBSD: ssh-rsa.h,v 1.6 2002/02/24 19:14:59 markus Exp $ */ - -#ifndef _SSH_RSA_H -#define _SSH_RSA_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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. - */ - -int ssh_rsa_sign(Key *, u_char **, u_int *, u_char *, u_int); -int ssh_rsa_verify(Key *, u_char *, u_int, u_char *, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSH_RSA_H */ diff --git a/usr/src/cmd/ssh/include/ssh.h b/usr/src/cmd/ssh/include/ssh.h deleted file mode 100644 index 746d2ff69b..0000000000 --- a/usr/src/cmd/ssh/include/ssh.h +++ /dev/null @@ -1,133 +0,0 @@ -/* $OpenBSD: ssh.h,v 1.71 2002/06/22 02:00:29 stevesk Exp $ */ - -#ifndef _SSH_H -#define _SSH_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <netinet/in.h> /* For struct sockaddr_in */ -#include <pwd.h> /* For struct pw */ -#include <stdarg.h> /* For va_list */ -#include <syslog.h> /* For LOG_AUTH and friends */ -#include <sys/socket.h> /* For struct sockaddr_storage */ -#include "fake-socket.h" /* For struct sockaddr_storage */ -#ifdef HAVE_SYS_SELECT_H -# include <sys/select.h> -#endif - -/* Cipher used for encrypting authentication files. */ -#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES - -/* Default port number. */ -#define SSH_DEFAULT_PORT 22 - -/* Maximum number of TCP/IP ports forwarded per direction. */ -#define SSH_MAX_FORWARDS_PER_DIRECTION 100 - -/* - * Maximum number of RSA authentication identity files that can be specified - * in configuration files or on the command line. - */ -#define SSH_MAX_IDENTITY_FILES 100 - -/* - * Major protocol version. Different version indicates major incompatibility - * that prevents communication. - * - * Minor protocol version. Different version indicates minor incompatibility - * that does not prevent interoperation. - */ -#define PROTOCOL_MAJOR_1 1 -#define PROTOCOL_MINOR_1 5 - -/* We support both SSH1 and SSH2 */ -#define PROTOCOL_MAJOR_2 2 -#define PROTOCOL_MINOR_2 0 - -/* - * Name for the service. The port named by this service overrides the - * default port if present. - */ -#define SSH_SERVICE_NAME "ssh" - -/* - * Name of the environment variable containing the process ID of the - * authentication agent. - */ -#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" - -/* - * Name of the environment variable containing the pathname of the - * authentication socket. - */ -#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" - -/* - * Environment variable for overwriting the default location of askpass - */ -#define SSH_ASKPASS_ENV "SSH_ASKPASS" - -/* - * Force host key length and server key length to differ by at least this - * many bits. This is to make double encryption with rsaref work. - */ -#define SSH_KEY_BITS_RESERVED 128 - -/* - * Length of the session key in bytes. (Specified as 256 bits in the - * protocol.) - */ -#define SSH_SESSION_KEY_LENGTH 32 - -/* Name of Kerberos service for SSH to use. */ -#define KRB4_SERVICE_NAME "rcmd" - -/* Used to identify ``EscapeChar none'' */ -#define SSH_ESCAPECHAR_NONE -2 - -/* - * unprivileged user when UsePrivilegeSeparation=yes; - * sshd will change its privileges to this user and its - * primary group. - */ -#ifndef SSH_PRIVSEP_USER -#define SSH_PRIVSEP_USER "sshd" -#endif - -/* Minimum modulus size (n) for RSA keys. */ -#define SSH_RSA_MINIMUM_MODULUS_SIZE 768 - -/* Listen backlog for sshd, ssh-agent and forwarding sockets */ -#define SSH_LISTEN_BACKLOG 128 - -/* - * Do not display banner when in remote command mode only. Note that RFC 4254 - * uses "exec" as a mode name for the channel opened for the execution of the - * given command. - */ -#define SSH_NO_BANNER_IN_EXEC_MODE 2 - -#ifdef __cplusplus -} -#endif - -#endif /* _SSH_H */ diff --git a/usr/src/cmd/ssh/include/ssh1.h b/usr/src/cmd/ssh/include/ssh1.h deleted file mode 100644 index 8a6f84c594..0000000000 --- a/usr/src/cmd/ssh/include/ssh1.h +++ /dev/null @@ -1,105 +0,0 @@ -/* $OpenBSD: ssh1.h,v 1.3 2001/05/30 12:55:13 markus Exp $ */ - -#ifndef _SSH1_H -#define _SSH1_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -/* - * Definition of message types. New values can be added, but old values - * should not be removed or without careful consideration of the consequences - * for compatibility. The maximum value is 254; value 255 is reserved for - * future extension. - */ -/* Message name */ /* msg code */ /* arguments */ -#define SSH_MSG_NONE 0 /* no message */ -#define SSH_MSG_DISCONNECT 1 /* cause (string) */ -#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */ -#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */ -#define SSH_CMSG_USER 4 /* user (string) */ -#define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */ -#define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */ -#define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */ -#define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */ -#define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */ -#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ -#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ -#define SSH_CMSG_EXEC_SHELL 12 /* */ -#define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */ -#define SSH_SMSG_SUCCESS 14 /* */ -#define SSH_SMSG_FAILURE 15 /* */ -#define SSH_CMSG_STDIN_DATA 16 /* data (string) */ -#define SSH_SMSG_STDOUT_DATA 17 /* data (string) */ -#define SSH_SMSG_STDERR_DATA 18 /* data (string) */ -#define SSH_CMSG_EOF 19 /* */ -#define SSH_SMSG_EXITSTATUS 20 /* status (int) */ -#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */ -#define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */ -#define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */ -#define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */ -#define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */ -/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ -#define SSH_SMSG_X11_OPEN 27 /* channel (int) */ -#define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */ -#define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */ -#define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */ -#define SSH_SMSG_AGENT_OPEN 31 /* port (int) */ -#define SSH_MSG_IGNORE 32 /* string */ -#define SSH_CMSG_EXIT_CONFIRMATION 33 /* */ -#define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */ -#define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */ -#define SSH_MSG_DEBUG 36 /* string */ -#define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */ -#define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */ -#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */ -#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */ -#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */ -#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */ -#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */ -#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */ -#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ - -/* protocol version 1.5 overloads some version 1.3 message types */ -#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE -#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION - -/* - * Authentication methods. New types can be added, but old types should not - * be removed for compatibility. The maximum allowed value is 31. - */ -#define SSH_AUTH_RHOSTS 1 -#define SSH_AUTH_RSA 2 -#define SSH_AUTH_PASSWORD 3 -#define SSH_AUTH_RHOSTS_RSA 4 -#define SSH_AUTH_TIS 5 -#define SSH_AUTH_KERBEROS 6 -#define SSH_PASS_KERBEROS_TGT 7 - /* 8 to 15 are reserved */ -#define SSH_PASS_AFS_TOKEN 21 - -/* Protocol flags. These are bit masks. */ -#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */ -#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SSH1_H */ diff --git a/usr/src/cmd/ssh/include/ssh2.h b/usr/src/cmd/ssh/include/ssh2.h deleted file mode 100644 index 20782bb266..0000000000 --- a/usr/src/cmd/ssh/include/ssh2.h +++ /dev/null @@ -1,184 +0,0 @@ -/* $OpenBSD: ssh2.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _SSH2_H -#define _SSH2_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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. - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * draft-ietf-secsh-architecture-05.txt - * - * Transport layer protocol: - * - * 1-19 Transport layer generic (e.g. disconnect, ignore, debug, - * etc) - * 20-29 Algorithm negotiation - * 30-49 Key exchange method specific (numbers can be reused for - * different authentication methods) - * - * User authentication protocol: - * - * 50-59 User authentication generic - * 60-79 User authentication method specific (numbers can be reused - * for different authentication methods) - * - * Connection protocol: - * - * 80-89 Connection protocol generic - * 90-127 Channel related messages - * - * Reserved for client protocols: - * - * 128-191 Reserved - * - * Local extensions: - * - * 192-255 Local extensions - */ - -/* ranges */ - -#define SSH2_MSG_TRANSPORT_MIN 1 -#define SSH2_MSG_TRANSPORT_MAX 49 -#define SSH2_MSG_USERAUTH_MIN 50 -#define SSH2_MSG_USERAUTH_MAX 79 -#define SSH2_MSG_CONNECTION_MIN 80 -#define SSH2_MSG_CONNECTION_MAX 127 -#define SSH2_MSG_RESERVED_MIN 128 -#define SSH2_MSG_RESERVED_MAX 191 -#define SSH2_MSG_LOCAL_MIN 192 -#define SSH2_MSG_LOCAL_MAX 255 -#define SSH2_MSG_MIN 1 -#define SSH2_MSG_MAX 255 - -/* transport layer: generic */ - -#define SSH2_MSG_DISCONNECT 1 -#define SSH2_MSG_IGNORE 2 -#define SSH2_MSG_UNIMPLEMENTED 3 -#define SSH2_MSG_DEBUG 4 -#define SSH2_MSG_SERVICE_REQUEST 5 -#define SSH2_MSG_SERVICE_ACCEPT 6 - -/* transport layer: alg negotiation */ - -#define SSH2_MSG_KEXINIT 20 -#define SSH2_MSG_NEWKEYS 21 - -/* transport layer: kex specific messages, can be reused */ - -#define SSH2_MSG_KEXDH_INIT 30 -#define SSH2_MSG_KEXDH_REPLY 31 - -/* dh-group-exchange */ -#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30 -#define SSH2_MSG_KEX_DH_GEX_GROUP 31 -#define SSH2_MSG_KEX_DH_GEX_INIT 32 -#define SSH2_MSG_KEX_DH_GEX_REPLY 33 -#define SSH2_MSG_KEX_DH_GEX_REQUEST 34 - -/* user authentication: generic */ - -#define SSH2_MSG_USERAUTH_REQUEST 50 -#define SSH2_MSG_USERAUTH_FAILURE 51 -#define SSH2_MSG_USERAUTH_SUCCESS 52 -#define SSH2_MSG_USERAUTH_BANNER 53 - -/* user authentication: method specific, can be reused */ - -#define SSH2_MSG_USERAUTH_PK_OK 60 -#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 -#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 -#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 - -/* connection protocol: generic */ - -#define SSH2_MSG_GLOBAL_REQUEST 80 -#define SSH2_MSG_REQUEST_SUCCESS 81 -#define SSH2_MSG_REQUEST_FAILURE 82 - -/* channel related messages */ - -#define SSH2_MSG_CHANNEL_OPEN 90 -#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 -#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 -#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 -#define SSH2_MSG_CHANNEL_DATA 94 -#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 -#define SSH2_MSG_CHANNEL_EOF 96 -#define SSH2_MSG_CHANNEL_CLOSE 97 -#define SSH2_MSG_CHANNEL_REQUEST 98 -#define SSH2_MSG_CHANNEL_SUCCESS 99 -#define SSH2_MSG_CHANNEL_FAILURE 100 - -/* ALTPRIVSEP */ -#ifdef ALTPRIVSEP -#define SSH2_PRIV_MSG_ALTPRIVSEP 254 -#endif /* ALTPRIVSEP */ - -/* disconnect reason code */ - -#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 -#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 -#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 -#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 -#define SSH2_DISCONNECT_RESERVED 4 -#define SSH2_DISCONNECT_MAC_ERROR 5 -#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 -#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 -#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 -#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 -#define SSH2_DISCONNECT_CONNECTION_LOST 10 -#define SSH2_DISCONNECT_BY_APPLICATION 11 -#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 -#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 -#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 -#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 - -/* misc */ - -#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 -#define SSH2_OPEN_CONNECT_FAILED 2 -#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 -#define SSH2_OPEN_RESOURCE_SHORTAGE 4 - -#define SSH2_EXTENDED_DATA_STDERR 1 - -#ifdef __cplusplus -} -#endif - -#endif /* _SSH2_H */ diff --git a/usr/src/cmd/ssh/include/sshconnect.h b/usr/src/cmd/ssh/include/sshconnect.h deleted file mode 100644 index 74eaccfbbc..0000000000 --- a/usr/src/cmd/ssh/include/sshconnect.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* $OpenBSD: sshconnect.h,v 1.17 2002/06/19 00:27:55 deraadt Exp $ */ - -#ifndef _SSHCONNECT_H -#define _SSHCONNECT_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Sensitive Sensitive; -struct Sensitive { - Key **keys; - int nkeys; - int external_keysign; -}; - -int -ssh_connect(const char *, struct sockaddr_storage *, ushort_t, int, int, - int, const char *); - -void -ssh_login(Sensitive *, const char *, struct sockaddr *, char *); - -int verify_host_key(char *, struct sockaddr *, Key *); -int accept_host_key(char *, struct sockaddr *, Key *); - -void ssh_kex(char *, struct sockaddr *); -void ssh_kex2(char *, struct sockaddr *); - -void ssh_userauth1(const char *, const char *, char *, Sensitive *); -void ssh_userauth2(const char *, const char *, char *, Sensitive *); - -void ssh_put_password(char *); - - -/* - * Macros to raise/lower permissions. - */ -#define PRIV_START do { \ - int save_errno = errno; \ - (void) seteuid(original_effective_uid); \ - errno = save_errno; \ -} while (0) - -#define PRIV_END do { \ - int save_errno = errno; \ - (void) seteuid(original_real_uid); \ - errno = save_errno; \ -} while (0) - -#ifdef __cplusplus -} -#endif - -#endif /* _SSHCONNECT_H */ diff --git a/usr/src/cmd/ssh/include/sshlogin.h b/usr/src/cmd/ssh/include/sshlogin.h deleted file mode 100644 index e7d2ee7c89..0000000000 --- a/usr/src/cmd/ssh/include/sshlogin.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* $OpenBSD: sshlogin.h,v 1.4 2002/08/29 15:57:25 stevesk Exp $ */ - -#ifndef _SSHLOGIN_H -#define _SSHLOGIN_H - -#ifdef __cplusplus -extern "C" { -#endif - -void -record_login(pid_t pid, const char *ttyname, const char *progname, - const char *user); -void -record_logout(pid_t pid, const char *ttyname, const char *progname, - const char *user); - -u_long -get_last_login_time(uid_t uid, const char *logname, char *buf, u_int bufsize); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSHLOGIN_H */ diff --git a/usr/src/cmd/ssh/include/sshpty.h b/usr/src/cmd/ssh/include/sshpty.h deleted file mode 100644 index f5dbf25640..0000000000 --- a/usr/src/cmd/ssh/include/sshpty.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $OpenBSD: sshpty.h,v 1.4 2002/03/04 17:27:39 stevesk Exp $ */ - -#ifndef _SSHPTY_H -#define _SSHPTY_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ - -int pty_allocate(int *, int *, char *, int); -void pty_release(const char *); -void pty_make_controlling_tty(int *, const char *); -void pty_change_window_size(int, int, int, int, int); -void pty_setowner(struct passwd *, const char *); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSHPTY_H */ diff --git a/usr/src/cmd/ssh/include/sshtty.h b/usr/src/cmd/ssh/include/sshtty.h deleted file mode 100644 index 584c63b6b9..0000000000 --- a/usr/src/cmd/ssh/include/sshtty.h +++ /dev/null @@ -1,58 +0,0 @@ -/* $OpenBSD: sshtty.h,v 1.2 2001/06/26 17:27:25 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) 2001 Markus Friedl. All rights reserved. - * Copyright (c) 2001 Kevin Steves. 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 _SSHTTY_H -#define _SSHTTY_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <termios.h> - -int in_raw_mode(void); -struct termios get_saved_tio(void); -void leave_raw_mode(void); -void enter_raw_mode(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSHTTY_H */ diff --git a/usr/src/cmd/ssh/include/strlcat.h b/usr/src/cmd/ssh/include/strlcat.h deleted file mode 100644 index b1b28cf33e..0000000000 --- a/usr/src/cmd/ssh/include/strlcat.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Id: strlcat.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _STRLCAT_H -#define _STRLCAT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" -#ifndef HAVE_STRLCAT -#include <sys/types.h> -size_t strlcat(char *dst, const char *src, size_t siz); -#endif /* !HAVE_STRLCAT */ - -#ifdef __cplusplus -} -#endif - -#endif /* _STRLCAT_H */ diff --git a/usr/src/cmd/ssh/include/strlcpy.h b/usr/src/cmd/ssh/include/strlcpy.h deleted file mode 100644 index 6215c105f7..0000000000 --- a/usr/src/cmd/ssh/include/strlcpy.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Id: strlcpy.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#ifndef _STRLCPY_H -#define _STRLCPY_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "config.h" -#ifndef HAVE_STRLCPY -#include <sys/types.h> -size_t strlcpy(char *dst, const char *src, size_t siz); -#endif /* !HAVE_STRLCPY */ - -#ifdef __cplusplus -} -#endif - -#endif /* _STRLCPY_H */ diff --git a/usr/src/cmd/ssh/include/strmode.h b/usr/src/cmd/ssh/include/strmode.h deleted file mode 100644 index cdbc4bd3c9..0000000000 --- a/usr/src/cmd/ssh/include/strmode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: strmode.h,v 1.3 2001/06/09 02:22:17 mouring Exp $ */ - -#ifndef _STRMODE_H -#define _STRMODE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef HAVE_STRMODE - -void strmode(register mode_t mode, register char *p); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _STRMODE_H */ diff --git a/usr/src/cmd/ssh/include/sys-queue.h b/usr/src/cmd/ssh/include/sys-queue.h deleted file mode 100644 index c5d8e6a5b5..0000000000 --- a/usr/src/cmd/ssh/include/sys-queue.h +++ /dev/null @@ -1,595 +0,0 @@ -/* $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $ */ -/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ - -#ifndef _SYS_QUEUE_H -#define _SYS_QUEUE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Copyright (c) 1991, 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. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -/* - * Ignore all <sys/queue.h> since older platforms have broken/incomplete - * <sys/queue.h> that are too hard to work around. - */ -#undef SLIST_HEAD -#undef SLIST_HEAD_INITIALIZER -#undef SLIST_ENTRY -#undef SLIST_FIRST -#undef SLIST_END -#undef SLIST_EMPTY -#undef SLIST_NEXT -#undef SLIST_FOREACH -#undef SLIST_INIT -#undef SLIST_INSERT_AFTER -#undef SLIST_INSERT_HEAD -#undef SLIST_REMOVE_HEAD -#undef SLIST_REMOVE -#undef LIST_HEAD -#undef LIST_HEAD_INITIALIZER -#undef LIST_ENTRY -#undef LIST_FIRST -#undef LIST_END -#undef LIST_EMPTY -#undef LIST_NEXT -#undef LIST_FOREACH -#undef LIST_INIT -#undef LIST_INSERT_AFTER -#undef LIST_INSERT_BEFORE -#undef LIST_INSERT_HEAD -#undef LIST_REMOVE -#undef LIST_REPLACE -#undef SIMPLEQ_HEAD -#undef SIMPLEQ_HEAD_INITIALIZER -#undef SIMPLEQ_ENTRY -#undef SIMPLEQ_FIRST -#undef SIMPLEQ_END -#undef SIMPLEQ_EMPTY -#undef SIMPLEQ_NEXT -#undef SIMPLEQ_FOREACH -#undef SIMPLEQ_INIT -#undef SIMPLEQ_INSERT_HEAD -#undef SIMPLEQ_INSERT_TAIL -#undef SIMPLEQ_INSERT_AFTER -#undef SIMPLEQ_REMOVE_HEAD -#undef TAILQ_HEAD -#undef TAILQ_HEAD_INITIALIZER -#undef TAILQ_ENTRY -#undef TAILQ_FIRST -#undef TAILQ_END -#undef TAILQ_NEXT -#undef TAILQ_LAST -#undef TAILQ_PREV -#undef TAILQ_EMPTY -#undef TAILQ_FOREACH -#undef TAILQ_FOREACH_REVERSE -#undef TAILQ_INIT -#undef TAILQ_INSERT_HEAD -#undef TAILQ_INSERT_TAIL -#undef TAILQ_INSERT_AFTER -#undef TAILQ_INSERT_BEFORE -#undef TAILQ_REMOVE -#undef TAILQ_REPLACE -#undef CIRCLEQ_HEAD -#undef CIRCLEQ_HEAD_INITIALIZER -#undef CIRCLEQ_ENTRY -#undef CIRCLEQ_FIRST -#undef CIRCLEQ_LAST -#undef CIRCLEQ_END -#undef CIRCLEQ_NEXT -#undef CIRCLEQ_PREV -#undef CIRCLEQ_EMPTY -#undef CIRCLEQ_FOREACH -#undef CIRCLEQ_FOREACH_REVERSE -#undef CIRCLEQ_INIT -#undef CIRCLEQ_INSERT_AFTER -#undef CIRCLEQ_INSERT_BEFORE -#undef CIRCLEQ_INSERT_HEAD -#undef CIRCLEQ_INSERT_TAIL -#undef CIRCLEQ_REMOVE -#undef CIRCLEQ_REPLACE - -/* - * This file defines five types of data structures: singly-linked lists, - * lists, simple queues, tail queues, and circular queues. - * - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -/* - * Singly-linked List definitions. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List access methods. - */ -#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_END(head) NULL -#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = SLIST_FIRST(head); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT(var, field)) - -/* - * Singly-linked List functions. - */ -#define SLIST_INIT(head) { \ - SLIST_FIRST(head) = SLIST_END(head); \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if ((head)->slh_first == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = (head)->slh_first; \ - while( curelm->field.sle_next != (elm) ) \ - curelm = curelm->field.sle_next; \ - curelm->field.sle_next = \ - curelm->field.sle_next->field.sle_next; \ - } \ -} while (0) - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List access methods - */ -#define LIST_FIRST(head) ((head)->lh_first) -#define LIST_END(head) NULL -#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_FOREACH(var, head, field) \ - for((var) = LIST_FIRST(head); \ - (var)!= LIST_END(head); \ - (var) = LIST_NEXT(var, field)) - -/* - * List functions. - */ -#define LIST_INIT(head) do { \ - LIST_FIRST(head) = LIST_END(head); \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} while (0) - -#define LIST_REPLACE(elm, elm2, field) do { \ - if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ - (elm2)->field.le_next->field.le_prev = \ - &(elm2)->field.le_next; \ - (elm2)->field.le_prev = (elm)->field.le_prev; \ - *(elm2)->field.le_prev = (elm2); \ -} while (0) - -/* - * Simple queue definitions. - */ -#define SIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define SIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define SIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for((var) = SIMPLEQ_FIRST(head); \ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT(var, field)) - -/* - * Simple queue functions. - */ -#define SIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (0) - -#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (0) - -#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ - if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * tail queue access methods - */ -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -/* XXX */ -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define TAILQ_EMPTY(head) \ - (TAILQ_FIRST(head) == TAILQ_END(head)) - -#define TAILQ_FOREACH(var, head, field) \ - for((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT(var, field)) - -#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ - for((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV(var, headname, field)) - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ - (elm2)->field.tqe_next->field.tqe_prev = \ - &(elm2)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm2)->field.tqe_next; \ - (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ - *(elm2)->field.tqe_prev = (elm2); \ -} while (0) - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue access methods - */ -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) -#define CIRCLEQ_LAST(head) ((head)->cqh_last) -#define CIRCLEQ_END(head) ((void *)(head)) -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) -#define CIRCLEQ_EMPTY(head) \ - (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for((var) = CIRCLEQ_FIRST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_NEXT(var, field)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for((var) = CIRCLEQ_LAST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_PREV(var, field)) - -/* - * Circular queue functions. - */ -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = CIRCLEQ_END(head); \ - (head)->cqh_last = CIRCLEQ_END(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = CIRCLEQ_END(head); \ - if ((head)->cqh_last == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = CIRCLEQ_END(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (0) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ -} while (0) - -#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ - CIRCLEQ_END(head)) \ - (head).cqh_last = (elm2); \ - else \ - (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ - if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ - CIRCLEQ_END(head)) \ - (head).cqh_first = (elm2); \ - else \ - (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ -} while (0) - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_QUEUE_H */ diff --git a/usr/src/cmd/ssh/include/sys-tree.h b/usr/src/cmd/ssh/include/sys-tree.h deleted file mode 100644 index fbd31a8f7c..0000000000 --- a/usr/src/cmd/ssh/include/sys-tree.h +++ /dev/null @@ -1,682 +0,0 @@ -/* $OpenBSD: tree.h,v 1.6 2002/06/11 22:09:52 provos Exp $ */ -/* - * Copyright 2002 Niels Provos <provos@citi.umich.edu> - * 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 _SYS_TREE_H -#define _SYS_TREE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This file defines data structures for different types of trees: - * splay trees and red-black trees. - * - * A splay tree is a self-organizing data structure. Every operation - * on the tree causes a splay to happen. The splay moves the requested - * node to the root of the tree and partly rebalances it. - * - * This has the benefit that request locality causes faster lookups as - * the requested nodes move to the top of the tree. On the other hand, - * every lookup causes memory writes. - * - * The Balance Theorem bounds the total access time for m operations - * and n inserts on an initially empty tree as O((m + n)lg n). The - * amortized cost for a sequence of m accesses to a splay tree is O(lg n); - * - * A red-black tree is a binary search tree with the node color as an - * extra attribute. It fulfills a set of conditions: - * - every search path from the root to a leaf consists of the - * same number of black nodes, - * - each red node (except for the root) has a black parent, - * - each leaf node is black. - * - * Every operation on a red-black tree is bounded as O(lg n). - * The maximum height of a red-black tree is 2lg (n+1). - */ - -#define SPLAY_HEAD(name, type) \ -struct name { \ - struct type *sph_root; /* root of the tree */ \ -} - -#define SPLAY_INITIALIZER(root) \ - { NULL } - -#define SPLAY_INIT(root) do { \ - (root)->sph_root = NULL; \ -} while (0) - -#define SPLAY_ENTRY(type) \ -struct { \ - struct type *spe_left; /* left element */ \ - struct type *spe_right; /* right element */ \ -} - -#define SPLAY_LEFT(elm, field) (elm)->field.spe_left -#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right -#define SPLAY_ROOT(head) (head)->sph_root -#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) - -/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ -#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (0) - -#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (0) - -#define SPLAY_LINKLEFT(head, tmp, field) do { \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ -} while (0) - -#define SPLAY_LINKRIGHT(head, tmp, field) do { \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ -} while (0) - -#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ - SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ -} while (0) - -/* Generates prototypes and inline functions */ - -#define SPLAY_PROTOTYPE(name, type, field, cmp) \ -void name##_SPLAY(struct name *, struct type *); \ -void name##_SPLAY_MINMAX(struct name *, int); \ -struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ -struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ - \ -/* Finds the node with the same key as elm */ \ -static __inline struct type * \ -name##_SPLAY_FIND(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) \ - return(NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) \ - return (head->sph_root); \ - return (NULL); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_NEXT(struct name *head, struct type *elm) \ -{ \ - name##_SPLAY(head, elm); \ - if (SPLAY_RIGHT(elm, field) != NULL) { \ - elm = SPLAY_RIGHT(elm, field); \ - while (SPLAY_LEFT(elm, field) != NULL) { \ - elm = SPLAY_LEFT(elm, field); \ - } \ - } else \ - elm = NULL; \ - return (elm); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_MIN_MAX(struct name *head, int val) \ -{ \ - name##_SPLAY_MINMAX(head, val); \ - return (SPLAY_ROOT(head)); \ -} - -/* Main splay operation. - * Moves node close to the key of elm to top - */ -#define SPLAY_GENERATE(name, type, field, cmp) \ -struct type * \ -name##_SPLAY_INSERT(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) { \ - SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ - } else { \ - int __comp; \ - name##_SPLAY(head, elm); \ - __comp = (cmp)(elm, (head)->sph_root); \ - if(__comp < 0) { \ - SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ - SPLAY_RIGHT(elm, field) = (head)->sph_root; \ - SPLAY_LEFT((head)->sph_root, field) = NULL; \ - } else if (__comp > 0) { \ - SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT(elm, field) = (head)->sph_root; \ - SPLAY_RIGHT((head)->sph_root, field) = NULL; \ - } else \ - return ((head)->sph_root); \ - } \ - (head)->sph_root = (elm); \ - return (NULL); \ -} \ - \ -struct type * \ -name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *__tmp; \ - if (SPLAY_EMPTY(head)) \ - return (NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) { \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ - } else { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ - name##_SPLAY(head, elm); \ - SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ - } \ - return (elm); \ - } \ - return (NULL); \ -} \ - \ -void \ -name##_SPLAY(struct name *head, struct type *elm) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ - int __comp; \ -\ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ - __left = __right = &__node; \ -\ - while ((__comp = (cmp)(elm, (head)->sph_root))) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) > 0){ \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} \ - \ -/* Splay with either the minimum or the maximum element \ - * Used to find minimum or maximum element in tree. \ - */ \ -void name##_SPLAY_MINMAX(struct name *head, int __comp) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ -\ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ - __left = __right = &__node; \ -\ - while (1) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp > 0) { \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} - -#define SPLAY_NEGINF -1 -#define SPLAY_INF 1 - -#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) -#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) -#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) -#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) -#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) -#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) - -#define SPLAY_FOREACH(x, name, head) \ - for ((x) = SPLAY_MIN(name, head); \ - (x) != NULL; \ - (x) = SPLAY_NEXT(name, head, x)) - -/* Macros that define a red-back tree */ -#define RB_HEAD(name, type) \ -struct name { \ - struct type *rbh_root; /* root of the tree */ \ -} - -#define RB_INITIALIZER(root) \ - { NULL } - -#define RB_INIT(root) do { \ - (root)->rbh_root = NULL; \ -} while (0) - -#define RB_BLACK 0 -#define RB_RED 1 -#define RB_ENTRY(type) \ -struct { \ - struct type *rbe_left; /* left element */ \ - struct type *rbe_right; /* right element */ \ - struct type *rbe_parent; /* parent element */ \ - int rbe_color; /* node color */ \ -} - -#define RB_LEFT(elm, field) (elm)->field.rbe_left -#define RB_RIGHT(elm, field) (elm)->field.rbe_right -#define RB_PARENT(elm, field) (elm)->field.rbe_parent -#define RB_COLOR(elm, field) (elm)->field.rbe_color -#define RB_ROOT(head) (head)->rbh_root -#define RB_EMPTY(head) (RB_ROOT(head) == NULL) - -#define RB_SET(elm, parent, field) do { \ - RB_PARENT(elm, field) = parent; \ - RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ - RB_COLOR(elm, field) = RB_RED; \ -} while (0) - -#define RB_SET_BLACKRED(black, red, field) do { \ - RB_COLOR(black, field) = RB_BLACK; \ - RB_COLOR(red, field) = RB_RED; \ -} while (0) - -#ifndef RB_AUGMENT -#define RB_AUGMENT(x) -#endif - -#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ - (tmp) = RB_RIGHT(elm, field); \ - if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ - RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - RB_AUGMENT(RB_PARENT(elm, field)); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_LEFT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ -} while (0) - -#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ - (tmp) = RB_LEFT(elm, field); \ - if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ - RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - RB_AUGMENT(RB_PARENT(elm, field)); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_RIGHT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ -} while (0) - -/* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ -void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -struct type *name##_RB_REMOVE(struct name *, struct type *); \ -struct type *name##_RB_INSERT(struct name *, struct type *); \ -struct type *name##_RB_FIND(struct name *, struct type *); \ -struct type *name##_RB_NEXT(struct name *, struct type *); \ -struct type *name##_RB_MINMAX(struct name *, int); - -/* Main rb operation. - * Moves node close to the key of elm to top - */ -#define RB_GENERATE(name, type, field, cmp) \ -void \ -name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ -{ \ - struct type *parent, *gparent, *tmp; \ - while ((parent = RB_PARENT(elm, field)) && \ - RB_COLOR(parent, field) == RB_RED) { \ - gparent = RB_PARENT(parent, field); \ - if (parent == RB_LEFT(gparent, field)) { \ - tmp = RB_RIGHT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_RIGHT(parent, field) == elm) { \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_RIGHT(head, gparent, tmp, field); \ - } else { \ - tmp = RB_LEFT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_LEFT(parent, field) == elm) { \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_LEFT(head, gparent, tmp, field); \ - } \ - } \ - RB_COLOR(head->rbh_root, field) = RB_BLACK; \ -} \ - \ -void \ -name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ -{ \ - struct type *tmp; \ - while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ - elm != RB_ROOT(head)) { \ - if (RB_LEFT(parent, field) == elm) { \ - tmp = RB_RIGHT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ - struct type *oleft; \ - if ((oleft = RB_LEFT(tmp, field)))\ - RB_COLOR(oleft, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_RIGHT(head, tmp, oleft, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_RIGHT(tmp, field)) \ - RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } else { \ - tmp = RB_LEFT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ - struct type *oright; \ - if ((oright = RB_RIGHT(tmp, field)))\ - RB_COLOR(oright, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_LEFT(head, tmp, oright, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_LEFT(tmp, field)) \ - RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } \ - } \ - if (elm) \ - RB_COLOR(elm, field) = RB_BLACK; \ -} \ - \ -struct type * \ -name##_RB_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *child, *parent, *old = elm; \ - int color; \ - if (RB_LEFT(elm, field) == NULL) \ - child = RB_RIGHT(elm, field); \ - else if (RB_RIGHT(elm, field) == NULL) \ - child = RB_LEFT(elm, field); \ - else { \ - struct type *left; \ - elm = RB_RIGHT(elm, field); \ - while ((left = RB_LEFT(elm, field))) \ - elm = left; \ - child = RB_RIGHT(elm, field); \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ - if (RB_PARENT(elm, field) == old) \ - parent = elm; \ - (elm)->field = (old)->field; \ - if (RB_PARENT(old, field)) { \ - if (RB_LEFT(RB_PARENT(old, field), field) == old)\ - RB_LEFT(RB_PARENT(old, field), field) = elm;\ - else \ - RB_RIGHT(RB_PARENT(old, field), field) = elm;\ - RB_AUGMENT(RB_PARENT(old, field)); \ - } else \ - RB_ROOT(head) = elm; \ - RB_PARENT(RB_LEFT(old, field), field) = elm; \ - if (RB_RIGHT(old, field)) \ - RB_PARENT(RB_RIGHT(old, field), field) = elm; \ - if (parent) { \ - left = parent; \ - do { \ - RB_AUGMENT(left); \ - } while ((left = RB_PARENT(left, field))); \ - } \ - goto color; \ - } \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ -color: \ - if (color == RB_BLACK) \ - name##_RB_REMOVE_COLOR(head, parent, child); \ - return (old); \ -} \ - \ -/* Inserts a node into the RB tree */ \ -struct type * \ -name##_RB_INSERT(struct name *head, struct type *elm) \ -{ \ - struct type *tmp; \ - struct type *parent = NULL; \ - int comp = 0; \ - tmp = RB_ROOT(head); \ - while (tmp) { \ - parent = tmp; \ - comp = (cmp)(elm, parent); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - RB_SET(elm, parent, field); \ - if (parent != NULL) { \ - if (comp < 0) \ - RB_LEFT(parent, field) = elm; \ - else \ - RB_RIGHT(parent, field) = elm; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = elm; \ - name##_RB_INSERT_COLOR(head, elm); \ - return (NULL); \ -} \ - \ -/* Finds the node with the same key as elm */ \ -struct type * \ -name##_RB_FIND(struct name *head, struct type *elm) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (NULL); \ -} \ - \ -struct type * \ -name##_RB_NEXT(struct name *head, struct type *elm) \ -{ \ - if (RB_RIGHT(elm, field)) { \ - elm = RB_RIGHT(elm, field); \ - while (RB_LEFT(elm, field)) \ - elm = RB_LEFT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ -} \ - \ -struct type * \ -name##_RB_MINMAX(struct name *head, int val) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - struct type *parent = NULL; \ - while (tmp) { \ - parent = tmp; \ - if (val < 0) \ - tmp = RB_LEFT(tmp, field); \ - else \ - tmp = RB_RIGHT(tmp, field); \ - } \ - return (parent); \ -} - -#define RB_NEGINF -1 -#define RB_INF 1 - -#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) -#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) -#define RB_FIND(name, x, y) name##_RB_FIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y) -#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) -#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) - -#define RB_FOREACH(x, name, head) \ - for ((x) = RB_MIN(name, head); \ - (x) != NULL; \ - (x) = name##_RB_NEXT(head, x)) - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_TREE_H */ diff --git a/usr/src/cmd/ssh/include/tildexpand.h b/usr/src/cmd/ssh/include/tildexpand.h deleted file mode 100644 index 22e95b7779..0000000000 --- a/usr/src/cmd/ssh/include/tildexpand.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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". - */ - -/* $OpenBSD: tildexpand.h,v 1.4 2001/06/26 17:27:25 markus Exp $ */ - -#ifndef _TILDEXPAND_H -#define _TILDEXPAND_H - -#ifdef __cplusplus -extern "C" { -#endif - -char *tilde_expand_filename(const char *, uid_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _TILDEXPAND_H */ diff --git a/usr/src/cmd/ssh/include/ttymodes.h b/usr/src/cmd/ssh/include/ttymodes.h deleted file mode 100644 index d464e7f308..0000000000 --- a/usr/src/cmd/ssh/include/ttymodes.h +++ /dev/null @@ -1,190 +0,0 @@ -/* $OpenBSD: ttymodes.h,v 1.12 2002/03/04 17:27:39 stevesk Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * NOTE: This file MUST NOT have a header guard added!!! - * - * This header is included twice in ttymodes.c, which defines the TTYCHAR() - * and TTYMODE() macros, used below, twice, once prior to inclusion of this - * file in tty_make_modes() and once prior to inclusion of this file in - * tty_parse_modes(). - */ - -/* - * 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". - */ - -/* - * SSH2 tty modes support by Kevin Steves. - * Copyright (c) 2001 Kevin Steves. 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 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * SSH1: - * 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). - * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer - * arguments. Opcodes 160-255 are not yet defined, and cause parsing to - * stop (they should only be used after any other data). - * - * SSH2: - * Differences between SSH1 and SSH2 terminal mode encoding include: - * 1. Encoded terminal modes are represented as a string, and a stream - * of bytes within that string. - * 2. Opcode arguments are uint32 (1-159); 160-255 remain undefined. - * 3. The values for TTY_OP_ISPEED and TTY_OP_OSPEED are different; - * 128 and 129 vs. 192 and 193 respectively. - * - * The client puts in the stream any modes it knows about, and the - * server ignores any modes it does not know about. This allows some degree - * of machine-independence, at least between systems that use a posix-like - * tty interface. The protocol can support other systems as well, but might - * require reimplementing as mode names would likely be different. - */ - -/* - * Some constants and prototypes are defined in packet.h; this file - * is only intended for including from ttymodes.c. - */ - -/* termios macro */ -/* name, op */ -TTYCHAR(VINTR, 1) -TTYCHAR(VQUIT, 2) -TTYCHAR(VERASE, 3) -#if defined(VKILL) -TTYCHAR(VKILL, 4) -#endif /* VKILL */ -TTYCHAR(VEOF, 5) -#if defined(VEOL) -TTYCHAR(VEOL, 6) -#endif /* VEOL */ -#ifdef VEOL2 -TTYCHAR(VEOL2, 7) -#endif /* VEOL2 */ -TTYCHAR(VSTART, 8) -TTYCHAR(VSTOP, 9) -#if defined(VSUSP) -TTYCHAR(VSUSP, 10) -#endif /* VSUSP */ -#if defined(VDSUSP) -TTYCHAR(VDSUSP, 11) -#endif /* VDSUSP */ -#if defined(VREPRINT) -TTYCHAR(VREPRINT, 12) -#endif /* VREPRINT */ -#if defined(VWERASE) -TTYCHAR(VWERASE, 13) -#endif /* VWERASE */ -#if defined(VLNEXT) -TTYCHAR(VLNEXT, 14) -#endif /* VLNEXT */ -#if defined(VFLUSH) -TTYCHAR(VFLUSH, 15) -#endif /* VFLUSH */ -#ifdef VSWTCH -TTYCHAR(VSWTCH, 16) -#endif /* VSWTCH */ -#if defined(VSTATUS) -TTYCHAR(VSTATUS, 17) -#endif /* VSTATUS */ -#ifdef VDISCARD -TTYCHAR(VDISCARD, 18) -#endif /* VDISCARD */ - -/* name, field, op */ -TTYMODE(IGNPAR, c_iflag, 30) -TTYMODE(PARMRK, c_iflag, 31) -TTYMODE(INPCK, c_iflag, 32) -TTYMODE(ISTRIP, c_iflag, 33) -TTYMODE(INLCR, c_iflag, 34) -TTYMODE(IGNCR, c_iflag, 35) -TTYMODE(ICRNL, c_iflag, 36) -#if defined(IUCLC) -TTYMODE(IUCLC, c_iflag, 37) -#endif -TTYMODE(IXON, c_iflag, 38) -TTYMODE(IXANY, c_iflag, 39) -TTYMODE(IXOFF, c_iflag, 40) -#ifdef IMAXBEL -TTYMODE(IMAXBEL,c_iflag, 41) -#endif /* IMAXBEL */ - -TTYMODE(ISIG, c_lflag, 50) -TTYMODE(ICANON, c_lflag, 51) -#ifdef XCASE -TTYMODE(XCASE, c_lflag, 52) -#endif -TTYMODE(ECHO, c_lflag, 53) -TTYMODE(ECHOE, c_lflag, 54) -TTYMODE(ECHOK, c_lflag, 55) -TTYMODE(ECHONL, c_lflag, 56) -TTYMODE(NOFLSH, c_lflag, 57) -TTYMODE(TOSTOP, c_lflag, 58) -#ifdef IEXTEN -TTYMODE(IEXTEN, c_lflag, 59) -#endif /* IEXTEN */ -#if defined(ECHOCTL) -TTYMODE(ECHOCTL,c_lflag, 60) -#endif /* ECHOCTL */ -#ifdef ECHOKE -TTYMODE(ECHOKE, c_lflag, 61) -#endif /* ECHOKE */ -#if defined(PENDIN) -TTYMODE(PENDIN, c_lflag, 62) -#endif /* PENDIN */ - -TTYMODE(OPOST, c_oflag, 70) -#if defined(OLCUC) -TTYMODE(OLCUC, c_oflag, 71) -#endif -#ifdef ONLCR -TTYMODE(ONLCR, c_oflag, 72) -#endif -#ifdef OCRNL -TTYMODE(OCRNL, c_oflag, 73) -#endif -#ifdef ONOCR -TTYMODE(ONOCR, c_oflag, 74) -#endif -#ifdef ONLRET -TTYMODE(ONLRET, c_oflag, 75) -#endif - -TTYMODE(CS7, c_cflag, 90) -TTYMODE(CS8, c_cflag, 91) -TTYMODE(PARENB, c_cflag, 92) -TTYMODE(PARODD, c_cflag, 93) diff --git a/usr/src/cmd/ssh/include/uidswap.h b/usr/src/cmd/ssh/include/uidswap.h deleted file mode 100644 index 5444f02d32..0000000000 --- a/usr/src/cmd/ssh/include/uidswap.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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". - */ - -/* $OpenBSD: uidswap.h,v 1.9 2001/06/26 17:27:25 markus Exp $ */ - -#ifndef _UIDSWAP_H -#define _UIDSWAP_H - -#ifdef __cplusplus -extern "C" { -#endif - -void temporarily_use_uid(struct passwd *); -void restore_uid(void); -void permanently_set_uid(struct passwd *, char *); - -#ifdef __cplusplus -} -#endif - -#endif /* _UIDSWAP_H */ diff --git a/usr/src/cmd/ssh/include/uuencode.h b/usr/src/cmd/ssh/include/uuencode.h deleted file mode 100644 index 89ba430779..0000000000 --- a/usr/src/cmd/ssh/include/uuencode.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $OpenBSD: uuencode.h,v 1.9 2002/02/25 16:33:27 markus Exp $ */ - -#ifndef _UUENCODE_H -#define _UUENCODE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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. - */ - -int uuencode(u_char *, u_int, char *, size_t); -int uudecode(const char *, u_char *, size_t); -void dump_base64(FILE *, u_char *, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _UUENCODE_H */ diff --git a/usr/src/cmd/ssh/include/version.h b/usr/src/cmd/ssh/include/version.h deleted file mode 100644 index 7d641b6967..0000000000 --- a/usr/src/cmd/ssh/include/version.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* $OpenBSD: version.h,v 1.35 2002/10/01 13:24:50 markus Exp $ */ - -#ifndef _VERSION_H -#define _VERSION_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* #define SSH_VERSION "OpenSSH_3.5p1" */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _VERSION_H */ diff --git a/usr/src/cmd/ssh/include/xlist.h b/usr/src/cmd/ssh/include/xlist.h deleted file mode 100644 index a6675c246b..0000000000 --- a/usr/src/cmd/ssh/include/xlist.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _XLIST_H -#define _XLIST_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -char ** xsplit(char *list, char sep); -char * xjoin(char **alist, char sep); -void xfree_split_list(char **list); - -#ifdef __cplusplus -} -#endif - -#endif /* _XLIST_H */ diff --git a/usr/src/cmd/ssh/include/xmalloc.h b/usr/src/cmd/ssh/include/xmalloc.h deleted file mode 100644 index 6477737a4e..0000000000 --- a/usr/src/cmd/ssh/include/xmalloc.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $OpenBSD: xmalloc.h,v 1.9 2002/06/19 00:27:55 deraadt Exp $ */ - -#ifndef _XMALLOC_H -#define _XMALLOC_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * 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". - */ - -void *xmalloc(size_t); -void *xcalloc(size_t, size_t); -void *xrealloc(void *, size_t); -void xfree(void *); -char *xstrdup(const char *); - -#ifdef __cplusplus -} -#endif - -#endif /* _XMALLOC_H */ diff --git a/usr/src/cmd/ssh/include/xmmap.h b/usr/src/cmd/ssh/include/xmmap.h deleted file mode 100644 index 09723b4ecf..0000000000 --- a/usr/src/cmd/ssh/include/xmmap.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 _XMMAP_H -#define _XMMAP_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -void *xmmap(size_t size); - -#ifdef __cplusplus -} -#endif - -#endif /* _XMMAP_H */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/Makefile b/usr/src/cmd/ssh/libopenbsd-compat/Makefile deleted file mode 100644 index 75acb9e97b..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# -# cmd/ssh/libssh/Makefile - -include $(SRC)/lib/Makefile.lib -include ../Makefile.ssh-common - -SUBDIRS= $(MACH) - -# Need to override the TEXT_DOMAIN here because we included a Makefile from -# usr/src/lib but this is a private library which is part of SUNW_OST_OSCMD -TEXT_DOMAIN= SUNW_OST_OSCMD - -POFILE=_messages.po - -all := TARGET= all -clean := TARGET= clean -clobber := TARGET= clobber -install := TARGET= install -lint := TARGET= lint -$(POFILE) := TARGET= $(POFILE) - -.KEEP_STATE: - -all clean clobber install lint $(POFILE): $(SUBDIRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include $(SRC)/lib/Makefile.targ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/Makefile.com b/usr/src/cmd/ssh/libopenbsd-compat/Makefile.com deleted file mode 100644 index 0b8ad1622b..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/Makefile.com +++ /dev/null @@ -1,92 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/libopenbsd-compat/Makefile.com -# - -LIBRARY = libopenbsd-compat.a -VERS = .1 - -OBJECTS = \ - bsd-arc4random.o \ - bsd-cray.o \ - bsd-cygwin_util.o \ - bsd-getpeereid.o \ - bsd-misc.o \ - bsd-asprintf.o \ - bsd-snprintf.o \ - bsd-waitpid.o \ - fake-getaddrinfo.o \ - fake-getnameinfo.o \ - xmmap.o \ - base64.o \ - bindresvport.o \ - dirname.o \ - getcwd.o \ - getgrouplist.o \ - getopt.o \ - glob.o \ - inet_aton.o \ - inet_ntoa.o \ - inet_ntop.o \ - mktemp.o \ - readpassphrase.o \ - realpath.o \ - rresvport.o \ - setenv.o \ - setproctitle.o \ - sigact.o \ - strlcat.o \ - strlcpy.o \ - strmode.o \ - port-irix.o \ - port-aix.o - -include $(SRC)/lib/Makefile.lib - -BUILD.AR = $(RM) $@ ; $(AR) $(ARFLAGS) $@ $(AROBJS) - -SRCDIR = ../common -SRCS = $(OBJECTS:%.o=../common/%.c) - -LIBS = $(LIBRARY) $(LINTLIB) - -$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) - -POFILE_DIR = ../.. - -.KEEP_STATE: - -all: $(LIBS) - -# lint requires the (non-installed) lint library -lint: $(LINTLIB) .WAIT lintcheck - -include $(SRC)/lib/Makefile.targ - -objs/%.o: $(SRCDIR)/%.c - $(COMPILE.c) -o $@ $< - $(POST_PROCESS_O) - -include ../../Makefile.ssh-common -include ../../Makefile.msg.targ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/base64.c b/usr/src/cmd/ssh/libopenbsd-compat/common/base64.c deleted file mode 100644 index 62776ce4e0..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/base64.c +++ /dev/null @@ -1,319 +0,0 @@ -/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */ - -/* - * Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1995 by International Business Machines, Inc. - * - * International Business Machines, Inc. (hereinafter called IBM) grants - * permission under its copyrights to use, copy, modify, and distribute this - * Software with or without fee, provided that the above copyright notice and - * all paragraphs of this notice appear in all copies, and that the name of IBM - * not be used in connection with the marketing of any product incorporating - * the Software or modifications thereof, without specific, written prior - * permission. - * - * To the extent it has a right to do so, IBM grants an immunity from suit - * under its patents, if any, for the use, sale or manufacture of products to - * the extent that such products are used for performing Domain Name System - * dynamic updates in TCP/IP networks by means of the Software. No immunity is - * granted for any product per se or for any other function of any product. - * - * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, - * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN - * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" - -#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <stdio.h> - -#include <stdlib.h> -#include <string.h> - -#include "base64.h" - -/* XXX abort illegal in library */ -#define Assert(Cond) if (!(Cond)) abort() - -static const char Base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char Pad64 = '='; - -/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) - The following encoding technique is taken from RFC 1521 by Borenstein - and Freed. It is reproduced here in a slightly edited form for - convenience. - - A 65-character subset of US-ASCII is used, enabling 6 bits to be - represented per printable character. (The extra 65th character, "=", - is used to signify a special processing function.) - - The encoding process represents 24-bit groups of input bits as output - strings of 4 encoded characters. Proceeding from left to right, a - 24-bit input group is formed by concatenating 3 8-bit input groups. - These 24 bits are then treated as 4 concatenated 6-bit groups, each - of which is translated into a single digit in the base64 alphabet. - - Each 6-bit group is used as an index into an array of 64 printable - characters. The character referenced by the index is placed in the - output string. - - Table 1: The Base64 Alphabet - - Value Encoding Value Encoding Value Encoding Value Encoding - 0 A 17 R 34 i 51 z - 1 B 18 S 35 j 52 0 - 2 C 19 T 36 k 53 1 - 3 D 20 U 37 l 54 2 - 4 E 21 V 38 m 55 3 - 5 F 22 W 39 n 56 4 - 6 G 23 X 40 o 57 5 - 7 H 24 Y 41 p 58 6 - 8 I 25 Z 42 q 59 7 - 9 J 26 a 43 r 60 8 - 10 K 27 b 44 s 61 9 - 11 L 28 c 45 t 62 + - 12 M 29 d 46 u 63 / - 13 N 30 e 47 v - 14 O 31 f 48 w (pad) = - 15 P 32 g 49 x - 16 Q 33 h 50 y - - Special processing is performed if fewer than 24 bits are available - at the end of the data being encoded. A full encoding quantum is - always completed at the end of a quantity. When fewer than 24 input - bits are available in an input group, zero bits are added (on the - right) to form an integral number of 6-bit groups. Padding at the - end of the data is performed using the '=' character. - - Since all base64 input is an integral number of octets, only the - ------------------------------------------------- - following cases can arise: - - (1) the final quantum of encoding input is an integral - multiple of 24 bits; here, the final unit of encoded - output will be an integral multiple of 4 characters - with no "=" padding, - (2) the final quantum of encoding input is exactly 8 bits; - here, the final unit of encoded output will be two - characters followed by two "=" padding characters, or - (3) the final quantum of encoding input is exactly 16 bits; - here, the final unit of encoded output will be three - characters followed by one "=" padding character. - */ - -int -b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) -{ - size_t datalength = 0; - u_char input[3]; - u_char output[4]; - int i; - - while (2 < srclength) { - input[0] = *src++; - input[1] = *src++; - input[2] = *src++; - srclength -= 3; - - output[0] = input[0] >> 2; - output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); - output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); - output[3] = input[2] & 0x3f; - Assert(output[0] < 64); - Assert(output[1] < 64); - Assert(output[2] < 64); - Assert(output[3] < 64); - - if (datalength + 4 > targsize) - return (-1); - target[datalength++] = Base64[output[0]]; - target[datalength++] = Base64[output[1]]; - target[datalength++] = Base64[output[2]]; - target[datalength++] = Base64[output[3]]; - } - - /* Now we worry about padding. */ - if (0 != srclength) { - /* Get what's left. */ - input[0] = input[1] = input[2] = '\0'; - for (i = 0; i < srclength; i++) - input[i] = *src++; - - output[0] = input[0] >> 2; - output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); - output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); - Assert(output[0] < 64); - Assert(output[1] < 64); - Assert(output[2] < 64); - - if (datalength + 4 > targsize) - return (-1); - target[datalength++] = Base64[output[0]]; - target[datalength++] = Base64[output[1]]; - if (srclength == 1) - target[datalength++] = Pad64; - else - target[datalength++] = Base64[output[2]]; - target[datalength++] = Pad64; - } - if (datalength >= targsize) - return (-1); - target[datalength] = '\0'; /* Returned value doesn't count \0. */ - return (datalength); -} - -/* skips all whitespace anywhere. - converts characters, four at a time, starting at (or after) - src from base - 64 numbers into three 8 bit bytes in the target area. - it returns the number of data bytes stored at the target, or -1 on error. - */ - -int -b64_pton(u_char const *src, u_char *target, size_t targsize) -{ - int tarindex, state, ch; - char *pos; - - state = 0; - tarindex = 0; - - while ((ch = *src++) != '\0') { - if (isspace(ch)) /* Skip whitespace anywhere. */ - continue; - - if (ch == Pad64) - break; - - pos = strchr(Base64, ch); - if (pos == 0) /* A non-base64 character. */ - return (-1); - - switch (state) { - case 0: - if (target) { - if (tarindex >= targsize) - return (-1); - target[tarindex] = (pos - Base64) << 2; - } - state = 1; - break; - case 1: - if (target) { - if (tarindex + 1 >= targsize) - return (-1); - target[tarindex] |= (pos - Base64) >> 4; - target[tarindex+1] = ((pos - Base64) & 0x0f) - << 4 ; - } - tarindex++; - state = 2; - break; - case 2: - if (target) { - if (tarindex + 1 >= targsize) - return (-1); - target[tarindex] |= (pos - Base64) >> 2; - target[tarindex+1] = ((pos - Base64) & 0x03) - << 6; - } - tarindex++; - state = 3; - break; - case 3: - if (target) { - if (tarindex >= targsize) - return (-1); - target[tarindex] |= (pos - Base64); - } - tarindex++; - state = 0; - break; - } - } - - /* - * We are done decoding Base-64 chars. Let's see if we ended - * on a byte boundary, and/or with erroneous trailing characters. - */ - - if (ch == Pad64) { /* We got a pad char. */ - ch = *src++; /* Skip it, get next. */ - switch (state) { - case 0: /* Invalid = in first position */ - case 1: /* Invalid = in second position */ - return (-1); - - case 2: /* Valid, means one byte of info */ - /* Skip any number of spaces. */ - for (; ch != '\0'; ch = *src++) - if (!isspace(ch)) - break; - /* Make sure there is another trailing = sign. */ - if (ch != Pad64) - return (-1); - ch = *src++; /* Skip the = */ - /* Fall through to "single trailing =" case. */ - /* FALLTHROUGH */ - - case 3: /* Valid, means two bytes of info */ - /* - * We know this char is an =. Is there anything but - * whitespace after it? - */ - for (; ch != '\0'; ch = *src++) - if (!isspace(ch)) - return (-1); - - /* - * Now make sure for cases 2 and 3 that the "extra" - * bits that slopped past the last full byte were - * zeros. If we don't check them, they become a - * subliminal channel. - */ - if (target && target[tarindex] != 0) - return (-1); - } - } else { - /* - * We ended by seeing the end of the string. Make sure we - * have no partial bytes lying around. - */ - if (state != 0) - return (-1); - } - - return (tarindex); -} - -#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bindresvport.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bindresvport.c deleted file mode 100644 index 8432233bb6..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bindresvport.c +++ /dev/null @@ -1,127 +0,0 @@ -/* This file has be modified from the original OpenBSD source */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -#include "includes.h" - -#ifndef HAVE_BINDRESVPORT_SA - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: bindresvport.c,v 1.13 2000/01/26 03:43:21 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -/* - * Copyright (c) 1987 by Sun Microsystems, Inc. - * - * Portions Copyright(C) 1996, Jason Downs. All rights reserved. - */ - -#include "includes.h" - -#define STARTPORT 600 -#define ENDPORT (IPPORT_RESERVED - 1) -#define NPORTS (ENDPORT - STARTPORT + 1) - -/* - * Bind a socket to a privileged IP port - */ -int -bindresvport_sa(sd, sa) - int sd; - struct sockaddr *sa; -{ - int error, af; - struct sockaddr_storage myaddr; - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; - u_int16_t *portp; - u_int16_t port; - socklen_t salen; - int i; - - if (sa == NULL) { - memset(&myaddr, 0, sizeof(myaddr)); - sa = (struct sockaddr *)&myaddr; - - if (getsockname(sd, sa, &salen) == -1) - return -1; /* errno is correctly set */ - - af = sa->sa_family; - memset(&myaddr, 0, salen); - } else - af = sa->sa_family; - - if (af == AF_INET) { - /* LINTED */ - sin = (struct sockaddr_in *)sa; - salen = sizeof(struct sockaddr_in); - portp = &sin->sin_port; - } else if (af == AF_INET6) { - /* LINTED */ - sin6 = (struct sockaddr_in6 *)sa; - salen = sizeof(struct sockaddr_in6); - portp = &sin6->sin6_port; - } else { - errno = EPFNOSUPPORT; - return (-1); - } - sa->sa_family = af; - - port = ntohs(*portp); - if (port == 0) - port = (arc4random() % NPORTS) + STARTPORT; - - /* Avoid warning */ - error = -1; - - for(i = 0; i < NPORTS; i++) { - *portp = htons(port); - - error = bind(sd, sa, salen); - - /* Terminate on success */ - if (error == 0) - break; - - /* Terminate on errors, except "address already in use" */ - if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) - break; - - port++; - if (port > ENDPORT) - port = STARTPORT; - } - - return (error); -} - -#endif /* HAVE_BINDRESVPORT_SA */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-arc4random.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-arc4random.c deleted file mode 100644 index 3dac16f70a..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-arc4random.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Copyright (c) 1999-2000 Damien Miller. 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 "log.h" - -RCSID("$Id: bsd-arc4random.c,v 1.5 2002/05/08 22:57:18 tim Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifndef HAVE_ARC4RANDOM - -#include <openssl/rand.h> -#include <openssl/rc4.h> -#include <openssl/err.h> - -/* Size of key to use */ -#define SEED_SIZE 20 - -/* Number of bytes to reseed after */ -#define REKEY_BYTES (1 << 24) - -static int rc4_ready = 0; -static RC4_KEY rc4; - -unsigned int arc4random(void) -{ - unsigned int r = 0; - static int first_time = 1; - - if (rc4_ready <= 0) { - if (first_time) - seed_rng(); - first_time = 0; - arc4random_stir(); - } - - RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r); - - rc4_ready -= sizeof(r); - - return(r); -} - -void arc4random_stir(void) -{ - unsigned char rand_buf[SEED_SIZE]; - - memset(&rc4, 0, sizeof(rc4)); - if (!RAND_bytes(rand_buf, sizeof(rand_buf))) - fatal("Couldn't obtain random bytes (error %ld)", - ERR_get_error()); - RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); - memset(rand_buf, 0, sizeof(rand_buf)); - - rc4_ready = REKEY_BYTES; -} -#endif /* !HAVE_ARC4RANDOM */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-asprintf.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-asprintf.c deleted file mode 100644 index f06e7415de..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-asprintf.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2004 Darren Tucker. - * - * Based originally on asprintf.c from OpenBSD: - * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" - -#ifndef HAVE_VASPRINTF - -#include <errno.h> -#include <stdarg.h> -#include <stdlib.h> - -#ifndef VA_COPY -#ifdef HAVE_VA_COPY -#define VA_COPY(dest, src) va_copy(dest, src) -#else -#ifdef HAVE___VA_COPY -#define VA_COPY(dest, src) __va_copy(dest, src) -#else -#define VA_COPY(dest, src) (dest) = (src) -#endif -#endif -#endif - -#define INIT_SZ 128 - -int -vasprintf(char **str, const char *fmt, va_list ap) -{ - int ret = -1; - va_list ap2; - char *string, *newstr; - size_t len; - - VA_COPY(ap2, ap); - if ((string = malloc(INIT_SZ)) == NULL) - goto fail; - - ret = vsnprintf(string, INIT_SZ, fmt, ap2); - if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ - *str = string; - } else if (ret == INT_MAX || ret < 0) { /* Bad length */ - free(string); - goto fail; - } else { /* bigger than initial, realloc allowing for nul */ - len = (size_t)ret + 1; - if ((newstr = realloc(string, len)) == NULL) { - free(string); - goto fail; - } else { - va_end(ap2); - VA_COPY(ap2, ap); - ret = vsnprintf(newstr, len, fmt, ap2); - if (ret >= 0 && (size_t)ret < len) { - *str = newstr; - } else { /* failed with realloc'ed string, give up */ - free(newstr); - goto fail; - } - } - } - va_end(ap2); - return (ret); - -fail: - *str = NULL; - errno = ENOMEM; - va_end(ap2); - return (-1); -} -#endif - -#ifndef HAVE_ASPRINTF -int -asprintf(char **str, const char *fmt, ...) -{ - va_list ap; - int ret; - - *str = NULL; - va_start(ap, fmt); - ret = vasprintf(str, fmt, ap); - va_end(ap); - - return (ret); -} -#endif diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-cray.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-cray.c deleted file mode 100644 index dd3bd2cac5..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-cray.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * $Id: bsd-cray.c,v 1.8 2002/09/26 00:38:51 tim Exp $ - * - * bsd-cray.c - * - * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) - * Significant portions provided by - * Wayne Schroeder, SDSC <schroeder@sdsc.edu> - * William Jones, UTexas <jones@tacc.utexas.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. - * - * Created: Apr 22 16.34:00 2002 wp - * - * This file contains functions required for proper execution - * on UNICOS systems. - * - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" - -#ifdef _UNICOS - -#include <udb.h> -#include <tmpdir.h> -#include <unistd.h> -#include <sys/category.h> -#include <utmp.h> -#include <sys/jtab.h> -#include <signal.h> -#include <sys/priv.h> -#include <sys/secparm.h> -#include <sys/tfm.h> -#include <sys/usrv.h> -#include <sys/sysv.h> -#include <sys/sectab.h> -#include <sys/secstat.h> -#include <sys/stat.h> -#include <sys/session.h> -#include <stdlib.h> -#include <pwd.h> -#include <fcntl.h> -#include <errno.h> -#include <ia.h> -#include <urm.h> -#include "ssh.h" -#include "log.h" -#include "servconf.h" -#include "bsd-cray.h" - -#define MAXACID 80 - -extern ServerOptions options; - -char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ - -struct sysv sysv; /* system security structure */ -struct usrv usrv; /* user security structure */ - -/* - * Functions. - */ -void cray_retain_utmp(struct utmp *, int); -void cray_delete_tmpdir(char *, int, uid_t); -void cray_init_job(struct passwd *); -void cray_set_tmpdir(struct utmp *); -void cray_login_failure(char *, int); -int cray_setup(uid_t, char *, const char *); -int cray_access_denied(char *); - -void -cray_login_failure(char *username, int errcode) -{ - struct udb *ueptr; /* UDB pointer for username */ - ia_failure_t fsent; /* ia_failure structure */ - ia_failure_ret_t fret; /* ia_failure return stuff */ - struct jtab jtab; /* job table structure */ - int jid = 0; /* job id */ - - if ((jid = getjtab(&jtab)) < 0) { - debug("cray_login_failure(): getjtab error"); - } - getsysudb(); - if ((ueptr = getudbnam(username)) == UDB_NULL) { - debug("cray_login_failure(): getudbname() returned NULL"); - } - endudb(); - fsent.revision = 0; - fsent.uname = username; - fsent.host = (char *)get_canonical_hostname(options.verify_reverse_mapping); - fsent.ttyn = "sshd"; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = ueptr; - fsent.jid = jid; - fsent.errcode = errcode; - fsent.pwdp = NULL; - fsent.exitcode = 0; /* dont exit in ia_failure() */ - - fret.revision = 0; - fret.normal = 0; - - /* - * Call ia_failure because of an login failure. - */ - ia_failure(&fsent,&fret); -} - -/* - * Cray access denied - */ -int -cray_access_denied(char *username) -{ - struct udb *ueptr; /* UDB pointer for username */ - int errcode; /* IA errorcode */ - - errcode = 0; - getsysudb(); - if ((ueptr = getudbnam(username)) == UDB_NULL) { - debug("cray_login_failure(): getudbname() returned NULL"); - } - endudb(); - if (ueptr && ueptr->ue_disabled) - errcode = IA_DISABLED; - if (errcode) - cray_login_failure(username, errcode); - return (errcode); -} - -int -cray_setup (uid_t uid, char *username, const char *command) -{ - extern struct udb *getudb(); - extern char *setlimits(); - - int err; /* error return */ - time_t system_time; /* current system clock */ - time_t expiration_time; /* password expiration time */ - int maxattempts; /* maximum no. of failed login attempts */ - int SecureSys; /* unicos security flag */ - int minslevel = 0; /* system minimum security level */ - int i, j; - int valid_acct = -1; /* flag for reading valid acct */ - char acct_name[MAXACID] = { "" }; /* used to read acct name */ - struct jtab jtab; /* Job table struct */ - struct udb ue; /* udb entry for logging-in user */ - struct udb *up; /* pointer to UDB entry */ - struct secstat secinfo; /* file security attributes */ - struct servprov init_info; /* used for sesscntl() call */ - int jid; /* job ID */ - int pid; /* process ID */ - char *sr; /* status return from setlimits() */ - char *ttyn = NULL; /* ttyname or command name*/ - char hostname[MAXHOSTNAMELEN]; - passwd_t pwdacm, - pwddialup, - pwdudb, - pwdwal, - pwddce; /* passwd stuff for ia_user */ - ia_user_ret_t uret; /* stuff returned from ia_user */ - ia_user_t usent; /* ia_user main structure */ - int ia_rcode; /* ia_user return code */ - ia_failure_t fsent; /* ia_failure structure */ - ia_failure_ret_t fret; /* ia_failure return stuff */ - ia_success_t ssent; /* ia_success structure */ - ia_success_ret_t sret; /* ia_success return stuff */ - int ia_mlsrcode; /* ia_mlsuser return code */ - int secstatrc; /* [f]secstat return code */ - - if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { - getsysv(&sysv, sizeof(struct sysv)); - minslevel = sysv.sy_minlvl; - if (getusrv(&usrv) < 0) { - debug("getusrv() failed, errno = %d",errno); - exit(1); - } - } - hostname[0] = '\0'; - strncpy(hostname, - (char *)get_canonical_hostname(options.verify_reverse_mapping), - MAXHOSTNAMELEN); - /* - * Fetch user's UDB entry. - */ - getsysudb(); - if ((up = getudbnam(username)) == UDB_NULL) { - debug("cannot fetch user's UDB entry"); - exit(1); - } - - /* - * Prevent any possible fudging so perform a data - * safety check and compare the supplied uid against - * the udb's uid. - */ - if (up->ue_uid != uid) { - debug("IA uid missmatch"); - exit(1); - } - endudb(); - - if ((jid = getjtab (&jtab)) < 0) { - debug("getjtab"); - return -1; - } - pid = getpid(); - ttyn = ttyname(0); - if (SecureSys) { - if (ttyn) { - secstatrc = secstat(ttyn, &secinfo); - } else { - secstatrc = fsecstat(1, &secinfo); - } - if (secstatrc == 0) { - debug("[f]secstat() successful"); - } else { - debug("[f]secstat() error, rc = %d", secstatrc); - exit(1); - } - } - if ((ttyn == NULL) && ((char *)command != NULL)) - ttyn = (char *)command; - /* - * Initialize all structures to call ia_user - */ - usent.revision = 0; - usent.uname = username; - usent.host = hostname; - usent.ttyn = ttyn; - usent.caller = IA_SSHD; - usent.pswdlist = &pwdacm; - usent.ueptr = &ue; - usent.flags = IA_INTERACTIVE | IA_FFLAG; - pwdacm.atype = IA_SECURID; - pwdacm.pwdp = NULL; - pwdacm.next = &pwdudb; - - pwdudb.atype = IA_UDB; - pwdudb.pwdp = NULL; - pwdudb.next = &pwddce; - - pwddce.atype = IA_DCE; - pwddce.pwdp = NULL; - pwddce.next = &pwddialup; - - pwddialup.atype = IA_DIALUP; - pwddialup.pwdp = NULL; - /* pwddialup.next = &pwdwal; */ - pwddialup.next = NULL; - - pwdwal.atype = IA_WAL; - pwdwal.pwdp = NULL; - pwdwal.next = NULL; - - uret.revision = 0; - uret.pswd = NULL; - uret.normal = 0; - - ia_rcode = ia_user(&usent, &uret); - - switch (ia_rcode) { - /* - * These are acceptable return codes from ia_user() - */ - case IA_UDBWEEK: /* Password Expires in 1 week */ - expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; - printf ("WARNING - your current password will expire %s\n", - ctime((const time_t *)&expiration_time)); - break; - case IA_UDBEXPIRED: - if (ttyname(0) != NULL) { - /* Force a password change */ - printf("Your password has expired; Choose a new one.\n"); - execl("/bin/passwd", "passwd", username, 0); - exit(9); - } - - break; - case IA_NORMAL: /* Normal Return Code */ - break; - case IA_BACKDOOR: - strcpy(ue.ue_name, "root"); - strcpy(ue.ue_passwd, ""); - strcpy(ue.ue_dir, "/"); - strcpy(ue.ue_shell, "/bin/sh"); - strcpy(ue.ue_age, ""); - strcpy(ue.ue_comment, ""); - strcpy(ue.ue_loghost, ""); - strcpy(ue.ue_logline, ""); - ue.ue_uid=-1; - ue.ue_nice[UDBRC_INTER]=0; - for (i=0;i<MAXVIDS;i++) - ue.ue_gids[i]=0; - ue.ue_logfails=0; - ue.ue_minlvl=minslevel; - ue.ue_maxlvl=minslevel; - ue.ue_deflvl=minslevel; - ue.ue_defcomps=0; - ue.ue_comparts=0; - ue.ue_permits=0; - ue.ue_trap=0; - ue.ue_disabled=0; - ue.ue_logtime=0; - break; - case IA_CONSOLE: /* Superuser not from Console */ - case IA_TRUSTED: /* Trusted user */ - if (options.permit_root_login > PERMIT_NO) - break; /* Accept root login */ - default: - /* - * These are failed return codes from ia_user() - */ - switch (ia_rcode) - { - case IA_BADAUTH: - printf ("Bad authorization, access denied.\n"); - break; - case IA_DIALUPERR: - break; - case IA_DISABLED: - printf ("Your login has been disabled. Contact the system "); - printf ("administrator for assistance.\n"); - break; - case IA_GETSYSV: - printf ("getsysv() failed - errno = %d\n", errno); - break; - case IA_LOCALHOST: - break; - case IA_MAXLOGS: - printf ("Maximum number of failed login attempts exceeded.\n"); - printf ("Access denied.\n"); - break; - case IA_NOPASS: - break; - case IA_PUBLIC: - break; - case IA_SECURIDERR: - break; - case IA_CONSOLE: - break; - case IA_TRUSTED: - break; - case IA_UDBERR: - break; - case IA_UDBPWDNULL: - /* - * NULL password not allowed on MLS systems - */ - if (SecureSys) { - printf("NULL Password not allowed on MLS systems.\n"); - } - break; - case IA_UNKNOWN: - break; - case IA_UNKNOWNYP: - break; - case IA_WALERR: - break; - default: - /* nothing special */ - ; - } /* 2. switch (ia_rcode) */ - /* - * Authentication failed. - */ - printf("sshd: Login incorrect, (0%o)\n", - ia_rcode-IA_ERRORCODE); - - /* - * Initialize structure for ia_failure - * which will exit. - */ - fsent.revision = 0; - fsent.uname = username; - fsent.host = hostname; - fsent.ttyn = ttyn; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = &ue; - fsent.jid = jid; - fsent.errcode = ia_rcode; - fsent.pwdp = uret.pswd; - fsent.exitcode = 1; - - fret.revision = 0; - fret.normal = 0; - - /* - * Call ia_failure because of an IA failure. - * There is no return because ia_failure exits. - */ - - ia_failure(&fsent,&fret); - - exit(1); - } /* 1. switch (ia_rcode) */ - ia_mlsrcode = IA_NORMAL; - if (SecureSys) { - debug("calling ia_mlsuser()"); - ia_mlsrcode = ia_mlsuser (&ue, &secinfo, &usrv, NULL, 0); - } - if (ia_mlsrcode != IA_NORMAL) { - printf("sshd: Login incorrect, (0%o)\n", - ia_mlsrcode-IA_ERRORCODE); - /* - * Initialize structure for ia_failure - * which will exit. - */ - fsent.revision = 0; - fsent.uname = username; - fsent.host = hostname; - fsent.ttyn = ttyn; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = &ue; - fsent.jid = jid; - fsent.errcode = ia_mlsrcode; - fsent.pwdp = uret.pswd; - fsent.exitcode = 1; - fret.revision = 0; - fret.normal = 0; - - /* - * Call ia_failure because of an IA failure. - * There is no return because ia_failure exits. - */ - ia_failure(&fsent,&fret); - exit(1); - } - - /* Provide login status information */ - if (options.print_lastlog && ue.ue_logtime != 0) { - printf("Last successful login was : %.*s ", - 19, (char *)ctime(&ue.ue_logtime)); - - if (*ue.ue_loghost != '\0') - printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost); - - else printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline); - - if ( SecureSys && (ue.ue_logfails != 0)) - printf(" followed by %d failed attempts\n", ue.ue_logfails); - } - - - /* - * Call ia_success to process successful I/A. - */ - ssent.revision = 0; - ssent.uname = username; - ssent.host = hostname; - ssent.ttyn = ttyn; - ssent.caller = IA_SSHD; - ssent.flags = IA_INTERACTIVE; - ssent.ueptr = &ue; - ssent.jid = jid; - ssent.errcode = ia_rcode; - ssent.us = NULL; - ssent.time = 1; /* Set ue_logtime */ - - sret.revision = 0; - sret.normal = 0; - - ia_success(&ssent,&sret); - - /* - * Query for account, iff > 1 valid acid & askacid permbit - */ - if (((ue.ue_permbits & PERMBITS_ACCTID) || - (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && - ue.ue_permbits & PERMBITS_ASKACID) { - if (ttyname(0) != NULL) { - debug("cray_setup: ttyname true case, %.100s", ttyname); - while (valid_acct == -1) { - printf("Account (? for available accounts)" - " [%s]: ", acid2nam(ue.ue_acids[0])); - gets(acct_name); - switch (acct_name[0]) { - case EOF: - exit(0); - break; - case '\0': - valid_acct = ue.ue_acids[0]; - strcpy(acct_name, acid2nam(valid_acct)); - break; - case '?': - /* Print the list 3 wide */ - for (i = 0, j = 0; i < MAXVIDS; i++) { - if (ue.ue_acids[i] == -1) { - printf("\n"); - break; - } - if (++j == 4) { - j = 1; - printf("\n"); - } - printf(" %s", - acid2nam(ue.ue_acids[i])); - } - if (ue.ue_permbits & PERMBITS_ACCTID) - printf("\"acctid\" permbit also allows" - " you to select any valid " - "account name.\n"); - printf("\n"); - break; - default: - if ((valid_acct = nam2acid(acct_name)) == -1) printf("Account id not found for" - " account name \"%s\"\n\n", - acct_name); - break; - } - /* - * If an account was given, search the user's - * acids array to verify they can use this account. - */ - if ((valid_acct != -1) && - !(ue.ue_permbits & PERMBITS_ACCTID)) { - for (i = 0; i < MAXVIDS; i++) { - if (ue.ue_acids[i] == -1) - break; - if (valid_acct == ue.ue_acids[i]) - break; - } - if (i == MAXVIDS || - ue.ue_acids[i] == -1) { - fprintf(stderr, "Cannot set" - " account name to " - "\"%s\", permission " - "denied\n\n", acct_name); - valid_acct = -1; - } - } - } - } else { - /* - * The client isn't connected to a terminal and can't - * respond to an acid prompt. Use default acid. - */ - debug("cray_setup: ttyname false case, %.100s", ttyname); - valid_acct = ue.ue_acids[0]; - } - } else { - /* - * The user doesn't have the askacid permbit set or - * only has one valid account to use. - */ - valid_acct = ue.ue_acids[0]; - } - if (acctid(0, valid_acct) < 0) { - printf ("Bad account id: %d\n", valid_acct); - exit(1); - } - -/* set up shares and quotas */ -/* Now set shares, quotas, limits, including CPU time for the (interactive) - * job and process, and set up permissions (for chown etc), etc. - */ - if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { - printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); - exit(1); - } - - sr = setlimits(username, C_PROC, pid, UDBRC_INTER); - if (sr != NULL) { - debug("%.200s", sr); - exit(1); - } - sr = setlimits(username, C_JOB, jid, UDBRC_INTER); - if (sr != NULL) { - debug("%.200s", sr); - exit(1); - } - /* - * Place the service provider information into - * the session table (Unicos) or job table (Unicos/mk). - * There exist double defines for the job/session table in - * unicos/mk (jtab.h) so no need for a compile time switch. - */ - bzero((char *)&init_info, sizeof(struct servprov)); - init_info.s_sessinit.si_id = URM_SPT_LOGIN; - init_info.s_sessinit.si_pid = getpid(); - init_info.s_sessinit.si_sid = jid; - init_info.s_routing.seqno = 0; - init_info.s_routing.iadrs = 0; - sesscntl(0, S_SETSERVPO, (int)&init_info); - - /* - * Set user and controlling tty security attributes. - */ - if (SecureSys) { - if (setusrv(&usrv) == -1) { - debug("setusrv() failed, errno = %d",errno); - exit(1); - } - } - - return(0); -} - -/* - * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk - * can have pal privileges that sshd can inherit which - * could allow a user to su to root with out a password. - * This subroutine clears all privileges. - */ -void -drop_cray_privs() -{ -#if defined(_SC_CRAY_PRIV_SU) - priv_proc_t* privstate; - int result; - extern int priv_set_proc(); - extern priv_proc_t* priv_init_proc(); - - /* - * If ether of theses two flags are not set - * then don't allow this version of ssh to run. - */ - if (!sysconf(_SC_CRAY_PRIV_SU)) - fatal("Not PRIV_SU system."); - if (!sysconf(_SC_CRAY_POSIX_PRIV)) - fatal("Not POSIX_PRIV."); - - debug("Setting MLS labels.");; - - if (sysconf(_SC_CRAY_SECURE_MAC)) { - usrv.sv_minlvl = SYSLOW; - usrv.sv_actlvl = SYSHIGH; - usrv.sv_maxlvl = SYSHIGH; - } else { - usrv.sv_minlvl = sysv.sy_minlvl; - usrv.sv_actlvl = sysv.sy_minlvl; - usrv.sv_maxlvl = sysv.sy_maxlvl; - } - usrv.sv_actcmp = 0; - usrv.sv_valcmp = sysv.sy_valcmp; - - usrv.sv_intcat = TFM_SYSTEM; - usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE); - - if (setusrv(&usrv) < 0) - fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, - strerror(errno)); - - if ((privstate = priv_init_proc()) != NULL) { - result = priv_set_proc(privstate); - if (result != 0 ) - fatal("%s(%d): priv_set_proc(): %s", - __FILE__, __LINE__, strerror(errno)); - priv_free_proc(privstate); - } - debug ("Privileges should be cleared..."); -#else - /* XXX: do this differently */ -# error Cray systems must be run with _SC_CRAY_PRIV_SU on! -#endif -} - - -/* - * Retain utmp/wtmp information - used by cray accounting. - */ -void -cray_retain_utmp(struct utmp *ut, int pid) -{ - int fd; - struct utmp utmp; - - if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { - while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { - if (pid == utmp.ut_pid) { - ut->ut_jid = utmp.ut_jid; - strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); - strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); - strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); - break; - } - } - close(fd); - } - else - fatal("Unable to open utmp file"); -} - -/* - * tmpdir support. - */ - -/* - * find and delete jobs tmpdir. - */ -void -cray_delete_tmpdir(char *login, int jid, uid_t uid) -{ - int child; - static char jtmp[TPATHSIZ]; - struct stat statbuf; - int c; - int wstat; - - for (c = 'a'; c <= 'z'; c++) { - snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); - if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) - break; - } - - if (c > 'z') - return; - - if ((child = fork()) == 0) { - execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); - fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); - } - - while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) - ; -} - -/* - * Remove tmpdir on job termination. - */ -void -cray_job_termination_handler(int sig) -{ - int jid; - char *login = NULL; - struct jtab jtab; - - debug("received signal %d",sig); - - if ((jid = waitjob(&jtab)) == -1 || - (login = uid2nam(jtab.j_uid)) == NULL) - return; - - cray_delete_tmpdir(login, jid, jtab.j_uid); -} - -/* - * Set job id and create tmpdir directory. - */ -void -cray_init_job(struct passwd *pw) -{ - int jid; - int c; - - jid = setjob(pw->pw_uid, WJSIGNAL); - if (jid < 0) - fatal("System call setjob failure"); - - for (c = 'a'; c <= 'z'; c++) { - snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); - if (mkdir(cray_tmpdir, JTMPMODE) != 0) - continue; - if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { - rmdir(cray_tmpdir); - continue; - } - break; - } - - if (c > 'z') - cray_tmpdir[0] = '\0'; -} - -void -cray_set_tmpdir(struct utmp *ut) -{ - int jid; - struct jtab jbuf; - - if ((jid = getjtab(&jbuf)) < 0) - return; - - /* - * Set jid and tmpdir in utmp record. - */ - ut->ut_jid = jid; - strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); -} -#endif diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-cygwin_util.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-cygwin_util.c deleted file mode 100644 index 5e31351628..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-cygwin_util.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * cygwin_util.c - * - * Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com> - * - * 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. - * - * Created: Sat Sep 02 12:17:00 2000 cv - * - * This file contains functions for forcing opened file descriptors to - * binary mode on Windows systems. - */ - -#include "includes.h" - -RCSID("$Id: bsd-cygwin_util.c,v 1.8 2002/04/15 22:00:52 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef HAVE_CYGWIN - -#include <fcntl.h> -#include <stdlib.h> -#include <sys/utsname.h> -#include <sys/vfs.h> -#include <windows.h> -#define is_winnt (GetVersion() < 0x80000000) - -#define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec")) -#define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea")) - -#if defined(open) && open == binary_open -# undef open -#endif -#if defined(pipe) && open == binary_pipe -# undef pipe -#endif - -int binary_open(const char *filename, int flags, ...) -{ - va_list ap; - mode_t mode; - - va_start(ap, flags); - mode = va_arg(ap, mode_t); - va_end(ap); - return open(filename, flags | O_BINARY, mode); -} - -int binary_pipe(int fd[2]) -{ - int ret = pipe(fd); - - if (!ret) { - setmode (fd[0], O_BINARY); - setmode (fd[1], O_BINARY); - } - return ret; -} - -int check_nt_auth(int pwd_authenticated, struct passwd *pw) -{ - /* - * The only authentication which is able to change the user - * context on NT systems is the password authentication. So - * we deny all requsts for changing the user context if another - * authentication method is used. - * - * This doesn't apply to Cygwin versions >= 1.3.2 anymore which - * uses the undocumented NtCreateToken() call to create a user - * token if the process has the appropriate privileges and if - * CYGWIN ntsec setting is on. - */ - static int has_create_token = -1; - - if (pw == NULL) - return 0; - if (is_winnt) { - if (has_create_token < 0) { - struct utsname uts; - int major_high = 0, major_low = 0, minor = 0; - char *cygwin = getenv("CYGWIN"); - - has_create_token = 0; - if (ntsec_on(cygwin) && !uname(&uts)) { - sscanf(uts.release, "%d.%d.%d", - &major_high, &major_low, &minor); - if (major_high > 1 || - (major_high == 1 && (major_low > 3 || - (major_low == 3 && minor >= 2)))) - has_create_token = 1; - } - } - if (has_create_token < 1 && - !pwd_authenticated && geteuid() != pw->pw_uid) - return 0; - } - return 1; -} - -int check_ntsec(const char *filename) -{ - char *cygwin; - int allow_ntea = 0; - int allow_ntsec = 0; - struct statfs fsstat; - - /* Windows 95/98/ME don't support file system security at all. */ - if (!is_winnt) - return 0; - - /* Evaluate current CYGWIN settings. */ - cygwin = getenv("CYGWIN"); - allow_ntea = ntea_on(cygwin); - allow_ntsec = ntsec_on(cygwin); - - /* - * `ntea' is an emulation of POSIX attributes. It doesn't support - * real file level security as ntsec on NTFS file systems does - * but it supports FAT filesystems. `ntea' is minimum requirement - * for security checks. - */ - if (allow_ntea) - return 1; - - /* - * Retrieve file system flags. In Cygwin, file system flags are - * copied to f_type which has no meaning in Win32 itself. - */ - if (statfs(filename, &fsstat)) - return 1; - - /* - * Only file systems supporting ACLs are able to set permissions. - * `ntsec' is the setting in Cygwin which switches using of NTFS - * ACLs to support POSIX permissions on files. - */ - if (fsstat.f_type & FS_PERSISTENT_ACLS) - return allow_ntsec; - - return 0; -} - -void register_9x_service(void) -{ - HINSTANCE kerneldll; - DWORD (*RegisterServiceProcess)(DWORD, DWORD); - - /* The service register mechanism in 9x/Me is pretty different from - * NT/2K/XP. In NT/2K/XP we're using a special service starter - * application to register and control sshd as service. This method - * doesn't play nicely with 9x/Me. For that reason we register here - * as service when running under 9x/Me. This function is only called - * by the child sshd when it's going to daemonize. - */ - if (is_winnt) - return; - if (! (kerneldll = LoadLibrary("KERNEL32.DLL"))) - return; - if (! (RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) - GetProcAddress(kerneldll, "RegisterServiceProcess"))) - return; - RegisterServiceProcess(0, 1); -} - -#endif /* HAVE_CYGWIN */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-getpeereid.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-getpeereid.c deleted file mode 100644 index 85e68ca6bf..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-getpeereid.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2002 Damien Miller. 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 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" - -RCSID("$Id: bsd-getpeereid.c,v 1.1 2002/09/12 00:33:02 djm Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#if !defined(HAVE_GETPEEREID) - -#if defined(SO_PEERCRED) -int -getpeereid(int s, uid_t *euid, gid_t *gid) -{ - struct ucred cred; - size_t len = sizeof(cred); - - if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) - return (-1); - *euid = cred.uid; - *gid = cred.gid; - - return (0); -} -#elif defined(HAVE_GETPEERUCRED) -int -getpeereid(int s, uid_t *euid, gid_t *gid) -{ - ucred_t *ucred = NULL; - - if (getpeerucred(s, &ucred) == -1) - return (-1); - if ((*euid = ucred_geteuid(ucred)) == (uid_t)-1) - return (-1); - if ((*gid = ucred_getrgid(ucred)) == (gid_t)-1) - return (-1); - - ucred_free(ucred); - - return (0); -} -#else -int -getpeereid(int s, uid_t *euid, gid_t *gid) -{ - *euid = geteuid(); - *gid = getgid(); - - return (0); -} -#endif /* defined(SO_PEERCRED) */ - -#endif /* !defined(HAVE_GETPEEREID) */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-misc.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-misc.c deleted file mode 100644 index a7b9cbf052..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-misc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 1999-2000 Damien Miller. 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: bsd-misc.c,v 1.10 2002/07/08 21:09:41 mouring Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -char *get_progname(char *argv0) -{ -#ifdef HAVE___PROGNAME - extern char *__progname; - - return __progname; -#else - char *p; - - if (argv0 == NULL) - return "unknown"; /* XXX */ - p = strrchr(argv0, '/'); - if (p == NULL) - p = argv0; - else - p++; - return p; -#endif -} - -#ifndef HAVE_SETLOGIN -int setlogin(const char *name) -{ - return(0); -} -#endif /* !HAVE_SETLOGIN */ - -#ifndef HAVE_INNETGR -int innetgr(const char *netgroup, const char *host, - const char *user, const char *domain) -{ - return(0); -} -#endif /* HAVE_INNETGR */ - -#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) -int seteuid(uid_t euid) -{ - return(setreuid(-1,euid)); -} -#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ - -#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) -int setegid(uid_t egid) -{ - return(setresgid(-1,egid,-1)); -} -#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ - -#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) -const char *strerror(int e) -{ - extern int sys_nerr; - extern char *sys_errlist[]; - - if ((e >= 0) && (e < sys_nerr)) - return(sys_errlist[e]); - else - return("unlisted error"); -} -#endif - -#ifndef HAVE_UTIMES -int utimes(char *filename, struct timeval *tvp) -{ - struct utimbuf ub; - - ub.actime = tvp[0].tv_sec; - ub.modtime = tvp[1].tv_sec; - - return(utime(filename, &ub)); -} -#endif - -#ifndef HAVE_TRUNCATE -int truncate (const char *path, off_t length) -{ - int fd, ret, saverrno; - - fd = open(path, O_WRONLY); - if (fd < 0) - return -1; - - ret = ftruncate(fd, length); - saverrno = errno; - (void) close (fd); - if (ret == -1) - errno = saverrno; - return(ret); -} -#endif /* HAVE_TRUNCATE */ - -#if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) -/* - * Cygwin setgroups should be a noop. - */ -int -setgroups(size_t size, const gid_t *list) -{ - return 0; -} -#endif - diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-snprintf.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-snprintf.c deleted file mode 100644 index 12148fd6c2..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-snprintf.c +++ /dev/null @@ -1,746 +0,0 @@ -/************************************************************** - * Original: - * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 - * A bombproof version of doprnt (dopr) included. - * Sigh. This sort of thing is always nasty do deal with. Note that - * the version here does not include floating point... - * - * snprintf() is used instead of sprintf() as it does limit checks - * for string length. This covers a nasty loophole. - * - * The other functions are there to prevent NULL pointers from - * causing nast effects. - * - * More Recently: - * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43 - * This was ugly. It is still ugly. I opted out of floating point - * numbers, but the formatter understands just about everything - * from the normal C string format, at least as far as I can tell from - * the Solaris 2.5 printf(3S) man page. - * - * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1 - * Ok, added some minimal floating point support, which means this - * probably requires libm on most operating systems. Don't yet - * support the exponent (e,E) and sigfig (g,G). Also, fmtint() - * was pretty badly broken, it just wasn't being exercised in ways - * which showed it, so that's been fixed. Also, formated the code - * to mutt conventions, and removed dead code left over from the - * original. Also, there is now a builtin-test, just compile with: - * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm - * and run snprintf for results. - * - * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. - * Unfortunately, unsigned formats simply didn't work. - * - * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8 - * The original code assumed that both snprintf() and vsnprintf() were - * missing. Some systems only have snprintf() but not vsnprintf(), so - * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. - * - * Ben Lindstrom <mouring@eviladmin.org> 09/27/00 for OpenSSH - * Welcome to the world of %lld and %qd support. With other - * long long support. This is needed for sftp-server to work - * right. - * - * Ben Lindstrom <mouring@eviladmin.org> 02/12/01 for OpenSSH - * Removed all hint of VARARGS stuff and banished it to the void, - * and did a bit of KNF style work to make things a bit more - * acceptable. Consider stealing from mutt or enlightenment. - **************************************************************/ - -#include "includes.h" - -RCSID("$Id: bsd-snprintf.c,v 1.5 2001/02/25 23:20:41 mouring Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ -# undef HAVE_SNPRINTF -# undef HAVE_VSNPRINTF -#endif - -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) - -static void -dopr(char *buffer, size_t maxlen, const char *format, va_list args); - -static void -fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, - int min, int max); - -static void -fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, - int min, int max, int flags); - -static void -fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, - int min, int max, int flags); - -static void -dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); - -/* - * dopr(): poor man's version of doprintf - */ - -/* format read states */ -#define DP_S_DEFAULT 0 -#define DP_S_FLAGS 1 -#define DP_S_MIN 2 -#define DP_S_DOT 3 -#define DP_S_MAX 4 -#define DP_S_MOD 5 -#define DP_S_CONV 6 -#define DP_S_DONE 7 - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UP (1 << 5) -#define DP_F_UNSIGNED (1 << 6) - -/* Conversion Flags */ -#define DP_C_SHORT 1 -#define DP_C_LONG 2 -#define DP_C_LDOUBLE 3 -#define DP_C_LONG_LONG 4 - -#define char_to_int(p) (p - '0') -#define abs_val(p) (p < 0 ? -p : p) - - -static void -dopr(char *buffer, size_t maxlen, const char *format, va_list args) -{ - char *strvalue; - char ch; - long value; - long double fvalue; - int min = 0; - int max = -1; - int state = DP_S_DEFAULT; - int flags = 0; - int cflags = 0; - size_t currlen = 0; - - ch = *format++; - - while (state != DP_S_DONE) { - if ((ch == '\0') || (currlen >= maxlen)) - state = DP_S_DONE; - - switch(state) { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - dopr_outch(buffer, &currlen, maxlen, ch); - ch = *format++; - break; - case DP_S_FLAGS: - switch (ch) { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) { - min = 10*min + char_to_int (ch); - ch = *format++; - } else if (ch == '*') { - min = va_arg (args, int); - ch = *format++; - state = DP_S_DOT; - } else - state = DP_S_DOT; - break; - case DP_S_DOT: - if (ch == '.') { - state = DP_S_MAX; - ch = *format++; - } else - state = DP_S_MOD; - break; - case DP_S_MAX: - if (isdigit((unsigned char)ch)) { - if (max < 0) - max = 0; - max = 10*max + char_to_int(ch); - ch = *format++; - } else if (ch == '*') { - max = va_arg (args, int); - ch = *format++; - state = DP_S_MOD; - } else - state = DP_S_MOD; - break; - case DP_S_MOD: - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - break; - case 'l': - cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { - cflags = DP_C_LONG_LONG; - ch = *format++; - } - break; - case 'q': - cflags = DP_C_LONG_LONG; - ch = *format++; - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - switch (ch) { - case 'd': - case 'i': - if (cflags == DP_C_SHORT) - value = va_arg(args, int); - else if (cflags == DP_C_LONG) - value = va_arg(args, long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, long long); - else - value = va_arg (args, int); - fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'o': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); - break; - case 'u': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'X': - flags |= DP_F_UP; - case 'x': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); - break; - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - else - fvalue = va_arg(args, double); - /* um, floating point? */ - fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); - break; - case 'E': - flags |= DP_F_UP; - case 'e': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - else - fvalue = va_arg(args, double); - break; - case 'G': - flags |= DP_F_UP; - case 'g': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - else - fvalue = va_arg(args, double); - break; - case 'c': - dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); - break; - case 's': - strvalue = va_arg(args, char *); - if (max < 0) - max = maxlen; /* ie, no max */ - fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); - break; - case 'p': - strvalue = va_arg(args, void *); - fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); - break; - case 'n': - if (cflags == DP_C_SHORT) { - short int *num; - num = va_arg(args, short int *); - *num = currlen; - } else if (cflags == DP_C_LONG) { - long int *num; - num = va_arg(args, long int *); - *num = currlen; - } else if (cflags == DP_C_LONG_LONG) { - long long *num; - num = va_arg(args, long long *); - *num = currlen; - } else { - int *num; - num = va_arg(args, int *); - *num = currlen; - } - break; - case '%': - dopr_outch(buffer, &currlen, maxlen, ch); - break; - case 'w': /* not supported yet, treat as next char */ - ch = *format++; - break; - default: /* Unknown, skip */ - break; - } - ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; - break; - case DP_S_DONE: - break; - default: /* hmm? */ - break; /* some picky compilers need this */ - } - } - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else - buffer[maxlen - 1] = '\0'; -} - -static void -fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max) -{ - int padlen, strln; /* amount to pad */ - int cnt = 0; - - if (value == 0) - value = "<NULL>"; - - for (strln = 0; value[strln]; ++strln); /* strlen */ - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - while ((padlen > 0) && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, ' '); - --padlen; - ++cnt; - } - while (*value && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, *value++); - ++cnt; - } - while ((padlen < 0) && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, ' '); - ++padlen; - ++cnt; - } -} - -/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ - -static void -fmtint(char *buffer, size_t *currlen, size_t maxlen, - long value, int base, int min, int max, int flags) -{ - unsigned long uvalue; - char convert[20]; - int signvalue = 0; - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - int caps = 0; - - if (max < 0) - max = 0; - - uvalue = value; - - if (!(flags & DP_F_UNSIGNED)) { - if (value < 0) { - signvalue = '-'; - uvalue = -value; - } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - } - - if (flags & DP_F_UP) - caps = 1; /* Should characters be upper case? */ - - do { - convert[place++] = - (caps? "0123456789ABCDEF":"0123456789abcdef") - [uvalue % (unsigned)base]; - uvalue = (uvalue / (unsigned)base ); - } while (uvalue && (place < 20)); - if (place == 20) - place--; - convert[place] = 0; - - zpadlen = max - place; - spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); - if (zpadlen < 0) - zpadlen = 0; - if (spadlen < 0) - spadlen = 0; - if (flags & DP_F_ZERO) { - zpadlen = MAX(zpadlen, spadlen); - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - - - /* Spaces */ - while (spadlen > 0) { - dopr_outch(buffer, currlen, maxlen, ' '); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch(buffer, currlen, maxlen, signvalue); - - /* Zeros */ - if (zpadlen > 0) { - while (zpadlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); - --zpadlen; - } - } - - /* Digits */ - while (place > 0) - dopr_outch(buffer, currlen, maxlen, convert[--place]); - - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - ++spadlen; - } -} - -static long double -pow10(int exp) -{ - long double result = 1; - - while (exp) { - result *= 10; - exp--; - } - - return result; -} - -static long -round(long double value) -{ - long intpart = value; - - value -= intpart; - if (value >= 0.5) - intpart++; - - return intpart; -} - -static void -fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, - int min, int max, int flags) -{ - char iconvert[20]; - char fconvert[20]; - int signvalue = 0; - int iplace = 0; - int fplace = 0; - int padlen = 0; /* amount to pad */ - int zpadlen = 0; - int caps = 0; - long intpart; - long fracpart; - long double ufvalue; - - /* - * AIX manpage says the default is 0, but Solaris says the default - * is 6, and sprintf on AIX defaults to 6 - */ - if (max < 0) - max = 6; - - ufvalue = abs_val(fvalue); - - if (fvalue < 0) - signvalue = '-'; - else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - - intpart = ufvalue; - - /* - * Sorry, we only support 9 digits past the decimal because of our - * conversion method - */ - if (max > 9) - max = 9; - - /* We "cheat" by converting the fractional part to integer by - * multiplying by a factor of 10 - */ - fracpart = round((pow10 (max)) * (ufvalue - intpart)); - - if (fracpart >= pow10 (max)) { - intpart++; - fracpart -= pow10 (max); - } - - /* Convert integer part */ - do { - iconvert[iplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; - intpart = (intpart / 10); - } while(intpart && (iplace < 20)); - if (iplace == 20) - iplace--; - iconvert[iplace] = 0; - - /* Convert fractional part */ - do { - fconvert[fplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; - fracpart = (fracpart / 10); - } while(fracpart && (fplace < 20)); - if (fplace == 20) - fplace--; - fconvert[fplace] = 0; - - /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); - zpadlen = max - fplace; - if (zpadlen < 0) - zpadlen = 0; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justifty */ - - if ((flags & DP_F_ZERO) && (padlen > 0)) { - if (signvalue) { - dopr_outch(buffer, currlen, maxlen, signvalue); - --padlen; - signvalue = 0; - } - while (padlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); - --padlen; - } - } - while (padlen > 0) { - dopr_outch(buffer, currlen, maxlen, ' '); - --padlen; - } - if (signvalue) - dopr_outch(buffer, currlen, maxlen, signvalue); - - while (iplace > 0) - dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); - - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - dopr_outch(buffer, currlen, maxlen, '.'); - - while (fplace > 0) - dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); - - while (zpadlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); - --zpadlen; - } - - while (padlen < 0) { - dopr_outch(buffer, currlen, maxlen, ' '); - ++padlen; - } -} - -static void -dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) -{ - if (*currlen < maxlen) - buffer[(*currlen)++] = c; -} -#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ - -#ifndef HAVE_VSNPRINTF -int -vsnprintf(char *str, size_t count, const char *fmt, va_list args) -{ - str[0] = 0; - dopr(str, count, fmt, args); - - return(strlen(str)); -} -#endif /* !HAVE_VSNPRINTF */ - -#ifndef HAVE_SNPRINTF -int -snprintf(char *str,size_t count,const char *fmt,...) -{ - va_list ap; - - va_start(ap, fmt); - (void) vsnprintf(str, count, fmt, ap); - va_end(ap); - - return(strlen(str)); -} - -#ifdef TEST_SNPRINTF -int -main(void) -{ -#define LONG_STRING 1024 - char buf1[LONG_STRING]; - char buf2[LONG_STRING]; - char *fp_fmt[] = { - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - NULL - }; - double fp_nums[] = { - -1.5, - 134.21, - 91340.2, - 341.1234, - 0203.9, - 0.96, - 0.996, - 0.9996, - 1.996, - 4.136, - 0 - }; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - "%lld", - "%qd", - NULL - }; - long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; - int x, y; - int fail = 0; - int num = 0; - - printf("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] != NULL ; x++) { - for (y = 0; fp_nums[y] != 0 ; y++) { - snprintf(buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); - sprintf (buf2, fp_fmt[x], fp_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\t" - "snprintf = %s\n\tsprintf = %s\n", - fp_fmt[x], buf1, buf2); - fail++; - } - num++; - } - } - for (x = 0; int_fmt[x] != NULL ; x++) { - for (y = 0; int_nums[y] != 0 ; y++) { - snprintf(buf1, sizeof (buf1), int_fmt[x], int_nums[y]); - sprintf(buf2, int_fmt[x], int_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\t" - "snprintf = %s\n\tsprintf = %s\n", - int_fmt[x], buf1, buf2); - fail++; - } - num++; - } - } - printf("%d tests failed out of %d.\n", fail, num); - return(0); -} -#endif /* SNPRINTF_TEST */ - -#endif /* !HAVE_SNPRINTF */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-waitpid.c b/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-waitpid.c deleted file mode 100644 index 8b221309a0..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/bsd-waitpid.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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: bsd-waitpid.c,v 1.3 2001/03/26 05:35:34 mouring Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifndef HAVE_WAITPID -#include <errno.h> -#include <sys/wait.h> -#include "bsd-waitpid.h" - -pid_t -waitpid(int pid, int *stat_loc, int options) -{ - union wait statusp; - pid_t wait_pid; - - if (pid <= 0) { - if (pid != -1) { - errno = EINVAL; - return -1; - } - pid = 0; /* wait4() wants pid=0 for indiscriminate wait. */ - } - wait_pid = wait4(pid, &statusp, options, NULL); - if (stat_loc) - *stat_loc = (int) statusp.w_status; - - return wait_pid; -} - -#endif /* !HAVE_WAITPID */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/dirname.c b/usr/src/cmd/ssh/libopenbsd-compat/common/dirname.c deleted file mode 100644 index b6dcff6f36..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/dirname.c +++ /dev/null @@ -1,82 +0,0 @@ -/* $OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $ */ - -/* - * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> - * 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. 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 ``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" -#ifndef HAVE_DIRNAME - -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <errno.h> -#include <string.h> -#include <sys/param.h> - -char * -dirname(path) - const char *path; -{ - static char bname[MAXPATHLEN]; - register const char *endp; - - /* Empty or NULL string gets treated as "." */ - if (path == NULL || *path == '\0') { - (void)strlcpy(bname, ".", sizeof bname); - return(bname); - } - - /* Strip trailing slashes */ - endp = path + strlen(path) - 1; - while (endp > path && *endp == '/') - endp--; - - /* Find the start of the dir */ - while (endp > path && *endp != '/') - endp--; - - /* Either the dir is "/" or there are no slashes */ - if (endp == path) { - (void)strlcpy(bname, *endp == '/' ? "/" : ".", sizeof bname); - return(bname); - } else { - do { - endp--; - } while (endp > path && *endp == '/'); - } - - if (endp - path + 2 > sizeof(bname)) { - errno = ENAMETOOLONG; - return(NULL); - } - strlcpy(bname, path, endp - path + 2); - return(bname); -} -#endif - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/fake-getaddrinfo.c b/usr/src/cmd/ssh/libopenbsd-compat/common/fake-getaddrinfo.c deleted file mode 100644 index ede2fa014a..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/fake-getaddrinfo.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * fake library for ssh - * - * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). - * These funtions are defined in rfc2133. - * - * But these functions are not implemented correctly. The minimum subset - * is implemented for ssh use only. For exapmle, this routine assumes - * that ai_family is AF_INET. Don't use it for another purpose. - */ - -#include "includes.h" -#include "ssh.h" - -RCSID("$Id: fake-getaddrinfo.c,v 1.2 2001/02/09 01:55:36 djm Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifndef HAVE_GAI_STRERROR -char *gai_strerror(int ecode) -{ - switch (ecode) { - case EAI_NODATA: - return "no address associated with hostname."; - case EAI_MEMORY: - return "memory allocation failure."; - default: - return "unknown error."; - } -} -#endif /* !HAVE_GAI_STRERROR */ - -#ifndef HAVE_FREEADDRINFO -void freeaddrinfo(struct addrinfo *ai) -{ - struct addrinfo *next; - - do { - next = ai->ai_next; - free(ai); - } while (NULL != (ai = next)); -} -#endif /* !HAVE_FREEADDRINFO */ - -#ifndef HAVE_GETADDRINFO -static struct addrinfo *malloc_ai(int port, u_long addr) -{ - struct addrinfo *ai; - - ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); - if (ai == NULL) - return(NULL); - - memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); - - ai->ai_addr = (struct sockaddr *)(ai + 1); - /* XXX -- ssh doesn't use sa_len */ - ai->ai_addrlen = sizeof(struct sockaddr_in); - ai->ai_addr->sa_family = ai->ai_family = AF_INET; - - ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; - ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; - - return(ai); -} - -int getaddrinfo(const char *hostname, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) -{ - struct addrinfo *cur, *prev = NULL; - struct hostent *hp; - struct in_addr in; - int i, port; - - if (servname) - port = htons(atoi(servname)); - else - port = 0; - - if (hints && hints->ai_flags & AI_PASSIVE) { - if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) - return 0; - else - return EAI_MEMORY; - } - - if (!hostname) { - if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) - return 0; - else - return EAI_MEMORY; - } - - if (inet_aton(hostname, &in)) { - if (NULL != (*res = malloc_ai(port, in.s_addr))) - return 0; - else - return EAI_MEMORY; - } - - hp = gethostbyname(hostname); - if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { - for (i = 0; hp->h_addr_list[i]; i++) { - cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); - if (cur == NULL) { - if (*res) - freeaddrinfo(*res); - return EAI_MEMORY; - } - - if (prev) - prev->ai_next = cur; - else - *res = cur; - - prev = cur; - } - return 0; - } - - return EAI_NODATA; -} -#endif /* !HAVE_GETADDRINFO */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/fake-getnameinfo.c b/usr/src/cmd/ssh/libopenbsd-compat/common/fake-getnameinfo.c deleted file mode 100644 index 60cef5cc2d..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/fake-getnameinfo.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * fake library for ssh - * - * This file includes getnameinfo(). - * These funtions are defined in rfc2133. - * - * But these functions are not implemented correctly. The minimum subset - * is implemented for ssh use only. For exapmle, this routine assumes - * that ai_family is AF_INET. Don't use it for another purpose. - */ - -#include "includes.h" -#include "ssh.h" - -RCSID("$Id: fake-getnameinfo.c,v 1.2 2001/02/09 01:55:36 djm Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifndef HAVE_GETNAMEINFO -int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, - size_t hostlen, char *serv, size_t servlen, int flags) -{ - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - struct hostent *hp; - char tmpserv[16]; - - if (serv) { - snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); - if (strlen(tmpserv) >= servlen) - return EAI_MEMORY; - else - strcpy(serv, tmpserv); - } - - if (host) { - if (flags & NI_NUMERICHOST) { - if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen) - return EAI_MEMORY; - - strcpy(host, inet_ntoa(sin->sin_addr)); - return 0; - } else { - hp = gethostbyaddr((char *)&sin->sin_addr, - sizeof(struct in_addr), AF_INET); - if (hp == NULL) - return EAI_NODATA; - - if (strlen(hp->h_name) >= hostlen) - return EAI_MEMORY; - - strcpy(host, hp->h_name); - return 0; - } - } - return 0; -} -#endif /* !HAVE_GETNAMEINFO */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/getcwd.c b/usr/src/cmd/ssh/libopenbsd-compat/common/getcwd.c deleted file mode 100644 index 35027a0e7b..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/getcwd.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 1989, 1991, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "includes.h" - -#if !defined(HAVE_GETCWD) - -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: getcwd.c,v 1.6 2000/07/19 15:25:13 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <errno.h> -#include <dirent.h> -#include <sys/dir.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "includes.h" - -#define ISDOT(dp) \ - (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ - (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) - -char * -getcwd(char *pt,size_t size) -{ - register struct dirent *dp; - register DIR *dir = NULL; - register dev_t dev; - register ino_t ino; - register int first; - register char *bpt, *bup; - struct stat s; - dev_t root_dev; - ino_t root_ino; - size_t ptsize, upsize; - int save_errno; - char *ept, *eup, *up; - - /* - * If no buffer specified by the user, allocate one as necessary. - * If a buffer is specified, the size has to be non-zero. The path - * is built from the end of the buffer backwards. - */ - if (pt) { - ptsize = 0; - if (!size) { - errno = EINVAL; - return (NULL); - } - ept = pt + size; - } else { - if ((pt = malloc(ptsize = 1024 - 4)) == NULL) - return (NULL); - ept = pt + ptsize; - } - bpt = ept - 1; - *bpt = '\0'; - - /* - * Allocate bytes (1024 - malloc space) for the string of "../"'s. - * Should always be enough (it's 340 levels). If it's not, allocate - * as necessary. Special * case the first stat, it's ".", not "..". - */ - if ((up = malloc(upsize = 1024 - 4)) == NULL) - goto err; - eup = up + MAXPATHLEN; - bup = up; - up[0] = '.'; - up[1] = '\0'; - - /* Save root values, so know when to stop. */ - if (stat("/", &s)) - goto err; - root_dev = s.st_dev; - root_ino = s.st_ino; - - errno = 0; /* XXX readdir has no error return. */ - - for (first = 1;; first = 0) { - /* Stat the current level. */ - if (lstat(up, &s)) - goto err; - - /* Save current node values. */ - ino = s.st_ino; - dev = s.st_dev; - - /* Check for reaching root. */ - if (root_dev == dev && root_ino == ino) { - *--bpt = '/'; - /* - * It's unclear that it's a requirement to copy the - * path to the beginning of the buffer, but it's always - * been that way and stuff would probably break. - */ - memmove(pt, bpt, ept - bpt); - free(up); - return (pt); - } - - /* - * Build pointer to the parent directory, allocating memory - * as necessary. Max length is 3 for "../", the largest - * possible component name, plus a trailing NULL. - */ - if (bup + 3 + MAXNAMLEN + 1 >= eup) { - char *nup; - - if ((nup = realloc(up, upsize *= 2)) == NULL) - goto err; - up = nup; - bup = up; - eup = up + upsize; - } - *bup++ = '.'; - *bup++ = '.'; - *bup = '\0'; - - /* Open and stat parent directory. - * RACE?? - replaced fstat(dirfd(dir), &s) w/ lstat(up,&s) - */ - if (!(dir = opendir(up)) || lstat(up,&s)) - goto err; - - /* Add trailing slash for next directory. */ - *bup++ = '/'; - - /* - * If it's a mount point, have to stat each element because - * the inode number in the directory is for the entry in the - * parent directory, not the inode number of the mounted file. - */ - save_errno = 0; - if (s.st_dev == dev) { - for (;;) { - if (!(dp = readdir(dir))) - goto notfound; - if (dp->d_fileno == ino) - break; - } - } else - for (;;) { - if (!(dp = readdir(dir))) - goto notfound; - if (ISDOT(dp)) - continue; - memmove(bup, dp->d_name, dp->d_namlen + 1); - - /* Save the first error for later. */ - if (lstat(up, &s)) { - if (!save_errno) - save_errno = errno; - errno = 0; - continue; - } - if (s.st_dev == dev && s.st_ino == ino) - break; - } - - /* - * Check for length of the current name, preceding slash, - * leading slash. - */ - if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { - size_t len, off; - char *npt; - - if (!ptsize) { - errno = ERANGE; - goto err; - } - off = bpt - pt; - len = ept - bpt; - if ((npt = realloc(pt, ptsize *= 2)) == NULL) - goto err; - pt = npt; - bpt = pt + off; - ept = pt + ptsize; - memmove(ept - len, bpt, len); - bpt = ept - len; - } - if (!first) - *--bpt = '/'; - bpt -= dp->d_namlen; - memmove(bpt, dp->d_name, dp->d_namlen); - (void)closedir(dir); - - /* Truncate any file name. */ - *bup = '\0'; - } - -notfound: - /* - * If readdir set errno, use it, not any saved error; otherwise, - * didn't find the current directory in its parent directory, set - * errno to ENOENT. - */ - if (!errno) - errno = save_errno ? save_errno : ENOENT; - /* FALLTHROUGH */ -err: - if (ptsize) - free(pt); - if (up) - free(up); - if (dir) - (void)closedir(dir); - return (NULL); -} - -#endif /* !defined(HAVE_GETCWD) */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/getgrouplist.c b/usr/src/cmd/ssh/libopenbsd-compat/common/getgrouplist.c deleted file mode 100644 index bdd4c3a153..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/getgrouplist.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 1991, 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. - */ - -#include "includes.h" - -#ifndef HAVE_GETGROUPLIST - -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: getgrouplist.c,v 1.7 1997/08/19 19:13:27 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -/* - * get credential - */ -#include <sys/types.h> -#include <string.h> -#include <grp.h> - -int -getgrouplist(uname, agroup, groups, grpcnt) - const char *uname; - gid_t agroup; - register gid_t *groups; - int *grpcnt; -{ - register struct group *grp; - register int i, ngroups; - int ret, maxgroups; - int bail; - - ret = 0; - ngroups = 0; - maxgroups = *grpcnt; - - /* - * install primary group - */ - if (ngroups >= maxgroups) { - *grpcnt = ngroups; - return (-1); - } - groups[ngroups++] = agroup; - - /* - * Scan the group file to find additional groups. - */ - setgrent(); - while ((grp = getgrent())) { - if (grp->gr_gid == agroup) - continue; - for (bail = 0, i = 0; bail == 0 && i < ngroups; i++) - if (groups[i] == grp->gr_gid) - bail = 1; - if (bail) - continue; - for (i = 0; grp->gr_mem[i]; i++) { - if (!strcmp(grp->gr_mem[i], uname)) { - if (ngroups >= maxgroups) { - ret = -1; - goto out; - } - groups[ngroups++] = grp->gr_gid; - break; - } - } - } -out: - endgrent(); - *grpcnt = ngroups; - return (ret); -} - -#endif /* HAVE_GETGROUPLIST */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/getopt.c b/usr/src/cmd/ssh/libopenbsd-compat/common/getopt.c deleted file mode 100644 index f69487950f..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/getopt.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 1987, 1993, 1994 - * 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. - */ - -#include "includes.h" -#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: getopt.c,v 1.2 1996/08/19 08:33:32 tholo Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -int BSDopterr = 1, /* if error message should be printed */ - BSDoptind = 1, /* index into parent argv vector */ - BSDoptopt, /* character checked for validity */ - BSDoptreset; /* reset getopt */ -char *BSDoptarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -BSDgetopt(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - extern char *__progname; - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - if (BSDoptreset || !*place) { /* update scanning pointer */ - BSDoptreset = 0; - if (BSDoptind >= nargc || *(place = nargv[BSDoptind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-') { /* found "--" */ - ++BSDoptind; - place = EMSG; - return (-1); - } - } /* option letter okay? */ - if ((BSDoptopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, BSDoptopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means -1. - */ - if (BSDoptopt == (int)'-') - return (-1); - if (!*place) - ++BSDoptind; - if (BSDopterr && *ostr != ':') - (void) fprintf(stderr, - gettext("%s: illegal option -- %c\n"), __progname, - BSDoptopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - BSDoptarg = NULL; - if (!*place) - ++BSDoptind; - } else { /* need an argument */ - if (*place) /* no white space */ - BSDoptarg = place; - else if (nargc <= ++BSDoptind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (BSDopterr) - (void) fprintf(stderr, - "%s: option requires an argument -- %c\n", - __progname, BSDoptopt); - return (BADCH); - /* white space */ - } else - BSDoptarg = nargv[BSDoptind]; - - place = EMSG; - ++BSDoptind; - } - return (BSDoptopt); /* dump back option letter */ -} - -#endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */ diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/glob.c b/usr/src/cmd/ssh/libopenbsd-compat/common/glob.c deleted file mode 100644 index 2688cccaee..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/glob.c +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * 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. - */ - -#include "includes.h" -#include <ctype.h> - -#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ - !defined(GLOB_HAS_GL_MATCHC) - -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; -#else -static char rcsid[] = "$OpenBSD: glob.c,v 1.20 2002/06/14 21:34:58 todd Exp $"; -#endif -#endif /* LIBC_SCCS and not lint */ - -/* - * glob(3) -- a superset of the one defined in POSIX 1003.2. - * - * The [!...] convention to negate a range is supported (SysV, Posix, ksh). - * - * Optional extra services, controlled by flags not defined by POSIX: - * - * GLOB_QUOTE: - * Escaping convention: \ inhibits any special meaning the following - * character might have (except \ at end of string is retained). - * GLOB_MAGCHAR: - * Set in gl_flags if pattern contained a globbing character. - * GLOB_NOMAGIC: - * Same as GLOB_NOCHECK, but it will only append pattern if it did - * not contain any magic characters. [Used in csh style globbing] - * GLOB_ALTDIRFUNC: - * Use alternately specified directory access functions. - * GLOB_TILDE: - * expand ~user/foo to the /home/dir/of/user/foo - * GLOB_BRACE: - * expand {1,2}{a,b} to 1a 1b 2a 2b - * gl_matchc: - * Number of matches in the current invocation of glob. - */ - - -#define DOLLAR '$' -#define DOT '.' -#define EOS '\0' -#define LBRACKET '[' -#define NOT '!' -#define QUESTION '?' -#define QUOTE '\\' -#define RANGE '-' -#define RBRACKET ']' -#define SEP '/' -#define STAR '*' -#undef TILDE /* Some platforms may already define it */ -#define TILDE '~' -#define UNDERSCORE '_' -#define LBRACE '{' -#define RBRACE '}' -#define SLASH '/' -#define COMMA ',' - -#ifndef DEBUG - -#define M_QUOTE 0x8000 -#define M_PROTECT 0x4000 -#define M_MASK 0xffff -#define M_ASCII 0x00ff - -typedef u_short Char; - -#else - -#define M_QUOTE 0x80 -#define M_PROTECT 0x40 -#define M_MASK 0xff -#define M_ASCII 0x7f - -typedef char Char; - -#endif - - -#define CHAR(c) ((Char)((c)&M_ASCII)) -#define META(c) ((Char)((c)|M_QUOTE)) -#define M_ALL META('*') -#define M_END META(']') -#define M_NOT META('!') -#define M_ONE META('?') -#define M_RNG META('-') -#define M_SET META('[') -#define ismeta(c) (((c)&M_QUOTE) != 0) - - -#define GLOB_LIMIT_MALLOC 65536 -#define GLOB_LIMIT_STAT 128 -#define GLOB_LIMIT_READDIR 16384 - -#define GLOB_INDEX_MALLOC 0 -#define GLOB_INDEX_STAT 1 -#define GLOB_INDEX_READDIR 2 - -static int compare(const void *, const void *); -static int g_Ctoc(const Char *, char *, u_int); -static int g_lstat(Char *, struct stat *, glob_t *); -static DIR *g_opendir(Char *, glob_t *); -static Char *g_strchr(Char *, int); -static int g_stat(Char *, struct stat *, glob_t *); -static int glob0(const Char *, glob_t *, size_t *); -static int glob1(Char *, Char *, glob_t *, size_t *); -static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, - glob_t *, size_t *); -static int glob3(Char *, Char *, Char *, Char *, Char *, Char *, - Char *, Char *, glob_t *, size_t *); -static int globextend(const Char *, glob_t *, size_t *); -static const Char * - globtilde(const Char *, Char *, size_t, glob_t *); -static int globexp1(const Char *, glob_t *, size_t *); -static int globexp2(const Char *, const Char *, glob_t *, int *, - size_t *); -static int match(Char *, Char *, Char *); -#ifdef DEBUG -static void qprintf(const char *, Char *); -#endif - -int -glob(pattern, flags, errfunc, pglob) - const char *pattern; - int flags, (*errfunc)(const char *, int); - glob_t *pglob; -{ - const u_char *patnext; - int c; - Char *bufnext, *bufend, patbuf[MAXPATHLEN]; - /* 0 = malloc(), 1 = stat(), 2 = readdir() */ - static size_t limit[] = { 0, 0, 0 }; - - patnext = (u_char *) pattern; - if (!(flags & GLOB_APPEND)) { - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; - if (!(flags & GLOB_DOOFFS)) - pglob->gl_offs = 0; - } - pglob->gl_flags = flags & ~GLOB_MAGCHAR; - pglob->gl_errfunc = errfunc; - pglob->gl_matchc = 0; - - bufnext = patbuf; - bufend = bufnext + MAXPATHLEN - 1; - if (flags & GLOB_NOESCAPE) - while (bufnext < bufend && (c = *patnext++) != EOS) - *bufnext++ = c; - else { - /* Protect the quoted characters. */ - while (bufnext < bufend && (c = *patnext++) != EOS) - if (c == QUOTE) { - if ((c = *patnext++) == EOS) { - c = QUOTE; - --patnext; - } - *bufnext++ = c | M_PROTECT; - } else - *bufnext++ = c; - } - *bufnext = EOS; - - if (flags & GLOB_BRACE) - return globexp1(patbuf, pglob, limit); - else - return glob0(patbuf, pglob, limit); -} - -/* - * Expand recursively a glob {} pattern. When there is no more expansion - * invoke the standard globbing routine to glob the rest of the magic - * characters - */ -static int -globexp1(pattern, pglob, limit) - const Char *pattern; - glob_t *pglob; - size_t *limit; -{ - const Char* ptr = pattern; - int rv; - - /* Protect a single {}, for find(1), like csh */ - if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) - return glob0(pattern, pglob, limit); - - while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) - if (!globexp2(ptr, pattern, pglob, &rv, limit)) - return rv; - - return glob0(pattern, pglob, limit); -} - - -/* - * Recursive brace globbing helper. Tries to expand a single brace. - * If it succeeds then it invokes globexp1 with the new pattern. - * If it fails then it tries to glob the rest of the pattern and returns. - */ -static int -globexp2(ptr, pattern, pglob, rv, limit) - const Char *ptr, *pattern; - glob_t *pglob; - int *rv; - size_t *limit; -{ - int i; - Char *lm, *ls; - const Char *pe, *pm, *pl; - Char patbuf[MAXPATHLEN]; - - /* copy part up to the brace */ - for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) - ; - *lm = EOS; - ls = lm; - - /* Find the balanced brace */ - for (i = 0, pe = ++ptr; *pe; pe++) - if (*pe == LBRACKET) { - /* Ignore everything between [] */ - for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) - ; - if (*pe == EOS) { - /* - * We could not find a matching RBRACKET. - * Ignore and just look for RBRACE - */ - pe = pm; - } - } else if (*pe == LBRACE) - i++; - else if (*pe == RBRACE) { - if (i == 0) - break; - i--; - } - - /* Non matching braces; just glob the pattern */ - if (i != 0 || *pe == EOS) { - *rv = glob0(patbuf, pglob, limit); - return 0; - } - - for (i = 0, pl = pm = ptr; pm <= pe; pm++) { - switch (*pm) { - case LBRACKET: - /* Ignore everything between [] */ - for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) - ; - if (*pm == EOS) { - /* - * We could not find a matching RBRACKET. - * Ignore and just look for RBRACE - */ - pm = pl; - } - break; - - case LBRACE: - i++; - break; - - case RBRACE: - if (i) { - i--; - break; - } - /* FALLTHROUGH */ - case COMMA: - if (i && *pm == COMMA) - break; - else { - /* Append the current string */ - for (lm = ls; (pl < pm); *lm++ = *pl++) - ; - - /* - * Append the rest of the pattern after the - * closing brace - */ - for (pl = pe + 1; (*lm++ = *pl++) != EOS; ) - ; - - /* Expand the current pattern */ -#ifdef DEBUG - qprintf("globexp2:", patbuf); -#endif - *rv = globexp1(patbuf, pglob, limit); - - /* move after the comma, to the next string */ - pl = pm + 1; - } - break; - - default: - break; - } - } - *rv = 0; - return 0; -} - - - -/* - * expand tilde from the passwd file. - */ -static const Char * -globtilde(pattern, patbuf, patbuf_len, pglob) - const Char *pattern; - Char *patbuf; - size_t patbuf_len; - glob_t *pglob; -{ - struct passwd *pwd; - char *h; - const Char *p; - Char *b, *eb; - - if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) - return pattern; - - /* Copy up to the end of the string or / */ - eb = &patbuf[patbuf_len - 1]; - for (p = pattern + 1, h = (char *) patbuf; - h < (char *)eb && *p && *p != SLASH; *h++ = *p++) - ; - - *h = EOS; - -#if 0 - if (h == (char *)eb) - return what; -#endif - - if (((char *) patbuf)[0] == EOS) { - /* - * handle a plain ~ or ~/ by expanding $HOME - * first and then trying the password file - */ -#if 0 - if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { -#endif - if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { - if ((pwd = getpwuid(getuid())) == NULL) - return pattern; - else - h = pwd->pw_dir; - } - } else { - /* - * Expand a ~user - */ - if ((pwd = getpwnam((char*) patbuf)) == NULL) - return pattern; - else - h = pwd->pw_dir; - } - - /* Copy the home directory */ - for (b = patbuf; b < eb && *h; *b++ = *h++) - ; - - /* Append the rest of the pattern */ - while (b < eb && (*b++ = *p++) != EOS) - ; - *b = EOS; - - return patbuf; -} - - -/* - * The main glob() routine: compiles the pattern (optionally processing - * quotes), calls glob1() to do the real pattern matching, and finally - * sorts the list (unless unsorted operation is requested). Returns 0 - * if things went well, nonzero if errors occurred. It is not an error - * to find no matches. - */ -static int -glob0(pattern, pglob, limit) - const Char *pattern; - glob_t *pglob; - size_t *limit; -{ - const Char *qpatnext; - int c, err, oldpathc; - Char *bufnext, patbuf[MAXPATHLEN]; - - qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); - oldpathc = pglob->gl_pathc; - bufnext = patbuf; - - /* We don't need to check for buffer overflow any more. */ - while ((c = *qpatnext++) != EOS) { - switch (c) { - case LBRACKET: - c = *qpatnext; - if (c == NOT) - ++qpatnext; - if (*qpatnext == EOS || - g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { - *bufnext++ = LBRACKET; - if (c == NOT) - --qpatnext; - break; - } - *bufnext++ = M_SET; - if (c == NOT) - *bufnext++ = M_NOT; - c = *qpatnext++; - do { - *bufnext++ = CHAR(c); - if (*qpatnext == RANGE && - (c = qpatnext[1]) != RBRACKET) { - *bufnext++ = M_RNG; - *bufnext++ = CHAR(c); - qpatnext += 2; - } - } while ((c = *qpatnext++) != RBRACKET); - pglob->gl_flags |= GLOB_MAGCHAR; - *bufnext++ = M_END; - break; - case QUESTION: - pglob->gl_flags |= GLOB_MAGCHAR; - *bufnext++ = M_ONE; - break; - case STAR: - pglob->gl_flags |= GLOB_MAGCHAR; - /* collapse adjacent stars to one, - * to avoid exponential behavior - */ - if (bufnext == patbuf || bufnext[-1] != M_ALL) - *bufnext++ = M_ALL; - break; - default: - *bufnext++ = CHAR(c); - break; - } - } - *bufnext = EOS; -#ifdef DEBUG - qprintf("glob0:", patbuf); -#endif - - if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limit)) != 0) - return(err); - - /* - * If there was no match we are going to append the pattern - * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified - * and the pattern did not contain any magic characters - * GLOB_NOMAGIC is there just for compatibility with csh. - */ - if (pglob->gl_pathc == oldpathc) { - if ((pglob->gl_flags & GLOB_NOCHECK) || - ((pglob->gl_flags & GLOB_NOMAGIC) && - !(pglob->gl_flags & GLOB_MAGCHAR))) - return(globextend(pattern, pglob, limit)); - else - return(GLOB_NOMATCH); - } - if (!(pglob->gl_flags & GLOB_NOSORT)) - qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, - pglob->gl_pathc - oldpathc, sizeof(char *), compare); - return(0); -} - -static int -compare(p, q) - const void *p, *q; -{ - return(strcmp(*(char **)p, *(char **)q)); -} - -static int -glob1(pattern, pattern_last, pglob, limit) - Char *pattern, *pattern_last; - glob_t *pglob; - size_t *limit; -{ - Char pathbuf[MAXPATHLEN]; - - /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ - if (*pattern == EOS) - return(0); - return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, - pathbuf, pathbuf+MAXPATHLEN-1, - pattern, pattern_last, pglob, limit)); -} - -/* - * The functions glob2 and glob3 are mutually recursive; there is one level - * of recursion for each segment in the pattern that contains one or more - * meta characters. - */ -static int -glob2(pathbuf, pathbuf_last, pathend, pathend_last, pattern, - pattern_last, pglob, limit) - Char *pathbuf, *pathbuf_last, *pathend, *pathend_last; - Char *pattern, *pattern_last; - glob_t *pglob; - size_t *limit; -{ - struct stat sb; - Char *p, *q; - int anymeta; - - /* - * Loop over pattern segments until end of pattern or until - * segment with meta character found. - */ - for (anymeta = 0;;) { - if (*pattern == EOS) { /* End of pattern? */ - *pathend = EOS; - if (g_lstat(pathbuf, &sb, pglob)) - return(0); - - if ((pglob->gl_flags & GLOB_LIMIT) && - limit[GLOB_INDEX_STAT]++ >= GLOB_LIMIT_STAT) { - errno = 0; - *pathend++ = SEP; - *pathend = EOS; - return GLOB_NOSPACE; - } - - if (((pglob->gl_flags & GLOB_MARK) && - pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || - (S_ISLNK(sb.st_mode) && - (g_stat(pathbuf, &sb, pglob) == 0) && - S_ISDIR(sb.st_mode)))) { - if (pathend+1 > pathend_last) - return (1); - *pathend++ = SEP; - *pathend = EOS; - } - ++pglob->gl_matchc; - return(globextend(pathbuf, pglob, limit)); - } - - /* Find end of next segment, copy tentatively to pathend. */ - q = pathend; - p = pattern; - while (*p != EOS && *p != SEP) { - if (ismeta(*p)) - anymeta = 1; - if (q+1 > pathend_last) - return (1); - *q++ = *p++; - } - - if (!anymeta) { /* No expansion, do next segment. */ - pathend = q; - pattern = p; - while (*pattern == SEP) { - if (pathend+1 > pathend_last) - return (1); - *pathend++ = *pattern++; - } - } else - /* Need expansion, recurse. */ - return(glob3(pathbuf, pathbuf_last, pathend, - pathend_last, pattern, pattern_last, - p, pattern_last, pglob, limit)); - } - /* NOTREACHED */ -} - -static int -glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, - restpattern, restpattern_last, pglob, limit) - Char *pathbuf, *pathbuf_last, *pathend, *pathend_last; - Char *pattern, *pattern_last, *restpattern, *restpattern_last; - glob_t *pglob; - size_t *limit; -{ - register struct dirent *dp; - DIR *dirp; - int err; - char buf[MAXPATHLEN]; - - /* - * The readdirfunc declaration can't be prototyped, because it is - * assigned, below, to two functions which are prototyped in glob.h - * and dirent.h as taking pointers to differently typed opaque - * structures. - */ - struct dirent *(*readdirfunc)(); - - if (pathend > pathend_last) - return (1); - *pathend = EOS; - errno = 0; - - if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { - /* TODO: don't call for ENOENT or ENOTDIR? */ - if (pglob->gl_errfunc) { - if (g_Ctoc(pathbuf, buf, sizeof(buf))) - return(GLOB_ABORTED); - if (pglob->gl_errfunc(buf, errno) || - pglob->gl_flags & GLOB_ERR) - return(GLOB_ABORTED); - } - return(0); - } - - err = 0; - - /* Search directory for matching names. */ - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - readdirfunc = pglob->gl_readdir; - else - readdirfunc = readdir; - while ((dp = (*readdirfunc)(dirp))) { - register u_char *sc; - register Char *dc; - - if ((pglob->gl_flags & GLOB_LIMIT) && - limit[GLOB_INDEX_READDIR]++ >= GLOB_LIMIT_READDIR) { - errno = 0; - *pathend++ = SEP; - *pathend = EOS; - return GLOB_NOSPACE; - } - - /* Initial DOT must be matched literally. */ - if (dp->d_name[0] == DOT && *pattern != DOT) - continue; - dc = pathend; - sc = (u_char *) dp->d_name; - while (dc < pathend_last && (*dc++ = *sc++) != EOS) - ; - if (dc >= pathend_last) { - *dc = EOS; - err = 1; - break; - } - - if (!match(pathend, pattern, restpattern)) { - *pathend = EOS; - continue; - } - err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, - restpattern, restpattern_last, pglob, limit); - if (err) - break; - } - - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - (*pglob->gl_closedir)(dirp); - else - closedir(dirp); - return(err); -} - - -/* - * Extend the gl_pathv member of a glob_t structure to accommodate a new item, - * add the new item, and update gl_pathc. - * - * This assumes the BSD realloc, which only copies the block when its size - * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic - * behavior. - * - * Return 0 if new item added, error code if memory couldn't be allocated. - * - * Invariant of the glob_t structure: - * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and - * gl_pathv points to (gl_offs + gl_pathc + 1) items. - */ -static int -globextend(path, pglob, limit) - const Char *path; - glob_t *pglob; - size_t *limit; -{ - register char **pathv; - register int i; - u_int newsize, len; - char *copy; - const Char *p; - - newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); - pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) : - malloc(newsize); - if (pathv == NULL) { - if (pglob->gl_pathv) { - free(pglob->gl_pathv); - pglob->gl_pathv = NULL; - } - return(GLOB_NOSPACE); - } - - if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { - /* first time around -- clear initial gl_offs items */ - pathv += pglob->gl_offs; - for (i = pglob->gl_offs; --i >= 0; ) - *--pathv = NULL; - } - pglob->gl_pathv = pathv; - - for (p = path; *p++;) - ; - len = (size_t)(p - path); - limit[GLOB_INDEX_MALLOC] += len; - if ((copy = malloc(len)) != NULL) { - if (g_Ctoc(path, copy, len)) { - free(copy); - return(GLOB_NOSPACE); - } - pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; - } - pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; - if ((pglob->gl_flags & GLOB_LIMIT) && - (newsize + limit[GLOB_INDEX_MALLOC]) >= GLOB_LIMIT_MALLOC) { - errno = 0; - return GLOB_NOSPACE; - } - - return(copy == NULL ? GLOB_NOSPACE : 0); -} - - -/* - * pattern matching function for filenames. Each occurrence of the * - * pattern causes a recursion level. - */ -static int -match(name, pat, patend) - register Char *name, *pat, *patend; -{ - int ok, negate_range; - Char c, k; - - while (pat < patend) { - c = *pat++; - switch (c & M_MASK) { - case M_ALL: - if (pat == patend) - return(1); - do - if (match(name, pat, patend)) - return(1); - while (*name++ != EOS) - ; - return(0); - case M_ONE: - if (*name++ == EOS) - return(0); - break; - case M_SET: - ok = 0; - if ((k = *name++) == EOS) - return(0); - if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) - ++pat; - while (((c = *pat++) & M_MASK) != M_END) - if ((*pat & M_MASK) == M_RNG) { - if (c <= k && k <= pat[1]) - ok = 1; - pat += 2; - } else if (c == k) - ok = 1; - if (ok == negate_range) - return(0); - break; - default: - if (*name++ != c) - return(0); - break; - } - } - return(*name == EOS); -} - -/* Free allocated data belonging to a glob_t structure. */ -void -globfree(pglob) - glob_t *pglob; -{ - register int i; - register char **pp; - - if (pglob->gl_pathv != NULL) { - pp = pglob->gl_pathv + pglob->gl_offs; - for (i = pglob->gl_pathc; i--; ++pp) - if (*pp) - free(*pp); - free(pglob->gl_pathv); - pglob->gl_pathv = NULL; - } -} - -static DIR * -g_opendir(str, pglob) - register Char *str; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - if (!*str) - strlcpy(buf, ".", sizeof buf); - else { - if (g_Ctoc(str, buf, sizeof(buf))) - return(NULL); - } - - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_opendir)(buf)); - - return(opendir(buf)); -} - -static int -g_lstat(fn, sb, pglob) - register Char *fn; - struct stat *sb; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - if (g_Ctoc(fn, buf, sizeof(buf))) - return(-1); - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_lstat)(buf, sb)); - return(lstat(buf, sb)); -} - -static int -g_stat(fn, sb, pglob) - register Char *fn; - struct stat *sb; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - if (g_Ctoc(fn, buf, sizeof(buf))) - return(-1); - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_stat)(buf, sb)); - return(stat(buf, sb)); -} - -static Char * -g_strchr(str, ch) - Char *str; - int ch; -{ - do { - if (*str == ch) - return (str); - } while (*str++); - return (NULL); -} - -static int -g_Ctoc(str, buf, len) - register const Char *str; - char *buf; - u_int len; -{ - - while (len--) { - if ((*buf++ = *str++) == EOS) - return (0); - } - return (1); -} - -#ifdef DEBUG -static void -qprintf(str, s) - const char *str; - register Char *s; -{ - register Char *p; - - (void)printf("%s:\n", str); - for (p = s; *p; p++) - (void)printf("%c", CHAR(*p)); - (void)printf("\n"); - for (p = s; *p; p++) - (void)printf("%c", *p & M_PROTECT ? '"' : ' '); - (void)printf("\n"); - for (p = s; *p; p++) - (void)printf("%c", ismeta(*p) ? '_' : ' '); - (void)printf("\n"); -} -#endif - -#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || - !defined(GLOB_HAS_GL_MATCHC) */ - - diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/inet_aton.c b/usr/src/cmd/ssh/libopenbsd-compat/common/inet_aton.c deleted file mode 100644 index d98afff30d..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/inet_aton.c +++ /dev/null @@ -1,195 +0,0 @@ -/* $OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $ */ - -/* - * ++Copyright++ 1983, 1990, 1993 - * - - * Copyright (c) 1983, 1990, 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. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include "includes.h" - -#if !defined(HAVE_INET_ATON) - -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; -static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; -#else -static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $"; -#endif -#endif /* LIBC_SCCS and not lint */ - -#include <sys/types.h> -#include <sys/param.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <ctype.h> - -#if 0 -/* - * Ascii internet address interpretation routine. - * The value returned is in network order. - */ -in_addr_t -inet_addr(cp) - register const char *cp; -{ - struct in_addr val; - - if (inet_aton(cp, &val)) - return (val.s_addr); - return (INADDR_NONE); -} -#endif - -/* - * Check whether "cp" is a valid ascii representation - * of an Internet address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * This replaces inet_addr, the return value from which - * cannot distinguish between failure and a local broadcast address. - */ -int -inet_aton(const char *cp, struct in_addr *addr) -{ - register u_int32_t val; - register int base, n; - register char c; - unsigned int parts[4]; - register unsigned int *pp = parts; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, isdigit=decimal. - */ - if (!isdigit(c)) - return (0); - val = 0; base = 10; - if (c == '0') { - c = *++cp; - if (c == 'x' || c == 'X') - base = 16, c = *++cp; - else - base = 8; - } - for (;;) { - if (isascii(c) && isdigit(c)) { - val = (val * base) + (c - '0'); - c = *++cp; - } else if (base == 16 && isascii(c) && isxdigit(c)) { - val = (val << 4) | - (c + 10 - (islower(c) ? 'a' : 'A')); - c = *++cp; - } else - break; - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3) - return (0); - *pp++ = val; - c = *++cp; - } else - break; - } - /* - * Check for trailing characters. - */ - if (c != '\0' && (!isascii(c) || !isspace(c))) - return (0); - /* - * Concoct the address according to - * the number of parts specified. - */ - n = pp - parts + 1; - switch (n) { - - case 0: - return (0); /* initial nondigit */ - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if ((val > 0xffffff) || (parts[0] > 0xff)) - return (0); - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - } - if (addr) - addr->s_addr = htonl(val); - return (1); -} - -#endif /* !defined(HAVE_INET_ATON) */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/inet_ntoa.c b/usr/src/cmd/ssh/libopenbsd-compat/common/inet_ntoa.c deleted file mode 100644 index e788c83ea0..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/inet_ntoa.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 1983, 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. - */ - -#include "includes.h" - -#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) - -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.3 2002/06/27 10:14:01 itojun Exp $"; -#endif /* LIBC_SCCS and not lint */ - -/* - * Convert network-format internet address - * to base 256 d.d.d.d representation. - */ -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <stdio.h> -#include "inet_ntoa.h" - -char *inet_ntoa(struct in_addr in) -{ - static char b[18]; - register char *p; - - p = (char *)∈ -#define UC(b) (((int)b)&0xff) - (void)snprintf(b, sizeof(b), - "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); - return (b); -} - -#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/inet_ntop.c b/usr/src/cmd/ssh/libopenbsd-compat/common/inet_ntop.c deleted file mode 100644 index ed1acbfb1e..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/inet_ntop.c +++ /dev/null @@ -1,232 +0,0 @@ -/* $OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $ */ - -/* Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "includes.h" - -#ifndef HAVE_INET_NTOP - -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; -#else -static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $"; -#endif -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include "fake-socket.h" -#include <netinet/in.h> -#include <arpa/inet.h> -#ifndef HAVE_CYGWIN -#include <arpa/nameser.h> -#endif -#include <string.h> -#include <errno.h> -#include <stdio.h> - -#ifndef IN6ADDRSZ -#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ -#endif - -#ifndef INT16SZ -#define INT16SZ 2 /* for systems without 16-bit ints */ -#endif - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static const char *inet_ntop4(const u_char *src, char *dst, size_t size); -static const char *inet_ntop6(const u_char *src, char *dst, size_t size); - -/* char * - * inet_ntop(af, src, dst, size) - * convert a network format address to presentation format. - * return: - * pointer to presentation format address (`dst'), or NULL (see errno). - * author: - * Paul Vixie, 1996. - */ -const char * -inet_ntop(af, src, dst, size) - int af; - const void *src; - char *dst; - size_t size; -{ - switch (af) { - case AF_INET: - return (inet_ntop4(src, dst, size)); - case AF_INET6: - return (inet_ntop6(src, dst, size)); - default: - errno = EAFNOSUPPORT; - return (NULL); - } - /* NOTREACHED */ -} - -/* const char * - * inet_ntop4(src, dst, size) - * format an IPv4 address, more or less like inet_ntoa() - * return: - * `dst' (as a const) - * notes: - * (1) uses no statics - * (2) takes a u_char* not an in_addr as input - * author: - * Paul Vixie, 1996. - */ -static const char * -inet_ntop4(src, dst, size) - const u_char *src; - char *dst; - size_t size; -{ - static const char fmt[] = "%u.%u.%u.%u"; - char tmp[sizeof "255.255.255.255"]; - int l; - - l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); - if (l <= 0 || l >= size) { - errno = ENOSPC; - return (NULL); - } - strlcpy(dst, tmp, size); - return (dst); -} - -/* const char * - * inet_ntop6(src, dst, size) - * convert IPv6 binary address into presentation (printable) format - * author: - * Paul Vixie, 1996. - */ -static const char * -inet_ntop6(src, dst, size) - const u_char *src; - char *dst; - size_t size; -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - char *tp, *ep; - struct { int base, len; } best, cur; - u_int words[IN6ADDRSZ / INT16SZ]; - int i; - int advance; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - cur.base = -1; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { - if (words[i] == 0) { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - ep = tmp + sizeof(tmp); - for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) { - if (tp + 1 >= ep) - return (NULL); - *tp++ = ':'; - } - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) { - if (tp + 1 >= ep) - return (NULL); - *tp++ = ':'; - } - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) - return (NULL); - tp += strlen(tp); - break; - } - advance = snprintf(tp, ep - tp, "%x", words[i]); - if (advance <= 0 || advance >= ep - tp) - return (NULL); - tp += advance; - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { - if (tp + 1 >= ep) - return (NULL); - *tp++ = ':'; - } - if (tp + 1 >= ep) - return (NULL); - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { - errno = ENOSPC; - return (NULL); - } - strlcpy(dst, tmp, size); - return (dst); -} - -#endif /* !HAVE_INET_NTOP */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/llib-lopenbsd-compat b/usr/src/cmd/ssh/libopenbsd-compat/common/llib-lopenbsd-compat deleted file mode 100644 index 3c5912997f..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/llib-lopenbsd-compat +++ /dev/null @@ -1,83 +0,0 @@ -/* LINTLIBRARY */ -/* PROTOLIB1 */ - -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <includes.h> -#include <atomicio.h> -#include <base64.h> -#include <bindresvport.h> -#include <bsd-arc4random.h> -#include <bsd-cray.h> -#include <bsd-cygwin_util.h> -#include <bsd-getpeereid.h> -#include <bsd-misc.h> -#include <bsd-snprintf.h> -#include <bsd-waitpid.h> -#include <config.h> -#include <crc32.h> -#include <deattack.h> -#include <defines.h> -#include <dirname.h> -#include <dispatch.h> -#include <entropy.h> -#include <fake-gai-errnos.h> -#include <fake-getaddrinfo.h> -#include <fake-getnameinfo.h> -#include <fake-socket.h> -#include <getcwd.h> -#include <getgrouplist.h> -#include <getopt.h> -#include <getput.h> -#include <glob.h> -#include <groupaccess.h> -#include <inet_ntoa.h> -#include <inet_ntop.h> -#include <log.h> -#include <match.h> -#include <misc.h> -#include <mktemp.h> -#include <openbsd-compat.h> -#include <pathnames.h> -#include <port-aix.h> -#include <port-irix.h> -#include <proxy-io.h> -#include <readpass.h> -#include <readpassphrase.h> -#include <realpath.h> -#include <rresvport.h> -#include <rsa.h> -#include <setproctitle.h> -#include <sigact.h> -#include <strlcat.h> -#include <strlcpy.h> -#include <strmode.h> -#include <sys-queue.h> -#include <sys-tree.h> -#include <tildexpand.h> -#include <uuencode.h> -#include <version.h> -#include <xmalloc.h> -#include <xmmap.h> diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/mktemp.c b/usr/src/cmd/ssh/libopenbsd-compat/common/mktemp.c deleted file mode 100644 index c6b18d22d4..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/mktemp.c +++ /dev/null @@ -1,186 +0,0 @@ -/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ -/* Changes: Removed mktemp */ - -/* - * Copyright (c) 1987, 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. - */ - -#include "includes.h" - -#ifndef HAVE_MKDTEMP - -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: mktemp.c,v 1.16 2002/05/27 18:20:45 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#ifdef HAVE_CYGWIN -#define open binary_open -extern int binary_open(); -#endif - -static int _gettemp(char *, int *, int, int); - -int -mkstemps(path, slen) - char *path; - int slen; -{ - int fd; - - return (_gettemp(path, &fd, 0, slen) ? fd : -1); -} - -int -mkstemp(path) - char *path; -{ - int fd; - - return (_gettemp(path, &fd, 0, 0) ? fd : -1); -} - -char * -mkdtemp(path) - char *path; -{ - return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); -} - -static int -_gettemp(path, doopen, domkdir, slen) - char *path; - register int *doopen; - int domkdir; - int slen; -{ - register char *start, *trv, *suffp; - struct stat sbuf; - int rval; - pid_t pid; - - if (doopen && domkdir) { - errno = EINVAL; - return(0); - } - - for (trv = path; *trv; ++trv) - ; - trv -= slen; - suffp = trv; - --trv; - if (trv < path) { - errno = EINVAL; - return (0); - } - pid = getpid(); - while (trv >= path && *trv == 'X' && pid != 0) { - *trv-- = (pid % 10) + '0'; - pid /= 10; - } - while (trv >= path && *trv == 'X') { - char c; - - pid = (arc4random() & 0xffff) % (26+26); - if (pid < 26) - c = pid + 'A'; - else - c = (pid - 26) + 'a'; - *trv-- = c; - } - start = trv + 1; - - /* - * check the target directory; if you have six X's and it - * doesn't exist this runs for a *very* long time. - */ - if (doopen || domkdir) { - for (;; --trv) { - if (trv <= path) - break; - if (*trv == '/') { - *trv = '\0'; - rval = stat(path, &sbuf); - *trv = '/'; - if (rval != 0) - return(0); - if (!S_ISDIR(sbuf.st_mode)) { - errno = ENOTDIR; - return(0); - } - break; - } - } - } - - for (;;) { - if (doopen) { - if ((*doopen = - open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) - return(1); - if (errno != EEXIST) - return(0); - } else if (domkdir) { - if (mkdir(path, 0700) == 0) - return(1); - if (errno != EEXIST) - return(0); - } else if (lstat(path, &sbuf)) - return(errno == ENOENT ? 1 : 0); - - /* tricky little algorithm for backward compatibility */ - for (trv = start;;) { - if (!*trv) - return (0); - if (*trv == 'Z') { - if (trv == suffp) - return (0); - *trv++ = 'a'; - } else { - if (isdigit(*trv)) - *trv = 'a'; - else if (*trv == 'z') /* inc from z to A */ - *trv = 'A'; - else { - if (trv == suffp) - return (0); - ++*trv; - } - break; - } - } - } - /*NOTREACHED*/ -} - -#endif /* !HAVE_MKDTEMP */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/port-aix.c b/usr/src/cmd/ssh/libopenbsd-compat/common/port-aix.c deleted file mode 100644 index 4b83f53c07..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/port-aix.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Copyright (c) 2001 Gert Doering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -#include "includes.h" - -#ifdef _AIX - -#include <uinfo.h> -#include <../xmalloc.h> - -/* - * AIX has a "usrinfo" area where logname and other stuff is stored - - * a few applications actually use this and die if it's not set - * - * NOTE: TTY= should be set, but since no one uses it and it's hard to - * acquire due to privsep code. We will just drop support. - */ -void -aix_usrinfo(struct passwd *pw) -{ - u_int i; - char *cp; - - cp = xmalloc(16 + 2 * strlen(pw->pw_name)); - i = sprintf(cp, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, 0, - pw->pw_name, 0); - if (usrinfo(SETUINFO, cp, i) == -1) - fatal("Couldn't set usrinfo: %s", strerror(errno)); - debug3("AIX/UsrInfo: set len %d", i); - xfree(cp); -} - -#endif /* _AIX */ - - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/port-irix.c b/usr/src/cmd/ssh/libopenbsd-compat/common/port-irix.c deleted file mode 100644 index 5f839043c0..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/port-irix.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "includes.h" - -#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) - -#ifdef WITH_IRIX_PROJECT -#include <proj.h> -#endif /* WITH_IRIX_PROJECT */ -#ifdef WITH_IRIX_JOBS -#include <sys/resource.h> -#endif -#ifdef WITH_IRIX_AUDIT -#include <sat.h> -#endif /* WITH_IRIX_AUDIT */ - -void -irix_setusercontext(struct passwd *pw) -{ -#ifdef WITH_IRIX_PROJECT - prid_t projid; -#endif /* WITH_IRIX_PROJECT */ -#ifdef WITH_IRIX_JOBS - jid_t jid = 0; -#else -# ifdef WITH_IRIX_ARRAY - int jid = 0; -# endif /* WITH_IRIX_ARRAY */ -#endif /* WITH_IRIX_JOBS */ - -#ifdef WITH_IRIX_JOBS - jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); - if (jid == -1) - fatal("Failed to create job container: %.100s", - strerror(errno)); -#endif /* WITH_IRIX_JOBS */ -#ifdef WITH_IRIX_ARRAY - /* initialize array session */ - if (jid == 0 && newarraysess() != 0) - fatal("Failed to set up new array session: %.100s", - strerror(errno)); -#endif /* WITH_IRIX_ARRAY */ -#ifdef WITH_IRIX_PROJECT - /* initialize irix project info */ - if ((projid = getdfltprojuser(pw->pw_name)) == -1) { - debug("Failed to get project id, using projid 0"); - projid = 0; - } - if (setprid(projid)) - fatal("Failed to initialize project %d for %s: %.100s", - (int)projid, pw->pw_name, strerror(errno)); -#endif /* WITH_IRIX_PROJECT */ -#ifdef WITH_IRIX_AUDIT - if (sysconf(_SC_AUDIT)) { - debug("Setting sat id to %d", (int) pw->pw_uid); - if (satsetid(pw->pw_uid)) - debug("error setting satid: %.100s", strerror(errno)); - } -#endif /* WITH_IRIX_AUDIT */ -} - - -#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/readpassphrase.c b/usr/src/cmd/ssh/libopenbsd-compat/common/readpassphrase.c deleted file mode 100644 index 67ed2caff7..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/readpassphrase.c +++ /dev/null @@ -1,192 +0,0 @@ -/* $OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $ */ - -/* - * Copyright (c) 2000-2002 Todd C. Miller <Todd.Miller@courtesan.com> - * 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. 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 ``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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include "includes.h" - -#ifndef HAVE_READPASSPHRASE - -#include <termios.h> -#include <readpassphrase.h> - -#ifdef TCSASOFT -# define _T_FLUSH (TCSAFLUSH|TCSASOFT) -#else -# define _T_FLUSH (TCSAFLUSH) -#endif - -/* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ -#if !defined(_POSIX_VDISABLE) && defined(VDISABLE) -# define _POSIX_VDISABLE VDISABLE -#endif - -static volatile sig_atomic_t signo; - -static void handler(int); - -char * -readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) -{ - ssize_t nr; - int input, output, save_errno; - char ch, *p, *end; - struct termios term, oterm; - struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; - struct sigaction savetstp, savettin, savettou, savepipe; - - /* I suppose we could alloc on demand in this case (XXX). */ - if (bufsiz == 0) { - errno = EINVAL; - return(NULL); - } - -restart: - signo = 0; - /* - * Read and write to /dev/tty if available. If not, read from - * stdin and write to stderr unless a tty is required. - */ - if ((flags & RPP_STDIN) || - (input = output = open(_PATH_TTY, O_RDWR)) == -1) { - if (flags & RPP_REQUIRE_TTY) { - errno = ENOTTY; - return(NULL); - } - input = STDIN_FILENO; - output = STDERR_FILENO; - } - - /* - * Catch signals that would otherwise cause the user to end - * up with echo turned off in the shell. Don't worry about - * things like SIGXCPU and SIGVTALRM for now. - */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; /* don't restart system calls */ - sa.sa_handler = handler; - (void)sigaction(SIGALRM, &sa, &savealrm); - (void)sigaction(SIGHUP, &sa, &savehup); - (void)sigaction(SIGINT, &sa, &saveint); - (void)sigaction(SIGPIPE, &sa, &savepipe); - (void)sigaction(SIGQUIT, &sa, &savequit); - (void)sigaction(SIGTERM, &sa, &saveterm); - (void)sigaction(SIGTSTP, &sa, &savetstp); - (void)sigaction(SIGTTIN, &sa, &savettin); - (void)sigaction(SIGTTOU, &sa, &savettou); - - /* Turn off echo if possible. */ - if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { - memcpy(&term, &oterm, sizeof(term)); - if (!(flags & RPP_ECHO_ON)) - term.c_lflag &= ~(ECHO | ECHONL); -#ifdef VSTATUS - if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) - term.c_cc[VSTATUS] = _POSIX_VDISABLE; -#endif - (void)tcsetattr(input, _T_FLUSH, &term); - } else { - memset(&term, 0, sizeof(term)); - term.c_lflag |= ECHO; - memset(&oterm, 0, sizeof(oterm)); - oterm.c_lflag |= ECHO; - } - - if (!(flags & RPP_STDIN)) - (void)write(output, prompt, strlen(prompt)); - end = buf + bufsiz - 1; - for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { - if (p < end) { - if ((flags & RPP_SEVENBIT)) - ch &= 0x7f; - if (isalpha(ch)) { - if ((flags & RPP_FORCELOWER)) - ch = tolower(ch); - if ((flags & RPP_FORCEUPPER)) - ch = toupper(ch); - } - *p++ = ch; - } - } - *p = '\0'; - save_errno = errno; - if (!(term.c_lflag & ECHO)) - (void)write(output, "\n", 1); - - /* Restore old terminal settings and signals. */ - if (memcmp(&term, &oterm, sizeof(term)) != 0) - (void)tcsetattr(input, _T_FLUSH, &oterm); - (void)sigaction(SIGALRM, &savealrm, NULL); - (void)sigaction(SIGHUP, &savehup, NULL); - (void)sigaction(SIGINT, &saveint, NULL); - (void)sigaction(SIGQUIT, &savequit, NULL); - (void)sigaction(SIGPIPE, &savepipe, NULL); - (void)sigaction(SIGTERM, &saveterm, NULL); - (void)sigaction(SIGTSTP, &savetstp, NULL); - (void)sigaction(SIGTTIN, &savettin, NULL); - if (input != STDIN_FILENO) - (void)close(input); - - /* - * If we were interrupted by a signal, resend it to ourselves - * now that we have restored the signal handlers. - */ - if (signo) { - kill(getpid(), signo); - switch (signo) { - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - goto restart; - } - } - - errno = save_errno; - return(nr == -1 ? NULL : buf); -} - -#if 0 -char * -getpass(const char *prompt) -{ - static char buf[_PASSWORD_LEN + 1]; - - return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); -} -#endif - -static void handler(int s) -{ - signo = s; -} -#endif /* HAVE_READPASSPHRASE */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/realpath.c b/usr/src/cmd/ssh/libopenbsd-compat/common/realpath.c deleted file mode 100644 index e962264a50..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/realpath.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "includes.h" - -#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: realpath.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <sys/stat.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -/* - * MAXSYMLINKS - */ -#ifndef MAXSYMLINKS -#define MAXSYMLINKS 5 -#endif - -/* - * char *realpath(const char *path, char resolved_path[MAXPATHLEN]); - * - * Find the real name of path, by removing all ".", ".." and symlink - * components. Returns (resolved) on success, or (NULL) on failure, - * in which case the path which caused trouble is left in (resolved). - */ -char * -realpath(const char *path, char *resolved) -{ - struct stat sb; - int fd, n, rootd, serrno = 0; - char *p, *q, wbuf[MAXPATHLEN], start[MAXPATHLEN]; - int symlinks = 0; - - /* Save the starting point. */ - getcwd(start,MAXPATHLEN); - if ((fd = open(".", O_RDONLY)) < 0) { - (void)strlcpy(resolved, ".", MAXPATHLEN); - return (NULL); - } - close(fd); - - /* Convert "." -> "" to optimize away a needless lstat() and chdir() */ - if (path[0] == '.' && path[1] == '\0') - path = ""; - - /* - * Find the dirname and basename from the path to be resolved. - * Change directory to the dirname component. - * lstat the basename part. - * if it is a symlink, read in the value and loop. - * if it is a directory, then change to that directory. - * get the current directory name and append the basename. - */ - strlcpy(resolved, path, MAXPATHLEN); -loop: - q = strrchr(resolved, '/'); - if (q != NULL) { - p = q + 1; - if (q == resolved) - q = "/"; - else { - do { - --q; - } while (q > resolved && *q == '/'); - q[1] = '\0'; - q = resolved; - } - if (chdir(q) < 0) - goto err1; - } else - p = resolved; - - /* Deal with the last component. */ - if (*p != '\0' && lstat(p, &sb) == 0) { - if (S_ISLNK(sb.st_mode)) { - if (++symlinks > MAXSYMLINKS) { - serrno = ELOOP; - goto err1; - } - n = readlink(p, resolved, MAXPATHLEN-1); - if (n < 0) - goto err1; - resolved[n] = '\0'; - goto loop; - } - if (S_ISDIR(sb.st_mode)) { - if (chdir(p) < 0) - goto err1; - p = ""; - } - } - - /* - * Save the last component name and get the full pathname of - * the current directory. - */ - (void)strlcpy(wbuf, p, sizeof wbuf); - if (getcwd(resolved, MAXPATHLEN) == 0) - goto err1; - - /* - * Join the two strings together, ensuring that the right thing - * happens if the last component is empty, or the dirname is root. - */ - if (resolved[0] == '/' && resolved[1] == '\0') - rootd = 1; - else - rootd = 0; - - if (*wbuf) { - if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) { - serrno = ENAMETOOLONG; - goto err1; - } - if (rootd == 0) - (void)strcat(resolved, "/"); - (void)strcat(resolved, wbuf); - } - - /* Go back to where we came from. */ - if (chdir(start) < 0) { - serrno = errno; - goto err2; - } - return (resolved); - -err1: chdir(start); -err2: errno = serrno; - return (NULL); -} -#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/rresvport.c b/usr/src/cmd/ssh/libopenbsd-compat/common/rresvport.c deleted file mode 100644 index bfb9a0a51c..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/rresvport.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. - * Copyright (c) 1983, 1993, 1994 - * 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. - * This product includes software developed by Theo de Raadt. - * 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. - */ - -#include "includes.h" - -#ifndef HAVE_RRESVPORT_AF - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: rresvport.c,v 1.5 2000/01/26 03:43:20 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include "includes.h" - -#if 0 -int -rresvport(alport) - int *alport; -{ - return rresvport_af(alport, AF_INET); -} -#endif - -int -rresvport_af(int *alport, sa_family_t af) -{ - struct sockaddr_storage ss; - struct sockaddr *sa; - u_int16_t *portp; - int s; - socklen_t salen; - - memset(&ss, '\0', sizeof ss); - sa = (struct sockaddr *)&ss; - - switch (af) { - case AF_INET: - salen = sizeof(struct sockaddr_in); - portp = &((struct sockaddr_in *)sa)->sin_port; - break; - case AF_INET6: - salen = sizeof(struct sockaddr_in6); - portp = &((struct sockaddr_in6 *)sa)->sin6_port; - break; - default: - errno = EPFNOSUPPORT; - return (-1); - } - sa->sa_family = af; - - s = socket(af, SOCK_STREAM, 0); - if (s < 0) - return (-1); - - *portp = htons(*alport); - if (*alport < IPPORT_RESERVED - 1) { - if (bind(s, sa, salen) >= 0) - return (s); - if (errno != EADDRINUSE) { - (void)close(s); - return (-1); - } - } - - *portp = 0; - sa->sa_family = af; - if (bindresvport_sa(s, sa) == -1) { - (void)close(s); - return (-1); - } - *alport = ntohs(*portp); - return (s); -} - -#endif /* HAVE_RRESVPORT_AF */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/setenv.c b/usr/src/cmd/ssh/libopenbsd-compat/common/setenv.c deleted file mode 100644 index ed5b9525ce..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/setenv.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 1987 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. - */ - -#include "includes.h" -#ifndef HAVE_SETENV - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: setenv.c,v 1.4 2001/07/09 06:57:45 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <stdlib.h> -#include <string.h> - -/* - * __findenv -- - * Returns pointer to value associated with name, if any, else NULL. - * Sets offset to be the offset of the name/value combination in the - * environmental array, for use by setenv(3) and unsetenv(3). - * Explicitly removes '=' in argument name. - * - * This routine *should* be a static; don't use it. - */ -char * -__findenv(name, offset) - register const char *name; - int *offset; -{ - extern char **environ; - register int len, i; - register const char *np; - register char **p, *cp; - - if (name == NULL || environ == NULL) - return (NULL); - for (np = name; *np && *np != '='; ++np) - ; - len = np - name; - for (p = environ; (cp = *p) != NULL; ++p) { - for (np = name, i = len; i && *cp; i--) - if (*cp++ != *np++) - break; - if (i == 0 && *cp++ == '=') { - *offset = p - environ; - return (cp); - } - } - return (NULL); -} - -/* - * setenv -- - * Set the value of the environmental variable "name" to be - * "value". If rewrite is set, replace any current value. - */ -int -setenv(name, value, rewrite) - register const char *name; - register const char *value; - int rewrite; -{ - extern char **environ; - static int alloced; /* if allocated space before */ - register char *C; - int l_value, offset; - char *__findenv(); - - if (*value == '=') /* no `=' in value */ - ++value; - l_value = strlen(value); - if ((C = __findenv(name, &offset))) { /* find if already exists */ - if (!rewrite) - return (0); - if (strlen(C) >= l_value) { /* old larger; copy over */ - while ((*C++ = *value++)) - ; - return (0); - } - } else { /* create new slot */ - register int cnt; - register char **P; - - for (P = environ, cnt = 0; *P; ++P, ++cnt); - if (alloced) { /* just increase size */ - P = (char **)realloc((void *)environ, - (size_t)(sizeof(char *) * (cnt + 2))); - if (!P) - return (-1); - environ = P; - } - else { /* get new space */ - alloced = 1; /* copy old entries into it */ - P = (char **)malloc((size_t)(sizeof(char *) * - (cnt + 2))); - if (!P) - return (-1); - memmove(P, environ, cnt * sizeof(char *)); - environ = P; - } - environ[cnt + 1] = NULL; - offset = cnt; - } - for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ - if (!(environ[offset] = /* name + `=' + value */ - malloc((size_t)((int)(C - name) + l_value + 2)))) - return (-1); - /* LINTED */ - for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) - ; - for (*C++ = '='; (*C++ = *value++); ) - ; - return (0); -} - -/* - * unsetenv(name) -- - * Delete environmental variable "name". - */ -void -unsetenv(name) - const char *name; -{ - extern char **environ; - register char **P; - int offset; - char *__findenv(); - - while (__findenv(name, &offset)) /* if set multiple times */ - for (P = &environ[offset];; ++P) - /* LINTED */ - if (!(*P = *(P + 1))) - break; -} - -#endif /* HAVE_SETENV */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/setproctitle.c b/usr/src/cmd/ssh/libopenbsd-compat/common/setproctitle.c deleted file mode 100644 index 4163f0cfec..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/setproctitle.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Modified for OpenSSH by Kevin Steves - * October 2000 - */ - -/* - * Copyright (c) 1994, 1995 Christopher G. Demetriou - * 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 Christopher G. Demetriou - * for the NetBSD Project. - * 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 - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.8 2001/11/06 19:21:40 art Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include "includes.h" - -#ifndef HAVE_SETPROCTITLE - -#define SPT_NONE 0 -#define SPT_PSTAT 1 - -#ifndef SPT_TYPE -#define SPT_TYPE SPT_NONE -#endif - -#if SPT_TYPE == SPT_PSTAT -#include <sys/param.h> -#include <sys/pstat.h> -#endif /* SPT_TYPE == SPT_PSTAT */ - -#define MAX_PROCTITLE 2048 - -extern char *__progname; - -/* - * Set Process Title (SPT) defines. Modeled after sendmail's - * SPT type definition strategy. - * - * SPT_TYPE: - * - * SPT_NONE: Don't set the process title. Default. - * SPT_PSTAT: Use pstat(PSTAT_SETCMD). HP-UX specific. - */ - -void -setproctitle(const char *fmt, ...) -{ -#if SPT_TYPE != SPT_NONE - va_list ap; - - char buf[MAX_PROCTITLE]; - size_t used; - -#if SPT_TYPE == SPT_PSTAT - union pstun pst; -#endif /* SPT_TYPE == SPT_PSTAT */ - - va_start(ap, fmt); - if (fmt != NULL) { - used = snprintf(buf, MAX_PROCTITLE, "%s: ", __progname); - if (used >= MAX_PROCTITLE) - used = MAX_PROCTITLE - 1; - (void)vsnprintf(buf + used, MAX_PROCTITLE - used, fmt, ap); - } else - (void)snprintf(buf, MAX_PROCTITLE, "%s", __progname); - va_end(ap); - used = strlen(buf); - -#if SPT_TYPE == SPT_PSTAT - pst.pst_command = buf; - pstat(PSTAT_SETCMD, pst, used, 0, 0); -#endif /* SPT_TYPE == SPT_PSTAT */ - -#endif /* SPT_TYPE != SPT_NONE */ -} -#endif /* HAVE_SETPROCTITLE */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/sigact.c b/usr/src/cmd/ssh/libopenbsd-compat/common/sigact.c deleted file mode 100644 index 5d89f8bb37..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/sigact.c +++ /dev/null @@ -1,104 +0,0 @@ -/* $OpenBSD: sigaction.c,v 1.3 1999/06/27 08:14:21 millert Exp $ */ - -/**************************************************************************** - * Copyright (c) 1998 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - ****************************************************************************/ - -#include "includes.h" -#include <signal.h> -#include "sigact.h" - -/* This file provides sigaction() emulation using sigvec() */ -/* Use only if this is non POSIX system */ - -#if !HAVE_SIGACTION && HAVE_SIGVEC - -int -sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) -{ - return sigvec(sig, &(sigact->sv), &(osigact->sv)); -} - -int -sigemptyset (sigset_t * mask) -{ - *mask = 0; - return 0; -} - -int -sigprocmask (int mode, sigset_t * mask, sigset_t * omask) -{ - sigset_t current = sigsetmask(0); - - if (omask) *omask = current; - - if (mode==SIG_BLOCK) - current |= *mask; - else if (mode==SIG_UNBLOCK) - current &= ~*mask; - else if (mode==SIG_SETMASK) - current = *mask; - - sigsetmask(current); - return 0; -} - -int -sigsuspend (sigset_t * mask) -{ - return sigpause(*mask); -} - -int -sigdelset (sigset_t * mask, int sig) -{ - *mask &= ~sigmask(sig); - return 0; -} - -int -sigaddset (sigset_t * mask, int sig) -{ - *mask |= sigmask(sig); - return 0; -} - -int -sigismember (sigset_t * mask, int sig) -{ - return (*mask & sigmask(sig)) != 0; -} - -#endif - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/strlcat.c b/usr/src/cmd/ssh/libopenbsd-compat/common/strlcat.c deleted file mode 100644 index 8143a627d0..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/strlcat.c +++ /dev/null @@ -1,81 +0,0 @@ -/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> - * 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. 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 ``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" -#ifndef HAVE_STRLCAT - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/types.h> -#include <string.h> -#include "strlcat.h" - -/* - * Appends src to string dst of size siz (unlike strncat, siz is the - * full size of dst, not space left). At most siz-1 characters - * will be copied. Always NUL terminates (unless siz <= strlen(dst)). - * Returns strlen(src) + MIN(siz, strlen(initial dst)). - * If retval >= siz, truncation occurred. - */ -size_t -strlcat(dst, src, siz) - char *dst; - const char *src; - size_t siz; -{ - register char *d = dst; - register const char *s = src; - register size_t n = siz; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - dlen = d - dst; - n = siz - dlen; - - if (n == 0) - return(dlen + strlen(s)); - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = '\0'; - - return(dlen + (s - src)); /* count does not include NUL */ -} - -#endif /* !HAVE_STRLCAT */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/strlcpy.c b/usr/src/cmd/ssh/libopenbsd-compat/common/strlcpy.c deleted file mode 100644 index fb87445cd2..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/strlcpy.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> - * 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. 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 ``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" -#ifndef HAVE_STRLCPY - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/types.h> -#include <string.h> -#include "strlcpy.h" - -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -strlcpy(dst, src, siz) - char *dst; - const char *src; - size_t siz; -{ - register char *d = dst; - register const char *s = src; - register size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} - -#endif /* !HAVE_STRLCPY */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/strmode.c b/usr/src/cmd/ssh/libopenbsd-compat/common/strmode.c deleted file mode 100644 index 2a52c22d19..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/strmode.c +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * Copyright (c) 1990 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. - */ - -#include "includes.h" -#ifndef HAVE_STRMODE - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strmode.c,v 1.3 1997/06/13 13:57:20 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> - -void -strmode(register mode_t mode, register char *p) -{ - /* print type */ - switch (mode & S_IFMT) { - case S_IFDIR: /* directory */ - *p++ = 'd'; - break; - case S_IFCHR: /* character special */ - *p++ = 'c'; - break; - case S_IFBLK: /* block special */ - *p++ = 'b'; - break; - case S_IFREG: /* regular */ - *p++ = '-'; - break; - case S_IFLNK: /* symbolic link */ - *p++ = 'l'; - break; -#ifdef S_IFSOCK - case S_IFSOCK: /* socket */ - *p++ = 's'; - break; -#endif -#ifdef S_IFIFO - case S_IFIFO: /* fifo */ - *p++ = 'p'; - break; -#endif -#ifdef S_IFWHT - case S_IFWHT: /* whiteout */ - *p++ = 'w'; - break; -#endif - default: /* unknown */ - *p++ = '?'; - break; - } - /* usr */ - if (mode & S_IRUSR) - *p++ = 'r'; - else - *p++ = '-'; - if (mode & S_IWUSR) - *p++ = 'w'; - else - *p++ = '-'; - switch (mode & (S_IXUSR | S_ISUID)) { - case 0: - *p++ = '-'; - break; - case S_IXUSR: - *p++ = 'x'; - break; - case S_ISUID: - *p++ = 'S'; - break; - case S_IXUSR | S_ISUID: - *p++ = 's'; - break; - } - /* group */ - if (mode & S_IRGRP) - *p++ = 'r'; - else - *p++ = '-'; - if (mode & S_IWGRP) - *p++ = 'w'; - else - *p++ = '-'; - switch (mode & (S_IXGRP | S_ISGID)) { - case 0: - *p++ = '-'; - break; - case S_IXGRP: - *p++ = 'x'; - break; - case S_ISGID: - *p++ = 'S'; - break; - case S_IXGRP | S_ISGID: - *p++ = 's'; - break; - } - /* other */ - if (mode & S_IROTH) - *p++ = 'r'; - else - *p++ = '-'; - if (mode & S_IWOTH) - *p++ = 'w'; - else - *p++ = '-'; - switch (mode & (S_IXOTH | S_ISVTX)) { - case 0: - *p++ = '-'; - break; - case S_IXOTH: - *p++ = 'x'; - break; - case S_ISVTX: - *p++ = 'T'; - break; - case S_IXOTH | S_ISVTX: - *p++ = 't'; - break; - } - *p++ = ' '; /* will be a '+' if ACL's implemented */ - *p = '\0'; -} -#endif - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/common/xmmap.c b/usr/src/cmd/ssh/libopenbsd-compat/common/xmmap.c deleted file mode 100644 index 9548d47e0d..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/common/xmmap.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" - -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -#include "log.h" - -void *xmmap(size_t size) -{ - void *address; - -#ifdef HAVE_MMAP -# ifdef MAP_ANON - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, - -1, 0); -# else - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, - open("/dev/zero", O_RDWR), 0); -# endif - -#define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX" - if (address == MAP_FAILED) { - char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE; - int tmpfd; - - tmpfd = mkstemp(tmpname); - if (tmpfd == -1) - fatal("mkstemp(\"%s\"): %s", - MM_SWAP_TEMPLATE, strerror(errno)); - unlink(tmpname); - ftruncate(tmpfd, size); - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, - tmpfd, 0); - close(tmpfd); - } - - return (address); -#else - fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", - __func__); -#endif /* HAVE_MMAP */ - -} - - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/libopenbsd-compat/i386/Makefile b/usr/src/cmd/ssh/libopenbsd-compat/i386/Makefile deleted file mode 100644 index fde6250470..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/i386/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all diff --git a/usr/src/cmd/ssh/libopenbsd-compat/sparc/Makefile b/usr/src/cmd/ssh/libopenbsd-compat/sparc/Makefile deleted file mode 100644 index fde6250470..0000000000 --- a/usr/src/cmd/ssh/libopenbsd-compat/sparc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all diff --git a/usr/src/cmd/ssh/libssh/Makefile b/usr/src/cmd/ssh/libssh/Makefile deleted file mode 100644 index dfc3be5088..0000000000 --- a/usr/src/cmd/ssh/libssh/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# -# cmd/ssh/libssh/Makefile - -include $(SRC)/lib/Makefile.lib -include ../Makefile.ssh-common - -SUBDIRS= $(MACH) -# Need to override the TEXT_DOMAIN here because we included a Makefile from -# usr/src/lib but this is a private library which is part of SUNW_OST_OSCMD -TEXT_DOMAIN= SUNW_OST_OSCMD - -POFILE=_messages.po - -all := TARGET= all -clean := TARGET= clean -clobber := TARGET= clobber -install := TARGET= install -lint := TARGET= lint -$(POFILE) := TARGET= $(POFILE) - -.KEEP_STATE: - -all clean clobber install lint $(POFILE): $(SUBDIRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include $(SRC)/lib/Makefile.targ diff --git a/usr/src/cmd/ssh/libssh/Makefile.com b/usr/src/cmd/ssh/libssh/Makefile.com deleted file mode 100644 index 569afe7207..0000000000 --- a/usr/src/cmd/ssh/libssh/Makefile.com +++ /dev/null @@ -1,116 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -LIBRARY = libssh.a -VERS = .1 - -OBJECTS = \ - addrmatch.o \ - atomicio.o \ - authfd.o \ - authfile.o \ - bufaux.o \ - buffer.o \ - canohost.o \ - channels.o \ - cipher.o \ - cipher-ctr.o \ - compat.o \ - compress.o \ - crc32.o \ - deattack.o \ - dh.o \ - dispatch.o \ - engine.o \ - entropy.o \ - fatal.o \ - g11n.o \ - hostfile.o \ - key.o \ - kex.o \ - kexdh.o \ - kexdhc.o \ - kexdhs.o \ - kexgex.o \ - kexgexc.o \ - kexgexs.o \ - kexgssc.o \ - kexgsss.o \ - log.o \ - mac.o \ - match.o \ - misc.o \ - mpaux.o \ - msg.o \ - nchan.o \ - packet.o \ - progressmeter.o \ - proxy-io.o \ - radix.o \ - readconf.o \ - readpass.o \ - rsa.o \ - sftp-common.o \ - ssh-dss.o \ - ssh-gss.o \ - ssh-rsa.o \ - tildexpand.o \ - ttymodes.o \ - uidswap.o \ - uuencode.o \ - xlist.o \ - xmalloc.o - -include $(SRC)/lib/Makefile.lib - -BUILD.AR = $(RM) $@ ; $(AR) $(ARFLAGS) $@ $(AROBJS) - -SRCDIR = ../common -SRCS = $(OBJECTS:%.o=../common/%.c) - -LIBS = $(LIBRARY) $(LINTLIB) - -# Define LDLIBS conditionally for lintcheck, rather than in general, since -# we're building an archive library which itself links to nothing, we just -# want lint to know about these libraries. -lintcheck := LDLIBS += -lcrypto -lz -lsocket -lnsl -lc -$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) - -POFILE_DIR = ../.. - -.KEEP_STATE: - -all: $(LIBS) - -# lint requires the (not installed) lint library -lint: $(LINTLIB) .WAIT lintcheck - -include $(SRC)/lib/Makefile.targ - -objs/%.o: $(SRCDIR)/%.c - $(COMPILE.c) -o $@ $< - $(POST_PROCESS_O) - -include ../../Makefile.ssh-common -include ../../Makefile.msg.targ diff --git a/usr/src/cmd/ssh/libssh/common/addrmatch.c b/usr/src/cmd/ssh/libssh/common/addrmatch.c deleted file mode 100644 index 91aa1e7ac7..0000000000 --- a/usr/src/cmd/ssh/libssh/common/addrmatch.c +++ /dev/null @@ -1,426 +0,0 @@ -/* $OpenBSD: addrmatch.c,v 1.4 2008/12/10 03:55:20 stevesk Exp $ */ - -/* - * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> - -#include "match.h" -#include "log.h" -#include "xmalloc.h" - -struct xaddr { - sa_family_t af; - union { - struct in_addr v4; - struct in6_addr v6; - u_int8_t addr8[16]; - u_int32_t addr32[4]; - } xa; /* 128-bit address */ - u_int32_t scope_id; /* iface scope id for v6 */ -#define v4 xa.v4 -#define v6 xa.v6 -#define addr8 xa.addr8 -#define addr32 xa.addr32 -}; - -static int -addr_unicast_masklen(int af) -{ - switch (af) { - case AF_INET: - return 32; - case AF_INET6: - return 128; - default: - return -1; - } -} - -static inline int -masklen_valid(int af, u_int masklen) -{ - switch (af) { - case AF_INET: - return masklen <= 32 ? 0 : -1; - case AF_INET6: - return masklen <= 128 ? 0 : -1; - default: - return -1; - } -} - -/* - * Convert struct sockaddr to struct xaddr - * Returns 0 on success, -1 on failure. - */ -static int -addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) -{ - /* LINTED E_BAD_PTR_CAST_ALIGN */ - struct sockaddr_in *in4 = (struct sockaddr_in *)sa; - /* LINTED E_BAD_PTR_CAST_ALIGN */ - struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; - - memset(xa, '\0', sizeof(*xa)); - - switch (sa->sa_family) { - case AF_INET: - if (slen < sizeof(*in4)) - return -1; - xa->af = AF_INET; - memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4)); - break; - case AF_INET6: - if (slen < sizeof(*in6)) - return -1; - xa->af = AF_INET6; - memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6)); -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID - xa->scope_id = in6->sin6_scope_id; -#endif - break; - default: - return -1; - } - - return 0; -} - -/* - * Calculate a netmask of length 'l' for address family 'af' and - * store it in 'n'. - * Returns 0 on success, -1 on failure. - */ -static int -addr_netmask(int af, u_int l, struct xaddr *n) -{ - int i; - - if (masklen_valid(af, l) != 0 || n == NULL) - return -1; - - memset(n, '\0', sizeof(*n)); - switch (af) { - case AF_INET: - n->af = AF_INET; - n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff); - return 0; - case AF_INET6: - n->af = AF_INET6; - for (i = 0; i < 4 && l >= 32; i++, l -= 32) - n->addr32[i] = 0xffffffffU; - if (i < 4 && l != 0) - n->addr32[i] = htonl((0xffffffff << (32 - l)) & - 0xffffffff); - return 0; - default: - return -1; - } -} - -/* - * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'. - * Returns 0 on success, -1 on failure. - */ -static int -addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) -{ - int i; - - if (dst == NULL || a == NULL || b == NULL || a->af != b->af) - return -1; - - memcpy(dst, a, sizeof(*dst)); - switch (a->af) { - case AF_INET: - dst->v4.s_addr &= b->v4.s_addr; - return 0; - case AF_INET6: - dst->scope_id = a->scope_id; - for (i = 0; i < 4; i++) - dst->addr32[i] &= b->addr32[i]; - return 0; - default: - return -1; - } -} - -/* - * Compare addresses 'a' and 'b' - * Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b) - */ -static int -addr_cmp(const struct xaddr *a, const struct xaddr *b) -{ - int i; - - if (a->af != b->af) - return a->af == AF_INET6 ? 1 : -1; - - switch (a->af) { - case AF_INET: - if (a->v4.s_addr == b->v4.s_addr) - return 0; - return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1; - case AF_INET6: - for (i = 0; i < 16; i++) - if (a->addr8[i] - b->addr8[i] != 0) - return a->addr8[i] > b->addr8[i] ? 1 : -1; - if (a->scope_id == b->scope_id) - return 0; - return a->scope_id > b->scope_id ? 1 : -1; - default: - return -1; - } -} - -/* - * Parse string address 'p' into 'n' - * Returns 0 on success, -1 on failure. - */ -static int -addr_pton(const char *p, struct xaddr *n) -{ - struct addrinfo hints, *ai; - - memset(&hints, '\0', sizeof(hints)); - hints.ai_flags = AI_NUMERICHOST; - - if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) - return -1; - - if (ai == NULL || ai->ai_addr == NULL) - return -1; - - if (n != NULL && - addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1) { - freeaddrinfo(ai); - return -1; - } - - freeaddrinfo(ai); - return 0; -} - -/* - * Perform bitwise negation of address - * Returns 0 on success, -1 on failure. - */ -static int -addr_invert(struct xaddr *n) -{ - int i; - - if (n == NULL) - return (-1); - - switch (n->af) { - case AF_INET: - n->v4.s_addr = ~n->v4.s_addr; - return (0); - case AF_INET6: - for (i = 0; i < 4; i++) - n->addr32[i] = ~n->addr32[i]; - return (0); - default: - return (-1); - } -} - -/* - * Calculate a netmask of length 'l' for address family 'af' and - * store it in 'n'. - * Returns 0 on success, -1 on failure. - */ -static int -addr_hostmask(int af, u_int l, struct xaddr *n) -{ - if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1) - return (-1); - return (0); -} - -/* - * Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::) - * Returns 0 on if address is all-zeros, -1 if not all zeros or on failure. - */ -static int -addr_is_all0s(const struct xaddr *a) -{ - int i; - - switch (a->af) { - case AF_INET: - return (a->v4.s_addr == 0 ? 0 : -1); - case AF_INET6:; - for (i = 0; i < 4; i++) - if (a->addr32[i] != 0) - return (-1); - return (0); - default: - return (-1); - } -} - -/* - * Test whether host portion of address 'a', as determined by 'masklen' - * is all zeros. - * Returns 0 on if host portion of address is all-zeros, - * -1 if not all zeros or on failure. - */ -static int -addr_host_is_all0s(const struct xaddr *a, u_int masklen) -{ - struct xaddr tmp_addr, tmp_mask, tmp_result; - - memcpy(&tmp_addr, a, sizeof(tmp_addr)); - if (addr_hostmask(a->af, masklen, &tmp_mask) == -1) - return (-1); - if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1) - return (-1); - return (addr_is_all0s(&tmp_result)); -} - -/* - * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z). - * Return -1 on parse error, -2 on inconsistency or 0 on success. - */ -static int -addr_pton_cidr(const char *p, struct xaddr *n, u_int *l) -{ - struct xaddr tmp; - long unsigned int masklen = 999; - char addrbuf[64], *mp, *cp; - - /* Don't modify argument */ - if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) > sizeof(addrbuf)) - return -1; - - if ((mp = strchr(addrbuf, '/')) != NULL) { - *mp = '\0'; - mp++; - masklen = strtoul(mp, &cp, 10); - if (*mp == '\0' || *cp != '\0' || masklen > 128) - return -1; - } - - if (addr_pton(addrbuf, &tmp) == -1) - return -1; - - if (mp == NULL) - masklen = addr_unicast_masklen(tmp.af); - if (masklen_valid(tmp.af, masklen) == -1) - return -2; - if (addr_host_is_all0s(&tmp, masklen) != 0) - return -2; - - if (n != NULL) - memcpy(n, &tmp, sizeof(*n)); - if (l != NULL) - *l = masklen; - - return 0; -} - -static int -addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen) -{ - struct xaddr tmp_mask, tmp_result; - - if (host->af != net->af) - return -1; - - if (addr_netmask(host->af, masklen, &tmp_mask) == -1) - return -1; - if (addr_and(&tmp_result, host, &tmp_mask) == -1) - return -1; - return addr_cmp(&tmp_result, net); -} - -/* - * Match "addr" against list pattern list "_list", which may contain a - * mix of CIDR addresses and old-school wildcards. - * - * If addr is NULL, then no matching is performed, but _list is parsed - * and checked for well-formedness. - * - * Returns 1 on match found (never returned when addr == NULL). - * Returns 0 on if no match found, or no errors found when addr == NULL. - * Returns -1 on negated match found (never returned when addr == NULL). - * Returns -2 on invalid list entry. - */ -int -addr_match_list(const char *addr, const char *_list) -{ - char *list, *cp, *o; - struct xaddr try_addr, match_addr; - u_int masklen, neg; - int ret = 0, r; - - if (addr != NULL && addr_pton(addr, &try_addr) != 0) { - debug2("%s: couldn't parse address %.100s", __func__, addr); - return 0; - } - if ((o = list = strdup(_list)) == NULL) - return -1; - while ((cp = strsep(&list, ",")) != NULL) { - neg = *cp == '!'; - if (neg) - cp++; - if (*cp == '\0') { - ret = -2; - break; - } - /* Prefer CIDR address matching */ - r = addr_pton_cidr(cp, &match_addr, &masklen); - if (r == -2) { - error("Inconsistent mask length for " - "network \"%.100s\"", cp); - ret = -2; - break; - } else if (r == 0) { - if (addr != NULL && addr_netmatch(&try_addr, - &match_addr, masklen) == 0) { - foundit: - if (neg) { - ret = -1; - break; - } - ret = 1; - } - continue; - } else { - /* If CIDR parse failed, try wildcard string match */ - if (addr != NULL && match_pattern(addr, cp) == 1) - goto foundit; - } - } - xfree(o); - - return ret; -} diff --git a/usr/src/cmd/ssh/libssh/common/atomicio.c b/usr/src/cmd/ssh/libssh/common/atomicio.c deleted file mode 100644 index f4a7945702..0000000000 --- a/usr/src/cmd/ssh/libssh/common/atomicio.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2006 Damien Miller. All rights reserved. - * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. - * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. - * 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: atomicio.c,v 1.10 2001/05/08 22:48:07 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "atomicio.h" - -/* - * ensure all of data on socket comes through. f==read || f==write - */ -ssize_t -atomicio(f, fd, _s, n) - ssize_t (*f) (); - int fd; - void *_s; - size_t n; -{ - char *s = _s; - ssize_t res, pos = 0; - - while (n > pos) { - res = (f) (fd, s + pos, n - pos); - switch (res) { - case -1: -#ifdef EWOULDBLOCK - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) -#else - if (errno == EINTR || errno == EAGAIN) -#endif - continue; - /* FALLTHROUGH */ - case 0: - return (res); - default: - pos += res; - } - } - return (pos); -} - -/* - * ensure all of data on socket comes through. f==readv || f==writev - */ -size_t -atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, - const struct iovec *_iov, int iovcnt) -{ - size_t pos = 0, rem; - ssize_t res; - struct iovec iov_array[IOV_MAX], *iov = iov_array; - - if (iovcnt > IOV_MAX) { - errno = EINVAL; - return 0; - } - /* Make a copy of the iov array because we may modify it below */ - memcpy(iov, _iov, iovcnt * sizeof(*_iov)); - - for (; iovcnt > 0 && iov[0].iov_len > 0;) { - res = (f) (fd, iov, iovcnt); - switch (res) { - case -1: - if (errno == EINTR || errno == EAGAIN) - continue; - return 0; - case 0: - errno = EPIPE; - return pos; - default: - rem = (size_t)res; - pos += rem; - /* skip completed iov entries */ - while (iovcnt > 0 && rem >= iov[0].iov_len) { - rem -= iov[0].iov_len; - iov++; - iovcnt--; - } - /* This shouldn't happen... */ - if (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) { - errno = EFAULT; - return 0; - } - if (iovcnt == 0) - break; - /* update pointer in partially complete iov */ - iov[0].iov_base = ((char *)iov[0].iov_base) + rem; - iov[0].iov_len -= rem; - } - } - return pos; -} diff --git a/usr/src/cmd/ssh/libssh/common/authfd.c b/usr/src/cmd/ssh/libssh/common/authfd.c deleted file mode 100644 index 43fbfbeb3c..0000000000 --- a/usr/src/cmd/ssh/libssh/common/authfd.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * 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. - * - * 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: authfd.c,v 1.57 2002/09/11 18:27:26 stevesk Exp $"); - -#include <openssl/evp.h> - -#include "ssh.h" -#include "rsa.h" -#include "buffer.h" -#include "bufaux.h" -#include "xmalloc.h" -#include "getput.h" -#include "key.h" -#include "authfd.h" -#include "cipher.h" -#include "kex.h" -#include "compat.h" -#include "log.h" -#include "atomicio.h" - -static int agent_present = 0; - -/* helper */ -int decode_reply(int type); - -/* macro to check for "agent failure" message */ -#define agent_failed(x) \ - ((x == SSH_AGENT_FAILURE) || (x == SSH_COM_AGENT2_FAILURE) || \ - (x == SSH2_AGENT_FAILURE)) - -int -ssh_agent_present(void) -{ - int authfd; - - if (agent_present) - return 1; - if ((authfd = ssh_get_authentication_socket()) == -1) - return 0; - else { - ssh_close_authentication_socket(authfd); - return 1; - } -} - -/* Returns the number of the authentication fd, or -1 if there is none. */ - -int -ssh_get_authentication_socket(void) -{ - const char *authsocket; - int sock; - struct sockaddr_un sunaddr; - - authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); - if (!authsocket) - return -1; - - sunaddr.sun_family = AF_UNIX; - strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - return -1; - - /* close on exec */ - if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { - close(sock); - return -1; - } - if (connect(sock, (struct sockaddr *) &sunaddr, sizeof sunaddr) < 0) { - close(sock); - return -1; - } - agent_present = 1; - return sock; -} - -static 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 == -1 && (errno == EAGAIN || errno == EINTR)) - continue; - 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 == -1 && (errno == EAGAIN || errno == EINTR)) - continue; - if (l <= 0) { - error("Error reading response from authentication socket."); - return 0; - } - buffer_append(reply, 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 - * ssh_get_authentication_socket(). - */ - -void -ssh_close_authentication_socket(int sock) -{ - if (getenv(SSH_AUTHSOCKET_ENV_NAME)) - close(sock); -} - -/* - * Opens and connects a private socket for communication with the - * authentication agent. Returns the file descriptor (which must be - * shut down and closed by the caller when no longer needed). - * Returns NULL if an error occurred and the connection could not be - * opened. - */ - -AuthenticationConnection * -ssh_get_authentication_connection(void) -{ - AuthenticationConnection *auth; - int sock; - - sock = ssh_get_authentication_socket(); - - /* - * Fail if we couldn't obtain a connection. This happens if we - * exited due to a timeout. - */ - if (sock < 0) - return NULL; - - auth = xmalloc(sizeof(*auth)); - auth->fd = sock; - buffer_init(&auth->identities); - auth->howmany = 0; - - return auth; -} - -/* - * Closes the connection to the authentication agent and frees any associated - * memory. - */ - -void -ssh_close_authentication_connection(AuthenticationConnection *auth) -{ - buffer_free(&auth->identities); - close(auth->fd); - xfree(auth); -} - -/* Lock/unlock agent */ -int -ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password) -{ - int type; - Buffer msg; - - buffer_init(&msg); - buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK); - buffer_put_cstring(&msg, password); - - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; - } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); -} - -/* - * Returns the first authentication identity held by the agent. - */ - -int -ssh_get_num_identities(AuthenticationConnection *auth, int version) -{ - 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 0; - } - - /* - * Send a message to the agent requesting for a list of the - * identities it can represent. - */ - buffer_init(&request); - buffer_put_char(&request, code1); - - buffer_clear(&auth->identities); - if (ssh_request_reply(auth, &request, &auth->identities) == 0) { - buffer_free(&request); - return 0; - } - buffer_free(&request); - - /* Get message type, and verify that we got a proper answer. */ - type = buffer_get_char(&auth->identities); - if (agent_failed(type)) { - return 0; - } 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", - auth->howmany); - - return auth->howmany; -} - -Key * -ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version) -{ - /* get number of identities and return the first entry (if any). */ - if (ssh_get_num_identities(auth, version) > 0) - return ssh_get_next_identity(auth, comment, version); - return NULL; -} - -Key * -ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version) -{ - u_int bits; - u_char *blob; - u_int blen; - Key *key = NULL; - - /* Return failure if no more entries. */ - if (auth->howmany <= 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. - */ - switch (version) { - case 1: - key = key_new(KEY_RSA1); - 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 = key_from_blob(blob, blen); - xfree(blob); - break; - default: - return NULL; - break; - } - /* Decrement the number of remaining entries. */ - auth->howmany--; - return key; -} - -/* - * Generates a random challenge, sends it to the agent, and waits for - * response from the agent. Returns true (non-zero) if the agent gave the - * correct answer, zero otherwise. Response type selects the style of - * response desired, with 0 corresponding to protocol version 1.0 (no longer - * supported) and 1 corresponding to protocol version 1.1. - */ - -int -ssh_decrypt_challenge(AuthenticationConnection *auth, - Key* key, BIGNUM *challenge, - u_char session_id[16], - u_int response_type, - u_char response[16]) -{ - Buffer buffer; - int success = 0; - int i; - int type; - - if (key->type != KEY_RSA1) - return 0; - if (response_type == 0) { - log("Compatibility with ssh protocol version 1.0 no longer supported."); - return 0; - } - buffer_init(&buffer); - 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, session_id, 16); - buffer_put_int(&buffer, response_type); - - if (ssh_request_reply(auth, &buffer, &buffer) == 0) { - buffer_free(&buffer); - return 0; - } - type = buffer_get_char(&buffer); - - if (agent_failed(type)) { - 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; -} - -/* ask agent to sign data, returns -1 on error, 0 on success */ -int -ssh_agent_sign(AuthenticationConnection *auth, - Key *key, - u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - Buffer msg; - u_char *blob; - u_int blen; - int type, flags = 0; - int ret = -1; - - if (key_to_blob(key, &blob, &blen) == 0) - return -1; - - if (datafellows & SSH_BUG_SIGBLOB) - flags = SSH_AGENT_OLD_SIGNATURE; - - 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, flags); - xfree(blob); - - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return -1; - } - type = buffer_get_char(&msg); - if (agent_failed(type)) { - 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); - } - buffer_free(&msg); - return ret; -} - -/* Encode key for a message to the agent. */ - -static void -ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment) -{ - 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_cstring(b, comment); -} - -static void -ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) -{ - buffer_put_cstring(b, key_ssh_name(key)); - switch (key->type) { - case KEY_RSA: - buffer_put_bignum2(b, key->rsa->n); - buffer_put_bignum2(b, key->rsa->e); - buffer_put_bignum2(b, key->rsa->d); - buffer_put_bignum2(b, key->rsa->iqmp); - buffer_put_bignum2(b, key->rsa->p); - buffer_put_bignum2(b, key->rsa->q); - break; - case KEY_DSA: - buffer_put_bignum2(b, key->dsa->p); - buffer_put_bignum2(b, key->dsa->q); - buffer_put_bignum2(b, key->dsa->g); - buffer_put_bignum2(b, key->dsa->pub_key); - buffer_put_bignum2(b, key->dsa->priv_key); - break; - } - buffer_put_cstring(b, comment); -} - -/* - * Adds an identity to the authentication server. This call is not meant to - * be used by normal applications. - */ - -int -ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, - const char *comment, u_int life) -{ - Buffer msg; - int type, constrained = (life != 0); - - buffer_init(&msg); - - switch (key->type) { - case KEY_RSA1: - type = constrained ? - SSH_AGENTC_ADD_RSA_ID_CONSTRAINED : - SSH_AGENTC_ADD_RSA_IDENTITY; - buffer_put_char(&msg, type); - ssh_encode_identity_rsa1(&msg, key->rsa, comment); - break; - case KEY_RSA: - case KEY_DSA: - type = constrained ? - SSH2_AGENTC_ADD_ID_CONSTRAINED : - SSH2_AGENTC_ADD_IDENTITY; - buffer_put_char(&msg, type); - ssh_encode_identity_ssh2(&msg, key, comment); - break; - default: - buffer_free(&msg); - return 0; - break; - } - if (constrained) { - if (life != 0) { - buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); - buffer_put_int(&msg, life); - } - } - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; - } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); -} - -int -ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) -{ - return ssh_add_identity_constrained(auth, key, comment, 0); -} - -/* - * Removes an identity from the authentication server. This call is not - * meant to be used by normal applications. - */ - -int -ssh_remove_identity(AuthenticationConnection *auth, Key *key) -{ - Buffer msg; - int type; - u_char *blob; - u_int blen; - - buffer_init(&msg); - - if (key->type == KEY_RSA1) { - 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 || key->type == KEY_RSA) { - key_to_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; - } - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; - } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); -} - - -/* - * Removes all identities from the agent. This call is not meant to be used - * by normal applications. - */ - -int -ssh_remove_all_identities(AuthenticationConnection *auth, int version) -{ - Buffer msg; - int type; - int code = (version==1) ? - SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : - SSH2_AGENTC_REMOVE_ALL_IDENTITIES; - - buffer_init(&msg); - buffer_put_char(&msg, code); - - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; - } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); -} - -int -decode_reply(int type) -{ - switch (type) { - case SSH_AGENT_FAILURE: - case SSH_COM_AGENT2_FAILURE: - case SSH2_AGENT_FAILURE: - log("SSH_AGENT_FAILURE"); - return 0; - case SSH_AGENT_SUCCESS: - return 1; - default: - fatal("Bad response from authentication agent: %d", type); - } - /* NOTREACHED */ - return 0; -} diff --git a/usr/src/cmd/ssh/libssh/common/authfile.c b/usr/src/cmd/ssh/libssh/common/authfile.c deleted file mode 100644 index 29076f390f..0000000000 --- a/usr/src/cmd/ssh/libssh/common/authfile.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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("$OpenBSD: authfile.c,v 1.50 2002/06/24 14:55:38 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/err.h> -#include <openssl/evp.h> -#include <openssl/pem.h> - -#include "cipher.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "ssh.h" -#include "log.h" -#include "authfile.h" -#include "rsa.h" - -/* Version identification string for SSH v1 identity files. */ -static const char authfile_id_string[] = - "SSH PRIVATE KEY FILE FORMAT 1.1\n"; - -/* - * Saves the authentication (private) key in a file, encrypting it with - * passphrase. The identification of the file (lowest 64 bits of n) will - * precede the key to provide identification of the key without needing a - * passphrase. - */ - -static int -key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, - const char *comment) -{ - Buffer buffer, encrypted; - u_char buf[100], *cp; - int fd, i, cipher_num; - CipherContext ciphercontext; - Cipher *cipher; - u_int32_t rand; - - /* - * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting - * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. - */ - cipher_num = (strcmp(passphrase, "") == 0) ? - SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER; - if ((cipher = cipher_by_number(cipher_num)) == NULL) - fatal("save_private_key_rsa: bad cipher"); - - /* This buffer is used to built the secret part of the private key. */ - buffer_init(&buffer); - - /* Put checkbytes for checking passphrase validity. */ - rand = arc4random(); - buf[0] = rand & 0xff; - buf[1] = (rand >> 8) & 0xff; - buf[2] = buf[0]; - buf[3] = buf[1]; - buffer_append(&buffer, buf, 4); - - /* - * Store the private key (n and e will not be stored because they - * will be stored in plain text, and storing them also in encrypted - * format would just give known plaintext). - */ - buffer_put_bignum(&buffer, key->rsa->d); - buffer_put_bignum(&buffer, key->rsa->iqmp); - buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */ - buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */ - - /* Pad the part to be encrypted until its size is a multiple of 8. */ - while (buffer_len(&buffer) % 8 != 0) - buffer_put_char(&buffer, 0); - - /* This buffer will be used to contain the data in the file. */ - buffer_init(&encrypted); - - /* First store keyfile id string. */ - for (i = 0; authfile_id_string[i]; i++) - buffer_put_char(&encrypted, authfile_id_string[i]); - buffer_put_char(&encrypted, 0); - - /* Store cipher type. */ - buffer_put_char(&encrypted, cipher_num); - buffer_put_int(&encrypted, 0); /* For future extension */ - - /* Store public key. This will be in plain text. */ - buffer_put_int(&encrypted, BN_num_bits(key->rsa->n)); - buffer_put_bignum(&encrypted, key->rsa->n); - buffer_put_bignum(&encrypted, key->rsa->e); - buffer_put_cstring(&encrypted, comment); - - /* Allocate space for the private part of the key in the buffer. */ - cp = buffer_append_space(&encrypted, buffer_len(&buffer)); - - cipher_set_key_string(&ciphercontext, cipher, passphrase, - CIPHER_ENCRYPT); - cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer)); - cipher_cleanup(&ciphercontext); - memset(&ciphercontext, 0, sizeof(ciphercontext)); - - /* Destroy temporary data. */ - memset(buf, 0, sizeof(buf)); - buffer_free(&buffer); - - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd < 0) { - error("open %s failed: %s.", filename, strerror(errno)); - return 0; - } - if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) != - buffer_len(&encrypted)) { - error("write to key file %s failed: %s", filename, - strerror(errno)); - buffer_free(&encrypted); - close(fd); - unlink(filename); - return 0; - } - close(fd); - buffer_free(&encrypted); - return 1; -} - -/* save SSH v2 key in OpenSSL PEM format */ -static int -key_save_private_pem(Key *key, const char *filename, const char *_passphrase, - const char *comment) -{ - FILE *fp; - int fd; - int success = 0; - int len = strlen(_passphrase); - u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; - const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; - - if (len > 0 && len <= 4) { - error("passphrase too short: have %d bytes, need > 4", len); - return 0; - } - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd < 0) { - error("open %s failed: %s.", filename, strerror(errno)); - return 0; - } - fp = fdopen(fd, "w"); - if (fp == NULL ) { - error("fdopen %s failed: %s.", filename, strerror(errno)); - close(fd); - return 0; - } - switch (key->type) { - case KEY_DSA: - success = PEM_write_DSAPrivateKey(fp, key->dsa, - cipher, passphrase, len, NULL, NULL); - break; - case KEY_RSA: - success = PEM_write_RSAPrivateKey(fp, key->rsa, - cipher, passphrase, len, NULL, NULL); - break; - } - fclose(fp); - return success; -} - -int -key_save_private(Key *key, const char *filename, const char *passphrase, - const char *comment) -{ - switch (key->type) { - case KEY_RSA1: - return key_save_private_rsa1(key, filename, passphrase, - comment); - break; - case KEY_DSA: - case KEY_RSA: - return key_save_private_pem(key, filename, passphrase, - comment); - break; - default: - break; - } - error("key_save_private: cannot save key type %d", key->type); - return 0; -} - -/* - * Loads the public part of the ssh v1 key file. Returns NULL if an error was - * encountered (the file does not exist or is not readable), and the key - * otherwise. - */ - -static Key * -key_load_public_rsa1(int fd, const char *filename, char **commentp) -{ - Buffer buffer; - Key *pub; - char *cp; - int i; - off_t len; - - len = lseek(fd, (off_t) 0, SEEK_END); - lseek(fd, (off_t) 0, SEEK_SET); - - buffer_init(&buffer); - cp = buffer_append_space(&buffer, len); - - if (read(fd, cp, (size_t) len) != (size_t) len) { - debug("Read from key file %.200s failed: %.100s", filename, - strerror(errno)); - buffer_free(&buffer); - return NULL; - } - - /* Check that it is at least big enough to contain the ID string. */ - if (len < sizeof(authfile_id_string)) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - return NULL; - } - /* - * Make sure it begins with the id string. Consume the id string - * from the buffer. - */ - for (i = 0; i < sizeof(authfile_id_string); i++) - if (buffer_get_char(&buffer) != authfile_id_string[i]) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - return NULL; - } - /* Skip cipher type and reserved data. */ - (void) buffer_get_char(&buffer); /* cipher type */ - (void) buffer_get_int(&buffer); /* reserved */ - - /* Read the public key from the buffer. */ - (void) buffer_get_int(&buffer); - pub = key_new(KEY_RSA1); - buffer_get_bignum(&buffer, pub->rsa->n); - buffer_get_bignum(&buffer, pub->rsa->e); - if (commentp) - *commentp = buffer_get_string(&buffer, NULL); - /* The encrypted private part is not parsed by this function. */ - - buffer_free(&buffer); - return pub; -} - -/* load public key from private-key file, works only for SSH v1 */ -Key * -key_load_public_type(int type, const char *filename, char **commentp) -{ - Key *pub; - int fd; - - if (type == KEY_RSA1) { - fd = open(filename, O_RDONLY); - if (fd < 0) - return NULL; - pub = key_load_public_rsa1(fd, filename, commentp); - close(fd); - return pub; - } - return NULL; -} - -/* - * Loads the private key from the file. Returns 0 if an error is encountered - * (file does not exist or is not readable, or passphrase is bad). This - * initializes the private key. - * Assumes we are called under uid of the owner of the file. - */ - -static Key * -key_load_private_rsa1(int fd, const char *filename, const char *passphrase, - char **commentp) -{ - int i, check1, check2, cipher_type; - off_t len; - Buffer buffer, decrypted; - u_char *cp; - CipherContext ciphercontext; - Cipher *cipher; - Key *prv = NULL; - - len = lseek(fd, (off_t) 0, SEEK_END); - lseek(fd, (off_t) 0, SEEK_SET); - - buffer_init(&buffer); - cp = buffer_append_space(&buffer, len); - - if (read(fd, cp, (size_t) len) != (size_t) len) { - debug("Read from key file %.200s failed: %.100s", filename, - strerror(errno)); - buffer_free(&buffer); - close(fd); - return NULL; - } - - /* Check that it is at least big enough to contain the ID string. */ - if (len < sizeof(authfile_id_string)) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - close(fd); - return NULL; - } - /* - * Make sure it begins with the id string. Consume the id string - * from the buffer. - */ - for (i = 0; i < sizeof(authfile_id_string); i++) - if (buffer_get_char(&buffer) != authfile_id_string[i]) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - close(fd); - return NULL; - } - - /* Read cipher type. */ - cipher_type = buffer_get_char(&buffer); - (void) buffer_get_int(&buffer); /* Reserved data. */ - - /* Read the public key from the buffer. */ - (void) buffer_get_int(&buffer); - prv = key_new_private(KEY_RSA1); - - buffer_get_bignum(&buffer, prv->rsa->n); - buffer_get_bignum(&buffer, prv->rsa->e); - if (commentp) - *commentp = buffer_get_string(&buffer, NULL); - else - xfree(buffer_get_string(&buffer, NULL)); - - /* Check that it is a supported cipher. */ - cipher = cipher_by_number(cipher_type); - if (cipher == NULL) { - debug("Unsupported cipher %d used in key file %.200s.", - cipher_type, filename); - buffer_free(&buffer); - goto fail; - } - /* Initialize space for decrypted data. */ - buffer_init(&decrypted); - cp = buffer_append_space(&decrypted, buffer_len(&buffer)); - - /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ - cipher_set_key_string(&ciphercontext, cipher, passphrase, - CIPHER_DECRYPT); - cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer)); - cipher_cleanup(&ciphercontext); - memset(&ciphercontext, 0, sizeof(ciphercontext)); - buffer_free(&buffer); - - check1 = buffer_get_char(&decrypted); - check2 = buffer_get_char(&decrypted); - if (check1 != buffer_get_char(&decrypted) || - check2 != buffer_get_char(&decrypted)) { - if (strcmp(passphrase, "") != 0) - debug("Bad passphrase supplied for key file %.200s.", - filename); - /* Bad passphrase. */ - buffer_free(&decrypted); - goto fail; - } - /* Read the rest of the private key. */ - buffer_get_bignum(&decrypted, prv->rsa->d); - buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ - /* in SSL and SSH v1 p and q are exchanged */ - buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ - buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ - - /* calculate p-1 and q-1 */ - rsa_generate_additional_parameters(prv->rsa); - - buffer_free(&decrypted); - close(fd); - return prv; - -fail: - if (commentp) - xfree(*commentp); - close(fd); - key_free(prv); - return NULL; -} - -Key * -key_load_private_pem(int fd, int type, const char *passphrase, - char **commentp) -{ - FILE *fp; - EVP_PKEY *pk = NULL; - Key *prv = NULL; - char *name = "<no key>"; - - fp = fdopen(fd, "r"); - if (fp == NULL) { - error("fdopen failed: %s", strerror(errno)); - close(fd); - return NULL; - } - pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); - if (pk == NULL) { - debug("PEM_read_PrivateKey failed"); - (void)ERR_get_error(); - } else if (pk->type == EVP_PKEY_RSA && - (type == KEY_UNSPEC||type==KEY_RSA)) { - prv = key_new(KEY_UNSPEC); - prv->rsa = EVP_PKEY_get1_RSA(pk); - prv->type = KEY_RSA; - name = "rsa w/o comment"; -#ifdef DEBUG_PK - RSA_print_fp(stderr, prv->rsa, 8); -#endif - } else if (pk->type == EVP_PKEY_DSA && - (type == KEY_UNSPEC||type==KEY_DSA)) { - prv = key_new(KEY_UNSPEC); - prv->dsa = EVP_PKEY_get1_DSA(pk); - prv->type = KEY_DSA; - name = "dsa w/o comment"; -#ifdef DEBUG_PK - DSA_print_fp(stderr, prv->dsa, 8); -#endif - } else { - error("PEM_read_PrivateKey: mismatch or " - "unknown EVP_PKEY save_type %d", pk->save_type); - } - fclose(fp); - if (pk != NULL) - EVP_PKEY_free(pk); - if (prv != NULL && commentp) - *commentp = xstrdup(name); - debug("read PEM private key done: type %s", - prv ? key_type(prv) : "<unknown>"); - return prv; -} - -static int -key_perm_ok(int fd, const char *filename) -{ - struct stat st; - - if (fstat(fd, &st) < 0) - return 0; - /* - * if a key owned by the user is accessed, then we check the - * permissions of the file. if the key owned by a different user, - * then we don't care. - */ -#ifdef HAVE_CYGWIN - if (check_ntsec(filename)) -#endif - if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("Permissions 0%3.3o for '%s' are too open.", - (int)(st.st_mode & 0777), filename); - error("It is recommended that your private key files are NOT accessible by others."); - error("This private key will be ignored."); - return 0; - } - return 1; -} - -Key * -key_load_private_type(int type, const char *filename, const char *passphrase, - char **commentp) -{ - int fd; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return NULL; - if (!key_perm_ok(fd, filename)) { - error("bad permissions: ignore key: %s", filename); - close(fd); - return NULL; - } - switch (type) { - case KEY_RSA1: - return key_load_private_rsa1(fd, filename, passphrase, - commentp); - /* closes fd */ - break; - case KEY_DSA: - case KEY_RSA: - case KEY_UNSPEC: - return key_load_private_pem(fd, type, passphrase, commentp); - /* closes fd */ - break; - default: - close(fd); - break; - } - return NULL; -} - -Key * -key_load_private(const char *filename, const char *passphrase, - char **commentp) -{ - Key *pub, *prv; - int fd; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return NULL; - if (!key_perm_ok(fd, filename)) { - error("bad permissions: ignore key: %s", filename); - close(fd); - return NULL; - } - pub = key_load_public_rsa1(fd, filename, commentp); - lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ - if (pub == NULL) { - /* closes fd */ - prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); - /* use the filename as a comment for PEM */ - if (commentp && prv) - *commentp = xstrdup(filename); - } else { - /* it's a SSH v1 key if the public key part is readable */ - key_free(pub); - /* closes fd */ - prv = key_load_private_rsa1(fd, filename, passphrase, NULL); - } - return prv; -} - -static int -key_try_load_public(Key *k, const char *filename, char **commentp) -{ - FILE *f; - char line[4096]; - 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) { - if (key_read(k, &cp) == 1) { - if (commentp) - *commentp=xstrdup(filename); - fclose(f); - return 1; - } - } - } - fclose(f); - } - return 0; -} - -/* load public key from ssh v1 private or any pubkey file */ -Key * -key_load_public(const char *filename, char **commentp) -{ - Key *pub; - char file[MAXPATHLEN]; - - pub = key_load_public_type(KEY_RSA1, filename, commentp); - if (pub != NULL) - return pub; - pub = key_new(KEY_UNSPEC); - if (key_try_load_public(pub, filename, commentp) == 1) - return pub; - if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && - (strlcat(file, ".pub", sizeof file) < sizeof(file)) && - (key_try_load_public(pub, file, commentp) == 1)) - return pub; - key_free(pub); - return NULL; -} diff --git a/usr/src/cmd/ssh/libssh/common/bufaux.c b/usr/src/cmd/ssh/libssh/common/bufaux.c deleted file mode 100644 index 0a94ba9054..0000000000 --- a/usr/src/cmd/ssh/libssh/common/bufaux.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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("$OpenBSD: bufaux.c,v 1.27 2002/06/26 08:53:12 markus Exp $"); - -#include <langinfo.h> -#include <openssl/bn.h> -#include "bufaux.h" -#include "xmalloc.h" -#include "getput.h" -#include "log.h" -#include "g11n.h" - -/* - * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed - * by (bits+7)/8 bytes of binary data, msb first. - */ -int -buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value) -{ - int bits = BN_num_bits(value); - int bin_size = (bits + 7) / 8; - u_char *buf = xmalloc(bin_size); - int oi; - char msg[2]; - - /* Get the value of in binary */ - oi = BN_bn2bin(value, buf); - if (oi != bin_size) { - error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d", - oi, bin_size); - xfree(buf); - return (-1); - } - - /* Store the number of bits in the buffer in two bytes, msb first. */ - PUT_16BIT(msg, bits); - buffer_append(buffer, msg, 2); - /* Store the binary data. */ - buffer_append(buffer, (char *)buf, oi); - - memset(buf, 0, bin_size); - xfree(buf); - - return (0); -} - -void -buffer_put_bignum(Buffer *buffer, const BIGNUM *value) -{ - if (buffer_put_bignum_ret(buffer, value) == -1) - fatal("buffer_put_bignum: buffer error"); -} - -/* - * Retrieves an BIGNUM from the buffer. - */ -int -buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value) -{ - u_int bits, bytes; - u_char buf[2], *bin; - - /* Get the number for bits. */ - if (buffer_get_ret(buffer, (char *) buf, 2) == -1) { - error("buffer_get_bignum_ret: invalid length"); - return (-1); - } - bits = GET_16BIT(buf); - /* Compute the number of binary bytes that follow. */ - bytes = (bits + 7) / 8; - if (bytes > 8 * 1024) { - error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes); - return (-1); - } - if (buffer_len(buffer) < bytes) { - error("buffer_get_bignum_ret: input buffer too small"); - return (-1); - } - bin = buffer_ptr(buffer); - BN_bin2bn(bin, bytes, value); - if (buffer_consume_ret(buffer, bytes) == -1) { - error("buffer_get_bignum_ret: buffer_consume failed"); - return (-1); - } - return (0); -} - -void -buffer_get_bignum(Buffer *buffer, BIGNUM *value) -{ - if (buffer_get_bignum_ret(buffer, value) == -1) - fatal("buffer_get_bignum: buffer error"); -} - -/* - * Stores an BIGNUM in the buffer in SSH2 format. - */ -int -buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) -{ - u_int bytes; - u_char *buf; - int oi; - u_int hasnohigh = 0; - - if (BN_is_zero(value)) { - buffer_put_int(buffer, 0); - return 0; - } - if (value->neg) { - error("buffer_put_bignum2_ret: negative numbers not supported"); - return (-1); - } - bytes = BN_num_bytes(value) + 1; /* extra padding byte */ - if (bytes < 2) { - error("buffer_put_bignum2_ret: BN too small"); - return (-1); - } - buf = xmalloc(bytes); - buf[0] = 0x00; - /* Get the value of in binary */ - oi = BN_bn2bin(value, buf+1); - if (oi < 0 || (u_int)oi != bytes - 1) { - error("buffer_put_bignum2_ret: BN_bn2bin() failed: " - "oi %d != bin_size %d", oi, bytes); - xfree(buf); - return (-1); - } - hasnohigh = (buf[1] & 0x80) ? 0 : 1; - buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); - memset(buf, 0, bytes); - xfree(buf); - return (0); -} - -void -buffer_put_bignum2(Buffer *buffer, const BIGNUM *value) -{ - if (buffer_put_bignum2_ret(buffer, value) == -1) - fatal("buffer_put_bignum2: buffer error"); -} - -/* XXX does not handle negative BNs */ -int -buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value) -{ - u_int len; - u_char *bin; - - if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) { - error("buffer_get_bignum2_ret: invalid bignum"); - return (-1); - } - - if (len > 0 && (bin[0] & 0x80)) { - error("buffer_get_bignum2_ret: negative numbers not supported"); - xfree(bin); - return (-1); - } - if (len > 8 * 1024) { - error("buffer_get_bignum2_ret: cannot handle BN of size %d", len); - xfree(bin); - return (-1); - } - BN_bin2bn(bin, len, value); - xfree(bin); - return (0); -} - -void -buffer_get_bignum2(Buffer *buffer, BIGNUM *value) -{ - if (buffer_get_bignum2_ret(buffer, value) == -1) - fatal("buffer_get_bignum2: buffer error"); -} - -/* - * Returns integers from the buffer (msb first). - */ - -int -buffer_get_short_ret(u_short *ret, Buffer *buffer) -{ - u_char buf[2]; - - if (buffer_get_ret(buffer, (char *) buf, 2) == -1) - return (-1); - *ret = GET_16BIT(buf); - return (0); -} - -u_short -buffer_get_short(Buffer *buffer) -{ - u_short ret; - - if (buffer_get_short_ret(&ret, buffer) == -1) - fatal("buffer_get_short: buffer error"); - - return (ret); -} - -int -buffer_get_int_ret(u_int *ret, Buffer *buffer) -{ - u_char buf[4]; - - if (buffer_get_ret(buffer, (char *) buf, 4) == -1) - return (-1); - *ret = GET_32BIT(buf); - return (0); -} - -u_int -buffer_get_int(Buffer *buffer) -{ - u_int ret; - - if (buffer_get_int_ret(&ret, buffer) == -1) - fatal("buffer_get_int: buffer error"); - - return (ret); -} - -#ifdef HAVE_U_INT64_T -int -buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer) -{ - u_char buf[8]; - - if (buffer_get_ret(buffer, (char *) buf, 8) == -1) - return (-1); - *ret = GET_64BIT(buf); - return (0); -} - -u_int64_t -buffer_get_int64(Buffer *buffer) -{ - u_int64_t ret; - - if (buffer_get_int64_ret(&ret, buffer) == -1) - fatal("buffer_get_int: buffer error"); - - return (ret); -} -#endif - -/* - * Stores integers in the buffer, msb first. - */ -void -buffer_put_short(Buffer *buffer, u_short value) -{ - char buf[2]; - - PUT_16BIT(buf, value); - buffer_append(buffer, buf, 2); -} - -void -buffer_put_int(Buffer *buffer, u_int value) -{ - char buf[4]; - - PUT_32BIT(buf, value); - buffer_append(buffer, buf, 4); -} - -#ifdef HAVE_U_INT64_T -void -buffer_put_int64(Buffer *buffer, u_int64_t value) -{ - char buf[8]; - - PUT_64BIT(buf, value); - buffer_append(buffer, buf, 8); -} -#endif - -/* - * Returns an arbitrary binary string from the buffer. The string cannot - * be longer than 256k. The returned value points to memory allocated - * with xmalloc; it is the responsibility of the calling function to free - * the data. If length_ptr is non-NULL, the length of the returned data - * will be stored there. A null character will be automatically appended - * to the returned string, and is not counted in length. - */ -void * -buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) -{ - u_char *value; - u_int len; - - /* Get the length. */ - len = buffer_get_int(buffer); - if (len > 256 * 1024) { - error("buffer_get_string_ret: bad string length %u", len); - return (NULL); - } - /* Allocate space for the string. Add one byte for a null character. */ - value = xmalloc(len + 1); - /* Get the string. */ - if (buffer_get_ret(buffer, value, len) == -1) { - error("buffer_get_string_ret: buffer_get failed"); - xfree(value); - return (NULL); - } - /* Append a null character to make processing easier. */ - value[len] = 0; - /* Optionally return the length of the string. */ - if (length_ptr) - *length_ptr = len; - return (value); -} - -void * -buffer_get_string(Buffer *buffer, u_int *length_ptr) -{ - void *ret; - - if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL) - fatal("buffer_get_string: buffer error"); - return (ret); -} - -char * -buffer_get_utf8_string(Buffer *buffer, uint_t *length_ptr) -{ - char *value, *converted, *estr; - uint_t len; - - if ((value = buffer_get_string(buffer, &len)) == NULL) - return (value); - - converted = g11n_convert_from_utf8(value, &len, &estr); - if (converted == NULL) { - if (estr != NULL) - error("invalid UTF-8 sequence: %s", estr); - converted = value; - } else { - xfree(value); - } - - if (length_ptr != NULL) - *length_ptr = len; - - return (converted); -} - -/* - * Stores and arbitrary binary string in the buffer. - */ -void -buffer_put_string(Buffer *buffer, const void *buf, u_int len) -{ - buffer_put_int(buffer, len); - buffer_append(buffer, buf, len); -} -void -buffer_put_cstring(Buffer *buffer, const char *s) -{ - if (s == NULL) - fatal("buffer_put_cstring: s == NULL"); - buffer_put_string(buffer, s, strlen(s)); -} - -/* - * UTF-8 versions of the above. - */ -void -buffer_put_utf8_string(Buffer *buffer, const char *s, uint_t len) -{ - char *converted, *estr; - uint_t nlen = len; - - converted = g11n_convert_to_utf8(s, &nlen, 0, &estr); - if (converted == NULL) { - if (estr != NULL) - error("Can't convert to UTF-8: %s", estr); - converted = (char *)s; - } - - buffer_put_string(buffer, converted, nlen); - - if (converted != s) - xfree(converted); -} - -void -buffer_put_utf8_cstring(Buffer *buffer, const char *s) -{ - buffer_put_utf8_string(buffer, s, strlen(s)); -} - -/* - * Returns a character from the buffer (0 - 255). - */ -int -buffer_get_char_ret(char *ret, Buffer *buffer) -{ - if (buffer_get_ret(buffer, ret, 1) == -1) { - error("buffer_get_char_ret: buffer_get_ret failed"); - return (-1); - } - return (0); -} - -int -buffer_get_char(Buffer *buffer) -{ - char ch; - - if (buffer_get_char_ret(&ch, buffer) == -1) - fatal("buffer_get_char: buffer error"); - return (u_char) ch; -} - -/* - * Stores a character in the buffer. - */ -void -buffer_put_char(Buffer *buffer, int value) -{ - char ch = value; - - buffer_append(buffer, &ch, 1); -} diff --git a/usr/src/cmd/ssh/libssh/common/buffer.c b/usr/src/cmd/ssh/libssh/common/buffer.c deleted file mode 100644 index 2ec761b7ad..0000000000 --- a/usr/src/cmd/ssh/libssh/common/buffer.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */ - -#include "includes.h" - -#include "xmalloc.h" -#include "buffer.h" -#include "log.h" - -#define BUFFER_MAX_CHUNK 0x100000 -#define BUFFER_MAX_LEN 0xa00000 -#define BUFFER_ALLOCSZ 0x008000 - -/* Initializes the buffer structure. */ - -void -buffer_init(Buffer *buffer) -{ - const u_int len = 4096; - - buffer->alloc = 0; - buffer->buf = xmalloc(len); - buffer->alloc = len; - buffer->offset = 0; - buffer->end = 0; -} - -/* Frees any memory used for the buffer. */ - -void -buffer_free(Buffer *buffer) -{ - if (buffer->alloc > 0) { - memset(buffer->buf, 0, buffer->alloc); - buffer->alloc = 0; - xfree(buffer->buf); - } -} - -/* - * Clears any data from the buffer, making it empty. This does not actually - * zero the memory. - */ - -void -buffer_clear(Buffer *buffer) -{ - buffer->offset = 0; - buffer->end = 0; -} - -/* Appends data to the buffer, expanding it if necessary. */ - -void -buffer_append(Buffer *buffer, const void *data, u_int len) -{ - void *p; - p = buffer_append_space(buffer, len); - memcpy(p, data, len); -} - -static int -buffer_compact(Buffer *buffer) -{ - /* - * If the buffer is quite empty, but all data is at the end, move the - * data to the beginning. - */ - if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) { - memmove(buffer->buf, buffer->buf + buffer->offset, - buffer->end - buffer->offset); - buffer->end -= buffer->offset; - buffer->offset = 0; - return (1); - } - return (0); -} - -/* - * Appends space to the buffer, expanding the buffer if necessary. This does - * not actually copy the data into the buffer, but instead returns a pointer - * to the allocated region. - */ - -void * -buffer_append_space(Buffer *buffer, u_int len) -{ - u_int newlen; - void *p; - - if (len > BUFFER_MAX_CHUNK) - fatal("buffer_append_space: len %u not supported", len); - - /* If the buffer is empty, start using it from the beginning. */ - if (buffer->offset == buffer->end) { - buffer->offset = 0; - buffer->end = 0; - } -restart: - /* If there is enough space to store all data, store it now. */ - if (buffer->end + len < buffer->alloc) { - p = buffer->buf + buffer->end; - buffer->end += len; - return p; - } - - /* Compact data back to the start of the buffer if necessary */ - if (buffer_compact(buffer)) - goto restart; - - /* Increase the size of the buffer and retry. */ - newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ); - if (newlen > BUFFER_MAX_LEN) - fatal("buffer_append_space: alloc %u not supported", - newlen); - buffer->buf = xrealloc(buffer->buf, newlen); - buffer->alloc = newlen; - goto restart; - /* NOTREACHED */ -} - -/* - * Check whether an allocation of 'len' will fit in the buffer - * This must follow the same math as buffer_append_space - */ -int -buffer_check_alloc(Buffer *buffer, u_int len) -{ - if (buffer->offset == buffer->end) { - buffer->offset = 0; - buffer->end = 0; - } - restart: - if (buffer->end + len < buffer->alloc) - return (1); - if (buffer_compact(buffer)) - goto restart; - if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN) - return (1); - return (0); -} - -/* Returns the number of bytes of data in the buffer. */ - -u_int -buffer_len(Buffer *buffer) -{ - return buffer->end - buffer->offset; -} - -/* Gets data from the beginning of the buffer. */ - -int -buffer_get_ret(Buffer *buffer, void *buf, u_int len) -{ - if (len > buffer->end - buffer->offset) { - error("buffer_get_ret: trying to get more bytes %d than in buffer %d", - len, buffer->end - buffer->offset); - return (-1); - } - memcpy(buf, buffer->buf + buffer->offset, len); - buffer->offset += len; - return (0); -} - -void -buffer_get(Buffer *buffer, void *buf, u_int len) -{ - if (buffer_get_ret(buffer, buf, len) == -1) - fatal("buffer_get: buffer error"); -} - -/* Consumes the given number of bytes from the beginning of the buffer. */ - -int -buffer_consume_ret(Buffer *buffer, u_int bytes) -{ - if (bytes > buffer->end - buffer->offset) { - error("buffer_consume_ret: trying to get more bytes than in buffer"); - return (-1); - } - buffer->offset += bytes; - return (0); -} - -void -buffer_consume(Buffer *buffer, u_int bytes) -{ - if (buffer_consume_ret(buffer, bytes) == -1) - fatal("buffer_consume: buffer error"); -} - -/* Consumes the given number of bytes from the end of the buffer. */ - -int -buffer_consume_end_ret(Buffer *buffer, u_int bytes) -{ - if (bytes > buffer->end - buffer->offset) - return (-1); - buffer->end -= bytes; - return (0); -} - -void -buffer_consume_end(Buffer *buffer, u_int bytes) -{ - if (buffer_consume_end_ret(buffer, bytes) == -1) - fatal("buffer_consume_end: trying to get more bytes than in buffer"); -} - -/* Returns a pointer to the first used byte in the buffer. */ - -void * -buffer_ptr(Buffer *buffer) -{ - return buffer->buf + buffer->offset; -} - -/* Dumps the contents of the buffer to stderr. */ -void -buffer_dump(Buffer *buffer) -{ - u_int i; - u_char *ucp = buffer->buf; - - for (i = buffer->offset; i < buffer->end; i++) { - fprintf(stderr, "%02x", ucp[i]); - if ((i-buffer->offset)%16==15) - fprintf(stderr, "\n"); - else if ((i-buffer->offset)%2==1) - fprintf(stderr, " "); - } - - if (buffer->offset == buffer->end) { - /* explicitly state when the buffer is empty */ - fprintf(stderr, "<EMPTY BUFFER>\n"); - } else { - /* print the terminal '\n' if it wasn't already printed */ - if ((i - buffer->offset) % 16 != 0) - fprintf(stderr, "\n"); - } - /* - * We want an extra empty line after the packet dump for better - * readability. - */ - fprintf(stderr, "\n"); -} diff --git a/usr/src/cmd/ssh/libssh/common/canohost.c b/usr/src/cmd/ssh/libssh/common/canohost.c deleted file mode 100644 index 87aab396cf..0000000000 --- a/usr/src/cmd/ssh/libssh/common/canohost.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Copyright 2012 Nexenta Systems, Inc. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.34 2002/09/23 20:46:27 stevesk Exp $"); - -#include "packet.h" -#include "xmalloc.h" -#include "log.h" -#include "canohost.h" - -static const char *inet_ntop_native(int af, const void *src, - char *dst, size_t size); - - -/* - * Return the canonical name of the host at the other end of the socket. The - * caller should free the returned string with xfree. - */ - -static char * -get_remote_hostname(int socket, int verify_reverse_mapping) -{ - struct sockaddr_storage from; - int i, res; - socklen_t fromlen; - struct addrinfo hints, *ai, *aitop; - char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; - - /* Get IP address of client. */ - fromlen = sizeof(from); - memset(&from, 0, sizeof(from)); - if (getpeername(socket, (struct sockaddr *) &from, &fromlen) < 0) { - debug("getpeername failed: %.100s", strerror(errno)); - fatal_cleanup(); - } - - if ((res = getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), - NULL, 0, NI_NUMERICHOST)) != 0) - fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed: %d", res); - -#ifdef IPV4_IN_IPV6 - if (from.ss_family == AF_INET6) { - struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; - - (void) inet_ntop_native(from.ss_family, - from6->sin6_addr.s6_addr, - ntop, sizeof(ntop)); - } -#endif /* IPV4_IN_IPV6 */ - - if (!verify_reverse_mapping) - return xstrdup(ntop); - - debug3("Trying to reverse map address %.100s.", ntop); - /* Map the IP address to a host name. */ - if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), - NULL, 0, NI_NAMEREQD) != 0) { - /* Host name not found. Use ip address. */ - return xstrdup(ntop); - } - - /* Got host name. */ - name[sizeof(name) - 1] = '\0'; - /* - * Convert it to all lowercase (which is expected by the rest - * of this software). - */ - for (i = 0; name[i]; i++) - if (isupper(name[i])) - name[i] = tolower(name[i]); - - /* - * Map it back to an IP address and check that the given - * address actually is an address of this host. This is - * necessary because anyone with access to a name server can - * define arbitrary names for an IP address. Mapping from - * name to IP address can be trusted better (but can still be - * fooled if the intruder has access to the name server of - * the domain). - */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = from.ss_family; - hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { - log("reverse mapping checking getaddrinfo for %.700s " - "failed - POSSIBLE BREAKIN ATTEMPT!", name); - return xstrdup(ntop); - } - /* Look for the address from the list of addresses. */ - for (ai = aitop; ai; ai = ai->ai_next) { - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, - sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && - (strcmp(ntop, ntop2) == 0)) - break; - } - freeaddrinfo(aitop); - /* If we reached the end of the list, the address was not there. */ - if (!ai) { - /* Address not found for the host name. */ - log("Address %.100s maps to %.600s, but this does not " - "map back to the address - POSSIBLE BREAKIN ATTEMPT!", - ntop, name); - return xstrdup(ntop); - } - return xstrdup(name); -} - -/* - * Return the canonical name of the host in the other side of the current - * connection. The host name is cached, so it is efficient to call this - * several times. - */ - -const char * -get_canonical_hostname(int verify_reverse_mapping) -{ - static char *canonical_host_name = NULL; - static int verify_reverse_mapping_done = 0; - - /* Check if we have previously retrieved name with same option. */ - if (canonical_host_name != NULL) { - if (verify_reverse_mapping_done != verify_reverse_mapping) - xfree(canonical_host_name); - else - return canonical_host_name; - } - - /* Get the real hostname if socket; otherwise return UNKNOWN. */ - if (packet_connection_is_on_socket()) - canonical_host_name = get_remote_hostname( - packet_get_connection_in(), verify_reverse_mapping); - else - canonical_host_name = xstrdup("UNKNOWN"); - - verify_reverse_mapping_done = verify_reverse_mapping; - return canonical_host_name; -} - -/* - * Returns the remote IP-address of socket as a string. The returned - * string must be freed. - */ -char * -get_socket_address(int socket, int remote, int flags) -{ - struct sockaddr_storage addr; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; - socklen_t addrlen; - char ntop[NI_MAXHOST]; - const char *result; - char abuf[INET6_ADDRSTRLEN]; - - /* Get IP address of client. */ - addrlen = sizeof (addr); - memset(&addr, 0, sizeof (addr)); - - if (remote) { - if (getpeername(socket, (struct sockaddr *)&addr, &addrlen) - < 0) { - debug("get_socket_ipaddr: getpeername failed: %.100s", - strerror(errno)); - return (NULL); - } - } else { - if (getsockname(socket, (struct sockaddr *)&addr, &addrlen) - < 0) { - debug("get_socket_ipaddr: getsockname failed: %.100s", - strerror(errno)); - return (NULL); - } - } - - /* Get the address in ascii. */ - if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof (ntop), - NULL, 0, flags) != 0) { - error("get_socket_ipaddr: getnameinfo %d failed", flags); - return (NULL); - } - - if (addr.ss_family == AF_INET) { - return (xstrdup(ntop)); - } - - result = inet_ntop_native(addr.ss_family, - addr6->sin6_addr.s6_addr, abuf, sizeof (abuf)); - - return (xstrdup(result)); -} - -char * -get_peer_ipaddr(int socket) -{ - char *p; - - if ((p = get_socket_address(socket, 1, NI_NUMERICHOST)) != NULL) - return p; - return xstrdup("UNKNOWN"); -} - -char * -get_local_ipaddr(int socket) -{ - char *p; - - if ((p = get_socket_address(socket, 0, NI_NUMERICHOST)) != NULL) - return p; - return xstrdup("UNKNOWN"); -} - -char * -get_local_name(int socket) -{ - return get_socket_address(socket, 0, NI_NAMEREQD); -} - -/* - * Returns the IP-address of the remote host as a string. The returned - * string must not be freed. - */ - -const char * -get_remote_ipaddr(void) -{ - static char *canonical_host_ip = NULL; - - /* Check whether we have cached the ipaddr. */ - if (canonical_host_ip == NULL) { - if (packet_connection_is_on_socket()) { - canonical_host_ip = - get_peer_ipaddr(packet_get_connection_in()); - if (canonical_host_ip == NULL) - fatal_cleanup(); - } else { - /* If not on socket, return UNKNOWN. */ - canonical_host_ip = xstrdup("UNKNOWN"); - } - } - return canonical_host_ip; -} - -const char * -get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping) -{ - static const char *remote = ""; - if (utmp_len > 0) - remote = get_canonical_hostname(verify_reverse_mapping); - if (utmp_len == 0 || strlen(remote) > utmp_len) - remote = get_remote_ipaddr(); - return remote; -} - -/* Returns the local/remote port for the socket. */ - -static int -get_sock_port(int sock, int local) -{ - struct sockaddr_storage from; - socklen_t fromlen; - char strport[NI_MAXSERV]; - - /* Get IP address of client. */ - fromlen = sizeof(from); - memset(&from, 0, sizeof(from)); - if (local) { - if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { - error("getsockname failed: %.100s", strerror(errno)); - return 0; - } - } else { - if (getpeername(sock, (struct sockaddr *) & from, &fromlen) < 0) { - debug("getpeername failed: %.100s", strerror(errno)); - fatal_cleanup(); - } - } - /* Return port number. */ - if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, - strport, sizeof(strport), NI_NUMERICSERV) != 0) - fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed"); - return atoi(strport); -} - -/* Returns remote/local port number for the current connection. */ - -static int -get_port(int local) -{ - /* - * If the connection is not a socket, return 65535. This is - * intentionally chosen to be an unprivileged port number. - */ - if (!packet_connection_is_on_socket()) - return 65535; - - /* Get socket and return the port number. */ - return get_sock_port(packet_get_connection_in(), local); -} - -int -get_peer_port(int sock) -{ - return get_sock_port(sock, 0); -} - -int -get_remote_port(void) -{ - return get_port(0); -} - -int -get_local_port(void) -{ - return get_port(1); -} - -/* - * Taken from inetd.c - * This is a wrapper function for inet_ntop(). In case the af is AF_INET6 - * and the address pointed by src is a IPv4-mapped IPv6 address, it - * returns printable IPv4 address, not IPv4-mapped IPv6 address. In other cases - * it behaves just like inet_ntop(). - */ -static const char * -inet_ntop_native(int af, const void *src, char *dst, size_t size) -{ - struct in_addr src4; - const char *result; - - if (af == AF_INET6) { - if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) { - IN6_V4MAPPED_TO_INADDR((struct in6_addr *)src, &src4); - result = inet_ntop(AF_INET, &src4, dst, size); - } else { - result = inet_ntop(AF_INET6, src, dst, size); - } - } else { - result = inet_ntop(af, src, dst, size); - } - - return (result); -} diff --git a/usr/src/cmd/ssh/libssh/common/channels.c b/usr/src/cmd/ssh/libssh/common/channels.c deleted file mode 100644 index 7133758b73..0000000000 --- a/usr/src/cmd/ssh/libssh/common/channels.c +++ /dev/null @@ -1,3035 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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, 2001, 2002 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. - */ -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.183 2002/09/17 07:47:02 itojun Exp $"); - -#include "ssh.h" -#include "ssh1.h" -#include "ssh2.h" -#include "packet.h" -#include "xmalloc.h" -#include "log.h" -#include "misc.h" -#include "channels.h" -#include "compat.h" -#include "canohost.h" -#include "key.h" -#include "authfd.h" -#include "pathnames.h" -#include "bufaux.h" - - -/* -- channel core */ - -/* - * Pointer to an array containing all allocated channels. The array is - * dynamically extended as needed. - */ -static Channel **channels = NULL; - -/* - * Size of the channel array. All slots of the array must always be - * initialized (at least the type field); unused slots set to NULL - */ -static int channels_alloc = 0; - -/* - * Maximum file descriptor value used in any of the channels. This is - * updated in channel_new. - */ -static int channel_max_fd = 0; - - -/* -- tcp forwarding */ - -/* - * Data structure for storing which hosts are permitted for forward requests. - * The local sides of any remote forwards are stored in this array to prevent - * a corrupt remote server from accessing arbitrary TCP/IP ports on our local - * network (which might be behind a firewall). - */ -typedef struct { - char *host_to_connect; /* Connect to 'host'. */ - u_short port_to_connect; /* Connect to 'port'. */ - u_short listen_port; /* Remote side should listen port number. */ -} ForwardPermission; - -/* List of all permitted host/port pairs to connect. */ -static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; - -/* Number of permitted host/port pairs in the array. */ -static int num_permitted_opens = 0; -/* - * If this is true, all opens are permitted. This is the case on the server - * on which we have to trust the client anyway, and the user could do - * anything after logging in anyway. - */ -static int all_opens_permitted = 0; - - -/* -- X11 forwarding */ - -/* Maximum number of fake X11 displays to try. */ -#define MAX_DISPLAYS 1000 - -/* Saved X11 authentication protocol name. */ -static char *x11_saved_proto = NULL; - -/* Saved X11 authentication data. This is the real data. */ -static char *x11_saved_data = NULL; -static u_int x11_saved_data_len = 0; - -/* - * Fake X11 authentication data. This is what the server will be sending us; - * we should replace any occurrences of this by the real data. - */ -static u_char *x11_fake_data = NULL; -static u_int x11_fake_data_len; - - -/* -- agent forwarding */ - -#define NUM_SOCKS 10 - -/* AF_UNSPEC or AF_INET or AF_INET6 */ -static int IPv4or6 = AF_UNSPEC; - -/* helper */ -static void port_open_helper(Channel *c, char *rtype); - -/* -- channel core */ - -Channel * -channel_lookup(int id) -{ - Channel *c; - - if (id < 0 || id >= channels_alloc) { - log("channel_lookup: %d: bad id", id); - return NULL; - } - c = channels[id]; - if (c == NULL) { - log("channel_lookup: %d: bad id: channel free", id); - return NULL; - } - return c; -} - -/* - * Register filedescriptors for a channel, used when allocating a channel or - * when the channel consumer/producer is ready, e.g. shell exec'd - */ - -static void -channel_register_fds(Channel *c, int rfd, int wfd, int efd, - int extusage, int nonblock) -{ - /* Update the maximum file descriptor value. */ - channel_max_fd = MAX(channel_max_fd, rfd); - channel_max_fd = MAX(channel_max_fd, wfd); - channel_max_fd = MAX(channel_max_fd, efd); - - /* XXX set close-on-exec -markus */ - - c->rfd = rfd; - c->wfd = wfd; - c->sock = (rfd == wfd) ? rfd : -1; - c->efd = efd; - c->extended_usage = extusage; - - /* XXX ugly hack: nonblock is only set by the server */ - if (nonblock && isatty(c->rfd)) { - debug("channel %d: rfd %d isatty", c->self, c->rfd); - c->isatty = 1; - if (!isatty(c->wfd)) { - error("channel %d: wfd %d is not a tty?", - c->self, c->wfd); - } - } else { - c->isatty = 0; - } - c->wfd_isatty = isatty(c->wfd); - - /* enable nonblocking mode */ - if (nonblock) { - if (rfd != -1) - set_nonblock(rfd); - if (wfd != -1) - set_nonblock(wfd); - if (efd != -1) - set_nonblock(efd); - } -} - -/* - * Allocate a new channel object and set its type and socket. This will cause - * remote_name to be freed. - */ - -Channel * -channel_new(char *ctype, int type, int rfd, int wfd, int efd, - u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock) -{ - int i, found; - Channel *c; - - /* Do initial allocation if this is the first call. */ - if (channels_alloc == 0) { - channels_alloc = 10; - channels = xmalloc(channels_alloc * sizeof(Channel *)); - for (i = 0; i < channels_alloc; i++) - channels[i] = NULL; - fatal_add_cleanup((void (*) (void *)) channel_free_all, NULL); - } - /* Try to find a free slot where to put the new channel. */ - for (found = -1, i = 0; i < channels_alloc; i++) - if (channels[i] == NULL) { - /* Found a free slot. */ - found = i; - break; - } - if (found == -1) { - /* There are no free slots. Take last+1 slot and expand the array. */ - found = channels_alloc; - if (channels_alloc > 10000) - fatal("channel_new: internal error: channels_alloc %d " - "too big.", channels_alloc); - channels = xrealloc(channels, - (channels_alloc + 10) * sizeof(Channel *)); - channels_alloc += 10; - debug2("channel: expanding %d", channels_alloc); - for (i = found; i < channels_alloc; i++) - channels[i] = NULL; - } - /* Initialize and return new channel. */ - c = channels[found] = xmalloc(sizeof(Channel)); - memset(c, 0, sizeof(Channel)); - buffer_init(&c->input); - buffer_init(&c->output); - buffer_init(&c->extended); - c->ostate = CHAN_OUTPUT_OPEN; - c->istate = CHAN_INPUT_OPEN; - c->flags = 0; - channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); - c->self = found; - c->type = type; - c->ctype = ctype; - c->local_window = window; - c->local_window_max = window; - c->local_consumed = 0; - c->local_maxpacket = maxpack; - c->remote_id = -1; - c->remote_name = remote_name; - c->remote_window = 0; - c->remote_maxpacket = 0; - c->force_drain = 0; - c->single_connection = 0; - c->detach_user = NULL; - c->confirm = NULL; - c->input_filter = NULL; - c->delayed = 1; /* prevent call to channel_post handler */ - debug("channel %d: new [%s]", found, remote_name); - return c; -} - -static int -channel_find_maxfd(void) -{ - int i, max = 0; - Channel *c; - - for (i = 0; i < channels_alloc; i++) { - c = channels[i]; - if (c != NULL) { - max = MAX(max, c->rfd); - max = MAX(max, c->wfd); - max = MAX(max, c->efd); - } - } - return max; -} - -int -channel_close_fd(int *fdp) -{ - int ret = 0, fd = *fdp; - - if (fd != -1) { - ret = close(fd); - *fdp = -1; - if (fd == channel_max_fd) - channel_max_fd = channel_find_maxfd(); - } - return ret; -} - -/* Close all channel fd/socket. */ - -static void -channel_close_fds(Channel *c) -{ - debug3("channel_close_fds: channel %d: r %d w %d e %d", - c->self, c->rfd, c->wfd, c->efd); - - channel_close_fd(&c->sock); - channel_close_fd(&c->rfd); - channel_close_fd(&c->wfd); - channel_close_fd(&c->efd); -} - -/* Free the channel and close its fd/socket. */ - -void -channel_free(Channel *c) -{ - char *s; - int i, n; - - for (n = 0, i = 0; i < channels_alloc; i++) - if (channels[i]) - n++; - debug("channel_free: channel %d: %s, nchannels %d", c->self, - c->remote_name ? c->remote_name : "???", n); - - s = channel_open_message(); - debug3("channel_free: status: %s", s); - xfree(s); - - if (c->sock != -1) - shutdown(c->sock, SHUT_RDWR); - channel_close_fds(c); - buffer_free(&c->input); - buffer_free(&c->output); - buffer_free(&c->extended); - if (c->remote_name) { - xfree(c->remote_name); - c->remote_name = NULL; - } - channels[c->self] = NULL; - xfree(c); -} - -void -channel_free_all(void) -{ - int i; - - for (i = 0; i < channels_alloc; i++) - if (channels[i] != NULL) - channel_free(channels[i]); -} - -/* - * Closes the sockets/fds of all channels. This is used to close extra file - * descriptors after a fork. - */ - -void -channel_close_all(void) -{ - int i; - - for (i = 0; i < channels_alloc; i++) - if (channels[i] != NULL) - channel_close_fds(channels[i]); -} - -/* - * Stop listening to channels. - */ - -void -channel_stop_listening(void) -{ - int i; - Channel *c; - - for (i = 0; i < channels_alloc; i++) { - c = channels[i]; - if (c != NULL) { - switch (c->type) { - case SSH_CHANNEL_AUTH_SOCKET: - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_RPORT_LISTENER: - case SSH_CHANNEL_X11_LISTENER: - channel_close_fd(&c->sock); - channel_free(c); - break; - } - } - } -} - -/* - * Returns true if no channel has too much buffered data, and false if one or - * more channel is overfull. - */ - -int -channel_not_very_much_buffered_data(void) -{ - u_int i; - Channel *c; - - for (i = 0; i < channels_alloc; i++) { - c = channels[i]; - if (c != NULL && c->type == SSH_CHANNEL_OPEN) { -#if 0 - if (!compat20 && - buffer_len(&c->input) > packet_get_maxsize()) { - debug("channel %d: big input buffer %d", - c->self, buffer_len(&c->input)); - return 0; - } -#endif - if (buffer_len(&c->output) > packet_get_maxsize()) { - debug("channel %d: big output buffer %d > %d", - c->self, buffer_len(&c->output), - packet_get_maxsize()); - return 0; - } - } - } - return 1; -} - -/* Returns true if any channel is still open. */ - -int -channel_still_open(void) -{ - int i; - Channel *c; - - for (i = 0; i < channels_alloc; i++) { - c = channels[i]; - if (c == NULL) - continue; - switch (c->type) { - case SSH_CHANNEL_X11_LISTENER: - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_RPORT_LISTENER: - case SSH_CHANNEL_CLOSED: - case SSH_CHANNEL_AUTH_SOCKET: - case SSH_CHANNEL_DYNAMIC: - case SSH_CHANNEL_CONNECTING: - case SSH_CHANNEL_ZOMBIE: - continue; - case SSH_CHANNEL_LARVAL: - if (!compat20) - fatal("cannot happen: SSH_CHANNEL_LARVAL"); - continue; - case SSH_CHANNEL_OPENING: - case SSH_CHANNEL_OPEN: - case SSH_CHANNEL_X11_OPEN: - return 1; - case SSH_CHANNEL_INPUT_DRAINING: - case SSH_CHANNEL_OUTPUT_DRAINING: - if (!compat13) - fatal("cannot happen: OUT_DRAIN"); - return 1; - default: - fatal("channel_still_open: bad channel type %d", c->type); - /* NOTREACHED */ - } - } - return 0; -} - -/* Returns the id of an open channel suitable for keepaliving */ - -int -channel_find_open(void) -{ - int i; - Channel *c; - - for (i = 0; i < channels_alloc; i++) { - c = channels[i]; - if (c == NULL) - continue; - switch (c->type) { - case SSH_CHANNEL_CLOSED: - case SSH_CHANNEL_DYNAMIC: - case SSH_CHANNEL_X11_LISTENER: - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_RPORT_LISTENER: - case SSH_CHANNEL_OPENING: - case SSH_CHANNEL_CONNECTING: - case SSH_CHANNEL_ZOMBIE: - continue; - case SSH_CHANNEL_LARVAL: - case SSH_CHANNEL_AUTH_SOCKET: - case SSH_CHANNEL_OPEN: - case SSH_CHANNEL_X11_OPEN: - return i; - case SSH_CHANNEL_INPUT_DRAINING: - case SSH_CHANNEL_OUTPUT_DRAINING: - if (!compat13) - fatal("cannot happen: OUT_DRAIN"); - return i; - default: - fatal("channel_find_open: bad channel type %d", c->type); - /* NOTREACHED */ - } - } - return -1; -} - - -/* - * Returns a message describing the currently open forwarded connections, - * suitable for sending to the client. The message contains crlf pairs for - * newlines. - */ - -char * -channel_open_message(void) -{ - Buffer buffer; - Channel *c; - char buf[1024], *cp; - int i; - - buffer_init(&buffer); - snprintf(buf, sizeof buf, "The following connections are open:\r\n"); - buffer_append(&buffer, buf, strlen(buf)); - for (i = 0; i < channels_alloc; i++) { - c = channels[i]; - if (c == NULL) - continue; - switch (c->type) { - case SSH_CHANNEL_X11_LISTENER: - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_RPORT_LISTENER: - case SSH_CHANNEL_CLOSED: - case SSH_CHANNEL_AUTH_SOCKET: - case SSH_CHANNEL_ZOMBIE: - continue; - case SSH_CHANNEL_LARVAL: - case SSH_CHANNEL_OPENING: - case SSH_CHANNEL_CONNECTING: - case SSH_CHANNEL_DYNAMIC: - case SSH_CHANNEL_OPEN: - case SSH_CHANNEL_X11_OPEN: - case SSH_CHANNEL_INPUT_DRAINING: - case SSH_CHANNEL_OUTPUT_DRAINING: - snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n", - c->self, c->remote_name, - c->type, c->remote_id, - c->istate, buffer_len(&c->input), - c->ostate, buffer_len(&c->output), - c->rfd, c->wfd); - buffer_append(&buffer, buf, strlen(buf)); - continue; - default: - fatal("channel_open_message: bad channel type %d", c->type); - /* NOTREACHED */ - } - } - buffer_append(&buffer, "\0", 1); - cp = xstrdup(buffer_ptr(&buffer)); - buffer_free(&buffer); - return cp; -} - -void -channel_send_open(int id) -{ - Channel *c = channel_lookup(id); - - if (c == NULL) { - log("channel_send_open: %d: bad id", id); - return; - } - debug("send channel open %d", id); - packet_start(SSH2_MSG_CHANNEL_OPEN); - packet_put_cstring(c->ctype); - packet_put_int(c->self); - packet_put_int(c->local_window); - packet_put_int(c->local_maxpacket); - packet_send(); -} - -void -channel_request_start(int local_id, char *service, int wantconfirm) -{ - Channel *c = channel_lookup(local_id); - - debug("channel request %d: %s", local_id, service); - if (c == NULL) { - log("channel_request_start: %d: unknown channel id", local_id); - return; - } - packet_start(SSH2_MSG_CHANNEL_REQUEST); - packet_put_int(c->remote_id); - packet_put_cstring(service); - packet_put_char(wantconfirm); -} -void -channel_register_confirm(int id, channel_callback_fn *fn) -{ - Channel *c = channel_lookup(id); - - if (c == NULL) { - log("channel_register_comfirm: %d: bad id", id); - return; - } - c->confirm = fn; -} -void -channel_register_cleanup(int id, channel_callback_fn *fn) -{ - Channel *c = channel_lookup(id); - - if (c == NULL) { - log("channel_register_cleanup: %d: bad id", id); - return; - } - c->detach_user = fn; -} -void -channel_cancel_cleanup(int id) -{ - Channel *c = channel_lookup(id); - - if (c == NULL) { - log("channel_cancel_cleanup: %d: bad id", id); - return; - } - c->detach_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, int nonblock, u_int window_max) -{ - Channel *c = channel_lookup(id); - - if (c == NULL || c->type != SSH_CHANNEL_LARVAL) - fatal("channel_activate for non-larval channel %d.", id); - channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); - c->type = SSH_CHANNEL_OPEN; - c->local_window = c->local_window_max = window_max; - packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); - packet_put_int(c->remote_id); - packet_put_int(c->local_window); - packet_send(); -} - -void -channel_set_wait_for_exit(int id, int wait_for_exit) -{ - Channel *c = channel_lookup(id); - - if (c == NULL || c->type != SSH_CHANNEL_OPEN) - fatal("channel_set_wait_for_exit for non-open channel %d.", id); - - debug3("channel_set_wait_for_exit %d, %d (type: %d)", id, wait_for_exit, c->type); - c->wait_for_exit = wait_for_exit; -} - -/* - * 'channel_pre*' are called just before select() to add any bits relevant to - * channels in the select bitmasks. - */ -/* - * 'channel_post*': perform any appropriate operations for channels which - * have events pending. - */ -typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset); -chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE]; -chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE]; - -static void -channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - FD_SET(c->sock, readset); -} - -static void -channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset) -{ - debug3("channel %d: waiting for connection", c->self); - FD_SET(c->sock, writeset); -} - -static void -channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset) -{ - if (buffer_len(&c->input) < packet_get_maxsize()) - FD_SET(c->sock, readset); - if (buffer_len(&c->output) > 0) - FD_SET(c->sock, writeset); -} - -static void -channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset) -{ - u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); - - if (c->istate == CHAN_INPUT_OPEN && - limit > 0 && - buffer_len(&c->input) < limit && - buffer_check_alloc(&c->input, CHAN_RBUF)) - FD_SET(c->rfd, readset); - if (c->ostate == CHAN_OUTPUT_OPEN || - c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { - if (buffer_len(&c->output) > 0) { - FD_SET(c->wfd, writeset); - } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { - if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) - debug2("channel %d: obuf_empty delayed efd %d/(%d)", - c->self, c->efd, buffer_len(&c->extended)); - else - chan_obuf_empty(c); - } - } - /** XXX check close conditions, too */ - if (compat20 && c->efd != -1) { - if (c->extended_usage == CHAN_EXTENDED_WRITE && - buffer_len(&c->extended) > 0) - FD_SET(c->efd, writeset); - else if (!(c->flags & CHAN_EOF_SENT) && - c->extended_usage == CHAN_EXTENDED_READ && - buffer_len(&c->extended) < c->remote_window) - FD_SET(c->efd, readset); - } -} - -static void -channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset) -{ - if (buffer_len(&c->input) == 0) { - packet_start(SSH_MSG_CHANNEL_CLOSE); - packet_put_int(c->remote_id); - packet_send(); - c->type = SSH_CHANNEL_CLOSED; - debug("channel %d: closing after input drain.", c->self); - } -} - -static void -channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) -{ - if (buffer_len(&c->output) == 0) - chan_mark_dead(c); - else - FD_SET(c->sock, writeset); -} - -/* - * This is a special state for X11 authentication spoofing. An opened X11 - * connection (when authentication spoofing is being done) remains in this - * state until the first packet has been completely read. The authentication - * data in that packet is then substituted by the real data if it matches the - * fake data, and the channel is put into normal mode. - * XXX All this happens at the client side. - * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok - */ -static int -x11_open_helper(Buffer *b) -{ - u_char *ucp; - u_int proto_len, data_len; - - /* Check if the fixed size part of the packet is in buffer. */ - if (buffer_len(b) < 12) - return 0; - - /* Parse the lengths of variable-length fields. */ - ucp = buffer_ptr(b); - if (ucp[0] == 0x42) { /* Byte order MSB first. */ - proto_len = 256 * ucp[6] + ucp[7]; - data_len = 256 * ucp[8] + ucp[9]; - } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */ - proto_len = ucp[6] + 256 * ucp[7]; - data_len = ucp[8] + 256 * ucp[9]; - } else { - debug("Initial X11 packet contains bad byte order byte: 0x%x", - ucp[0]); - return -1; - } - - /* Check if the whole packet is in buffer. */ - if (buffer_len(b) < - 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) - return 0; - - /* Check if authentication protocol matches. */ - if (proto_len != strlen(x11_saved_proto) || - memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { - debug("X11 connection uses different authentication protocol."); - return -1; - } - /* Check if authentication data matches our fake data. */ - if (data_len != x11_fake_data_len || - memcmp(ucp + 12 + ((proto_len + 3) & ~3), - x11_fake_data, x11_fake_data_len) != 0) { - debug("X11 auth data does not match fake data."); - return -1; - } - /* Check fake data length */ - if (x11_fake_data_len != x11_saved_data_len) { - error("X11 fake_data_len %d != saved_data_len %d", - x11_fake_data_len, x11_saved_data_len); - return -1; - } - /* - * Received authentication protocol and data match - * our fake data. Substitute the fake data with real - * data. - */ - memcpy(ucp + 12 + ((proto_len + 3) & ~3), - x11_saved_data, x11_saved_data_len); - return 1; -} - -static void -channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) -{ - int ret = x11_open_helper(&c->output); - - if (ret == 1) { - /* Start normal processing for the channel. */ - c->type = SSH_CHANNEL_OPEN; - channel_pre_open_13(c, readset, writeset); - } else if (ret == -1) { - /* - * We have received an X11 connection that has bad - * authentication information. - */ - log("X11 connection rejected because of wrong authentication."); - buffer_clear(&c->input); - buffer_clear(&c->output); - channel_close_fd(&c->sock); - c->sock = -1; - c->type = SSH_CHANNEL_CLOSED; - packet_start(SSH_MSG_CHANNEL_CLOSE); - packet_put_int(c->remote_id); - packet_send(); - } -} - -static void -channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) -{ - int ret = x11_open_helper(&c->output); - - /* c->force_drain = 1; */ - - if (ret == 1) { - c->type = SSH_CHANNEL_OPEN; - channel_pre_open(c, readset, writeset); - } else if (ret == -1) { - log("X11 connection rejected because of wrong authentication."); - debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); - chan_read_failed(c); - buffer_clear(&c->input); - chan_ibuf_empty(c); - buffer_clear(&c->output); - /* for proto v1, the peer will send an IEOF */ - if (compat20) - chan_write_failed(c); - else - c->type = SSH_CHANNEL_OPEN; - debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); - } -} - -/* try to decode a socks4 header */ -static int -channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) -{ - char *p, *host; - int len, have, i, found; - char username[256]; - struct { - u_int8_t version; - u_int8_t command; - u_int16_t dest_port; - struct in_addr dest_addr; - } s4_req, s4_rsp; - - debug2("channel %d: decode socks4", c->self); - - have = buffer_len(&c->input); - len = sizeof(s4_req); - if (have < len) - return 0; - p = buffer_ptr(&c->input); - for (found = 0, i = len; i < have; i++) { - if (p[i] == '\0') { - found = 1; - break; - } - if (i > 1024) { - /* the peer is probably sending garbage */ - debug("channel %d: decode socks4: too long", - c->self); - return -1; - } - } - if (!found) - return 0; - buffer_get(&c->input, (char *)&s4_req.version, 1); - buffer_get(&c->input, (char *)&s4_req.command, 1); - buffer_get(&c->input, (char *)&s4_req.dest_port, 2); - buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); - have = buffer_len(&c->input); - p = buffer_ptr(&c->input); - len = strlen(p); - debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); - if (len > have) - fatal("channel %d: decode socks4: len %d > have %d", - c->self, len, have); - strlcpy(username, p, sizeof(username)); - buffer_consume(&c->input, len); - buffer_consume(&c->input, 1); /* trailing '\0' */ - - host = inet_ntoa(s4_req.dest_addr); - strlcpy(c->path, host, sizeof(c->path)); - c->host_port = ntohs(s4_req.dest_port); - - debug("channel %d: dynamic request: socks4 host %s port %u command %u", - c->self, host, c->host_port, s4_req.command); - - if (s4_req.command != 1) { - debug("channel %d: cannot handle: socks4 cn %d", - c->self, s4_req.command); - return -1; - } - s4_rsp.version = 0; /* vn: 0 for reply */ - s4_rsp.command = 90; /* cd: req granted */ - s4_rsp.dest_port = 0; /* ignored */ - s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ - buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp)); - return 1; -} - -/* try to decode a socks5 header */ -#define SSH_SOCKS5_AUTHDONE 0x1000 -#define SSH_SOCKS5_NOAUTH 0x00 -#define SSH_SOCKS5_IPV4 0x01 -#define SSH_SOCKS5_DOMAIN 0x03 -#define SSH_SOCKS5_IPV6 0x04 -#define SSH_SOCKS5_CONNECT 0x01 -#define SSH_SOCKS5_SUCCESS 0x00 - -/* ARGSUSED */ -static int -channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) -{ - struct { - u_int8_t version; - u_int8_t command; - u_int8_t reserved; - u_int8_t atyp; - } s5_req, s5_rsp; - u_int16_t dest_port; - u_char *p, dest_addr[255+1]; - u_int have, need, i, found, nmethods, addrlen; - struct in_addr bnd_addr; - int af; - - debug2("channel %d: decode socks5", c->self); - p = buffer_ptr(&c->input); - if (p[0] != 0x05) - return -1; - have = buffer_len(&c->input); - if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { - /* format: ver | nmethods | methods */ - if (have < 2) - return 0; - nmethods = p[1]; - if (have < nmethods + 2) - return 0; - /* look for method: "NO AUTHENTICATION REQUIRED" */ - for (found = 0, i = 2 ; i < nmethods + 2; i++) { - if (p[i] == SSH_SOCKS5_NOAUTH) { - found = 1; - break; - } - } - if (!found) { - error("channel %d: socks5 authentication methods not implemented", - c->self); - error("channel %d: forwarding failed: " - "SSH_SOCKS5_NOAUTH method not found", c->self); - return -1; - } - buffer_consume(&c->input, nmethods + 2); - buffer_put_char(&c->output, 0x05); /* version */ - buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */ - FD_SET(c->sock, writeset); - c->flags |= SSH_SOCKS5_AUTHDONE; - debug2("channel %d: socks5 auth done", c->self); - return 0; /* need more */ - } - debug2("channel %d: socks5 post auth", c->self); - if (have < sizeof(s5_req)+1) - return 0; /* need more */ - memcpy(&s5_req, p, sizeof(s5_req)); - if (s5_req.version != 0x05 || - s5_req.command != SSH_SOCKS5_CONNECT || - s5_req.reserved != 0x00) { - error("channel %d: forwarding failed: " - "only socks5 connect is supported", c->self); - return -1; - } - switch (s5_req.atyp){ - case SSH_SOCKS5_IPV4: - addrlen = 4; - af = AF_INET; - break; - case SSH_SOCKS5_DOMAIN: - addrlen = p[sizeof(s5_req)]; - af = -1; - break; - case SSH_SOCKS5_IPV6: - addrlen = 16; - af = AF_INET6; - break; - default: - error("channel %d: forwarding failed: " - "bad socks5 atyp %d", c->self, s5_req.atyp); - return -1; - } - need = sizeof(s5_req) + addrlen + 2; - if (s5_req.atyp == SSH_SOCKS5_DOMAIN) - need++; - if (have < need) - return 0; - buffer_consume(&c->input, sizeof(s5_req)); - if (s5_req.atyp == SSH_SOCKS5_DOMAIN) - buffer_consume(&c->input, 1); /* host string length */ - buffer_get(&c->input, (char *)&dest_addr, addrlen); - buffer_get(&c->input, (char *)&dest_port, 2); - dest_addr[addrlen] = '\0'; - if (s5_req.atyp == SSH_SOCKS5_DOMAIN) - strlcpy(c->path, (char *)dest_addr, sizeof(c->path)); - else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) - return -1; - c->host_port = ntohs(dest_port); - - debug2("channel %d: dynamic request: socks5 host %s port %u command %u", - c->self, c->path, c->host_port, s5_req.command); - - s5_rsp.version = 0x05; - s5_rsp.command = SSH_SOCKS5_SUCCESS; - s5_rsp.reserved = 0; /* ignored */ - s5_rsp.atyp = SSH_SOCKS5_IPV4; - bzero(&bnd_addr, sizeof(bnd_addr)); - bnd_addr.s_addr = htonl(INADDR_ANY); - dest_port = 0; /* ignored */ - - buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); - buffer_append(&c->output, &bnd_addr, sizeof(struct in_addr)); - buffer_append(&c->output, &dest_port, sizeof(dest_port)); - return 1; -} - -/* dynamic port forwarding */ -static void -channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) -{ - u_char *p; - int have, ret; - - have = buffer_len(&c->input); - debug2("channel %d: pre_dynamic: have %d", c->self, have); - /* buffer_dump(&c->input); */ - /* check if the fixed size part of the packet is in buffer. */ - if (have < 3) { - /* need more */ - FD_SET(c->sock, readset); - return; - } - /* try to guess the protocol */ - p = buffer_ptr(&c->input); - switch (p[0]) { - case 0x04: - ret = channel_decode_socks4(c, readset, writeset); - break; - case 0x05: - ret = channel_decode_socks5(c, readset, writeset); - break; - default: - error("channel %d: forwarding failed: unknown socks " - "version 0x%02X", c->self, p[0]); - ret = -1; - break; - } - if (ret < 0) { - chan_mark_dead(c); - } else if (ret == 0) { - debug2("channel %d: pre_dynamic: need more", c->self); - /* need more */ - FD_SET(c->sock, readset); - } else { - /* switch to the next state */ - c->type = SSH_CHANNEL_OPENING; - port_open_helper(c, "direct-tcpip"); - } -} - -/* This is our fake X11 server socket. */ -static void -channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - Channel *nc; - struct sockaddr addr; - int newsock; - socklen_t addrlen; - char buf[16384], *remote_ipaddr; - int remote_port; - - if (FD_ISSET(c->sock, readset)) { - debug("X11 connection requested."); - addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); - if (c->single_connection) { - debug("single_connection: closing X11 listener."); - channel_close_fd(&c->sock); - chan_mark_dead(c); - } - if (newsock < 0) { - error("accept: %.100s", strerror(errno)); - return; - } - set_nodelay(newsock); - remote_ipaddr = get_peer_ipaddr(newsock); - remote_port = get_peer_port(newsock); - snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", - remote_ipaddr, remote_port); - - nc = channel_new("accepted x11 socket", - SSH_CHANNEL_OPENING, newsock, newsock, -1, - c->local_window_max, c->local_maxpacket, - 0, xstrdup(buf), 1); - if (compat20) { - packet_start(SSH2_MSG_CHANNEL_OPEN); - packet_put_cstring("x11"); - packet_put_int(nc->self); - packet_put_int(nc->local_window_max); - packet_put_int(nc->local_maxpacket); - /* originator ipaddr and port */ - packet_put_cstring(remote_ipaddr); - if (datafellows & SSH_BUG_X11FWD) { - debug("ssh2 x11 bug compat mode"); - } else { - packet_put_int(remote_port); - } - packet_send(); - } else { - packet_start(SSH_SMSG_X11_OPEN); - packet_put_int(nc->self); - if (packet_get_protocol_flags() & - SSH_PROTOFLAG_HOST_IN_FWD_OPEN) - packet_put_cstring(buf); - packet_send(); - } - xfree(remote_ipaddr); - } -} - -static void -port_open_helper(Channel *c, char *rtype) -{ - int direct; - char buf[1024]; - char *remote_ipaddr = get_peer_ipaddr(c->sock); - u_short remote_port = get_peer_port(c->sock); - - direct = (strcmp(rtype, "direct-tcpip") == 0); - - snprintf(buf, sizeof buf, - "%s: listening port %d for %.100s port %d, " - "connect from %.200s port %d", - rtype, c->listening_port, c->path, c->host_port, - remote_ipaddr, remote_port); - - xfree(c->remote_name); - c->remote_name = xstrdup(buf); - - if (compat20) { - packet_start(SSH2_MSG_CHANNEL_OPEN); - packet_put_cstring(rtype); - packet_put_int(c->self); - packet_put_int(c->local_window_max); - packet_put_int(c->local_maxpacket); - if (direct) { - /* target host, port */ - packet_put_cstring(c->path); - packet_put_int(c->host_port); - } else { - /* listen address, port */ - packet_put_cstring(c->path); - packet_put_int(c->listening_port); - } - /* originator host and port */ - packet_put_cstring(remote_ipaddr); - packet_put_int(remote_port); - packet_send(); - } else { - packet_start(SSH_MSG_PORT_OPEN); - packet_put_int(c->self); - packet_put_cstring(c->path); - packet_put_int(c->host_port); - if (packet_get_protocol_flags() & - SSH_PROTOFLAG_HOST_IN_FWD_OPEN) - packet_put_cstring(c->remote_name); - packet_send(); - } - xfree(remote_ipaddr); -} - -/* - * This socket is listening for connections to a forwarded TCP/IP port. - */ -static void -channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - Channel *nc; - struct sockaddr addr; - int newsock, nextstate; - socklen_t addrlen; - char *rtype; - - if (FD_ISSET(c->sock, readset)) { - debug("Connection to port %d forwarding " - "to %.100s port %d requested.", - c->listening_port, c->path, c->host_port); - - if (c->type == SSH_CHANNEL_RPORT_LISTENER) { - nextstate = SSH_CHANNEL_OPENING; - rtype = "forwarded-tcpip"; - } else { - if (c->host_port == 0) { - nextstate = SSH_CHANNEL_DYNAMIC; - rtype = "dynamic-tcpip"; - } else { - nextstate = SSH_CHANNEL_OPENING; - rtype = "direct-tcpip"; - } - } - - addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); - if (newsock < 0) { - error("accept: %.100s", strerror(errno)); - return; - } - set_nodelay(newsock); - nc = channel_new(rtype, - nextstate, newsock, newsock, -1, - c->local_window_max, c->local_maxpacket, - 0, xstrdup(rtype), 1); - nc->listening_port = c->listening_port; - nc->host_port = c->host_port; - strlcpy(nc->path, c->path, sizeof(nc->path)); - - if (nextstate != SSH_CHANNEL_DYNAMIC) - port_open_helper(nc, rtype); - } -} - -/* - * This is the authentication agent socket listening for connections from - * clients. - */ -static void -channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - Channel *nc; - char *name; - int newsock; - struct sockaddr addr; - socklen_t addrlen; - - if (FD_ISSET(c->sock, readset)) { - addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); - if (newsock < 0) { - error("accept from auth socket: %.100s", strerror(errno)); - return; - } - name = xstrdup("accepted auth socket"); - nc = channel_new("accepted auth socket", - SSH_CHANNEL_OPENING, newsock, newsock, -1, - c->local_window_max, c->local_maxpacket, - 0, name, 1); - if (compat20) { - packet_start(SSH2_MSG_CHANNEL_OPEN); - packet_put_cstring("auth-agent@openssh.com"); - packet_put_int(nc->self); - packet_put_int(c->local_window_max); - packet_put_int(c->local_maxpacket); - } else { - packet_start(SSH_SMSG_AGENT_OPEN); - packet_put_int(nc->self); - } - packet_send(); - } -} - -static void -channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset) -{ - int err = 0; - socklen_t sz = sizeof(err); - - if (FD_ISSET(c->sock, writeset)) { - if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) { - err = errno; - error("getsockopt SO_ERROR failed"); - } - if (err == 0) { - debug("channel %d: connected", c->self); - c->type = SSH_CHANNEL_OPEN; - if (compat20) { - packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(c->remote_id); - packet_put_int(c->self); - packet_put_int(c->local_window); - packet_put_int(c->local_maxpacket); - } else { - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(c->remote_id); - packet_put_int(c->self); - } - } else { - debug("channel %d: not connected: %s", - c->self, strerror(err)); - if (compat20) { - packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(c->remote_id); - packet_put_int(SSH2_OPEN_CONNECT_FAILED); - if (!(datafellows & SSH_BUG_OPENFAILURE)) { - packet_put_utf8_cstring(strerror(err)); - packet_put_cstring(""); - } - } else { - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(c->remote_id); - } - chan_mark_dead(c); - } - packet_send(); - } -} - -static int -channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) -{ - char buf[CHAN_RBUF]; - int len; - - if (c->rfd != -1 && - FD_ISSET(c->rfd, readset)) { - len = read(c->rfd, buf, sizeof(buf)); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) - return 1; - if (len <= 0) { - debug("channel %d: read<=0 rfd %d len %d", - c->self, c->rfd, len); - if (c->type != SSH_CHANNEL_OPEN) { - debug("channel %d: not open", c->self); - chan_mark_dead(c); - return -1; - } else if (compat13) { - buffer_clear(&c->output); - c->type = SSH_CHANNEL_INPUT_DRAINING; - debug("channel %d: input draining.", c->self); - } else { - chan_read_failed(c); - } - return -1; - } - if (c->input_filter != NULL) { - if (c->input_filter(c, buf, len) == -1) { - debug("channel %d: filter stops", c->self); - chan_read_failed(c); - } - } else { - buffer_append(&c->input, buf, len); - } - } - return 1; -} -static int -channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) -{ - struct termios tio; - u_char *data; - u_int dlen; - int len; - - /* Send buffered output data to the socket. */ - if (c->wfd != -1 && - FD_ISSET(c->wfd, writeset) && - buffer_len(&c->output) > 0) { - data = buffer_ptr(&c->output); - dlen = buffer_len(&c->output); -#ifdef _AIX - /* XXX: Later AIX versions can't push as much data to tty */ - if (compat20 && c->wfd_isatty && dlen > 8*1024) - dlen = 8*1024; -#endif - len = write(c->wfd, data, dlen); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) - return 1; - if (len <= 0) { - if (c->type != SSH_CHANNEL_OPEN) { - debug("channel %d: not open", c->self); - chan_mark_dead(c); - return -1; - } else if (compat13) { - buffer_clear(&c->output); - debug("channel %d: input draining.", c->self); - c->type = SSH_CHANNEL_INPUT_DRAINING; - } else { - chan_write_failed(c); - } - return -1; - } - if (compat20 && c->isatty && dlen >= 1 && data[0] != '\r') { - if (tcgetattr(c->wfd, &tio) == 0 && - !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { - /* - * Simulate echo to reduce the impact of - * traffic analysis. We need to match the - * size of a SSH2_MSG_CHANNEL_DATA message - * (4 byte channel id + data) - */ - packet_send_ignore(4 + len); - packet_send(); - } - } - buffer_consume(&c->output, len); - if (compat20 && len > 0) { - c->local_consumed += len; - } - } - return 1; -} -static int -channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) -{ - char buf[CHAN_RBUF]; - int len; - -/** XXX handle drain efd, too */ - if (c->efd != -1) { - if (c->extended_usage == CHAN_EXTENDED_WRITE && - FD_ISSET(c->efd, writeset) && - buffer_len(&c->extended) > 0) { - len = write(c->efd, buffer_ptr(&c->extended), - buffer_len(&c->extended)); - debug2("channel %d: written %d to efd %d", - c->self, len, c->efd); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) - return 1; - if (len <= 0) { - debug2("channel %d: closing write-efd %d", - c->self, c->efd); - channel_close_fd(&c->efd); - } else { - buffer_consume(&c->extended, len); - c->local_consumed += len; - } - } else if (c->extended_usage == CHAN_EXTENDED_READ && - FD_ISSET(c->efd, readset)) { - len = read(c->efd, buf, sizeof(buf)); - debug2("channel %d: read %d from efd %d", - c->self, len, c->efd); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) - return 1; - if (len <= 0) { - debug2("channel %d: closing read-efd %d", - c->self, c->efd); - channel_close_fd(&c->efd); - } else { - buffer_append(&c->extended, buf, len); - } - } - } - return 1; -} -static int -channel_check_window(Channel *c) -{ - if (c->type == SSH_CHANNEL_OPEN && - !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && - c->local_window < c->local_window_max/2 && - c->local_consumed > 0) { - packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); - packet_put_int(c->remote_id); - packet_put_int(c->local_consumed); - packet_send(); - debug2("channel %d: window %d sent adjust %d", - c->self, c->local_window, - c->local_consumed); - c->local_window += c->local_consumed; - c->local_consumed = 0; - } - return 1; -} - -static void -channel_post_open(Channel *c, fd_set * readset, fd_set * writeset) -{ - channel_handle_rfd(c, readset, writeset); - channel_handle_wfd(c, readset, writeset); - if (!compat20) - return; - channel_handle_efd(c, readset, writeset); - channel_check_window(c); -} - -static void -channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset) -{ - int len; - - /* Send buffered output data to the socket. */ - if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) { - len = write(c->sock, buffer_ptr(&c->output), - buffer_len(&c->output)); - if (len <= 0) - buffer_clear(&c->output); - else - buffer_consume(&c->output, len); - } -} - -static void -channel_handler_init_20(void) -{ - channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open; - channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; - channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; - channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; - - channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; - channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; - channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; - channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; - channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; - channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; - channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; -} - -static void -channel_handler_init_13(void) -{ - channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13; - channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13; - channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; - channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; - channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; - channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; - - channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; - channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; - channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; - channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; - channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; - channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; - channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; -} - -static void -channel_handler_init_15(void) -{ - channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open; - channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; - channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; - channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; - - channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; - channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; - channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; - channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; - channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; - channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; -} - -static void -channel_handler_init(void) -{ - int i; - - for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) { - channel_pre[i] = NULL; - channel_post[i] = NULL; - } - if (compat20) - channel_handler_init_20(); - else if (compat13) - channel_handler_init_13(); - else - channel_handler_init_15(); -} - -/* gc dead channels */ -static void -channel_garbage_collect(Channel *c) -{ - if (c == NULL) - return; - if (c->detach_user != NULL) { - if (!chan_is_dead(c, 0)) - return; - debug("channel %d: gc: notify user", c->self); - c->detach_user(c->self, NULL); - /* if we still have a callback */ - if (c->detach_user != NULL) - return; - debug("channel %d: gc: user detached", c->self); - } - if (!c->wait_for_exit && !chan_is_dead(c, 1)) - return; - debug("channel %d: garbage collecting", c->self); - channel_free(c); -} - -static void -channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) -{ - static int did_init = 0; - int i, oalloc; - Channel *c; - - if (!did_init) { - channel_handler_init(); - did_init = 1; - } - for (i = 0, oalloc = channels_alloc; i < oalloc; i++) { - c = channels[i]; - if (c == NULL) - continue; - if (c->delayed) { - if (ftab == channel_pre) - c->delayed = 0; - else - continue; - } - if (ftab[c->type] != NULL) - (*ftab[c->type])(c, readset, writeset); - channel_garbage_collect(c); - } -} - -/* - * Allocate/update select bitmasks and add any bits relevant to channels in - * select bitmasks. - */ -void -channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, - int *nallocp, int rekeying) -{ - int n; - u_int sz; - - n = MAX(*maxfdp, channel_max_fd); - - sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); - /* perhaps check sz < nalloc/2 and shrink? */ - if (*readsetp == NULL || sz > *nallocp) { - *readsetp = xrealloc(*readsetp, sz); - *writesetp = xrealloc(*writesetp, sz); - *nallocp = sz; - } - *maxfdp = n; - memset(*readsetp, 0, sz); - memset(*writesetp, 0, sz); - - if (!rekeying) - channel_handler(channel_pre, *readsetp, *writesetp); -} - -/* - * After select, perform any appropriate operations for channels which have - * events pending. - */ -void -channel_after_select(fd_set * readset, fd_set * writeset) -{ - channel_handler(channel_post, readset, writeset); -} - - -/* If there is data to send to the connection, enqueue some of it now. */ - -void -channel_output_poll(void) -{ - Channel *c; - int i; - u_int len; - - for (i = 0; i < channels_alloc; i++) { - c = channels[i]; - if (c == NULL) - continue; - - /* - * We are only interested in channels that can have buffered - * incoming data. - */ - if (compat13) { - if (c->type != SSH_CHANNEL_OPEN && - c->type != SSH_CHANNEL_INPUT_DRAINING) - continue; - } else { - if (c->type != SSH_CHANNEL_OPEN) - continue; - } - if (compat20 && - (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { - /* XXX is this true? */ - debug3("channel %d: will not send data after close", c->self); - continue; - } - - /* Get the amount of buffered data for this channel. */ - if ((c->istate == CHAN_INPUT_OPEN || - c->istate == CHAN_INPUT_WAIT_DRAIN) && - (len = buffer_len(&c->input)) > 0) { - /* - * Send some data for the other side over the secure - * connection. - */ - if (compat20) { - if (len > c->remote_window) - len = c->remote_window; - if (len > c->remote_maxpacket) - len = c->remote_maxpacket; - } else { - if (packet_is_interactive()) { - if (len > 1024) - len = 512; - } else { - /* Keep the packets at reasonable size. */ - if (len > packet_get_maxsize()/2) - len = packet_get_maxsize()/2; - } - } - if (len > 0) { - packet_start(compat20 ? - SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA); - packet_put_int(c->remote_id); - packet_put_string(buffer_ptr(&c->input), len); - packet_send(); - buffer_consume(&c->input, len); - c->remote_window -= len; - } - } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { - if (compat13) - fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); - /* - * input-buffer is empty and read-socket shutdown: - * tell peer, that we will not send more data: send IEOF. - * hack for extended data: delay EOF if EFD still in use. - */ - if (CHANNEL_EFD_INPUT_ACTIVE(c)) - debug2("channel %d: ibuf_empty delayed efd %d/(%d)", - c->self, c->efd, buffer_len(&c->extended)); - else - chan_ibuf_empty(c); - } - /* Send extended data, i.e. stderr */ - if (compat20 && - !(c->flags & CHAN_EOF_SENT) && - c->remote_window > 0 && - (len = buffer_len(&c->extended)) > 0 && - c->extended_usage == CHAN_EXTENDED_READ) { - debug2("channel %d: rwin %u elen %u euse %d", - c->self, c->remote_window, buffer_len(&c->extended), - c->extended_usage); - if (len > c->remote_window) - len = c->remote_window; - if (len > c->remote_maxpacket) - len = c->remote_maxpacket; - packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA); - packet_put_int(c->remote_id); - packet_put_int(SSH2_EXTENDED_DATA_STDERR); - packet_put_string(buffer_ptr(&c->extended), len); - packet_send(); - buffer_consume(&c->extended, len); - c->remote_window -= len; - debug2("channel %d: sent ext data %d", c->self, len); - } - } -} - - -/* -- protocol input */ - -void -channel_input_data(int type, u_int32_t seq, void *ctxt) -{ - int id; - char *data; - u_int data_len; - Channel *c; - - /* Get the channel number and verify it. */ - id = packet_get_int(); - c = channel_lookup(id); - if (c == NULL) - packet_disconnect("Received data for nonexistent channel %d.", id); - - /* Ignore any data for non-open channels (might happen on close) */ - if (c->type != SSH_CHANNEL_OPEN && - c->type != SSH_CHANNEL_X11_OPEN) - return; - - /* same for protocol 1.5 if output end is no longer open */ - if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) - return; - - /* Get the data. */ - data = packet_get_string(&data_len); - - if (compat20) { - if (data_len > c->local_maxpacket) { - log("channel %d: rcvd big packet %d, maxpack %d", - c->self, data_len, c->local_maxpacket); - } - if (data_len > c->local_window) { - log("channel %d: rcvd too much data %d, win %d", - c->self, data_len, c->local_window); - xfree(data); - return; - } - c->local_window -= data_len; - } - packet_check_eom(); - buffer_append(&c->output, data, data_len); - xfree(data); -} - -void -channel_input_extended_data(int type, u_int32_t seq, void *ctxt) -{ - int id; - char *data; - u_int data_len, tcode; - Channel *c; - - /* Get the channel number and verify it. */ - id = packet_get_int(); - c = channel_lookup(id); - - if (c == NULL) - packet_disconnect("Received extended_data for bad channel %d.", id); - if (c->type != SSH_CHANNEL_OPEN) { - log("channel %d: ext data for non open", id); - return; - } - if (c->flags & CHAN_EOF_RCVD) { - if (datafellows & SSH_BUG_EXTEOF) - debug("channel %d: accepting ext data after eof", id); - else - packet_disconnect("Received extended_data after EOF " - "on channel %d.", id); - } - tcode = packet_get_int(); - if (c->efd == -1 || - c->extended_usage != CHAN_EXTENDED_WRITE || - tcode != SSH2_EXTENDED_DATA_STDERR) { - log("channel %d: bad ext data", c->self); - return; - } - data = packet_get_string(&data_len); - packet_check_eom(); - if (data_len > c->local_window) { - log("channel %d: rcvd too much extended_data %d, win %d", - c->self, data_len, c->local_window); - xfree(data); - return; - } - debug2("channel %d: rcvd ext data %d", c->self, data_len); - c->local_window -= data_len; - buffer_append(&c->extended, data, data_len); - xfree(data); -} - -void -channel_input_ieof(int type, u_int32_t seq, void *ctxt) -{ - int id; - Channel *c; - - id = packet_get_int(); - packet_check_eom(); - c = channel_lookup(id); - if (c == NULL) - packet_disconnect("Received ieof for nonexistent channel %d.", id); - chan_rcvd_ieof(c); - - /* XXX force input close */ - if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { - debug("channel %d: FORCE input drain", c->self); - c->istate = CHAN_INPUT_WAIT_DRAIN; - if (buffer_len(&c->input) == 0) - chan_ibuf_empty(c); - } - -} - -void -channel_input_close(int type, u_int32_t seq, void *ctxt) -{ - int id; - Channel *c; - - id = packet_get_int(); - packet_check_eom(); - c = channel_lookup(id); - if (c == NULL) - packet_disconnect("Received close for nonexistent channel %d.", id); - - /* - * Send a confirmation that we have closed the channel and no more - * data is coming for it. - */ - packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); - packet_put_int(c->remote_id); - packet_send(); - - /* - * If the channel is in closed state, we have sent a close request, - * and the other side will eventually respond with a confirmation. - * Thus, we cannot free the channel here, because then there would be - * no-one to receive the confirmation. The channel gets freed when - * the confirmation arrives. - */ - if (c->type != SSH_CHANNEL_CLOSED) { - /* - * Not a closed channel - mark it as draining, which will - * cause it to be freed later. - */ - buffer_clear(&c->input); - c->type = SSH_CHANNEL_OUTPUT_DRAINING; - } -} - -/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ -void -channel_input_oclose(int type, u_int32_t seq, void *ctxt) -{ - int id = packet_get_int(); - Channel *c = channel_lookup(id); - - packet_check_eom(); - if (c == NULL) - packet_disconnect("Received oclose for nonexistent channel %d.", id); - chan_rcvd_oclose(c); -} - -void -channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) -{ - int id = packet_get_int(); - Channel *c = channel_lookup(id); - - packet_check_eom(); - if (c == NULL) - packet_disconnect("Received close confirmation for " - "out-of-range channel %d.", id); - if (c->type != SSH_CHANNEL_CLOSED) - packet_disconnect("Received close confirmation for " - "non-closed channel %d (type %d).", id, c->type); - channel_free(c); -} - -void -channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) -{ - int id, remote_id; - Channel *c; - - id = packet_get_int(); - c = channel_lookup(id); - - if (c==NULL || c->type != SSH_CHANNEL_OPENING) - packet_disconnect("Received open confirmation for " - "non-opening channel %d.", id); - remote_id = packet_get_int(); - /* Record the remote channel number and mark that the channel is now open. */ - c->remote_id = remote_id; - c->type = SSH_CHANNEL_OPEN; - - if (compat20) { - c->remote_window = packet_get_int(); - c->remote_maxpacket = packet_get_int(); - if (c->confirm) { - debug2("callback start"); - c->confirm(c->self, NULL); - debug2("callback done"); - } - debug("channel %d: open confirm rwindow %u rmax %u", c->self, - c->remote_window, c->remote_maxpacket); - } - packet_check_eom(); -} - -static char * -reason2txt(int reason) -{ - switch (reason) { - case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED: - return "administratively prohibited"; - case SSH2_OPEN_CONNECT_FAILED: - return "connect failed"; - case SSH2_OPEN_UNKNOWN_CHANNEL_TYPE: - return "unknown channel type"; - case SSH2_OPEN_RESOURCE_SHORTAGE: - return "resource shortage"; - } - return "unknown reason"; -} - -void -channel_input_open_failure(int type, u_int32_t seq, void *ctxt) -{ - int id, reason; - char *msg = NULL, *lang = NULL; - Channel *c; - - id = packet_get_int(); - c = channel_lookup(id); - - if (c==NULL || c->type != SSH_CHANNEL_OPENING) - packet_disconnect("Received open failure for " - "non-opening channel %d.", id); - if (compat20) { - reason = packet_get_int(); - if (!(datafellows & SSH_BUG_OPENFAILURE)) { - msg = packet_get_string(NULL); - lang = packet_get_string(NULL); - } - log("channel %d: open failed: %s%s%s", id, - reason2txt(reason), msg ? ": ": "", msg ? msg : ""); - if (msg != NULL) - xfree(msg); - if (lang != NULL) - xfree(lang); - } - packet_check_eom(); - /* Free the channel. This will also close the socket. */ - channel_free(c); -} - -void -channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) -{ - Channel *c; - int id; - u_int adjust; - - if (!compat20) - return; - - /* Get the channel number and verify it. */ - id = packet_get_int(); - c = channel_lookup(id); - - if (c == NULL || c->type != SSH_CHANNEL_OPEN) { - log("Received window adjust for " - "non-open channel %d.", id); - return; - } - adjust = packet_get_int(); - packet_check_eom(); - debug2("channel %d: rcvd adjust %u", id, adjust); - c->remote_window += adjust; -} - -void -channel_input_port_open(int type, u_int32_t seq, void *ctxt) -{ - Channel *c = NULL; - u_short host_port; - char *host, *originator_string; - int remote_id, sock = -1; - - remote_id = packet_get_int(); - host = packet_get_string(NULL); - host_port = packet_get_int(); - - if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) { - originator_string = packet_get_string(NULL); - } else { - originator_string = xstrdup("unknown (remote did not supply name)"); - } - packet_check_eom(); - sock = channel_connect_to(host, host_port); - if (sock != -1) { - c = channel_new("connected socket", - SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0, - originator_string, 1); - c->remote_id = remote_id; - } - if (c == NULL) { - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_id); - packet_send(); - } - xfree(host); -} - - -/* -- tcp forwarding */ - -void -channel_set_af(int af) -{ - IPv4or6 = af; -} - -static int -channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, - const char *host_to_connect, u_short port_to_connect, int gateway_ports) -{ - Channel *c; - int sock, r, is_client, on = 1, wildcard = 0, success = 0; - struct addrinfo hints, *ai, *aitop; - const char *host, *addr; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - - host = (type == SSH_CHANNEL_RPORT_LISTENER) ? - listen_addr : host_to_connect; - is_client = (type == SSH_CHANNEL_PORT_LISTENER); - - if (host == NULL) { - error("No forward host name."); - return 0; - } - if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { - error("Forward host name too long."); - return 0; - } - - /* - * Determine whether or not a port forward listens to loopback, - * specified address or wildcard. On the client, a specified bind - * address will always override gateway_ports. On the server, a - * gateway_ports of 1 (``yes'') will override the client's - * specification and force a wildcard bind, whereas a value of 2 - * (``clientspecified'') will bind to whatever address the client - * asked for. - * - * Special-case listen_addrs are: - * - * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR - * "" (empty string), "*" -> wildcard v4/v6 - * "localhost" -> loopback v4/v6 - */ - addr = NULL; - if (listen_addr == NULL) { - /* No address specified: default to gateway_ports setting */ - if (gateway_ports) - wildcard = 1; - } else if (gateway_ports || is_client) { - if (((datafellows & SSH_OLD_FORWARD_ADDR) && - strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || - *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || - (!is_client && gateway_ports == 1)) - wildcard = 1; - else if (strcmp(listen_addr, "localhost") != 0) - addr = listen_addr; - } - - debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", - type, wildcard, (addr == NULL) ? "NULL" : addr); - - /* - * getaddrinfo returns a loopback address if the hostname is - * set to NULL and hints.ai_flags is not AI_PASSIVE - */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_flags = wildcard ? AI_PASSIVE : 0; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%d", listen_port); - if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) { - if (addr == NULL) { - /* This really shouldn't happen */ - packet_disconnect("getaddrinfo: fatal error: %s", - gai_strerror(r)); - } else { - error("channel_setup_fwd_listener: " - "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); - } - return 0; - } - - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) - continue; - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), - strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("channel_setup_fwd_listener: getnameinfo failed"); - continue; - } - /* Create a port to listen for the host. */ - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (sock < 0) { - /* this is no error since kernel may not support ipv6 */ - verbose("socket: %.100s", strerror(errno)); - continue; - } - /* - * Set socket options. - * Allow local port reuse in TIME_WAIT. - */ - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, - sizeof(on)) == -1) - error("setsockopt SO_REUSEADDR: %s", strerror(errno)); - - debug("Local forwarding listening on %s port %s.", ntop, strport); - - /* Bind the socket to the address. */ - if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - /* address can be in use ipv6 address is already bound */ - if (!ai->ai_next) - error("bind: %.100s", strerror(errno)); - else - verbose("bind: %.100s", strerror(errno)); - - close(sock); - continue; - } - /* Start listening for connections on the socket. */ - if (listen(sock, 5) < 0) { - error("listen: %.100s", strerror(errno)); - close(sock); - continue; - } - /* Allocate a channel number for the socket. */ - c = channel_new("port listener", type, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, - 0, xstrdup("port listener"), 1); - strlcpy(c->path, host, sizeof(c->path)); - c->host_port = port_to_connect; - c->listening_port = listen_port; - success = 1; - } - if (success == 0) - error("channel_setup_fwd_listener: cannot listen to port: %d", - listen_port); - freeaddrinfo(aitop); - return success; -} - -int -channel_cancel_rport_listener(const char *host, u_short port) -{ - u_int i; - int found = 0; - - for (i = 0; i < channels_alloc; i++) { - Channel *c = channels[i]; - - if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && - strncmp(c->path, host, sizeof(c->path)) == 0 && - c->listening_port == port) { - debug2("%s: close channel %d", __func__, i); - channel_free(c); - found = 1; - } - } - - return (found); -} - -/* protocol local port fwd, used by ssh (and sshd in v1) */ -int -channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, - const char *host_to_connect, u_short port_to_connect, int gateway_ports) -{ - return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, - listen_host, listen_port, host_to_connect, port_to_connect, - gateway_ports); -} - -/* protocol v2 remote port fwd, used by sshd */ -int -channel_setup_remote_fwd_listener(const char *listen_address, - u_short listen_port, int gateway_ports) -{ - return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, - listen_address, listen_port, NULL, 0, gateway_ports); -} - -/* - * Initiate forwarding of connections to port "port" on remote host through - * the secure channel to host:port from local side. - */ - -int -channel_request_remote_forwarding(const char *listen_host, u_short listen_port, - const char *host_to_connect, u_short port_to_connect) -{ - int type, success = 0; - - /* Record locally that connection to this host/port is permitted. */ - if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) - fatal("channel_request_remote_forwarding: too many forwards"); - - if (listen_host != NULL && - strlen(listen_host) > SSH_CHANNEL_PATH_LEN - 1) { - error("Binding address too long."); - return -1; - } - - /* Send the forward request to the remote side. */ - if (compat20) { - const char *address_to_bind; - if (listen_host == NULL) { - if (datafellows & SSH_BUG_RFWD_ADDR) - address_to_bind = "127.0.0.1"; - else - address_to_bind = "localhost"; - } else if (*listen_host == '\0' || - strcmp(listen_host, "*") == 0) { - if (datafellows & SSH_BUG_RFWD_ADDR) - address_to_bind = "0.0.0.0"; - else - address_to_bind = ""; - } else - address_to_bind = listen_host; - - packet_start(SSH2_MSG_GLOBAL_REQUEST); - packet_put_cstring("tcpip-forward"); - packet_put_char(1); /* boolean: want reply */ - packet_put_cstring(address_to_bind); - packet_put_int(listen_port); - packet_send(); - packet_write_wait(); - /* Assume that server accepts the request */ - success = 1; - } else { - packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); - packet_put_int(listen_port); - packet_put_cstring(host_to_connect); - packet_put_int(port_to_connect); - packet_send(); - packet_write_wait(); - - /* Wait for response from the remote side. */ - type = packet_read(); - switch (type) { - case SSH_SMSG_SUCCESS: - success = 1; - break; - case SSH_SMSG_FAILURE: - log("Warning: Server denied remote port forwarding."); - break; - default: - /* Unknown packet */ - packet_disconnect("Protocol error for port forward request:" - "received packet type %d.", type); - } - } - if (success) { - permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); - permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; - permitted_opens[num_permitted_opens].listen_port = listen_port; - num_permitted_opens++; - } - return (success ? 0 : -1); -} - -/* - * Request cancellation of remote forwarding of connection host:port from - * local side. - */ -void -channel_request_rforward_cancel(const char *host, u_short port) -{ - int i; - - if (!compat20) - return; - - for (i = 0; i < num_permitted_opens; i++) { - if (permitted_opens[i].host_to_connect != NULL && - permitted_opens[i].listen_port == port) - break; - } - if (i >= num_permitted_opens) { - debug("%s: requested forward not found", __func__); - return; - } - packet_start(SSH2_MSG_GLOBAL_REQUEST); - packet_put_cstring("cancel-tcpip-forward"); - packet_put_char(0); - packet_put_cstring(host == NULL ? "" : host); - packet_put_int(port); - packet_send(); - - permitted_opens[i].listen_port = 0; - permitted_opens[i].port_to_connect = 0; - xfree(permitted_opens[i].host_to_connect); - permitted_opens[i].host_to_connect = NULL; -} - -/* - * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates - * listening for the port, and sends back a success reply (or disconnect - * message if there was an error). This never returns if there was an error. - */ - -void -channel_input_port_forward_request(int is_root, int gateway_ports) -{ - u_short port, host_port; - char *hostname; - - /* Get arguments from the packet. */ - port = packet_get_int(); - hostname = packet_get_string(NULL); - host_port = packet_get_int(); - -#ifndef HAVE_CYGWIN - /* - * Check that an unprivileged user is not trying to forward a - * privileged port. - */ - if (port < IPPORT_RESERVED && !is_root) - packet_disconnect("Requested forwarding of port %d but user is not root.", - port); -#endif - /* Initiate forwarding */ - channel_setup_local_fwd_listener(NULL, port, hostname, - host_port, gateway_ports); - - /* Free the argument string. */ - xfree(hostname); -} - -/* - * Permits opening to any host/port if permitted_opens[] is empty. This is - * usually called by the server, because the user could connect to any port - * anyway, and the server has no way to know but to trust the client anyway. - */ -void -channel_permit_all_opens(void) -{ - if (num_permitted_opens == 0) - all_opens_permitted = 1; -} - -void -channel_add_permitted_opens(char *host, int port) -{ - if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) - fatal("channel_add_permitted_opens: too many forwards"); - debug("allow port forwarding to host %s port %d", host, port); - - permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); - permitted_opens[num_permitted_opens].port_to_connect = port; - num_permitted_opens++; - - all_opens_permitted = 0; -} - -void -channel_clear_permitted_opens(void) -{ - int i; - - for (i = 0; i < num_permitted_opens; i++) - xfree(permitted_opens[i].host_to_connect); - num_permitted_opens = 0; -} - - -/* return socket to remote host, port */ -static int -connect_to(const char *host, u_short port) -{ - struct addrinfo hints, *ai, *aitop; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int gaierr; - int sock = -1; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%d", port); - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { - error("connect_to %.100s: unknown host (%s)", host, - gai_strerror(gaierr)); - return -1; - } - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) - continue; - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), - strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("connect_to: getnameinfo failed"); - continue; - } - sock = socket(ai->ai_family, SOCK_STREAM, 0); - if (sock < 0) { - error("socket: %.100s", strerror(errno)); - continue; - } - if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) - fatal("connect_to: F_SETFL: %s", strerror(errno)); - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && - errno != EINPROGRESS) { - error("connect_to %.100s port %s: %.100s", ntop, strport, - strerror(errno)); - close(sock); - continue; /* fail -- try next */ - } - break; /* success */ - - } - freeaddrinfo(aitop); - if (!ai) { - error("connect_to %.100s port %d: failed.", host, port); - return -1; - } - /* success */ - set_nodelay(sock); - return sock; -} - -int -channel_connect_by_listen_address(u_short listen_port) -{ - int i; - - for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].listen_port == listen_port) - return connect_to( - permitted_opens[i].host_to_connect, - permitted_opens[i].port_to_connect); - error("WARNING: Server requests forwarding for unknown listen_port %d", - listen_port); - return -1; -} - -/* Check if connecting to that port is permitted and connect. */ -int -channel_connect_to(const char *host, u_short port) -{ - int i, permit; - - permit = all_opens_permitted; - if (!permit) { - for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].port_to_connect == port && - strcmp(permitted_opens[i].host_to_connect, host) == 0) - permit = 1; - - } - if (!permit) { - log("Received request to connect to host %.100s port %d, " - "but the request was denied.", host, port); - return -1; - } - return connect_to(host, port); -} - -/* -- X11 forwarding */ - -/* - * Creates an internet domain socket for listening for X11 connections. - * Returns 0 and a suitable display number for the DISPLAY variable - * stored in display_numberp , or -1 if an error occurs. - */ -int -x11_create_display_inet(int x11_display_offset, int x11_use_localhost, - int single_connection, u_int *display_numberp) -{ - Channel *nc = NULL; - int display_number, sock; - u_short port; - struct addrinfo hints, *ai, *aitop; - char strport[NI_MAXSERV]; - int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; - - for (display_number = x11_display_offset; - display_number < MAX_DISPLAYS; - display_number++) { - port = 6000 + display_number; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%d", port); - if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { - error("getaddrinfo: %.100s", gai_strerror(gaierr)); - return -1; - } - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) - continue; - sock = socket(ai->ai_family, SOCK_STREAM, 0); - if (sock < 0) { - if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { - error("socket: %.100s", strerror(errno)); - freeaddrinfo(aitop); - for (n = 0; n < num_socks; n++) - close(socks[n]); - return -1; - } else { - debug("x11_create_display_inet: Socket family %d not supported", - ai->ai_family); - continue; - } - } -#ifdef IPV6_V6ONLY - if (ai->ai_family == AF_INET6) { - int on = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) - error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); - } -#endif - if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - /* - * If bind() fails with EADDRNOTAVAIL, we - * should not break immediately but rather - * try the next address available. - */ - if (errno == EADDRNOTAVAIL) { - close(sock); - continue; - } - - debug("bind port %d: %.100s; skipping this port", port, - strerror(errno)); - close(sock); - - for (n = 0; n < num_socks; n++) { - close(socks[n]); - } - num_socks = 0; - break; - } - socks[num_socks++] = sock; -#ifndef DONT_TRY_OTHER_AF - if (num_socks == NUM_SOCKS) - break; -#else - if (x11_use_localhost) { - if (num_socks == NUM_SOCKS) - break; - } else { - break; - } -#endif - } - freeaddrinfo(aitop); - if (num_socks > 0) - break; - } - if (display_number >= MAX_DISPLAYS) { - error("Failed to allocate internet-domain X11 display socket."); - return -1; - } - /* Start listening for connections on the socket. */ - for (n = 0; n < num_socks; n++) { - sock = socks[n]; - if (listen(sock, 5) < 0) { - int i; - error("listen: %.100s", strerror(errno)); - for (i = 0; i < num_socks; i++) - close(socks[i]); - return -1; - } - } - - /* Allocate a channel for each socket. */ - for (n = 0; n < num_socks; n++) { - sock = socks[n]; - nc = channel_new("x11 listener", - SSH_CHANNEL_X11_LISTENER, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, - 0, xstrdup("X11 inet listener"), 1); - nc->single_connection = single_connection; - } - - /* Return the display number for the DISPLAY environment variable. */ - *display_numberp = display_number; - return (0); -} - -static int -connect_local_xsocket(u_int dnr) -{ - int sock; - struct sockaddr_un addr; - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - error("socket: %.100s", strerror(errno)); - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr); - if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0) - return sock; - close(sock); - error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); - return -1; -} - -int -x11_connect_display(void) -{ - int display_number, sock = 0; - const char *display; - char buf[1024], *cp; - struct addrinfo hints, *ai, *aitop; - char strport[NI_MAXSERV]; - int gaierr; - - /* Try to open a socket for the local X server. */ - display = getenv("DISPLAY"); - if (!display) { - error("DISPLAY not set."); - return -1; - } - /* - * Now we decode the value of the DISPLAY variable and make a - * connection to the real X server. - */ - - /* - * Check if it is a unix domain socket. Unix domain displays are in - * one of the following formats: unix:d[.s], :d[.s], ::d[.s] - */ - if (strncmp(display, "unix:", 5) == 0 || - display[0] == ':') { - /* Connect to the unix domain socket. */ - if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) { - error("Could not parse display number from DISPLAY: %.100s", - display); - return -1; - } - /* Create a socket. */ - sock = connect_local_xsocket(display_number); - if (sock < 0) - return -1; - - /* OK, we now have a connection to the display. */ - return sock; - } - /* - * Connect to an inet socket. The DISPLAY value is supposedly - * hostname:d[.s], where hostname may also be numeric IP address. - */ - strlcpy(buf, display, sizeof(buf)); - cp = strchr(buf, ':'); - if (!cp) { - error("Could not find ':' in DISPLAY: %.100s", display); - return -1; - } - *cp = 0; - /* buf now contains the host name. But first we parse the display number. */ - if (sscanf(cp + 1, "%d", &display_number) != 1) { - error("Could not parse display number from DISPLAY: %.100s", - display); - return -1; - } - - /* Look up the host address */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%d", 6000 + display_number); - if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { - error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); - return -1; - } - for (ai = aitop; ai; ai = ai->ai_next) { - /* Create a socket. */ - sock = socket(ai->ai_family, SOCK_STREAM, 0); - if (sock < 0) { - debug("socket: %.100s", strerror(errno)); - continue; - } - /* Connect it to the display. */ - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - debug("connect %.100s port %d: %.100s", buf, - 6000 + display_number, strerror(errno)); - close(sock); - continue; - } - /* Success */ - break; - } - freeaddrinfo(aitop); - if (!ai) { - error("connect %.100s port %d: %.100s", buf, 6000 + display_number, - strerror(errno)); - return -1; - } - set_nodelay(sock); - return sock; -} - -/* - * This is called when SSH_SMSG_X11_OPEN is received. The packet contains - * the remote channel number. We should do whatever we want, and respond - * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. - */ - -void -x11_input_open(int type, u_int32_t seq, void *ctxt) -{ - Channel *c = NULL; - int remote_id, sock = 0; - char *remote_host; - - debug("Received X11 open request."); - - remote_id = packet_get_int(); - - if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) { - remote_host = packet_get_string(NULL); - } else { - remote_host = xstrdup("unknown (remote did not supply name)"); - } - packet_check_eom(); - - /* Obtain a connection to the real X display. */ - sock = x11_connect_display(); - if (sock != -1) { - /* Allocate a channel for this connection. */ - c = channel_new("connected x11 socket", - SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0, - remote_host, 1); - c->remote_id = remote_id; - c->force_drain = 1; - } - if (c == NULL) { - /* Send refusal to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_id); - } else { - /* Send a confirmation to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remote_id); - packet_put_int(c->self); - } - packet_send(); -} - -/* dummy protocol handler that denies SSH-1 requests (agent/x11) */ -void -deny_input_open(int type, u_int32_t seq, void *ctxt) -{ - int rchan = packet_get_int(); - - switch (type) { - case SSH_SMSG_AGENT_OPEN: - error("Warning: ssh server tried agent forwarding."); - break; - case SSH_SMSG_X11_OPEN: - error("Warning: ssh server tried X11 forwarding."); - break; - default: - error("deny_input_open: type %d", type); - break; - } - error("Warning: this is probably a break in attempt by a malicious server."); - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(rchan); - packet_send(); -} - -/* - * Requests forwarding of X11 connections, generates fake authentication - * data, and enables authentication spoofing. - * This should be called in the client only. - */ -void -x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, - const char *proto, const char *data) -{ - u_int data_len = (u_int) strlen(data) / 2; - u_int i, value; - char *new_data; - int screen_number; - const char *cp; - u_int32_t rand = 0; - - cp = disp; - if (disp) - cp = strchr(disp, ':'); - if (cp) - cp = strchr(cp, '.'); - if (cp) - screen_number = atoi(cp + 1); - else - screen_number = 0; - - /* Save protocol name. */ - x11_saved_proto = xstrdup(proto); - - /* - * Extract real authentication data and generate fake data of the - * same length. - */ - x11_saved_data = xmalloc(data_len); - x11_fake_data = xmalloc(data_len); - for (i = 0; i < data_len; i++) { - if (sscanf(data + 2 * i, "%2x", &value) != 1) - fatal("x11_request_forwarding: bad authentication data: %.100s", data); - if (i % 4 == 0) - rand = arc4random(); - x11_saved_data[i] = value; - x11_fake_data[i] = rand & 0xff; - rand >>= 8; - } - x11_saved_data_len = data_len; - x11_fake_data_len = data_len; - - /* Convert the fake data into hex. */ - new_data = tohex(x11_fake_data, data_len); - - /* Send the request packet. */ - if (compat20) { - channel_request_start(client_session_id, "x11-req", 0); - packet_put_char(0); /* XXX bool single connection */ - } else { - packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); - } - packet_put_cstring(proto); - packet_put_cstring(new_data); - packet_put_int(screen_number); - packet_send(); - packet_write_wait(); - xfree(new_data); -} - - -/* -- agent forwarding */ - -/* Sends a message to the server to request authentication fd forwarding. */ - -void -auth_request_forwarding(void) -{ - packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); - packet_send(); - packet_write_wait(); -} - -/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ - -void -auth_input_open_request(int type, u_int32_t seq, void *ctxt) -{ - Channel *c = NULL; - int remote_id, sock; - char *name; - - /* Read the remote channel number from the message. */ - remote_id = packet_get_int(); - packet_check_eom(); - - /* - * Get a connection to the local authentication agent (this may again - * get forwarded). - */ - sock = ssh_get_authentication_socket(); - - /* - * If we could not connect the agent, send an error message back to - * the server. This should never happen unless the agent dies, - * because authentication forwarding is only enabled if we have an - * agent. - */ - if (sock >= 0) { - name = xstrdup("authentication agent connection"); - c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, - -1, 0, 0, 0, name, 1); - c->remote_id = remote_id; - c->force_drain = 1; - } - if (c == NULL) { - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_id); - } else { - /* Send a confirmation to the remote host. */ - debug("Forwarding authentication connection."); - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remote_id); - packet_put_int(c->self); - } - packet_send(); -} diff --git a/usr/src/cmd/ssh/libssh/common/cipher-ctr.c b/usr/src/cmd/ssh/libssh/common/cipher-ctr.c deleted file mode 100644 index d728064b53..0000000000 --- a/usr/src/cmd/ssh/libssh/common/cipher-ctr.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2003 Markus Friedl <markus@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: cipher-ctr.c,v 1.4 2004/02/06 23:41:13 dtucker Exp $"); - -#include <openssl/evp.h> - -#include "log.h" -#include "xmalloc.h" -#include <openssl/aes.h> - -const EVP_CIPHER *evp_aes_128_ctr(void); -void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); - -struct ssh_aes_ctr_ctx -{ - AES_KEY aes_ctx; - u_char aes_counter[AES_BLOCK_SIZE]; -}; - -/* - * increment counter 'ctr', - * the counter is of size 'len' bytes and stored in network-byte-order. - * (LSB at ctr[len-1], MSB at ctr[0]) - */ -static void -ssh_ctr_inc(u_char *ctr, u_int len) -{ - int i; - - for (i = len - 1; i >= 0; i--) - if (++ctr[i]) /* continue on overflow */ - return; -} - -static int -ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, - u_int len) -{ - struct ssh_aes_ctr_ctx *c; - u_int n = 0; - u_char buf[AES_BLOCK_SIZE]; - - if (len == 0) - return (1); - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) - return (0); - - while ((len--) > 0) { - if (n == 0) { - AES_encrypt(c->aes_counter, buf, &c->aes_ctx); - ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); - } - *(dest++) = *(src++) ^ buf[n]; - n = (n + 1) % AES_BLOCK_SIZE; - } - return (1); -} - -static int -ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, - int enc) -{ - struct ssh_aes_ctr_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { - c = xmalloc(sizeof(*c)); - EVP_CIPHER_CTX_set_app_data(ctx, c); - } - if (key != NULL) - AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, - &c->aes_ctx); - if (iv != NULL) - memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); - return (1); -} - -static int -ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) -{ - struct ssh_aes_ctr_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { - memset(c, 0, sizeof(*c)); - xfree(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); - } - return (1); -} - -void -ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len) -{ - struct ssh_aes_ctr_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) - fatal("ssh_aes_ctr_iv: no context"); - if (doset) - memcpy(c->aes_counter, iv, len); - else - memcpy(iv, c->aes_counter, len); -} - -/* - * Function fills an EVP_CIPHER structure for AES CTR functions based on the NID - * and the key length. - */ -static const EVP_CIPHER * -evp_aes_ctr(const char *nid, int key_len, EVP_CIPHER *aes_ctr) -{ - memset(aes_ctr, 0, sizeof(EVP_CIPHER)); - /* - * If the PKCS#11 engine is used the AES CTR NIDs were dynamically - * created during the engine initialization. If the engine is not used - * we work with NID_undef's which is OK since in that case OpenSSL - * doesn't use NIDs at all. - */ - if ((aes_ctr->nid = OBJ_ln2nid(nid)) != NID_undef) - debug3("%s NID found", nid); - - aes_ctr->block_size = AES_BLOCK_SIZE; - aes_ctr->iv_len = AES_BLOCK_SIZE; - aes_ctr->key_len = key_len; - aes_ctr->init = ssh_aes_ctr_init; - aes_ctr->cleanup = ssh_aes_ctr_cleanup; - aes_ctr->do_cipher = ssh_aes_ctr; - aes_ctr->flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | - EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; - return (aes_ctr); -} - -const EVP_CIPHER * -evp_aes_128_ctr(void) -{ - static EVP_CIPHER aes_ctr; - - return (evp_aes_ctr("aes-128-ctr", 16, &aes_ctr)); -} - -const EVP_CIPHER * -evp_aes_192_ctr(void) -{ - static EVP_CIPHER aes_ctr; - - return (evp_aes_ctr("aes-192-ctr", 24, &aes_ctr)); -} - -const EVP_CIPHER * -evp_aes_256_ctr(void) -{ - static EVP_CIPHER aes_ctr; - - return (evp_aes_ctr("aes-256-ctr", 32, &aes_ctr)); -} diff --git a/usr/src/cmd/ssh/libssh/common/cipher.c b/usr/src/cmd/ssh/libssh/common/cipher.c deleted file mode 100644 index 3cb001a150..0000000000 --- a/usr/src/cmd/ssh/libssh/common/cipher.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * 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) 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. - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: cipher.c,v 1.61 2002/07/12 15:50:17 markus Exp $"); - -#include "xmalloc.h" -#include "log.h" -#include "cipher.h" - -#include <openssl/md5.h> - -/* - * Symmetric ciphers can be offloaded to any engine through the EVP API only. - * However, OpenSSL doesn't offer AES in counter mode through EVP. So, we must - * define our own EVP functions. - */ -extern const EVP_CIPHER *evp_aes_128_ctr(void); -extern const EVP_CIPHER *evp_aes_192_ctr(void); -extern const EVP_CIPHER *evp_aes_256_ctr(void); -extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); - -static const EVP_CIPHER *evp_ssh1_3des(void); -static const EVP_CIPHER *evp_ssh1_bf(void); - -struct Cipher { - char *name; - int number; /* for ssh1 only */ - u_int block_size; - u_int key_len; - u_int discard_len; - const EVP_CIPHER *(*evptype)(void); -} ciphers[] = { - { "none", SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null }, - { "des", SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc }, - { "3des", SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des }, - { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf }, - { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc }, - { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc }, -#ifdef SOLARIS_SSH_ENABLE_CAST5_128 - { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc }, -#endif /* SOLARIS_SSH_ENABLE_CAST5_128 */ - { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4 }, - { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4 }, - { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4 }, - { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc }, - { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc }, - { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc }, - { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr }, - { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_192_ctr }, - { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_256_ctr }, - { NULL, SSH_CIPHER_ILLEGAL, 0, 0, 0, NULL } -}; - -/*--*/ - -u_int -cipher_blocksize(Cipher *c) -{ - return (c->block_size); -} - -u_int -cipher_keylen(Cipher *c) -{ - return (c->key_len); -} - -u_int -cipher_get_number(Cipher *c) -{ - return (c->number); -} - -u_int -cipher_mask_ssh1(int client) -{ - u_int mask = 0; - mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ - mask |= 1 << SSH_CIPHER_BLOWFISH; - if (client) { - mask |= 1 << SSH_CIPHER_DES; - } - return mask; -} - -Cipher * -cipher_by_name(const char *name) -{ - Cipher *c; - for (c = ciphers; c->name != NULL; c++) - if (strcasecmp(c->name, name) == 0) - return c; - return NULL; -} - -Cipher * -cipher_by_number(int id) -{ - Cipher *c; - for (c = ciphers; c->name != NULL; c++) - if (c->number == id) - return c; - return NULL; -} - -#define CIPHER_SEP "," -int -ciphers_valid(const char *names) -{ - Cipher *c; - char *ciphers, *cp; - char *p; - - if (names == NULL || strcmp(names, "") == 0) - return 0; - ciphers = cp = xstrdup(names); - for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; - (p = strsep(&cp, CIPHER_SEP))) { - c = cipher_by_name(p); - if (c == NULL || c->number != SSH_CIPHER_SSH2) { - debug("bad cipher %s [%s]", p, names); - xfree(ciphers); - return 0; - } else { - debug3("cipher ok: %s [%s]", p, names); - } - } - debug3("ciphers ok: [%s]", names); - xfree(ciphers); - return 1; -} - -/* - * Parses the name of the cipher. Returns the number of the corresponding - * cipher, or -1 on error. - */ - -int -cipher_number(const char *name) -{ - Cipher *c; - if (name == NULL) - return -1; - c = cipher_by_name(name); - return (c==NULL) ? -1 : c->number; -} - -char * -cipher_name(int id) -{ - Cipher *c = cipher_by_number(id); - return (c==NULL) ? "<unknown>" : c->name; -} - -void -cipher_init(CipherContext *cc, Cipher *cipher, - const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, - int encrypt) -{ - static int dowarn = 1; - const EVP_CIPHER *type; - int klen; - u_char *junk, *discard; - - if (cipher->number == SSH_CIPHER_DES) { - if (dowarn) { - error("Warning: use of DES is strongly discouraged " - "due to cryptographic weaknesses"); - dowarn = 0; - } - if (keylen > 8) - keylen = 8; - } - cc->plaintext = (cipher->number == SSH_CIPHER_NONE); - - if (keylen < cipher->key_len) - fatal("cipher_init: key length %d is insufficient for %s.", - keylen, cipher->name); - if (iv != NULL && ivlen < cipher->block_size) - fatal("cipher_init: iv length %d is insufficient for %s.", - ivlen, cipher->name); - cc->cipher = cipher; - - type = (*cipher->evptype)(); - - EVP_CIPHER_CTX_init(&cc->evp); - /* - * cc->evp is of type EVP_CIPHER_CTX and its key_len will be set to the - * default value here for the cipher type. If the requested key length - * is different from the default value we will call EVP_CipherInit() - * again, see below. - */ - if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, - (encrypt == CIPHER_ENCRYPT)) == 0) - fatal("cipher_init: EVP_CipherInit failed for %s", - cipher->name); - klen = EVP_CIPHER_CTX_key_length(&cc->evp); - if (klen > 0 && keylen != klen) { - debug("cipher_init: set keylen (%d -> %d)", klen, keylen); - if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) - fatal("cipher_init: set keylen failed (%d -> %d)", - klen, keylen); - } - if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) - fatal("cipher_init: EVP_CipherInit: set key failed for %s", - cipher->name); - - if (cipher->discard_len > 0) { - junk = xmalloc(cipher->discard_len); - discard = xmalloc(cipher->discard_len); - if (EVP_Cipher(&cc->evp, discard, junk, - cipher->discard_len) == 0) - fatal("cipher_init: EVP_Cipher failed during discard"); - memset(discard, 0, cipher->discard_len); - xfree(junk); - xfree(discard); - } -} - -void -cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) -{ - if (len % cc->cipher->block_size) - fatal("cipher_encrypt: bad plaintext length %d", len); - if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) - fatal("evp_crypt: EVP_Cipher failed"); -} - -void -cipher_cleanup(CipherContext *cc) -{ - if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) - error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); -} - -/* - * Selects the cipher, and keys if by computing the MD5 checksum of the - * passphrase and using the resulting 16 bytes as the key. - */ - -void -cipher_set_key_string(CipherContext *cc, Cipher *cipher, - const char *passphrase, int encrypt) -{ - MD5_CTX md; - u_char digest[16]; - - MD5_Init(&md); - MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); - MD5_Final(digest, &md); - - cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt); - - memset(digest, 0, sizeof(digest)); - memset(&md, 0, sizeof(md)); -} - -/* Implementations for other non-EVP ciphers */ - -/* - * This is used by SSH1: - * - * What kind of triple DES are these 2 routines? - * - * Why is there a redundant initialization vector? - * - * If only iv3 was used, then, this would till effect have been - * outer-cbc. However, there is also a private iv1 == iv2 which - * perhaps makes differential analysis easier. On the other hand, the - * private iv1 probably makes the CRC-32 attack ineffective. This is a - * result of that there is no longer any known iv1 to use when - * choosing the X block. - */ -struct ssh1_3des_ctx -{ - EVP_CIPHER_CTX k1, k2, k3; -}; - -static int -ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, - int enc) -{ - struct ssh1_3des_ctx *c; - u_char *k1, *k2, *k3; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { - c = xmalloc(sizeof(*c)); - EVP_CIPHER_CTX_set_app_data(ctx, c); - } - if (key == NULL) - return (1); - if (enc == -1) - enc = ctx->encrypt; - k1 = k2 = k3 = (u_char *) key; - k2 += 8; - if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { - if (enc) - k3 += 16; - else - k1 += 16; - } - EVP_CIPHER_CTX_init(&c->k1); - EVP_CIPHER_CTX_init(&c->k2); - EVP_CIPHER_CTX_init(&c->k3); - if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || - EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || - EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { - memset(c, 0, sizeof(*c)); - xfree(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); - return (0); - } - return (1); -} - -static int -ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len) -{ - struct ssh1_3des_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { - error("ssh1_3des_cbc: no context"); - return (0); - } - if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || - EVP_Cipher(&c->k2, dest, dest, len) == 0 || - EVP_Cipher(&c->k3, dest, dest, len) == 0) - return (0); - return (1); -} - -static int -ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) -{ - struct ssh1_3des_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { - memset(c, 0, sizeof(*c)); - xfree(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); - } - return (1); -} - -static const EVP_CIPHER * -evp_ssh1_3des(void) -{ - static EVP_CIPHER ssh1_3des; - - memset(&ssh1_3des, 0, sizeof(EVP_CIPHER)); - ssh1_3des.nid = NID_undef; - ssh1_3des.block_size = 8; - ssh1_3des.iv_len = 0; - ssh1_3des.key_len = 16; - ssh1_3des.init = ssh1_3des_init; - ssh1_3des.cleanup = ssh1_3des_cleanup; - ssh1_3des.do_cipher = ssh1_3des_cbc; - ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; - return (&ssh1_3des); -} - -/* - * SSH1 uses a variation on Blowfish, all bytes must be swapped before - * and after encryption/decryption. Thus the swap_bytes stuff (yuk). - */ -static void -swap_bytes(const u_char *src, u_char *dst, int n) -{ - u_char c[4]; - - /* Process 4 bytes every lap. */ - for (n = n / 4; n > 0; n--) { - c[3] = *src++; - c[2] = *src++; - c[1] = *src++; - c[0] = *src++; - - *dst++ = c[0]; - *dst++ = c[1]; - *dst++ = c[2]; - *dst++ = c[3]; - } -} - -static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL; - -static int -bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len) -{ - int ret; - - swap_bytes(in, out, len); - ret = (*orig_bf)(ctx, out, out, len); - swap_bytes(out, out, len); - return (ret); -} - -static const EVP_CIPHER * -evp_ssh1_bf(void) -{ - static EVP_CIPHER ssh1_bf; - - memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER)); - orig_bf = ssh1_bf.do_cipher; - ssh1_bf.nid = NID_undef; - ssh1_bf.do_cipher = bf_ssh1_cipher; - ssh1_bf.key_len = 32; - return (&ssh1_bf); -} - -/* - * Exports an IV from the CipherContext required to export the key - * state back from the unprivileged child to the privileged parent - * process. - */ - -int -cipher_get_keyiv_len(CipherContext *cc) -{ - Cipher *c = cc->cipher; - int ivlen; - - if (c->number == SSH_CIPHER_3DES) - ivlen = 24; - else - ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); - return (ivlen); -} - -void -cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) -{ - Cipher *c = cc->cipher; - u_char *civ = NULL; - int evplen; - - switch (c->number) { - case SSH_CIPHER_SSH2: - case SSH_CIPHER_DES: - case SSH_CIPHER_BLOWFISH: - evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); - if (evplen == 0) - return; - if (evplen != len) - fatal("%s: wrong iv length %d != %d", __func__, - evplen, len); - - if (c->evptype == evp_aes_128_ctr) { - ssh_aes_ctr_iv(&cc->evp, 0, iv, len); - return; - } else { - civ = cc->evp.iv; - } - break; - case SSH_CIPHER_3DES: { - struct ssh1_3des_ctx *desc; - if (len != 24) - fatal("%s: bad 3des iv length: %d", __func__, len); - desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); - if (desc == NULL) - fatal("%s: no 3des context", __func__); - debug3("%s: Copying 3DES IV", __func__); - memcpy(iv, desc->k1.iv, 8); - memcpy(iv + 8, desc->k2.iv, 8); - memcpy(iv + 16, desc->k3.iv, 8); - return; - } - default: - fatal("%s: bad cipher %d", __func__, c->number); - } - memcpy(iv, civ, len); -} - -void -cipher_set_keyiv(CipherContext *cc, u_char *iv) -{ - Cipher *c = cc->cipher; - u_char *div = NULL; - int evplen = 0; - - switch (c->number) { - case SSH_CIPHER_SSH2: - case SSH_CIPHER_DES: - case SSH_CIPHER_BLOWFISH: - evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); - if (evplen == 0) - return; - - if (c->evptype == evp_aes_128_ctr) { - ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); - return; - } else { - div = cc->evp.iv; - } - break; - case SSH_CIPHER_3DES: { - struct ssh1_3des_ctx *desc; - desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); - if (desc == NULL) - fatal("%s: no 3des context", __func__); - debug3("%s: Installed 3DES IV", __func__); - memcpy(desc->k1.iv, iv, 8); - memcpy(desc->k2.iv, iv + 8, 8); - memcpy(desc->k3.iv, iv + 16, 8); - return; - } - default: - fatal("%s: bad cipher %d", __func__, c->number); - } - memcpy(div, iv, evplen); -} - -#if OPENSSL_VERSION_NUMBER < 0x00907000L -#define EVP_X_STATE(evp) &(evp).c -#define EVP_X_STATE_LEN(evp) sizeof((evp).c) -#else -#define EVP_X_STATE(evp) (evp).cipher_data -#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size -#endif - -int -cipher_get_keycontext(CipherContext *cc, u_char *dat) -{ - int plen = 0; - Cipher *c = cc->cipher; - - if (c->evptype == EVP_rc4) { - plen = EVP_X_STATE_LEN(cc->evp); - if (dat == NULL) - return (plen); - memcpy(dat, EVP_X_STATE(cc->evp), plen); - } - return (plen); -} - -void -cipher_set_keycontext(CipherContext *cc, u_char *dat) -{ - Cipher *c = cc->cipher; - int plen; - - if (c->evptype == EVP_rc4) { - plen = EVP_X_STATE_LEN(cc->evp); - memcpy(EVP_X_STATE(cc->evp), dat, plen); - } -} diff --git a/usr/src/cmd/ssh/libssh/common/compat.c b/usr/src/cmd/ssh/libssh/common/compat.c deleted file mode 100644 index 6d85d6e511..0000000000 --- a/usr/src/cmd/ssh/libssh/common/compat.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 1999, 2000, 2001, 2002 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: compat.c,v 1.65 2002/09/27 10:42:09 mickey Exp $"); - -#include "buffer.h" -#include "packet.h" -#include "xmalloc.h" -#include "compat.h" -#include "log.h" -#include "match.h" - -int compat13 = 0; -int compat20 = 0; -uint32_t datafellows = 0; - -void -enable_compat20(void) -{ - debug("Enabling compatibility mode for protocol 2.0"); - compat20 = 1; -} -void -enable_compat13(void) -{ - debug("Enabling compatibility mode for protocol 1.3"); - compat13 = 1; -} -/* datafellows bug compatibility */ -void -compat_datafellows(const char *version) -{ - int i; - static struct { - char *pat; - uint32_t bugs; - } check[] = { - { "OpenSSH-2.0*," - "OpenSSH-2.1*," - "OpenSSH_2.1*," - "OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| - SSH_OLD_DHGEX|SSH_BUG_NOREKEY| - SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| - SSH_OLD_DHGEX|SSH_BUG_NOREKEY| - SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| - SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| - SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_2.5.0p1*," - "OpenSSH_2.5.1p1*", - SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| - SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| - SSH_OLD_GSSAPI|SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_2.5.0*," - "OpenSSH_2.5.1*," - "OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| - SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| - SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_2.9p*", SSH_BUG_EXTEOF|SSH_OLD_GSSAPI| - SSH_BUG_GSSKEX_HOSTKEY|SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_2.*," - "OpenSSH_3.0*," - "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR| - SSH_OLD_GSSAPI|SSH_BUG_GSSAPI_BER| - SSH_BUG_GSSKEX_HOSTKEY}, - { "OpenSSH_3.2*," - "OpenSSH_3.3*," - "OpenSSH_3.4*," - "OpenSSH_3.5*", SSH_BUG_GSSAPI_BER|SSH_OLD_GSSAPI| - SSH_BUG_GSSKEX_HOSTKEY|SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_3.6*," - "OpenSSH_3.7*," - "OpenSSH_3.8*", SSH_BUG_GSSKEX_HOSTKEY|SSH_OLD_FORWARD_ADDR}, - { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR}, - { "OpenSSH*", 0 }, - { "Sun_SSH_1.0.*", SSH_BUG_NOREKEY| - SSH_BUG_LOCALES_NOT_LANGTAGS|SSH_OLD_FORWARD_ADDR}, - { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| - SSH_BUG_LOCALES_NOT_LANGTAGS|SSH_OLD_FORWARD_ADDR}, - { "Sun_SSH_1.1.1*", SSH_OLD_FORWARD_ADDR|SSH_BUG_STRING_ENCODING}, - { "Sun_SSH_1.1.2*", SSH_OLD_FORWARD_ADDR}, - { "Sun_SSH_1.1*", SSH_OLD_FORWARD_ADDR|SSH_BUG_STRING_ENCODING}, - { "Sun_SSH_1.2*", SSH_BUG_STRING_ENCODING}, - { "Sun_SSH_1.3*", SSH_BUG_STRING_ENCODING}, - { "Sun_SSH_1.4*", 0 }, - { "Sun_SSH_1.5*", 0 }, - { "Sun_SSH_*", 0 }, - { "*MindTerm*", 0 }, - { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| - SSH_OLD_SESSIONID|SSH_BUG_DEBUG| - SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE| - SSH_BUG_FIRSTKEX }, - { "2.1 *", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| - SSH_OLD_SESSIONID|SSH_BUG_DEBUG| - SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE| - SSH_BUG_FIRSTKEX }, - { "2.0.13*," - "2.0.14*," - "2.0.15*," - "2.0.16*," - "2.0.17*," - "2.0.18*," - "2.0.19*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| - SSH_OLD_SESSIONID|SSH_BUG_DEBUG| - SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| - SSH_BUG_PKOK|SSH_BUG_RSASIGMD5| - SSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE| - SSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX }, - { "2.0.11*," - "2.0.12*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| - SSH_OLD_SESSIONID|SSH_BUG_DEBUG| - SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| - SSH_BUG_PKAUTH|SSH_BUG_PKOK| - SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE| - SSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX }, - { "2.0.*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| - SSH_OLD_SESSIONID|SSH_BUG_DEBUG| - SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| - SSH_BUG_PKAUTH|SSH_BUG_PKOK| - SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE| - SSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN| - SSH_BUG_FIRSTKEX }, - { "2.2.0*," - "2.3.0*", SSH_BUG_HMAC|SSH_BUG_DEBUG| - SSH_BUG_RSASIGMD5|SSH_BUG_FIRSTKEX }, - { "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5| - SSH_BUG_FIRSTKEX }, - { "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */ - { "2.*", SSH_BUG_DEBUG|SSH_BUG_FIRSTKEX| - SSH_BUG_RFWD_ADDR}, - { "3.0.*", SSH_BUG_DEBUG }, - { "3.0 SecureCRT*", SSH_OLD_SESSIONID }, - { "1.7 SecureFX*", SSH_OLD_SESSIONID }, - { "1.2.18*," - "1.2.19*," - "1.2.20*," - "1.2.21*," - "1.2.22*", SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, - { "1.3.2*", /* F-Secure */ - SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, - { "1.2.1*," - "1.2.2*," - "1.2.3*", SSH_BUG_K5USER }, - { "*SSH Compatible Server*", /* Netscreen */ - SSH_BUG_PASSWORDPAD }, - { "*OSU_0*," - "OSU_1.0*," - "OSU_1.1*," - "OSU_1.2*," - "OSU_1.3*," - "OSU_1.4*," - "OSU_1.5alpha1*," - "OSU_1.5alpha2*," - "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, - { "*SSH_Version_Mapper*", - SSH_BUG_SCANNER }, - { "Probe-*", - SSH_BUG_PROBE }, - { NULL, 0 } - }; - - /* process table, return first match */ - for (i = 0; check[i].pat; i++) { - if (match_pattern_list(version, check[i].pat, - strlen(check[i].pat), 0) == 1) { - debug("match: %s pat %s", version, check[i].pat); - datafellows = check[i].bugs; - return; - } - } - debug("no match: %s", version); -} - -#define SEP "," -int -proto_spec(const char *spec) -{ - char *s, *p, *q; - int ret = SSH_PROTO_UNKNOWN; - - if (spec == NULL) - return ret; - 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) - ret |= SSH_PROTO_1_PREFERRED; - ret |= SSH_PROTO_1; - break; - case 2: - ret |= SSH_PROTO_2; - break; - default: - log("ignoring bad proto spec: '%s'.", p); - break; - } - } - xfree(s); - return ret; -} - -char * -compat_cipher_proposal(char *cipher_prop) -{ - Buffer b; - char *orig_prop, *fix_ciphers; - char *cp, *tmp; - - if (!(datafellows & SSH_BUG_BIGENDIANAES)) - return(cipher_prop); - - buffer_init(&b); - tmp = orig_prop = xstrdup(cipher_prop); - while ((cp = strsep(&tmp, ",")) != NULL) { - if (strncmp(cp, "aes", 3) != 0) { - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - buffer_append(&b, cp, strlen(cp)); - } - } - buffer_append(&b, "\0", 1); - fix_ciphers = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - xfree(orig_prop); - debug2("Original cipher proposal: %s", cipher_prop); - debug2("Compat cipher proposal: %s", fix_ciphers); - if (!*fix_ciphers) - fatal("No available ciphers found."); - - return(fix_ciphers); -} diff --git a/usr/src/cmd/ssh/libssh/common/compress.c b/usr/src/cmd/ssh/libssh/common/compress.c deleted file mode 100644 index 6a4965c461..0000000000 --- a/usr/src/cmd/ssh/libssh/common/compress.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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("$OpenBSD: compress.c,v 1.19 2002/03/18 17:31:54 provos Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "log.h" -#include "buffer.h" -#include "zlib.h" -#include "compress.h" - -z_stream incoming_stream; -z_stream outgoing_stream; -static int compress_init_send_called = 0; -static int compress_init_recv_called = 0; -static int inflate_failed = 0; -static int deflate_failed = 0; - -/* - * Initializes compression; level is compression level from 1 to 9 - * (as in gzip). - */ - -void -buffer_compress_init_send(int level) -{ - if (compress_init_send_called == 1) - deflateEnd(&outgoing_stream); - compress_init_send_called = 1; - debug("Enabling compression at level %d.", level); - if (level < 1 || level > 9) - fatal("Bad compression level %d.", level); - deflateInit(&outgoing_stream, level); -} -void -buffer_compress_init_recv(void) -{ - if (compress_init_recv_called == 1) - inflateEnd(&incoming_stream); - compress_init_recv_called = 1; - inflateInit(&incoming_stream); -} - -/* Frees any data structures allocated for compression. */ - -void -buffer_compress_uninit(void) -{ - debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f", - outgoing_stream.total_in, outgoing_stream.total_out, - outgoing_stream.total_in == 0 ? 0.0 : - (double) outgoing_stream.total_out / outgoing_stream.total_in); - debug("compress incoming: raw data %lu, compressed %lu, factor %.2f", - incoming_stream.total_out, incoming_stream.total_in, - incoming_stream.total_out == 0 ? 0.0 : - (double) incoming_stream.total_in / incoming_stream.total_out); - if (compress_init_recv_called == 1 && inflate_failed == 0) - inflateEnd(&incoming_stream); - if (compress_init_send_called == 1 && deflate_failed == 0) - deflateEnd(&outgoing_stream); -} - -/* - * Compresses the contents of input_buffer into output_buffer. All packets - * compressed using this function will form a single compressed data stream; - * however, data will be flushed at the end of every call so that each - * output_buffer can be decompressed independently (but in the appropriate - * order since they together form a single compression stream) by the - * receiver. This appends the compressed data to the output buffer. - */ - -void -buffer_compress(Buffer * input_buffer, Buffer * output_buffer) -{ - u_char buf[4096]; - int status; - - /* This case is not handled below. */ - if (buffer_len(input_buffer) == 0) - return; - - /* Input is the contents of the input buffer. */ - outgoing_stream.next_in = buffer_ptr(input_buffer); - outgoing_stream.avail_in = buffer_len(input_buffer); - - /* Loop compressing until deflate() returns with avail_out != 0. */ - do { - /* Set up fixed-size output buffer. */ - outgoing_stream.next_out = buf; - outgoing_stream.avail_out = sizeof(buf); - - /* Compress as much data into the buffer as possible. */ - status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH); - switch (status) { - case Z_OK: - /* Append compressed data to output_buffer. */ - buffer_append(output_buffer, buf, - sizeof(buf) - outgoing_stream.avail_out); - break; - default: - deflate_failed = 1; - fatal("buffer_compress: deflate returned %d", status); - /* NOTREACHED */ - } - } while (outgoing_stream.avail_out == 0); -} - -/* - * Uncompresses the contents of input_buffer into output_buffer. All packets - * uncompressed using this function will form a single compressed data - * stream; however, data will be flushed at the end of every call so that - * each output_buffer. This must be called for the same size units that the - * buffer_compress was called, and in the same order that buffers compressed - * with that. This appends the uncompressed data to the output buffer. - */ - -void -buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) -{ - u_char buf[4096]; - int status; - - incoming_stream.next_in = buffer_ptr(input_buffer); - incoming_stream.avail_in = buffer_len(input_buffer); - - for (;;) { - /* Set up fixed-size output buffer. */ - incoming_stream.next_out = buf; - incoming_stream.avail_out = sizeof(buf); - - status = inflate(&incoming_stream, Z_PARTIAL_FLUSH); - switch (status) { - case Z_OK: - buffer_append(output_buffer, buf, - sizeof(buf) - incoming_stream.avail_out); - break; - case Z_BUF_ERROR: - /* - * Comments in zlib.h say that we should keep calling - * inflate() until we get an error. This appears to - * be the error that we get. - */ - return; - default: - inflate_failed = 1; - fatal("buffer_uncompress: inflate returned %d", status); - /* NOTREACHED */ - } - } -} diff --git a/usr/src/cmd/ssh/libssh/common/crc32.c b/usr/src/cmd/ssh/libssh/common/crc32.c deleted file mode 100644 index 213b7b8aa8..0000000000 --- a/usr/src/cmd/ssh/libssh/common/crc32.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 u_(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("$OpenBSD: crc32.c,v 1.8 2000/12/19 23:17:56 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "crc32.h" - -static u_int crc32_tab[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d -}; - -/* Return a 32-bit CRC of the contents of the buffer. */ - -u_int -ssh_crc32(const u_char *s, u_int len) -{ - u_int i; - u_int crc32val; - - crc32val = 0; - for (i = 0; i < len; i ++) { - crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); - } - return crc32val; -} diff --git a/usr/src/cmd/ssh/libssh/common/deattack.c b/usr/src/cmd/ssh/libssh/common/deattack.c deleted file mode 100644 index 82afd4f16b..0000000000 --- a/usr/src/cmd/ssh/libssh/common/deattack.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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> - */ - -#include "includes.h" -RCSID("$OpenBSD: deattack.c,v 1.18 2002/03/04 17:27:39 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "deattack.h" -#include "log.h" -#include "crc32.h" -#include "getput.h" -#include "xmalloc.h" -#include "deattack.h" - -/* - * CRC attack detection has a worst-case behaviour that is O(N^2) over - * the number of identical blocks in a packet. This behaviour can be - * exploited to create a limited denial of service attack. - * - * However, because we are dealing with encrypted data, identical - * blocks should only occur every 2^35 maximally-sized packets or so. - * Consequently, we can detect this DoS by looking for identical blocks - * in a packet. - * - * The parameter below determines how many identical blocks we will - * accept in a single packet, trading off between attack detection and - * likelihood of terminating a legitimate connection. A value of 32 - * corresponds to an average of 2^40 messages before an attack is - * misdetected - */ -#define MAX_IDENTICAL 32 - -/* SSH Constants */ -#define SSH_MAXBLOCKS (32 * 1024) -#define SSH_BLOCKSIZE (8) - -/* Hashing constants */ -#define HASH_MINSIZE (8 * 1024) -#define HASH_ENTRYSIZE (2) -#define HASH_FACTOR(x) ((x)*3/2) -#define HASH_UNUSEDCHAR (0xff) -#define HASH_UNUSED (0xffff) -#define HASH_IV (0xfffe) - -#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) - - -/* Hash function (Input keys are cipher results) */ -#define HASH(x) GET_32BIT(x) - -#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE)) - -static void -crc_update(u_int32_t *a, u_int32_t b) -{ - b ^= *a; - *a = ssh_crc32((u_char *) &b, sizeof(b)); -} - -/* detect if a block is used in a particular pattern */ -static int -check_crc(u_char *S, u_char *buf, u_int32_t len, - u_char *IV) -{ - u_int32_t crc; - u_char *c; - - crc = 0; - if (IV && !CMP(S, IV)) { - crc_update(&crc, 1); - crc_update(&crc, 0); - } - for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { - if (!CMP(S, c)) { - crc_update(&crc, 1); - crc_update(&crc, 0); - } else { - crc_update(&crc, 0); - crc_update(&crc, 0); - } - } - return (crc == 0); -} - - -/* Detect a crc32 compensation attack on a packet */ -int -detect_attack(u_char *buf, u_int32_t len, u_char *IV) -{ - static u_int16_t *h = (u_int16_t *) NULL; - static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; - u_int32_t i, j; - u_int32_t l, same; - u_char *c; - u_char *d; - - if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || - len % SSH_BLOCKSIZE != 0) { - fatal("detect_attack: bad length %d", len); - } - for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) - ; - - if (h == NULL) { - debug("Installing crc compensation attack detector."); - n = l; - h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); - } else { - if (l > n) { - n = l; - h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); - } - } - - if (len <= HASH_MINBLOCKS) { - for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { - if (IV && (!CMP(c, IV))) { - if ((check_crc(c, buf, len, IV))) - return (DEATTACK_DETECTED); - else - break; - } - for (d = buf; d < c; d += SSH_BLOCKSIZE) { - if (!CMP(c, d)) { - if ((check_crc(c, buf, len, IV))) - return (DEATTACK_DETECTED); - else - break; - } - } - } - return (DEATTACK_OK); - } - memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); - - if (IV) - h[HASH(IV) & (n - 1)] = HASH_IV; - - for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { - for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; - i = (i + 1) & (n - 1)) { - if (h[i] == HASH_IV) { - if (!CMP(c, IV)) { - if (check_crc(c, buf, len, IV)) - return (DEATTACK_DETECTED); - else - break; - } - } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { - if (++same > MAX_IDENTICAL) - return (DEATTACK_DOS_DETECTED); - if (check_crc(c, buf, len, IV)) - return (DEATTACK_DETECTED); - else - break; - } - } - h[i] = j; - } - return (DEATTACK_OK); -} diff --git a/usr/src/cmd/ssh/libssh/common/dh.c b/usr/src/cmd/ssh/libssh/common/dh.c deleted file mode 100644 index 9293db7bb7..0000000000 --- a/usr/src/cmd/ssh/libssh/common/dh.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2000 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: dh.c,v 1.22 2002/06/27 08:49:44 markus Exp $"); - -#include "xmalloc.h" - -#include <openssl/bn.h> -#include <openssl/dh.h> -#include <openssl/evp.h> - -#include "buffer.h" -#include "cipher.h" -#include "kex.h" -#include "dh.h" -#include "pathnames.h" -#include "log.h" -#include "misc.h" - -static int -parse_prime(int linenum, char *line, struct dhgroup *dhg) -{ - char *cp, *arg; - char *strsize, *gen, *prime; - - cp = line; - arg = strdelim(&cp); - /* Ignore leading whitespace */ - if (*arg == '\0') - arg = strdelim(&cp); - if (!arg || !*arg || *arg == '#') - return 0; - - /* time */ - if (cp == NULL || *arg == '\0') - goto fail; - arg = strsep(&cp, " "); /* type */ - if (cp == NULL || *arg == '\0') - goto fail; - arg = strsep(&cp, " "); /* tests */ - if (cp == NULL || *arg == '\0') - goto fail; - arg = strsep(&cp, " "); /* tries */ - if (cp == NULL || *arg == '\0') - goto fail; - strsize = strsep(&cp, " "); /* size */ - if (cp == NULL || *strsize == '\0' || - (dhg->size = atoi(strsize)) == 0) - goto fail; - /* The whole group is one bit larger */ - dhg->size++; - gen = strsep(&cp, " "); /* gen */ - if (cp == NULL || *gen == '\0') - goto fail; - prime = strsep(&cp, " "); /* prime */ - if (cp != NULL || *prime == '\0') - goto fail; - - if ((dhg->g = BN_new()) == NULL) - fatal("parse_prime: BN_new failed"); - if ((dhg->p = BN_new()) == NULL) - fatal("parse_prime: BN_new failed"); - if (BN_hex2bn(&dhg->g, gen) == 0) - goto failclean; - - if (BN_hex2bn(&dhg->p, prime) == 0) - goto failclean; - - if (BN_num_bits(dhg->p) != dhg->size) - goto failclean; - - return (1); - - failclean: - BN_clear_free(dhg->g); - BN_clear_free(dhg->p); - fail: - error("Bad prime description in line %d", linenum); - return (0); -} - -DH * -choose_dh(int min, int wantbits, int max) -{ - FILE *f; - char line[2048]; - int best, bestcount, which; - int linenum; - struct dhgroup dhg; - - if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL && - (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) { - log("WARNING: %s does not exist, using old modulus", _PATH_DH_MODULI); - return (dh_new_group1()); - } - - linenum = 0; - best = bestcount = 0; - while (fgets(line, sizeof(line), f)) { - linenum++; - if (!parse_prime(linenum, line, &dhg)) - continue; - BN_clear_free(dhg.g); - BN_clear_free(dhg.p); - - if (dhg.size > max || dhg.size < min) - continue; - - if ((dhg.size > wantbits && dhg.size < best) || - (dhg.size > best && best < wantbits)) { - best = dhg.size; - bestcount = 0; - } - if (dhg.size == best) - bestcount++; - } - rewind(f); - - if (bestcount == 0) { - fclose(f); - log("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); - return (NULL); - } - - linenum = 0; - which = arc4random() % bestcount; - while (fgets(line, sizeof(line), f)) { - if (!parse_prime(linenum, line, &dhg)) - continue; - if ((dhg.size > max || dhg.size < min) || - dhg.size != best || - linenum++ != which) { - BN_clear_free(dhg.g); - BN_clear_free(dhg.p); - continue; - } - break; - } - fclose(f); - if (linenum != which+1) - fatal("WARNING: line %d disappeared in %s, giving up", - which, _PATH_DH_PRIMES); - - return (dh_new_group(dhg.g, dhg.p)); -} - -/* diffie-hellman-group1-sha1 */ - -int -dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) -{ - int i; - int n = BN_num_bits(dh_pub); - int bits_set = 0; - - if (dh_pub->neg) { - log("invalid public DH value: negativ"); - return 0; - } - for (i = 0; i <= n; i++) - if (BN_is_bit_set(dh_pub, i)) - bits_set++; - debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); - - /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ - if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1)) - return 1; - log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); - return 0; -} - -void -dh_gen_key(DH *dh, int need) -{ - int i, bits_set = 0, tries = 0; - - if (dh->p == NULL) - fatal("dh_gen_key: dh->p == NULL"); - if (2*need >= BN_num_bits(dh->p)) - fatal("dh_gen_key: group too small: %d (2*need %d)", - BN_num_bits(dh->p), 2*need); - do { - if (dh->priv_key != NULL) - BN_clear_free(dh->priv_key); - if ((dh->priv_key = BN_new()) == NULL) - fatal("dh_gen_key: BN_new failed"); - /* generate a 2*need bits random private exponent */ - if (!BN_rand(dh->priv_key, 2*need, 0, 0)) - fatal("dh_gen_key: BN_rand failed"); - if (DH_generate_key(dh) == 0) - fatal("dh_gen_key: DH_generate_key() failed"); - for (i = 0; i <= BN_num_bits(dh->priv_key); i++) - if (BN_is_bit_set(dh->priv_key, i)) - bits_set++; - debug("dh_gen_key: priv key bits set: %d/%d", - bits_set, BN_num_bits(dh->priv_key)); - if (tries++ > 10) - fatal("dh_gen_key: too many bad keys: giving up"); - } while (!dh_pub_is_valid(dh, dh->pub_key)); -} - -DH * -dh_new_group_asc(const char *gen, const char *modulus) -{ - DH *dh; - - if ((dh = DH_new()) == NULL) - fatal("dh_new_group_asc: DH_new"); - - if (BN_hex2bn(&dh->p, modulus) == 0) - fatal("BN_hex2bn p"); - if (BN_hex2bn(&dh->g, gen) == 0) - fatal("BN_hex2bn g"); - - return (dh); -} - -/* - * This just returns the group, we still need to generate the exchange - * value. - */ - -DH * -dh_new_group(BIGNUM *gen, BIGNUM *modulus) -{ - DH *dh; - - if ((dh = DH_new()) == NULL) - fatal("dh_new_group: DH_new"); - dh->p = modulus; - dh->g = gen; - - return (dh); -} - -DH * -dh_new_group1(void) -{ - static char *gen = "2", *group1 = - "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" - "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" - "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" - "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" - "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" - "FFFFFFFF" "FFFFFFFF"; - - return (dh_new_group_asc(gen, group1)); -} - -/* - * Estimates the group order for a Diffie-Hellman group that has an - * attack complexity approximately the same as O(2**bits). Estimate - * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))) - */ - -int -dh_estimate(int bits) -{ - - if (bits < 64) - return (512); /* O(2**63) */ - if (bits < 128) - return (1024); /* O(2**86) */ - if (bits < 192) - return (2048); /* O(2**116) */ - return (4096); /* O(2**156) */ -} diff --git a/usr/src/cmd/ssh/libssh/common/dispatch.c b/usr/src/cmd/ssh/libssh/common/dispatch.c deleted file mode 100644 index f2bf9b6847..0000000000 --- a/usr/src/cmd/ssh/libssh/common/dispatch.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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: dispatch.c,v 1.15 2002/01/11 13:39:36 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "ssh1.h" -#include "ssh2.h" -#include "log.h" -#include "dispatch.h" -#include "packet.h" -#include "compat.h" - -#define DISPATCH_MIN 0 -#define DISPATCH_MAX 255 - -dispatch_fn *dispatch[DISPATCH_MAX]; - -void -dispatch_protocol_error(int type, u_int32_t seq, void *ctxt) -{ - log("dispatch_protocol_error: type %d seq %u", type, seq); - if (!compat20) - fatal("protocol error"); - packet_start(SSH2_MSG_UNIMPLEMENTED); - packet_put_int(seq); - packet_send(); - packet_write_wait(); -} -void -dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt) -{ - log("dispatch_protocol_ignore: type %d seq %u", type, seq); -} -void -dispatch_init(dispatch_fn *dflt) -{ - u_int i; - for (i = 0; i < DISPATCH_MAX; i++) - dispatch[i] = dflt; -} -void -dispatch_range(u_int from, u_int to, dispatch_fn *fn) -{ - u_int i; - - for (i = from; i <= to; i++) { - if (i >= DISPATCH_MAX) - break; - dispatch[i] = fn; - } -} -void -dispatch_set(int type, dispatch_fn *fn) -{ - dispatch[type] = fn; -} -void -dispatch_run(int mode, int *done, void *ctxt) -{ - for (;;) { - int type; - u_int32_t seqnr; - - if (mode == DISPATCH_BLOCK) { - type = packet_read_seqnr(&seqnr); - } else { - type = packet_read_poll_seqnr(&seqnr); - if (type == SSH_MSG_NONE) - return; - } - if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) - (*dispatch[type])(type, seqnr, ctxt); - else - packet_disconnect("protocol error: rcvd type %d", type); - if (done != NULL && *done) - return; - } -} diff --git a/usr/src/cmd/ssh/libssh/common/engine.c b/usr/src/cmd/ssh/libssh/common/engine.c deleted file mode 100644 index 0541c658df..0000000000 --- a/usr/src/cmd/ssh/libssh/common/engine.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -#include "log.h" -#include "engine.h" - -#define PKCS11_ENGINE "pkcs11" - -/* - * Loads the PKCS#11 engine if the UseOpenSSLEngine is set to yes which is the - * default value. - */ -ENGINE * -pkcs11_engine_load(int use_engine) -{ - ENGINE *e = NULL; - - debug("use_engine is '%s'", use_engine == 1 ? "yes" : "no"); - if (use_engine == 0) - return (NULL); - - ENGINE_load_pk11(); - /* get structural reference */ - if ((e = ENGINE_by_id(PKCS11_ENGINE)) == NULL) { - error("%s engine does not exist", PKCS11_ENGINE); - return (NULL); - } - - /* get functional reference */ - if (ENGINE_init(e) == 0) { - error("can't initialize %s engine", PKCS11_ENGINE); - return (NULL); - } - - debug("%s engine initialized, now setting it as default for " - "RSA, DSA, and symmetric ciphers", PKCS11_ENGINE); - - /* - * Offloading RSA, DSA and symmetric ciphers to the engine is all we - * want. We don't offload Diffie-Helmann since we use longer DH keys - * than supported in ncp/n2cp (2048 bits). And, we don't offload digest - * operations since that would be beneficial if only big packets were - * processed (~8K). However, that's not the case. For example, - * SSH_MSG_CHANNEL_WINDOW_ADJUST messages are always small. Given the - * fact that digest operations are fast in software and the inherent - * overhead of offloading anything to HW is quite big, not offloading - * digests to HW actually makes SSH data transfer faster. - */ - if (!ENGINE_set_default_RSA(e)) { - error("can't use %s engine for RSA", PKCS11_ENGINE); - return (NULL); - } - if (!ENGINE_set_default_DSA(e)) { - error("can't use %s engine for DSA", PKCS11_ENGINE); - return (NULL); - } - if (!ENGINE_set_default_ciphers(e)) { - error("can't use %s engine for symmetric ciphers", - PKCS11_ENGINE); - return (NULL); - } - - debug("%s engine initialization complete", PKCS11_ENGINE); - return (e); -} - -/* - * Finishes the PKCS#11 engine after all remaining structural and functional - * references to the ENGINE structure are freed. - */ -void -pkcs11_engine_finish(void *engine) -{ - ENGINE *e = (ENGINE *)engine; - - debug("in pkcs11_engine_finish(), engine pointer is %p", e); - /* UseOpenSSLEngine was 'no' */ - if (engine == NULL) - return; - - debug("unregistering RSA"); - ENGINE_unregister_RSA(e); - debug("unregistering DSA"); - ENGINE_unregister_DSA(e); - debug("unregistering ciphers"); - ENGINE_unregister_ciphers(e); - - debug("calling ENGINE_finish()"); - ENGINE_finish(engine); - debug("calling ENGINE_remove()"); - ENGINE_remove(engine); - debug("calling ENGINE_free()"); - ENGINE_free(engine); - debug("%s engine finished", PKCS11_ENGINE); -} diff --git a/usr/src/cmd/ssh/libssh/common/entropy.c b/usr/src/cmd/ssh/libssh/common/entropy.c deleted file mode 100644 index c661b74496..0000000000 --- a/usr/src/cmd/ssh/libssh/common/entropy.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2001 Damien Miller. 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 <openssl/rand.h> -#include <openssl/crypto.h> - -#include "ssh.h" -#include "misc.h" -#include "xmalloc.h" -#include "atomicio.h" -#include "pathnames.h" -#include "log.h" - -/* - * Portable OpenSSH PRNG seeding: - * If OpenSSL has not "internally seeded" itself (e.g. pulled data from - * /dev/random), then we execute a "ssh-rand-helper" program which - * collects entropy and writes it to stdout. The child program must - * write at least RANDOM_SEED_SIZE bytes. The child is run with stderr - * attached, so error/debugging output should be visible. - * - * XXX: we should tell the child how many bytes we need. - */ - -RCSID("$Id: entropy.c,v 1.44 2002/06/09 19:41:48 mouring Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifndef OPENSSL_PRNG_ONLY -#define RANDOM_SEED_SIZE 48 -static uid_t original_uid, original_euid; -#endif - -void -seed_rng(void) -{ -#ifndef OPENSSL_PRNG_ONLY - int devnull; - int p[2]; - pid_t pid; - int ret; - unsigned char buf[RANDOM_SEED_SIZE]; - mysig_t old_sigchld; - - if (RAND_status() == 1) { - debug3("RNG is ready, skipping seeding"); - return; - } - - debug3("Seeding PRNG from %s", SSH_RAND_HELPER); - - if ((devnull = open("/dev/null", O_RDWR)) == -1) - fatal("Couldn't open /dev/null: %s", strerror(errno)); - if (pipe(p) == -1) - fatal("pipe: %s", strerror(errno)); - - old_sigchld = mysignal(SIGCHLD, SIG_DFL); - if ((pid = fork()) == -1) - fatal("Couldn't fork: %s", strerror(errno)); - if (pid == 0) { - dup2(devnull, STDIN_FILENO); - dup2(p[1], STDOUT_FILENO); - /* Keep stderr open for errors */ - close(p[0]); - close(p[1]); - close(devnull); - - if (original_uid != original_euid && - ( seteuid(getuid()) == -1 || - setuid(original_uid) == -1) ) { - fprintf(stderr, "(rand child) setuid(%d): %s\n", - original_uid, strerror(errno)); - _exit(1); - } - - execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL); - fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n", - SSH_RAND_HELPER, strerror(errno)); - _exit(1); - } - - close(devnull); - close(p[1]); - - memset(buf, '\0', sizeof(buf)); - ret = atomicio(read, p[0], buf, sizeof(buf)); - if (ret == -1) - fatal("Couldn't read from ssh-rand-helper: %s", - strerror(errno)); - if (ret != sizeof(buf)) - fatal("ssh-rand-helper child produced insufficient data"); - - close(p[0]); - - if (waitpid(pid, &ret, 0) == -1) - fatal("Couldn't wait for ssh-rand-helper completion: %s", - strerror(errno)); - mysignal(SIGCHLD, old_sigchld); - - /* We don't mind if the child exits upon a SIGPIPE */ - if (!WIFEXITED(ret) && - (!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE)) - fatal("ssh-rand-helper terminated abnormally"); - if (WEXITSTATUS(ret) != 0) - fatal("ssh-rand-helper exit with exit status %d", ret); - - RAND_add(buf, sizeof(buf), sizeof(buf)); - memset(buf, '\0', sizeof(buf)); - -#endif /* OPENSSL_PRNG_ONLY */ - if (RAND_status() != 1) - fatal("PRNG is not seeded"); -} - -void -init_rng(void) -{ - /* - * OpenSSL version numbers: MNNFFPPS: major minor fix patch status - * We match major, minor, fix and status (not patch) - */ - if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) - fatal("OpenSSL version mismatch. Built against %lx, you " - "have %lx", OPENSSL_VERSION_NUMBER, SSLeay()); - -#ifndef OPENSSL_PRNG_ONLY - if ((original_uid = getuid()) == -1) - fatal("getuid: %s", strerror(errno)); - if ((original_euid = geteuid()) == -1) - fatal("geteuid: %s", strerror(errno)); -#endif -} - diff --git a/usr/src/cmd/ssh/libssh/common/fatal.c b/usr/src/cmd/ssh/libssh/common/fatal.c deleted file mode 100644 index 0b5038f365..0000000000 --- a/usr/src/cmd/ssh/libssh/common/fatal.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2002 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: fatal.c,v 1.1 2002/02/22 12:20:34 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "log.h" - -/* Fatal messages. This function never returns. */ - -void -fatal(const char *fmt,...) -{ - va_list args; - va_start(args, fmt); - do_log(SYSLOG_LEVEL_FATAL, fmt, args); - va_end(args); - fatal_cleanup(); -} diff --git a/usr/src/cmd/ssh/libssh/common/g11n.c b/usr/src/cmd/ssh/libssh/common/g11n.c deleted file mode 100644 index 558b410c96..0000000000 --- a/usr/src/cmd/ssh/libssh/common/g11n.c +++ /dev/null @@ -1,964 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <errno.h> -#include <locale.h> -#include <langinfo.h> -#include <iconv.h> -#include <ctype.h> -#include <wctype.h> -#include <strings.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include "includes.h" -#include "xmalloc.h" -#include "xlist.h" -#include "compat.h" -#include "log.h" - -#ifdef MIN -#undef MIN -#endif /* MIN */ - -#define MIN(x, y) ((x) < (y) ? (x) : (y)) - -#define LOCALE_PATH "/usr/bin/locale" - -/* two-char country code, '-' and two-char region code */ -#define LANGTAG_MAX 5 - -static int locale_cmp(const void *d1, const void *d2); -static char *g11n_locale2langtag(char *locale); - -static char *do_iconv(iconv_t cd, const char *s, uint_t *lenp, char **err_str); - -/* - * native_codeset records the codeset of the default system locale. - * It is used to convert the contents of file (eg /etc/issue) which is - * supposed to be in the codeset of default system locale. - */ -static char *native_codeset; - -/* - * Convert locale string name into a language tag. The caller is responsible for - * freeing the memory allocated for the result. - */ -static char * -g11n_locale2langtag(char *locale) -{ - char *langtag; - - /* base cases */ - if (!locale || !*locale) - return (NULL); - - if (strcmp(locale, "POSIX") == 0 || strcmp(locale, "C") == 0) - return (xstrdup("i-default")); - - /* punt for language codes which are not exactly 2 letters */ - if (strlen(locale) < 2 || - !isalpha(locale[0]) || - !isalpha(locale[1]) || - (locale[2] != '\0' && - locale[2] != '_' && - locale[2] != '.' && - locale[2] != '@')) - return (NULL); - - - /* we have a primary language sub-tag */ - langtag = (char *)xmalloc(LANGTAG_MAX + 1); - - strncpy(langtag, locale, 2); - langtag[2] = '\0'; - - /* do we have country sub-tag? For example: cs_CZ */ - if (locale[2] == '_') { - if (strlen(locale) < 5 || - !isalpha(locale[3]) || - !isalpha(locale[4]) || - (locale[5] != '\0' && (locale[5] != '.' && - locale[5] != '@'))) { - return (langtag); - } - - /* example: create cs-CZ from cs_CZ */ - if (snprintf(langtag, 6, "%.*s-%.*s", 2, locale, 2, - locale + 3) == 5) - return (langtag); - } - - /* in all other cases we just use the primary language sub-tag */ - return (langtag); -} - -uint_t -g11n_langtag_is_default(char *langtag) -{ - return (strcmp(langtag, "i-default") == 0); -} - -/* - * This lang tag / locale matching function works only for two-character - * language primary sub-tags and two-character country sub-tags. - */ -uint_t -g11n_langtag_matches_locale(char *langtag, char *locale) -{ - /* match "i-default" to the process' current locale if possible */ - if (g11n_langtag_is_default(langtag)) { - if (strcasecmp(locale, "POSIX") == 0 || - strcasecmp(locale, "C") == 0) - return (1); - else - return (0); - } - - /* - * locale must be at least 2 chars long and the lang part must be - * exactly two characters - */ - if (strlen(locale) < 2 || - (!isalpha(locale[0]) || !isalpha(locale[1]) || - (locale[2] != '\0' && locale[2] != '_' && - locale[2] != '.' && locale[2] != '@'))) - return (0); - - /* same thing with the langtag */ - if (strlen(langtag) < 2 || - (!isalpha(langtag[0]) || !isalpha(langtag[1]) || - (langtag[2] != '\0' && langtag[2] != '-'))) - return (0); - - /* primary language sub-tag and the locale's language part must match */ - if (strncasecmp(langtag, locale, 2) != 0) - return (0); - - /* - * primary language sub-tag and the locale's language match, now - * fuzzy check country part - */ - - /* neither langtag nor locale have more than one component */ - if (langtag[2] == '\0' && - (locale[2] == '\0' || locale[2] == '.' || locale[2] == '@')) - return (2); - - /* langtag has only one sub-tag... */ - if (langtag[2] == '\0') - return (1); - - /* locale has no country code... */ - if (locale[2] == '\0' || locale[2] == '.' || locale[2] == '@') - return (1); - - /* langtag has more than one subtag and the locale has a country code */ - - /* ignore second subtag if not two chars */ - if (strlen(langtag) < 5) - return (1); - - if (!isalpha(langtag[3]) || !isalpha(langtag[4]) || - (langtag[5] != '\0' && langtag[5] != '-')) - return (1); - - /* ignore rest of locale if there is no two-character country part */ - if (strlen(locale) < 5) - return (1); - - if (locale[2] != '_' || !isalpha(locale[3]) || !isalpha(locale[4]) || - (locale[5] != '\0' && locale[5] != '.' && locale[5] != '@')) - return (1); - - /* if the country part matches, return 2 */ - if (strncasecmp(&langtag[3], &locale[3], 2) == 0) - return (2); - - return (1); -} - -char * -g11n_getlocale() -{ - /* we have one text domain - always set it */ - (void) textdomain(TEXT_DOMAIN); - - /* if the locale is not set, set it from the env vars */ - if (!setlocale(LC_MESSAGES, NULL)) - (void) setlocale(LC_MESSAGES, ""); - - return (setlocale(LC_MESSAGES, NULL)); -} - -void -g11n_setlocale(int category, const char *locale) -{ - char *curr; - - if (native_codeset == NULL) { - /* set default locale, and record current codeset */ - (void) setlocale(LC_ALL, ""); - curr = nl_langinfo(CODESET); - native_codeset = xstrdup(curr); - } - - /* we have one text domain - always set it */ - (void) textdomain(TEXT_DOMAIN); - - if (!locale) - return; - - if (*locale && ((curr = setlocale(category, NULL))) && - strcmp(curr, locale) == 0) - return; - - /* if <category> is bogus, setlocale() will do nothing */ - (void) setlocale(category, locale); -} - -char ** -g11n_getlocales() -{ - FILE *locale_out; - uint_t n_elems, list_size, long_line = 0; - char **list; - char locale[64]; /* 64 bytes is plenty for locale names */ - - if ((locale_out = popen(LOCALE_PATH " -a", "r")) == NULL) - return (NULL); - - /* - * start with enough room for 65 locales - that's a lot fewer than - * all the locales available for installation, but a lot more than - * what most users will need and install - */ - n_elems = 0; - list_size = 192; - list = (char **) xmalloc(sizeof (char *) * (list_size + 1)); - memset(list, 0, sizeof (char *) * (list_size + 1)); - - while (fgets(locale, sizeof (locale), locale_out)) { - /* skip long locale names (if any) */ - if (!strchr(locale, '\n')) { - long_line = 1; - continue; - } else if (long_line) { - long_line = 0; - continue; - } - - if (strncmp(locale, "iso_8859", 8) == 0) - /* ignore locale names like "iso_8859-1" */ - continue; - - if (n_elems == list_size) { - list_size *= 2; - list = (char **)xrealloc((void *) list, - (list_size + 1) * sizeof (char *)); - memset(&list[n_elems + 1], 0, - sizeof (char *) * (list_size - n_elems + 1)); - } - - *(strchr(locale, '\n')) = '\0'; /* remove the trailing \n */ - list[n_elems++] = xstrdup(locale); - } - - (void) pclose(locale_out); - - if (n_elems == 0) { - xfree(list); - return (NULL); - } - - list[n_elems] = NULL; - - qsort(list, n_elems - 1, sizeof (char *), locale_cmp); - return (list); -} - -char * -g11n_getlangs() -{ - char *locale; - - if (getenv("SSH_LANGS")) - return (xstrdup(getenv("SSH_LANGS"))); - - locale = g11n_getlocale(); - - if (!locale || !*locale) - return (xstrdup("i-default")); - - return (g11n_locale2langtag(locale)); -} - -char * -g11n_locales2langs(char **locale_set) -{ - char **p, **r, **q; - char *langtag, *langs; - int locales, skip; - - for (locales = 0, p = locale_set; p && *p; p++) - locales++; - - r = (char **)xmalloc((locales + 1) * sizeof (char *)); - memset(r, 0, (locales + 1) * sizeof (char *)); - - for (p = locale_set; p && *p && ((p - locale_set) <= locales); p++) { - skip = 0; - if ((langtag = g11n_locale2langtag(*p)) == NULL) - continue; - for (q = r; (q - r) < locales; q++) { - if (!*q) - break; - if (*q && strcmp(*q, langtag) == 0) - skip = 1; - } - if (!skip) - *(q++) = langtag; - else - xfree(langtag); - *q = NULL; - } - - langs = xjoin(r, ','); - g11n_freelist(r); - - return (langs); -} - -static int -sortcmp(const void *d1, const void *d2) -{ - char *s1 = *(char **)d1; - char *s2 = *(char **)d2; - - return (strcmp(s1, s2)); -} - -int -g11n_langtag_match(char *langtag1, char *langtag2) -{ - int len1, len2; - char c1, c2; - - len1 = (strchr(langtag1, '-')) ? - (strchr(langtag1, '-') - langtag1) - : strlen(langtag1); - - len2 = (strchr(langtag2, '-')) ? - (strchr(langtag2, '-') - langtag2) - : strlen(langtag2); - - /* no match */ - if (len1 != len2 || strncmp(langtag1, langtag2, len1) != 0) - return (0); - - c1 = *(langtag1 + len1); - c2 = *(langtag2 + len2); - - /* no country sub-tags - exact match */ - if (c1 == '\0' && c2 == '\0') - return (2); - - /* one langtag has a country sub-tag, the other doesn't */ - if (c1 == '\0' || c2 == '\0') - return (1); - - /* can't happen - both langtags have a country sub-tag */ - if (c1 != '-' || c2 != '-') - return (1); - - /* compare country subtags */ - langtag1 = langtag1 + len1 + 1; - langtag2 = langtag2 + len2 + 1; - - len1 = (strchr(langtag1, '-')) ? - (strchr(langtag1, '-') - langtag1) : strlen(langtag1); - - len2 = (strchr(langtag2, '-')) ? - (strchr(langtag2, '-') - langtag2) : strlen(langtag2); - - if (len1 != len2 || strncmp(langtag1, langtag2, len1) != 0) - return (1); - - /* country tags matched - exact match */ - return (2); -} - -char * -g11n_langtag_set_intersect(char *set1, char *set2) -{ - char **list1, **list2, **list3, **p, **q, **r; - char *set3, *lang_subtag; - uint_t n1, n2, n3; - uint_t do_append; - - list1 = xsplit(set1, ','); - list2 = xsplit(set2, ','); - - for (n1 = 0, p = list1; p && *p; p++, n1++) - ; - for (n2 = 0, p = list2; p && *p; p++, n2++) - ; - - list3 = (char **) xmalloc(sizeof (char *) * (n1 + n2 + 1)); - *list3 = NULL; - - /* - * we must not sort the user langtags - sorting or not the server's - * should not affect the outcome - */ - qsort(list2, n2, sizeof (char *), sortcmp); - - for (n3 = 0, p = list1; p && *p; p++) { - do_append = 0; - for (q = list2; q && *q; q++) { - if (g11n_langtag_match(*p, *q) != 2) continue; - /* append element */ - for (r = list3; (r - list3) <= (n1 + n2); r++) { - do_append = 1; - if (!*r) - break; - if (strcmp(*p, *r) == 0) { - do_append = 0; - break; - } - } - if (do_append && n3 <= (n1 + n2)) { - list3[n3++] = xstrdup(*p); - list3[n3] = NULL; - } - } - } - - for (p = list1; p && *p; p++) { - do_append = 0; - for (q = list2; q && *q; q++) { - if (g11n_langtag_match(*p, *q) != 1) - continue; - - /* append element */ - lang_subtag = xstrdup(*p); - if (strchr(lang_subtag, '-')) - *(strchr(lang_subtag, '-')) = '\0'; - for (r = list3; (r - list3) <= (n1 + n2); r++) { - do_append = 1; - if (!*r) - break; - if (strcmp(lang_subtag, *r) == 0) { - do_append = 0; - break; - } - } - if (do_append && n3 <= (n1 + n2)) { - list3[n3++] = lang_subtag; - list3[n3] = NULL; - } else - xfree(lang_subtag); - } - } - - set3 = xjoin(list3, ','); - xfree_split_list(list1); - xfree_split_list(list2); - xfree_split_list(list3); - - return (set3); -} - -char * -g11n_clnt_langtag_negotiate(char *clnt_langtags, char *srvr_langtags) -{ - char *list, *result; - char **xlist; - - /* g11n_langtag_set_intersect uses xmalloc - should not return NULL */ - list = g11n_langtag_set_intersect(clnt_langtags, srvr_langtags); - - if (!list) - return (NULL); - - xlist = xsplit(list, ','); - - xfree(list); - - if (!xlist || !*xlist) - return (NULL); - - result = xstrdup(*xlist); - xfree_split_list(xlist); - - return (result); -} - -/* - * Compare locales, preferring UTF-8 codesets to others, otherwise doing - * a stright strcmp() - */ -static int -locale_cmp(const void *d1, const void *d2) -{ - char *dot_ptr; - char *s1 = *(char **)d1; - char *s2 = *(char **)d2; - int s1_is_utf8 = 0; - int s2_is_utf8 = 0; - - /* check if s1 is a UTF-8 locale */ - if (((dot_ptr = strchr((char *)s1, '.')) != NULL) && - (*dot_ptr != '\0') && (strncmp(dot_ptr + 1, "UTF-8", 5) == 0) && - (*(dot_ptr + 6) == '\0' || *(dot_ptr + 6) == '@')) { - s1_is_utf8++; - } - - /* check if s2 is a UTF-8 locale */ - if (((dot_ptr = strchr((char *)s2, '.')) != NULL) && - (*dot_ptr != '\0') && (strncmp(dot_ptr + 1, "UTF-8", 5) == 0) && - (*(dot_ptr + 6) == '\0' || *(dot_ptr + 6) == '@')) { - s2_is_utf8++; - } - - /* prefer UTF-8 locales */ - if (s1_is_utf8 && !s2_is_utf8) - return (-1); - - if (s2_is_utf8 && !s1_is_utf8) - return (1); - - /* prefer any locale over the default locales */ - if (strcmp(s1, "C") == 0 || strcmp(s1, "POSIX") == 0 || - strcmp(s1, "common") == 0) { - if (strcmp(s2, "C") != 0 && strcmp(s2, "POSIX") != 0 && - strcmp(s2, "common") != 0) - return (1); - } - - if (strcmp(s2, "C") == 0 || strcmp(s2, "POSIX") == 0 || - strcmp(s2, "common") == 0) { - if (strcmp(s1, "C") != 0 && - strcmp(s1, "POSIX") != 0 && - strcmp(s1, "common") != 0) - return (-1); - } - - return (strcmp(s1, s2)); -} - - -char ** -g11n_langtag_set_locale_set_intersect(char *langtag_set, char **locale_set) -{ - char **langtag_list, **result, **p, **q, **r; - char *s; - uint_t do_append, n_langtags, n_locales, n_results, max_results; - - if (locale_set == NULL) - return (NULL); - - /* count lang tags and locales */ - for (n_locales = 0, p = locale_set; p && *p; p++) - n_locales++; - - n_langtags = ((s = langtag_set) != NULL && *s && *s != ',') ? 1 : 0; - /* count the number of langtags */ - for (; s = strchr(s, ','); s++, n_langtags++) - ; - - qsort(locale_set, n_locales, sizeof (char *), locale_cmp); - - langtag_list = xsplit(langtag_set, ','); - for (n_langtags = 0, p = langtag_list; p && *p; p++, n_langtags++) - ; - - max_results = MIN(n_locales, n_langtags) * 2; - result = (char **) xmalloc(sizeof (char *) * (max_results + 1)); - *result = NULL; - n_results = 0; - - /* more specific matches first */ - for (p = langtag_list; p && *p; p++) { - do_append = 0; - for (q = locale_set; q && *q; q++) { - if (g11n_langtag_matches_locale(*p, *q) == 2) { - do_append = 1; - for (r = result; (r - result) <= - MIN(n_locales, n_langtags); r++) { - if (!*r) - break; - if (strcmp(*q, *r) == 0) { - do_append = 0; - break; - } - } - if (do_append && n_results < max_results) { - result[n_results++] = xstrdup(*q); - result[n_results] = NULL; - } - break; - } - } - } - - for (p = langtag_list; p && *p; p++) { - do_append = 0; - for (q = locale_set; q && *q; q++) { - if (g11n_langtag_matches_locale(*p, *q) == 1) { - do_append = 1; - for (r = result; (r - result) <= - MIN(n_locales, n_langtags); r++) { - if (!*r) - break; - if (strcmp(*q, *r) == 0) { - do_append = 0; - break; - } - } - if (do_append && n_results < max_results) { - result[n_results++] = xstrdup(*q); - result[n_results] = NULL; - } - break; - } - } - } - - xfree_split_list(langtag_list); - - return (result); -} - -char * -g11n_srvr_locale_negotiate(char *clnt_langtags, char **srvr_locales) -{ - char **results, **locales, *result = NULL; - - if (srvr_locales == NULL) - locales = g11n_getlocales(); - else - locales = srvr_locales; - - if ((results = g11n_langtag_set_locale_set_intersect(clnt_langtags, - locales)) == NULL) - goto err; - - if (*results != NULL) - result = xstrdup(*results); - - xfree_split_list(results); - -err: - if (locales != NULL && locales != srvr_locales) - g11n_freelist(locales); - return (result); -} - -/* - * Functions for converting to UTF-8 from the local codeset and - * converting from UTF-8 to the local codeset. - * - * The error_str parameter is an pointer to a char variable where to - * store a string suitable for use with error() or fatal() or friends. - * It is also used for an error indicator when NULL is returned. - * - * If conversion isn't necessary, *error_str is set to NULL, and - * NULL is returned. - * If conversion error occured, *error_str points to an error message, - * and NULL is returned. - */ -char * -g11n_convert_from_utf8(const char *str, uint_t *lenp, char **error_str) -{ - static char *last_codeset; - static iconv_t cd = (iconv_t)-1; - char *codeset; - - *error_str = NULL; - - codeset = nl_langinfo(CODESET); - - if (strcmp(codeset, "UTF-8") == 0) - return (NULL); - - if (last_codeset == NULL || strcmp(codeset, last_codeset) != 0) { - if (last_codeset != NULL) { - xfree(last_codeset); - last_codeset = NULL; - } - if (cd != (iconv_t)-1) - (void) iconv_close(cd); - - if ((cd = iconv_open(codeset, "UTF-8")) == (iconv_t)-1) { - *error_str = gettext("Cannot convert UTF-8 " - "strings to the local codeset"); - return (NULL); - } - last_codeset = xstrdup(codeset); - } - return (do_iconv(cd, str, lenp, error_str)); -} - -char * -g11n_convert_to_utf8(const char *str, uint_t *lenp, - int native, char **error_str) -{ - static char *last_codeset; - static iconv_t cd = (iconv_t)-1; - char *codeset; - - *error_str = NULL; - - if (native) - codeset = native_codeset; - else - codeset = nl_langinfo(CODESET); - - if (strcmp(codeset, "UTF-8") == 0) - return (NULL); - - if (last_codeset == NULL || strcmp(codeset, last_codeset) != 0) { - if (last_codeset != NULL) { - xfree(last_codeset); - last_codeset = NULL; - } - if (cd != (iconv_t)-1) - (void) iconv_close(cd); - - if ((cd = iconv_open("UTF-8", codeset)) == (iconv_t)-1) { - *error_str = gettext("Cannot convert the " - "local codeset strings to UTF-8"); - return (NULL); - } - last_codeset = xstrdup(codeset); - } - return (do_iconv(cd, str, lenp, error_str)); -} - -/* - * Wrapper around iconv() - * - * The caller is responsible for freeing the result. NULL is returned when - * (errno && errno != E2BIG) (i.e., EILSEQ, EINVAL, EBADF). - * The caller must ensure that the input string isn't NULL pointer. - */ -static char * -do_iconv(iconv_t cd, const char *str, uint_t *lenp, char **err_str) -{ - int ilen, olen; - size_t ileft, oleft; - char *ostr, *optr; - const char *istr; - - ilen = *lenp; - olen = ilen + 1; - - ostr = NULL; - for (;;) { - olen *= 2; - oleft = olen; - ostr = optr = xrealloc(ostr, olen); - istr = (const char *)str; - if ((ileft = ilen) == 0) - break; - - if (iconv(cd, &istr, &ileft, &optr, &oleft) != (size_t)-1) { - /* success: generate reset sequence */ - if (iconv(cd, NULL, NULL, - &optr, &oleft) == (size_t)-1 && errno == E2BIG) { - continue; - } - break; - } - /* failed */ - if (errno != E2BIG) { - oleft = olen; - (void) iconv(cd, NULL, NULL, &ostr, &oleft); - xfree(ostr); - *err_str = gettext("Codeset conversion failed"); - return (NULL); - } - } - olen = optr - ostr; - optr = xmalloc(olen + 1); - (void) memcpy(optr, ostr, olen); - xfree(ostr); - - optr[olen] = '\0'; - *lenp = olen; - - return (optr); -} - -/* - * A filter for output string. Control and unprintable characters - * are converted into visible form (eg "\ooo"). - */ -char * -g11n_filter_string(char *s) -{ - int mb_cur_max = MB_CUR_MAX; - int mblen, len; - char *os = s; - wchar_t wc; - char *obuf, *op; - - /* all character may be converted into the form of \ooo */ - obuf = op = xmalloc(strlen(s) * 4 + 1); - - while (*s != '\0') { - mblen = mbtowc(&wc, s, mb_cur_max); - if (mblen <= 0) { - mblen = 1; - wc = (unsigned char)*s; - } - if (!iswprint(wc) && - wc != L'\n' && wc != L'\r' && wc != L'\t') { - /* - * control chars which need to be replaced - * with safe character sequence. - */ - while (mblen != 0) { - op += sprintf(op, "\\%03o", - (unsigned char)*s++); - mblen--; - } - } else { - while (mblen != 0) { - *op++ = *s++; - mblen--; - } - } - } - *op = '\0'; - len = op - obuf + 1; - op = xrealloc(os, len); - (void) memcpy(op, obuf, len); - xfree(obuf); - return (op); -} - -/* - * Once we negotiated with a langtag, server need to map it to a system - * locale. That is done based on the locale supported on the server side. - * We know (with the locale supported on Solaris) how the langtag is - * mapped to. However, from the client point of view, there is no way to - * know exactly what locale(encoding) will be used. - * - * With the bug fix of SSH_BUG_STRING_ENCODING, it is guaranteed that the - * UTF-8 characters always come over the wire, so it is no longer the problem - * as long as both side has the bug fix. However if the server side doesn't - * have the fix, client can't safely perform the code conversion since the - * incoming character encoding is unknown. - * - * To alleviate this situation, we take an empirical approach to find - * encoding from langtag. - * - * If langtag has a subtag, we can directly map the langtag to UTF-8 locale - * (eg en-US can be mapped to en_US.UTF-8) with a few exceptions. - * Certain xx_YY locales don't support UTF-8 encoding (probably due to lack - * of L10N support ..). Those are: - * - * no_NO, no_NY, sr_SP, sr_YU - * - * They all use ISO8859-X encoding. - * - * For those "xx" langtags, some of them can be mapped to "xx.UTF-8", - * but others cannot. So we need to use the "xx" as the locale name. - * Those locales are: - * - * ar, ca, cs, da, et, fi, he, hu, ja, lt, lv, nl, no, pt, sh, th, tr - * - * Their encoding vary. They could be ISO8859-X or EUC or something else. - * So we don't perform code conversion for these langtags. - */ -static const char *non_utf8_langtag[] = { - "no-NO", "no-NY", "sr-SP", "sr-YU", - "ar", "ca", "cs", "da", "et", "fi", "he", "hu", "ja", - "lt", "lv", "nl", "no", "pt", "sh", "th", "tr", NULL}; - -void -g11n_test_langtag(const char *lang, int server) -{ - const char **lp; - - if (datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS) { - /* - * We negotiated with real locale name (not lang tag). - * We shouldn't expect UTF-8, thus shouldn't do code - * conversion. - */ - datafellows |= SSH_BUG_STRING_ENCODING; - return; - } - - if (datafellows & SSH_BUG_STRING_ENCODING) { - if (server) { - /* - * Whatever bug exists in the client side, server - * side has nothing to do, since server has no way - * to know what actual encoding is used on the client - * side. For example, even if we negotiated with - * en_US, client locale could be en_US.ISO8859-X or - * en_US.UTF-8. - */ - return; - } - /* - * We are on the client side. We'll check with known - * locales to see if non-UTF8 characters could come in. - */ - for (lp = non_utf8_langtag; *lp != NULL; lp++) { - if (strcmp(lang, *lp) == 0) - break; - } - if (*lp == NULL) { - debug2("Server is expected to use UTF-8 locale"); - datafellows &= ~SSH_BUG_STRING_ENCODING; - } else { - /* - * Server is expected to use non-UTF8 encoding. - */ - debug2("Enforcing no code conversion: %s", lang); - } - } -} - -/* - * Free all strings in the list and then free the list itself. We know that the - * list ends with a NULL pointer. - */ -void -g11n_freelist(char **list) -{ - int i = 0; - - while (list[i] != NULL) { - xfree(list[i]); - i++; - } - - xfree(list); -} diff --git a/usr/src/cmd/ssh/libssh/common/hostfile.c b/usr/src/cmd/ssh/libssh/common/hostfile.c deleted file mode 100644 index f71463a973..0000000000 --- a/usr/src/cmd/ssh/libssh/common/hostfile.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * 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. - * - * 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 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. - */ - -/* $OpenBSD: hostfile.c,v 1.45 2006/08/03 03:34:42 deraadt Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" - -#include <openssl/hmac.h> -#include <openssl/sha.h> - -#include "packet.h" -#include "xmalloc.h" -#include "match.h" -#include "key.h" -#include "hostfile.h" -#include "log.h" - -/* - * Format of a hashed hostname is <MAGIC><SALT>|<HASHED_HOSTNAME>. <MAGIC> is - * "|1|". As in non-hashed hostnames this whole string is then followed by a - * space, a key type and the key (which is out of scope of this function). - * - * Example what can be in 's': - * - * |1|t17NtsuXSLwP0H0eYdd8vJeNakM=|9XFVPh3jZUrfY6YCWn8Ua5eGZtA= - */ -static int -extract_salt(const char *s, u_int l, char *salt, size_t salt_len) -{ - char *p; - u_char *b64salt; - u_int b64len; - int ret; - - if (l < sizeof(HASH_MAGIC) - 1) { - debug2("extract_salt: string too short"); - return (-1); - } - if (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) { - debug2("extract_salt: invalid magic identifier"); - return (-1); - } - s += sizeof(HASH_MAGIC) - 1; - l -= sizeof(HASH_MAGIC) - 1; - if ((p = memchr(s, HASH_DELIM, l)) == NULL) { - debug2("extract_salt: missing salt termination character"); - return (-1); - } - - b64len = p - s; - /* Sanity check */ - if (b64len == 0 || b64len > 1024) { - debug2("extract_salt: bad encoded salt length %u", b64len); - return (-1); - } - b64salt = xmalloc(1 + b64len); - memcpy(b64salt, s, b64len); - b64salt[b64len] = '\0'; - - ret = __b64_pton(b64salt, (u_char *) salt, salt_len); - xfree(b64salt); - if (ret == -1) { - debug2("extract_salt: salt decode error"); - return (-1); - } - if (ret != SHA_DIGEST_LENGTH) { - debug2("extract_salt: expected salt len %d, got %d", - SHA_DIGEST_LENGTH, ret); - return (-1); - } - - return (0); -} - -char * -host_hash(const char *host, const char *name_from_hostfile, u_int src_len) -{ - const EVP_MD *md = EVP_sha1(); - HMAC_CTX mac_ctx; - char salt[256], result[256], uu_salt[512], uu_result[512]; - static char encoded[1024]; - u_int i, len; - - len = EVP_MD_size(md); - - if (name_from_hostfile == NULL) { - /* Create new salt */ - for (i = 0; i < len; i++) - salt[i] = arc4random(); - } else { - /* Extract salt from known host entry */ - if (extract_salt(name_from_hostfile, src_len, salt, - sizeof(salt)) == -1) - return (NULL); - } - - HMAC_Init(&mac_ctx, salt, len, md); - HMAC_Update(&mac_ctx, (u_char *) host, strlen(host)); - HMAC_Final(&mac_ctx, (u_char *) result, NULL); - HMAC_cleanup(&mac_ctx); - - if (__b64_ntop((u_char *) salt, len, uu_salt, sizeof(uu_salt)) == -1 || - __b64_ntop((u_char *) result, len, uu_result, sizeof(uu_result)) == -1) - fatal("host_hash: __b64_ntop failed"); - - snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, - HASH_DELIM, uu_result); - - return (encoded); -} - -/* - * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the - * pointer over the key. Skips any whitespace at the beginning and at end. - */ - -int -hostfile_read_key(char **cpp, u_int *bitsp, Key *ret) -{ - char *cp; - - /* Skip leading whitespace. */ - for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) - ; - - if (key_read(ret, &cp) != 1) - return 0; - - /* Skip trailing whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - - /* Return results. */ - *cpp = cp; - *bitsp = key_size(ret); - return 1; -} - -static int -hostfile_check_key(int bits, const Key *key, const char *host, const char *filename, int linenum) -{ - if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) - return 1; - if (bits != BN_num_bits(key->rsa->n)) { - log("Warning: %s, line %d: keysize mismatch for host %s: " - "actual %d vs. announced %d.", - filename, linenum, host, BN_num_bits(key->rsa->n), bits); - log("Warning: replace %d with %d in %s, line %d.", - bits, BN_num_bits(key->rsa->n), filename, linenum); - } - return 1; -} - -/* - * Checks whether the given host (which must be in all lowercase) is already - * in the list of our known hosts. Returns HOST_OK if the host is known and - * has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED - * if the host is known but used to have a different host key. - * - * If no 'key' has been specified and a key of type 'keytype' is known - * for the specified host, then HOST_FOUND is returned. - */ - -static HostStatus -check_host_in_hostfile_by_key_or_type(const char *filename, - const char *host, const Key *key, int keytype, Key *found, int *numret) -{ - FILE *f; - char line[8192]; - int linenum = 0; - u_int kbits; - char *cp, *cp2, *hashed_host; - HostStatus end_return; - - debug3("check_host_in_hostfile: filename %s", filename); - - /* Open the file containing the list of known hosts. */ - f = fopen(filename, "r"); - if (!f) - return HOST_NEW; - - /* - * Return value when the loop terminates. This is set to - * HOST_CHANGED if we have seen a different key for the host and have - * not found the proper one. - */ - end_return = HOST_NEW; - - /* Go through the file. */ - while (fgets(line, sizeof(line), f)) { - cp = line; - linenum++; - - /* Skip any leading whitespace, comments and empty lines. */ - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '#' || *cp == '\n') - continue; - - /* Find the end of the host name portion. */ - for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) - ; - - /* Check if the host name matches. */ - if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) { - if (*cp != HASH_DELIM) - continue; - hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); - if (hashed_host == NULL) { - debug("Invalid hashed host line %d of %s", - linenum, filename); - continue; - } - if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0) - continue; - } - - /* Got a match. Skip host name. */ - cp = cp2; - - /* - * Extract the key from the line. This will skip any leading - * whitespace. Ignore badly formatted lines. - */ - if (!hostfile_read_key(&cp, &kbits, found)) - continue; - - if (numret != NULL) - *numret = linenum; - - if (key == NULL) { - /* we found a key of the requested type */ - if (found->type == keytype) { - fclose(f); - return HOST_FOUND; - } - continue; - } - - if (!hostfile_check_key(kbits, found, host, filename, linenum)) - continue; - - /* Check if the current key is the same as the given key. */ - if (key_equal(key, found)) { - /* Ok, they match. */ - debug3("check_host_in_hostfile: match line %d", linenum); - fclose(f); - return HOST_OK; - } - /* - * They do not match. We will continue to go through the - * file; however, we note that we will not return that it is - * new. - */ - end_return = HOST_CHANGED; - } - /* Clear variables and close the file. */ - fclose(f); - - /* - * Return either HOST_NEW or HOST_CHANGED, depending on whether we - * saw a different key for the host. - */ - return end_return; -} - -HostStatus -check_host_in_hostfile(const char *filename, const char *host, const Key *key, - Key *found, int *numret) -{ - if (key == NULL) - fatal("no key to look up"); - return (check_host_in_hostfile_by_key_or_type(filename, host, key, 0, - found, numret)); -} - -int -lookup_key_in_hostfile_by_type(const char *filename, const char *host, - int keytype, Key *found, int *numret) -{ - return (check_host_in_hostfile_by_key_or_type(filename, host, NULL, - keytype, found, numret) == HOST_FOUND); -} - -/* - * Appends an entry to the host file. Returns false if the entry could not - * be appended. - */ - -int -add_host_to_hostfile(const char *filename, const char *host, const Key *key, - int store_hash) -{ - FILE *f; - int success = 0; - char *hashed_host = NULL; - - if (key == NULL) - return 1; /* XXX ? */ - f = fopen(filename, "a"); - if (!f) - return 0; - - if (store_hash) { - if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { - error("add_host_to_hostfile: host_hash failed"); - fclose(f); - return 0; - } - } - fprintf(f, "%s ", store_hash ? hashed_host : host); - - if (key_write(key, f)) { - success = 1; - } else { - error("add_host_to_hostfile: saving key in %s failed", filename); - } - fprintf(f, "\n"); - fclose(f); - return success; -} diff --git a/usr/src/cmd/ssh/libssh/common/kex.c b/usr/src/cmd/ssh/libssh/common/kex.c deleted file mode 100644 index 0eb9e780fa..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kex.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $"); - -#include <locale.h> - -#include <openssl/crypto.h> - -#include "ssh2.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "packet.h" -#include "compat.h" -#include "cipher.h" -#include "kex.h" -#include "key.h" -#include "log.h" -#include "mac.h" -#include "match.h" -#include "dispatch.h" -#include "g11n.h" - -#ifdef GSSAPI -#include "ssh-gss.h" -#endif - -#define KEX_COOKIE_LEN 16 - -char *session_lang = NULL; - - -/* prototype */ -static void kex_do_hook(Kex *kex); -static void kex_kexinit_finish(Kex *); -static void kex_choose_conf(Kex *); - -/* put algorithm proposal into buffer */ -static -void -kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) -{ - int i; - - buffer_clear(b); - /* - * add a dummy cookie, the cookie will be overwritten by - * kex_send_kexinit(), each time a kexinit is set - */ - for (i = 0; i < KEX_COOKIE_LEN; i++) - buffer_put_char(b, 0); - for (i = 0; i < PROPOSAL_MAX; i++) - buffer_put_cstring(b, proposal[i]); - buffer_put_char(b, 0); /* first_kex_packet_follows */ - buffer_put_int(b, 0); /* uint32 reserved */ -} - -/* parse buffer and return algorithm proposal */ -static -char ** -kex_buf2prop(Buffer *raw, int *first_kex_follows) -{ - Buffer b; - int i; - char **proposal; - - proposal = xmalloc(PROPOSAL_MAX * sizeof(char *)); - - buffer_init(&b); - buffer_append(&b, buffer_ptr(raw), buffer_len(raw)); - /* skip cookie */ - for (i = 0; i < KEX_COOKIE_LEN; i++) - buffer_get_char(&b); - /* extract kex init proposal strings */ - for (i = 0; i < PROPOSAL_MAX; i++) { - proposal[i] = buffer_get_string(&b,NULL); - debug2("kex_parse_kexinit: %s", proposal[i]); - } - /* first kex follows / reserved */ - i = buffer_get_char(&b); - if (first_kex_follows != NULL) - *first_kex_follows = i; - debug2("kex_parse_kexinit: first_kex_follows %d ", i); - i = buffer_get_int(&b); - debug2("kex_parse_kexinit: reserved %d ", i); - buffer_free(&b); - return proposal; -} - -static -void -kex_prop_free(char **proposal) -{ - int i; - - for (i = 0; i < PROPOSAL_MAX; i++) - xfree(proposal[i]); - xfree(proposal); -} - -static void -kex_protocol_error(int type, u_int32_t seq, void *ctxt) -{ - error("Hm, kex protocol error: type %d seq %u", type, seq); -} - -static void -kex_reset_dispatch(void) -{ -#ifdef ALTPRIVSEP - /* unprivileged sshd has a kex packet handler that must not be reset */ - debug3("kex_reset_dispatch -- should we dispatch_set(KEXINIT) here? %d && !%d", - packet_is_server(), packet_is_monitor()); - if (packet_is_server() && !packet_is_monitor()) { - debug3("kex_reset_dispatch -- skipping dispatch_set(KEXINIT) in unpriv proc"); - return; - } -#endif /* ALTPRIVSEP */ - - dispatch_range(SSH2_MSG_TRANSPORT_MIN, - SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); - dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); -} - -void -kex_finish(Kex *kex) -{ - kex_reset_dispatch(); - - packet_start(SSH2_MSG_NEWKEYS); - packet_send(); - /* packet_write_wait(); */ - debug("SSH2_MSG_NEWKEYS sent"); - -#ifdef ALTPRIVSEP - if (packet_is_monitor()) - goto skip_newkeys; -#endif /* ALTPRIVSEP */ - debug("expecting SSH2_MSG_NEWKEYS"); - packet_read_expect(SSH2_MSG_NEWKEYS); - packet_check_eom(); - debug("SSH2_MSG_NEWKEYS received"); -#ifdef ALTPRIVSEP -skip_newkeys: -#endif /* ALTPRIVSEP */ - - kex->done = 1; - kex->initial_kex_done = 1; /* never to be cleared once set */ - buffer_clear(&kex->peer); - /* buffer_clear(&kex->my); */ - kex->flags &= ~KEX_INIT_SENT; - xfree(kex->name); - kex->name = NULL; -} - -void -kex_send_kexinit(Kex *kex) -{ - u_int32_t rand = 0; - u_char *cookie; - int i; - - if (kex == NULL) { - error("kex_send_kexinit: no kex, cannot rekey"); - return; - } - if (kex->flags & KEX_INIT_SENT) { - debug("KEX_INIT_SENT"); - return; - } - kex->done = 0; - - /* update my proposal -- e.g., add/remove GSS kexalgs */ - kex_do_hook(kex); - - /* generate a random cookie */ - if (buffer_len(&kex->my) < KEX_COOKIE_LEN) - fatal("kex_send_kexinit: kex proposal too short"); - cookie = buffer_ptr(&kex->my); - for (i = 0; i < KEX_COOKIE_LEN; i++) { - if (i % 4 == 0) - rand = arc4random(); - cookie[i] = rand; - rand >>= 8; - } - packet_start(SSH2_MSG_KEXINIT); - packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); - packet_send(); - debug("SSH2_MSG_KEXINIT sent"); - kex->flags |= KEX_INIT_SENT; -} - -void -kex_input_kexinit(int type, u_int32_t seq, void *ctxt) -{ - char *ptr; - u_int dlen; - int i; - Kex *kex = (Kex *)ctxt; - - debug("SSH2_MSG_KEXINIT received"); - if (kex == NULL) - fatal("kex_input_kexinit: no kex, cannot rekey"); - - ptr = packet_get_raw(&dlen); - buffer_append(&kex->peer, ptr, dlen); - - /* discard packet */ - for (i = 0; i < KEX_COOKIE_LEN; i++) - packet_get_char(); - for (i = 0; i < PROPOSAL_MAX; i++) - xfree(packet_get_string(NULL)); - (void) packet_get_char(); - (void) packet_get_int(); - packet_check_eom(); - - kex_kexinit_finish(kex); -} - -/* - * This is for GSS keyex, where actual KEX offer can change at rekey - * time due to credential expiration/renewal... - */ -static -void -kex_do_hook(Kex *kex) -{ - char **prop; - - if (kex->kex_hook == NULL) - return; - - /* Unmarshall my proposal, let the hook modify it, remarshall it */ - prop = kex_buf2prop(&kex->my, NULL); - buffer_clear(&kex->my); - (kex->kex_hook)(kex, prop); - kex_prop2buf(&kex->my, prop); - kex_prop_free(prop); -} - -/* Initiate the key exchange by sending the SSH2_MSG_KEXINIT message. */ -void -kex_start(Kex *kex) -{ - kex_send_kexinit(kex); - kex_reset_dispatch(); -} - -/* - * Allocate a key exchange structure and populate it with a proposal we are - * going to use. This function does not start the actual key exchange. - */ -Kex * -kex_setup(const char *host, char *proposal[PROPOSAL_MAX], Kex_hook_func hook) -{ - Kex *kex; - - kex = xmalloc(sizeof(*kex)); - memset(kex, 0, sizeof(*kex)); - buffer_init(&kex->peer); - buffer_init(&kex->my); - - kex->kex_hook = hook; /* called by kex_send_kexinit() */ - - if (host != NULL && *host != '\0') - kex->serverhost = xstrdup(host); - else - kex->server = 1; - - kex_prop2buf(&kex->my, proposal); - - return kex; -} - -static void -kex_kexinit_finish(Kex *kex) -{ - if (!(kex->flags & KEX_INIT_SENT)) - kex_send_kexinit(kex); - - kex_choose_conf(kex); - - if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && - kex->kex[kex->kex_type] != NULL) - (kex->kex[kex->kex_type])(kex); - else - fatal("Unsupported key exchange %d", kex->kex_type); -} - -static void -choose_lang(char **lang, char *client, char *server) -{ - if (datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS) - *lang = match_list(client, server, NULL); - else - *lang = g11n_srvr_locale_negotiate(client, NULL); -} - -/* - * Make the message clear enough so that if this happens the user can figure out - * the workaround of changing the Ciphers option. - */ -#define CLIENT_ERR_MSG \ - "Client and server could not agree on a common cipher:\n" \ - " client: %s\n" \ - " server: %s\n" \ - "\n" \ - "The client cipher list can be controlled using the \"Ciphers\" option, \n" \ - "see ssh_config(4) for more information. The \"-o Ciphers=<cipher-list>\"\n" \ - "option may be used to temporarily override the ciphers the client\n" \ - "offers." - -/* - * The server side message goes to syslogd and we do not want to send multiline - * messages there. What's more, the server side notification may be shorter - * since we expect that an administrator will deal with that, not the user. - */ -#define SERVER_ERR_MSG \ - "Client and server could not agree on a common cipher: client \"%s\", " \ - "server \"%s\". The server cipher list can be controlled using the " \ - "\"Ciphers\" option, see sshd_config(4) for more information." - -static void -choose_enc(int is_server, Enc *enc, char *client, char *server) -{ - char *name = match_list(client, server, NULL); - - if (name == NULL) { - if (is_server == 1) - fatal(SERVER_ERR_MSG, client, server); - else - fatal(CLIENT_ERR_MSG, client, server); - } - - if ((enc->cipher = cipher_by_name(name)) == NULL) - fatal("matching cipher is not supported: %s", name); - - enc->name = name; - enc->enabled = 0; - enc->iv = NULL; - enc->key = NULL; - enc->key_len = cipher_keylen(enc->cipher); - enc->block_size = cipher_blocksize(enc->cipher); -} - -static void -choose_mac(Mac *mac, char *client, char *server) -{ - char *name = match_list(client, server, NULL); - if (name == NULL) - fatal("no matching mac found: client %s server %s", - client, server); - if (mac_setup(mac, name) < 0) - fatal("unsupported mac %s", name); - /* truncate the key */ - if (datafellows & SSH_BUG_HMAC) - mac->key_len = 16; - mac->name = name; - mac->key = NULL; - mac->enabled = 0; -} - -static void -choose_comp(Comp *comp, char *client, char *server) -{ - char *name = match_list(client, server, NULL); - if (name == NULL) - fatal("no matching comp found: client %s server %s", client, server); - if (strcmp(name, "zlib") == 0) { - comp->type = 1; - } else if (strcmp(name, "none") == 0) { - comp->type = 0; - } else { - fatal("unsupported comp %s", name); - } - comp->name = name; -} - -static void -choose_kex(Kex *k, char *client, char *server) -{ - k->name = match_list(client, server, NULL); - if (k->name == NULL) - fatal("no common kex alg: client '%s', server '%s'", client, - server); - /* XXX Finish 3.6/7 merge of kex stuff -- choose_kex() done */ - if (strcmp(k->name, KEX_DH1) == 0) { - k->kex_type = KEX_DH_GRP1_SHA1; - } else if (strcmp(k->name, KEX_DHGEX) == 0) { - k->kex_type = KEX_DH_GEX_SHA1; -#ifdef GSSAPI - } else if (strncmp(k->name, KEX_GSS_SHA1, sizeof(KEX_GSS_SHA1)-1) == 0) { - k->kex_type = KEX_GSS_GRP1_SHA1; -#endif - } else - fatal("bad kex alg %s", k->name); -} - -static void -choose_hostkeyalg(Kex *k, char *client, char *server) -{ - char *hostkeyalg = match_list(client, server, NULL); - if (hostkeyalg == NULL) - fatal("no hostkey alg"); - k->hostkey_type = key_type_from_name(hostkeyalg); - if (k->hostkey_type == KEY_UNSPEC) - fatal("bad hostkey alg '%s'", hostkeyalg); - xfree(hostkeyalg); -} - -static int -proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) -{ - static int check[] = { - PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1 - }; - int *idx; - char *p; - - for (idx = &check[0]; *idx != -1; idx++) { - if ((p = strchr(my[*idx], ',')) != NULL) - *p = '\0'; - if ((p = strchr(peer[*idx], ',')) != NULL) - *p = '\0'; - if (strcmp(my[*idx], peer[*idx]) != 0) { - debug2("proposal mismatch: my %s peer %s", - my[*idx], peer[*idx]); - return (0); - } - } - debug2("proposals match"); - return (1); -} - -static void -kex_choose_conf(Kex *kex) -{ - Newkeys *newkeys; - char **my, **peer; - char **cprop, **sprop; - char *p_langs_c2s, *p_langs_s2c; /* peer's langs */ - char *plangs = NULL; /* peer's langs*/ - char *mlangs = NULL; /* my langs */ - int nenc, nmac, ncomp; - int mode; - int ctos; /* direction: if true client-to-server */ - int need; - int first_kex_follows, type; - - my = kex_buf2prop(&kex->my, NULL); - peer = kex_buf2prop(&kex->peer, &first_kex_follows); - - if (kex->server) { - cprop=peer; - sprop=my; - } else { - cprop=my; - sprop=peer; - } - - /* Algorithm Negotiation */ - for (mode = 0; mode < MODE_MAX; mode++) { - newkeys = xmalloc(sizeof(*newkeys)); - memset(newkeys, 0, sizeof(*newkeys)); - kex->newkeys[mode] = newkeys; - ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); - nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; - nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; - ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; - choose_enc(kex->server, &newkeys->enc, cprop[nenc], sprop[nenc]); - choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]); - choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); - debug("kex: %s %s %s %s", - ctos ? "client->server" : "server->client", - newkeys->enc.name, - newkeys->mac.name, - newkeys->comp.name); - } - choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); - choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], - sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); - need = 0; - for (mode = 0; mode < MODE_MAX; mode++) { - newkeys = kex->newkeys[mode]; - if (need < newkeys->enc.key_len) - need = newkeys->enc.key_len; - if (need < newkeys->enc.block_size) - need = newkeys->enc.block_size; - if (need < newkeys->mac.key_len) - need = newkeys->mac.key_len; - } - /* XXX need runden? */ - kex->we_need = need; - - /* ignore the next message if the proposals do not match */ - if (first_kex_follows && !proposals_match(my, peer) && - !(datafellows & SSH_BUG_FIRSTKEX)) { - type = packet_read(); - debug2("skipping next packet (type %u)", type); - } - - /* Language/locale negotiation -- not worth doing on re-key */ - - if (!kex->initial_kex_done) { - p_langs_c2s = peer[PROPOSAL_LANG_CTOS]; - p_langs_s2c = peer[PROPOSAL_LANG_STOC]; - debug("Peer sent proposed langtags, ctos: %s", p_langs_c2s); - debug("Peer sent proposed langtags, stoc: %s", p_langs_s2c); - plangs = NULL; - - /* We propose the same langs for each protocol direction */ - mlangs = my[PROPOSAL_LANG_STOC]; - debug("We proposed langtags, ctos: %s", my[PROPOSAL_LANG_CTOS]); - debug("We proposed langtags, stoc: %s", mlangs); - - /* - * Why oh why did they bother with negotiating langs for - * each protocol direction?! - * - * The semantics of this are vaguely specified, but one can - * imagine using one language (locale) for the whole session and - * a different one for message localization (e.g., 'en_US.UTF-8' - * overall and 'fr' for messages). Weird? Maybe. But lang - * tags don't include codeset info, like locales do... - * - * So, server-side we want: - * - setlocale(LC_ALL, c2s_locale); - * and - * - setlocale(LC_MESSAGES, s2c_locale); - * - * Client-side we don't really care. But we could do: - * - * - when very verbose, tell the use what lang the server's - * messages are in, if left out in the protocol - * - when sending messages to the server, and if applicable, we - * can localize them according to the language negotiated for - * that direction. - * - * But for now we do nothing on the client side. - */ - if ((p_langs_c2s && *p_langs_c2s) && !(p_langs_s2c && *p_langs_s2c)) - plangs = p_langs_c2s; - else if ((p_langs_s2c && *p_langs_s2c) && !(p_langs_c2s && *p_langs_c2s)) - plangs = p_langs_s2c; - else - plangs = p_langs_c2s; - - if (kex->server) { - if (plangs && mlangs && *plangs && *mlangs) { - char *locale; - - g11n_test_langtag(plangs, 1); - - choose_lang(&locale, plangs, mlangs); - if (locale) { - g11n_setlocale(LC_ALL, locale); - debug("Negotiated main locale: %s", locale); - packet_send_debug("Negotiated main locale: %s", locale); - xfree(locale); - } - if (plangs != p_langs_s2c && - p_langs_s2c && *p_langs_s2c) { - choose_lang(&locale, p_langs_s2c, mlangs); - if (locale) { - g11n_setlocale(LC_MESSAGES, locale); - debug("Negotiated messages locale: %s", locale); - packet_send_debug("Negotiated " - "messages locale: %s", locale); - xfree(locale); - } - } - } - } - else { - if (plangs && mlangs && *plangs && *mlangs && - !(datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS)) { - char *lang; - lang = g11n_clnt_langtag_negotiate(mlangs, plangs); - if (lang) { - session_lang = lang; - debug("Negotiated lang: %s", lang); - g11n_test_langtag(lang, 0); - } - } - } - } - - kex_prop_free(my); - kex_prop_free(peer); -} - -static u_char * -derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret) -{ - Buffer b; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - char c = id; - int have; - int mdsz = EVP_MD_size(evp_md); - u_char *digest = xmalloc(roundup(need, mdsz)); - - buffer_init(&b); - buffer_put_bignum2(&b, shared_secret); - - /* K1 = HASH(K || H || "A" || session_id) */ - EVP_DigestInit(&md, evp_md); - if (!(datafellows & SSH_BUG_DERIVEKEY)) - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestUpdate(&md, hash, mdsz); - EVP_DigestUpdate(&md, &c, 1); - EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); - EVP_DigestFinal(&md, digest, NULL); - - /* - * expand key: - * Kn = HASH(K || H || K1 || K2 || ... || Kn-1) - * Key = K1 || K2 || ... || Kn - */ - for (have = mdsz; need > have; have += mdsz) { - EVP_DigestInit(&md, evp_md); - if (!(datafellows & SSH_BUG_DERIVEKEY)) - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestUpdate(&md, hash, mdsz); - EVP_DigestUpdate(&md, digest, have); - EVP_DigestFinal(&md, digest + have, NULL); - } - buffer_free(&b); -#ifdef DEBUG_KEX - fprintf(stderr, "key '%c'== ", c); - dump_digest("key", digest, need); -#endif - return digest; -} - -Newkeys *current_keys[MODE_MAX]; - -#define NKEYS 6 -void -kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) -{ - u_char *keys[NKEYS]; - int i, mode, ctos; - - for (i = 0; i < NKEYS; i++) - keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); - - debug2("kex_derive_keys"); - for (mode = 0; mode < MODE_MAX; mode++) { - current_keys[mode] = kex->newkeys[mode]; - kex->newkeys[mode] = NULL; - ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); - current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; - current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; - current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; - } -} - -Newkeys * -kex_get_newkeys(int mode) -{ - Newkeys *ret; - - ret = current_keys[mode]; - current_keys[mode] = NULL; - return ret; -} - -#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) -void -dump_digest(char *msg, u_char *digest, int len) -{ - int i; - - fprintf(stderr, "%s\n", msg); - for (i = 0; i< len; i++) { - fprintf(stderr, "%02x", digest[i]); - if (i%32 == 31) - fprintf(stderr, "\n"); - else if (i%8 == 7) - fprintf(stderr, " "); - } - fprintf(stderr, "\n"); -} -#endif diff --git a/usr/src/cmd/ssh/libssh/common/kexdh.c b/usr/src/cmd/ssh/libssh/common/kexdh.c deleted file mode 100644 index b15ecd2c5b..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexdh.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/crypto.h> -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "ssh2.h" - -u_char * -kex_dh_hash( - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - u_char *serverhostkeyblob, int sbloblen, - BIGNUM *client_dh_pub, - BIGNUM *server_dh_pub, - BIGNUM *shared_secret) -{ - Buffer b; - static u_char digest[EVP_MAX_MD_SIZE]; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - - buffer_init(&b); - buffer_put_cstring(&b, client_version_string); - buffer_put_cstring(&b, server_version_string); - - /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ - buffer_put_int(&b, ckexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, ckexinit, ckexinitlen); - buffer_put_int(&b, skexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, skexinit, skexinitlen); - - buffer_put_string(&b, serverhostkeyblob, sbloblen); - buffer_put_bignum2(&b, client_dh_pub); - buffer_put_bignum2(&b, server_dh_pub); - buffer_put_bignum2(&b, shared_secret); - -#ifdef DEBUG_KEX - buffer_dump(&b); -#endif - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestFinal(&md, digest, NULL); - - buffer_free(&b); - -#ifdef DEBUG_KEX - dump_digest("hash", digest, EVP_MD_size(evp_md)); -#endif - return digest; -} diff --git a/usr/src/cmd/ssh/libssh/common/kexdhc.c b/usr/src/cmd/ssh/libssh/common/kexdhc.c deleted file mode 100644 index 1c75f8449f..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexdhc.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/crypto.h> -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "ssh2.h" - -void -kexdh_client(Kex *kex) -{ - BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; - DH *dh; - Key *server_host_key; - u_char *server_host_key_blob = NULL, *signature = NULL; - u_char *kbuf, *hash; - u_int klen, kout, slen, sbloblen; - - /* generate and send 'e', client DH public key */ - dh = dh_new_group1(); - dh_gen_key(dh, kex->we_need * 8); - packet_start(SSH2_MSG_KEXDH_INIT); - packet_put_bignum2(dh->pub_key); - packet_send(); - - debug("sending SSH2_MSG_KEXDH_INIT"); -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - - debug("expecting SSH2_MSG_KEXDH_REPLY"); - packet_read_expect(SSH2_MSG_KEXDH_REPLY); - - /* key, cert */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); - - /* DH paramter f, server public DH key */ - if ((dh_server_pub = BN_new()) == NULL) - fatal("dh_server_pub == NULL"); - packet_get_bignum2(dh_server_pub); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_server_pub= "); - BN_print_fp(stderr, dh_server_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_server_pub)); -#endif - - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); - - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_server_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexdh_client: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - /* calc and verify H */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - server_host_key_blob, sbloblen, - dh->pub_key, - dh_server_pub, - shared_secret - ); - xfree(server_host_key_blob); - BN_clear_free(dh_server_pub); - DH_free(dh); - - if (key_verify(server_host_key, signature, slen, hash, 20) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - xfree(signature); - - /* save session id */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); -} diff --git a/usr/src/cmd/ssh/libssh/common/kexdhs.c b/usr/src/cmd/ssh/libssh/common/kexdhs.c deleted file mode 100644 index 5e14b1333f..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexdhs.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/crypto.h> -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "ssh2.h" - -void -kexdh_server(Kex *kex) -{ - BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - DH *dh; - Key *server_host_key; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, kout; - u_int slen; - - /* generate server DH public key */ - dh = dh_new_group1(); - dh_gen_key(dh, kex->we_need * 8); - - debug("expecting SSH2_MSG_KEXDH_INIT"); - packet_read_expect(SSH2_MSG_KEXDH_INIT); - - if (kex->load_host_key == NULL) - fatal("Cannot load hostkey"); - server_host_key = kex->load_host_key(kex->hostkey_type); - if (server_host_key == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - - /* key, cert */ - if ((dh_client_pub = BN_new()) == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); - packet_check_eom(); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_client_pub= "); - BN_print_fp(stderr, dh_client_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_client_pub)); -#endif - -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_client_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexdh_server: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); - - /* calc H */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), - server_host_key_blob, sbloblen, - dh_client_pub, - dh->pub_key, - shared_secret - ); - BN_clear_free(dh_client_pub); - - /* save session id := H */ - /* XXX hashlen depends on KEX */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - - /* sign H */ - /* XXX hashlen depends on KEX */ - key_sign(server_host_key, &signature, &slen, hash, 20); - - /* destroy_sensitive_data(); */ - - /* send server hostkey, DH pubkey 'f' and singed H */ - packet_start(SSH2_MSG_KEXDH_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_bignum2(dh->pub_key); /* f */ - packet_put_string(signature, slen); - packet_send(); - - xfree(signature); - xfree(server_host_key_blob); - /* have keys, free DH */ - DH_free(dh); - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); -} diff --git a/usr/src/cmd/ssh/libssh/common/kexgex.c b/usr/src/cmd/ssh/libssh/common/kexgex.c deleted file mode 100644 index 3652e1c020..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexgex.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2000 Niels Provos. All rights reserved. - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "ssh2.h" -#include "compat.h" - -u_char * -kexgex_hash( - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - u_char *serverhostkeyblob, int sbloblen, - int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen, - BIGNUM *client_dh_pub, - BIGNUM *server_dh_pub, - BIGNUM *shared_secret) -{ - Buffer b; - static u_char digest[EVP_MAX_MD_SIZE]; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - - buffer_init(&b); - buffer_put_cstring(&b, client_version_string); - buffer_put_cstring(&b, server_version_string); - - /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ - buffer_put_int(&b, ckexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, ckexinit, ckexinitlen); - buffer_put_int(&b, skexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, skexinit, skexinitlen); - - buffer_put_string(&b, serverhostkeyblob, sbloblen); - if (min == -1 || max == -1) - buffer_put_int(&b, wantbits); - else { - buffer_put_int(&b, min); - buffer_put_int(&b, wantbits); - buffer_put_int(&b, max); - } - buffer_put_bignum2(&b, prime); - buffer_put_bignum2(&b, gen); - buffer_put_bignum2(&b, client_dh_pub); - buffer_put_bignum2(&b, server_dh_pub); - buffer_put_bignum2(&b, shared_secret); - -#ifdef DEBUG_KEXDH - buffer_dump(&b); -#endif - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestFinal(&md, digest, NULL); - - buffer_free(&b); - -#ifdef DEBUG_KEXDH - dump_digest("hash", digest, EVP_MD_size(evp_md)); -#endif - return digest; -} diff --git a/usr/src/cmd/ssh/libssh/common/kexgexc.c b/usr/src/cmd/ssh/libssh/common/kexgexc.c deleted file mode 100644 index 5fddebaed9..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexgexc.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2000 Niels Provos. All rights reserved. - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "ssh2.h" -#include "compat.h" - -void -kexgex_client(Kex *kex) -{ - BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; - BIGNUM *p = NULL, *g = NULL; - Key *server_host_key; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int klen, kout, slen, sbloblen; - int min, max, nbits; - DH *dh; - - nbits = dh_estimate(kex->we_need * 8); - - if (datafellows & SSH_OLD_DHGEX) { - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); - - /* Old GEX request */ - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); - packet_put_int(nbits); - min = DH_GRP_MIN; - max = DH_GRP_MAX; - } else { - debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); - - /* New GEX request */ - min = DH_GRP_MIN; - max = DH_GRP_MAX; - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); - packet_put_int(min); - packet_put_int(nbits); - packet_put_int(max); - } -#ifdef DEBUG_KEXDH - fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", - min, nbits, max); -#endif - packet_send(); - - debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); - - if ((p = BN_new()) == NULL) - fatal("BN_new"); - packet_get_bignum2(p); - if ((g = BN_new()) == NULL) - fatal("BN_new"); - packet_get_bignum2(g); - packet_check_eom(); - - if (BN_num_bits(p) < min || BN_num_bits(p) > max) - fatal("DH_GEX group out of range: %d !< %d !< %d", - min, BN_num_bits(p), max); - - dh = dh_new_group(g, p); - dh_gen_key(dh, kex->we_need * 8); - -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - - debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); - /* generate and send 'e', client DH public key */ - packet_start(SSH2_MSG_KEX_DH_GEX_INIT); - packet_put_bignum2(dh->pub_key); - packet_send(); - - debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); - - /* key, cert */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); - - /* DH paramter f, server public DH key */ - if ((dh_server_pub = BN_new()) == NULL) - fatal("dh_server_pub == NULL"); - packet_get_bignum2(dh_server_pub); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_server_pub= "); - BN_print_fp(stderr, dh_server_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_server_pub)); -#endif - - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); - - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_server_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexgex_client: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - if (datafellows & SSH_OLD_DHGEX) - min = max = -1; - - /* calc and verify H */ - hash = kexgex_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - server_host_key_blob, sbloblen, - min, nbits, max, - dh->p, dh->g, - dh->pub_key, - dh_server_pub, - shared_secret - ); - /* have keys, free DH */ - DH_free(dh); - xfree(server_host_key_blob); - BN_clear_free(dh_server_pub); - - if (key_verify(server_host_key, signature, slen, hash, 20) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - xfree(signature); - - /* save session id */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - - kex_finish(kex); -} diff --git a/usr/src/cmd/ssh/libssh/common/kexgexs.c b/usr/src/cmd/ssh/libssh/common/kexgexs.c deleted file mode 100644 index b0bd4e3272..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexgexs.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2000 Niels Provos. All rights reserved. - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "ssh2.h" -#include "compat.h" - -void -kexgex_server(Kex *kex) -{ - BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - Key *server_host_key; - DH *dh; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, kout, slen; - int min = -1, max = -1, nbits = -1, type; - - if (kex->load_host_key == NULL) - fatal("Cannot load hostkey"); - server_host_key = kex->load_host_key(kex->hostkey_type); - if (server_host_key == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - - type = packet_read(); - switch (type) { - case SSH2_MSG_KEX_DH_GEX_REQUEST: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); - min = packet_get_int(); - nbits = packet_get_int(); - max = packet_get_int(); - min = MAX(DH_GRP_MIN, min); - max = MIN(DH_GRP_MAX, max); - break; - case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - nbits = packet_get_int(); - min = DH_GRP_MIN; - max = DH_GRP_MAX; - /* unused for old GEX */ - break; - default: - fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); - } - packet_check_eom(); - - if (max < min || nbits < min || max < nbits) - fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", - min, nbits, max); - - /* Contact privileged parent */ - dh = choose_dh(min, nbits, max); - if (dh == NULL) - packet_disconnect("Protocol error: no matching DH grp found"); - - debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); - packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); - packet_put_bignum2(dh->p); - packet_put_bignum2(dh->g); - packet_send(); - - /* flush */ - packet_write_wait(); - - /* Compute our exchange value in parallel with the client */ - dh_gen_key(dh, kex->we_need * 8); - - debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); - - /* key, cert */ - if ((dh_client_pub = BN_new()) == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); - packet_check_eom(); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_client_pub= "); - BN_print_fp(stderr, dh_client_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_client_pub)); -#endif - -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_client_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexgex_server: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); - - if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) - min = max = -1; - - /* calc H */ /* XXX depends on 'kex' */ - hash = kexgex_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), - server_host_key_blob, sbloblen, - min, nbits, max, - dh->p, dh->g, - dh_client_pub, - dh->pub_key, - shared_secret - ); - BN_clear_free(dh_client_pub); - - /* save session id := H */ - /* XXX hashlen depends on KEX */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - - /* sign H */ - /* XXX hashlen depends on KEX */ - key_sign(server_host_key, &signature, &slen, hash, 20); - - /* destroy_sensitive_data(); */ - - /* send server hostkey, DH pubkey 'f' and singed H */ - debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); - packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_bignum2(dh->pub_key); /* f */ - packet_put_string(signature, slen); - packet_send(); - - xfree(signature); - xfree(server_host_key_blob); - /* have keys, free DH */ - DH_free(dh); - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - - kex_finish(kex); -} diff --git a/usr/src/cmd/ssh/libssh/common/kexgssc.c b/usr/src/cmd/ssh/libssh/common/kexgssc.c deleted file mode 100644 index 60c91ed57b..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexgssc.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - - -#include "includes.h" - -#ifdef GSSAPI - -#include <openssl/crypto.h> -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "canohost.h" -#include "ssh2.h" -#include "ssh-gss.h" - -extern char *xxx_host; - -Gssctxt *xxx_gssctxt; - -static void kexgss_verbose_cleanup(void *arg); - -void -kexgss_client(Kex *kex) -{ - gss_buffer_desc gssbuf, send_tok, recv_tok, msg_tok; - gss_buffer_t token_ptr; - gss_OID mech = GSS_C_NULL_OID; - Gssctxt *ctxt = NULL; - OM_uint32 maj_status, min_status, smaj_status, smin_status; - unsigned int klen, kout; - DH *dh; - BIGNUM *dh_server_pub = 0; - BIGNUM *shared_secret = 0; - Key *server_host_key = NULL; - unsigned char *kbuf; - unsigned char *hash; - unsigned char *server_host_key_blob = NULL; - char *msg, *lang; - int type = 0; - int first = 1; - uint_t sbloblen = 0; - uint_t strlen; - - /* Map the negotiated kex name to a mech OID */ - ssh_gssapi_oid_of_kexname(kex->name, &mech); - if (mech == GSS_C_NULL_OID) - fatal("Couldn't match the negotiated GSS key exchange"); - - ssh_gssapi_build_ctx(&ctxt, 1, mech); - - /* This code should match that in ssh_dh1_client */ - - /* Step 1 - e is dh->pub_key */ - dh = dh_new_group1(); - dh_gen_key(dh, kex->we_need * 8); - - /* This is f, we initialise it now to make life easier */ - dh_server_pub = BN_new(); - if (dh_server_pub == NULL) { - fatal("dh_server_pub == NULL"); - } - - token_ptr = GSS_C_NO_BUFFER; - - recv_tok.value = NULL; - recv_tok.length = 0; - - do { - debug("Calling gss_init_sec_context"); - - maj_status = ssh_gssapi_init_ctx(ctxt, xxx_host, - kex->options.gss_deleg_creds, token_ptr, &send_tok); - - if (GSS_ERROR(maj_status)) { - ssh_gssapi_error(ctxt, "performing GSS-API protected " - "SSHv2 key exchange"); - (void) gss_release_buffer(&min_status, &send_tok); - packet_disconnect("A GSS-API error occurred during " - "GSS-API protected SSHv2 key exchange\n"); - } - - /* If we've got an old receive buffer get rid of it */ - if (token_ptr != GSS_C_NO_BUFFER) { - /* We allocated recv_tok */ - xfree(recv_tok.value); - recv_tok.value = NULL; - recv_tok.length = 0; - token_ptr = GSS_C_NO_BUFFER; - } - - if (maj_status == GSS_S_COMPLETE) { - /* If mutual state flag is not true, kex fails */ - if (!(ctxt->flags & GSS_C_MUTUAL_FLAG)) { - fatal("Mutual authentication failed"); - } - /* If integ avail flag is not true kex fails */ - if (!(ctxt->flags & GSS_C_INTEG_FLAG)) { - fatal("Integrity check failed"); - } - } - - /* - * If we have data to send, then the last message that we - * received cannot have been a 'complete'. - */ - if (send_tok.length != 0) { - if (first) { - packet_start(SSH2_MSG_KEXGSS_INIT); - packet_put_string(send_tok.value, - send_tok.length); - packet_put_bignum2(dh->pub_key); - first = 0; - } else { - packet_start(SSH2_MSG_KEXGSS_CONTINUE); - packet_put_string(send_tok.value, - send_tok.length); - } - (void) gss_release_buffer(&min_status, &send_tok); - packet_send(); - packet_write_wait(); - - - /* - * If we've sent them data, they'd better be polite and - * reply. - */ - -next_packet: - /* - * We need to catch connection closing w/o error - * tokens or messages so we can tell the user - * _something_ more useful than "Connection - * closed by ..." - * - * We use a fatal cleanup function as that's - * all, really, that we can do for now. - */ - fatal_add_cleanup(kexgss_verbose_cleanup, NULL); - type = packet_read(); - fatal_remove_cleanup(kexgss_verbose_cleanup, NULL); - switch (type) { - case SSH2_MSG_KEXGSS_HOSTKEY: - debug("Received KEXGSS_HOSTKEY"); - server_host_key_blob = - packet_get_string(&sbloblen); - server_host_key = - key_from_blob(server_host_key_blob, - sbloblen); - goto next_packet; /* there MUSt be another */ - break; - case SSH2_MSG_KEXGSS_CONTINUE: - debug("Received GSSAPI_CONTINUE"); - if (maj_status == GSS_S_COMPLETE) - packet_disconnect("Protocol error: " - "received GSS-API context token " - "though the context was already " - "established"); - recv_tok.value = packet_get_string(&strlen); - recv_tok.length = strlen; /* u_int vs. size_t */ - break; - case SSH2_MSG_KEXGSS_COMPLETE: - debug("Received GSSAPI_COMPLETE"); - packet_get_bignum2(dh_server_pub); - msg_tok.value = packet_get_string(&strlen); - msg_tok.length = strlen; /* u_int vs. size_t */ - - /* Is there a token included? */ - if (packet_get_char()) { - recv_tok.value = - packet_get_string(&strlen); - /* u_int/size_t */ - recv_tok.length = strlen; - } - if (recv_tok.length > 0 && - maj_status == GSS_S_COMPLETE) { - packet_disconnect("Protocol error: " - "received GSS-API context token " - "though the context was already " - "established"); - } else if (recv_tok.length == 0 && - maj_status == GSS_S_CONTINUE_NEEDED) { - /* No token included */ - packet_disconnect("Protocol error: " - "did not receive expected " - "GSS-API context token"); - } - break; - case SSH2_MSG_KEXGSS_ERROR: - smaj_status = packet_get_int(); - smin_status = packet_get_int(); - msg = packet_get_string(NULL); - lang = packet_get_string(NULL); - xfree(lang); - error("Server had a GSS-API error; the " - "connection will close (%d/%d):\n%s", - smaj_status, smin_status, msg); - error("Use the GssKeyEx option to disable " - "GSS-API key exchange and try again."); - packet_disconnect("The server had a GSS-API " - "error during GSS-API protected SSHv2 " - "key exchange\n"); - break; - default: - packet_disconnect("Protocol error: " - "didn't expect packet type %d", type); - } - if (recv_tok.value) - token_ptr = &recv_tok; - } else { - /* No data, and not complete */ - if (maj_status != GSS_S_COMPLETE) { - fatal("Not complete, and no token output"); - } - } - } while (maj_status == GSS_S_CONTINUE_NEEDED); - - /* - * We _must_ have received a COMPLETE message in reply from the - * server, which will have set dh_server_pub and msg_tok. - */ - if (type != SSH2_MSG_KEXGSS_COMPLETE) - fatal("Expected SSH2_MSG_KEXGSS_COMPLETE never arrived"); - if (maj_status != GSS_S_COMPLETE) - fatal("Internal error in GSS-API protected SSHv2 key exchange"); - - /* Check f in range [1, p-1] */ - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - /* compute K=f^x mod p */ - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_server_pub, dh); - - shared_secret = BN_new(); - BN_bin2bn(kbuf, kout, shared_secret); - (void) memset(kbuf, 0, klen); - xfree(kbuf); - - /* The GSS hash is identical to the DH one */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - server_host_key_blob, sbloblen, /* server host key */ - dh->pub_key, /* e */ - dh_server_pub, /* f */ - shared_secret); /* K */ - - gssbuf.value = hash; - gssbuf.length = 20; - - /* Verify that H matches the token we just got. */ - if ((maj_status = gss_verify_mic(&min_status, ctxt->context, &gssbuf, - &msg_tok, NULL))) { - packet_disconnect("Hash's MIC didn't verify"); - } - - if (server_host_key && kex->accept_host_key != NULL) - (void) kex->accept_host_key(server_host_key); - - DH_free(dh); - - xxx_gssctxt = ctxt; /* for gss keyex w/ mic userauth */ - - /* save session id */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - (void) memcpy(kex->session_id, hash, kex->session_id_len); - } - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); -} - -/* ARGSUSED */ -static -void -kexgss_verbose_cleanup(void *arg) -{ - error("The GSS-API protected key exchange has failed without " - "indication\nfrom the server, possibly due to misconfiguration " - "of the server."); - error("Use the GssKeyEx option to disable GSS-API key exchange " - "and try again."); -} - -#endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/libssh/common/kexgsss.c b/usr/src/cmd/ssh/libssh/common/kexgsss.c deleted file mode 100644 index 9ee8b630bb..0000000000 --- a/usr/src/cmd/ssh/libssh/common/kexgsss.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" - -#ifdef GSSAPI - -#include <openssl/crypto.h> -#include <openssl/bn.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "compat.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" -#include "ssh2.h" -#include "ssh-gss.h" -#include "auth.h" - -Gssctxt *xxx_gssctxt; -extern Authctxt *x_authctxt; - -static void kex_gss_send_error(Gssctxt *ctxt); - -void -kexgss_server(Kex *kex) -{ - OM_uint32 maj_status, min_status; - gss_buffer_desc gssbuf, send_tok, recv_tok, msg_tok; - Gssctxt *ctxt = NULL; - unsigned int klen, kout; - unsigned int sbloblen = 0; - unsigned char *kbuf, *hash; - unsigned char *server_host_key_blob = NULL; - DH *dh; - Key *server_host_key = NULL; - BIGNUM *shared_secret = NULL; - BIGNUM *dh_client_pub = NULL; - int type = 0; - uint_t slen; - gss_OID oid; - - /* - * Load host key to advertise in a SSH_MSG_KEXGSS_HOSTKEY packet - * -- unlike KEX_DH/KEX_GEX no host key, no problem since it's - * the GSS-API that provides for server host authentication. - */ - if (kex->load_host_key != NULL && - !(datafellows & SSH_BUG_GSSKEX_HOSTKEY)) - server_host_key = kex->load_host_key(kex->hostkey_type); - if (server_host_key != NULL) - key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); - - - /* Initialise GSSAPI */ - - ssh_gssapi_oid_of_kexname(kex->name, &oid); - if (oid == GSS_C_NULL_OID) { - fatal("Couldn't match the negotiated GSS key exchange"); - } - - ssh_gssapi_build_ctx(&xxx_gssctxt, 0, oid); - - ctxt = xxx_gssctxt; - - do { - debug("Wait SSH2_MSG_GSSAPI_INIT"); - type = packet_read(); - switch (type) { - case SSH2_MSG_KEXGSS_INIT: - if (dh_client_pub != NULL) - fatal("Received KEXGSS_INIT after " - "initialising"); - recv_tok.value = packet_get_string(&slen); - recv_tok.length = slen; /* int vs. size_t */ - - dh_client_pub = BN_new(); - - if (dh_client_pub == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); - - /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ - if (sbloblen) { - packet_start(SSH2_MSG_KEXGSS_HOSTKEY); - packet_put_string(server_host_key_blob, - sbloblen); - packet_send(); - packet_write_wait(); - } - break; - case SSH2_MSG_KEXGSS_CONTINUE: - recv_tok.value = packet_get_string(&slen); - recv_tok.length = slen; /* int vs. size_t */ - break; - default: - packet_disconnect("Protocol error: didn't expect " - "packet type %d", type); - } - - maj_status = ssh_gssapi_accept_ctx(ctxt, &recv_tok, &send_tok); - - xfree(recv_tok.value); /* We allocated this, not gss */ - - if (dh_client_pub == NULL) - fatal("No client public key"); - - if (maj_status == GSS_S_CONTINUE_NEEDED) { - debug("Sending GSSAPI_CONTINUE"); - packet_start(SSH2_MSG_KEXGSS_CONTINUE); - packet_put_string(send_tok.value, send_tok.length); - packet_send(); - packet_write_wait(); - (void) gss_release_buffer(&min_status, &send_tok); - } - } while (maj_status == GSS_S_CONTINUE_NEEDED); - - if (GSS_ERROR(maj_status)) { - kex_gss_send_error(ctxt); - if (send_tok.length > 0) { - packet_start(SSH2_MSG_KEXGSS_CONTINUE); - packet_put_string(send_tok.value, send_tok.length); - packet_send(); - packet_write_wait(); - (void) gss_release_buffer(&min_status, &send_tok); - } - fatal("accept_ctx died"); - } - - debug("gss_complete"); - if (!(ctxt->flags & GSS_C_MUTUAL_FLAG)) - fatal("Mutual authentication flag wasn't set"); - - if (!(ctxt->flags & GSS_C_INTEG_FLAG)) - fatal("Integrity flag wasn't set"); - - dh = dh_new_group1(); - dh_gen_key(dh, kex->we_need * 8); - - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_client_pub, dh); - - shared_secret = BN_new(); - BN_bin2bn(kbuf, kout, shared_secret); - (void) memset(kbuf, 0, klen); - xfree(kbuf); - - /* The GSSAPI hash is identical to the Diffie Helman one */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), - server_host_key_blob, sbloblen, - dh_client_pub, - dh->pub_key, - shared_secret); - - BN_free(dh_client_pub); - - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - (void) memcpy(kex->session_id, hash, kex->session_id_len); - } else if (x_authctxt != NULL && x_authctxt->success) { - ssh_gssapi_storecreds(ctxt, x_authctxt); - } - - /* Should fix kex_dh_hash to output hash length */ - gssbuf.length = 20; /* yes, it's always 20 (SHA-1) */ - gssbuf.value = hash; /* and it's static constant storage */ - - if (GSS_ERROR(ssh_gssapi_get_mic(ctxt, &gssbuf, &msg_tok))) { - kex_gss_send_error(ctxt); - fatal("Couldn't get MIC"); - } - - packet_start(SSH2_MSG_KEXGSS_COMPLETE); - packet_put_bignum2(dh->pub_key); - packet_put_string((char *)msg_tok.value, msg_tok.length); - (void) gss_release_buffer(&min_status, &msg_tok); - - if (send_tok.length != 0) { - packet_put_char(1); /* true */ - packet_put_string((char *)send_tok.value, send_tok.length); - (void) gss_release_buffer(&min_status, &send_tok); - } else { - packet_put_char(0); /* false */ - } - packet_send(); - packet_write_wait(); - - DH_free(dh); - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); -} - -static void -kex_gss_send_error(Gssctxt *ctxt) { - char *errstr; - OM_uint32 maj, min; - - errstr = ssh_gssapi_last_error(ctxt, &maj, &min); - if (errstr) { - packet_start(SSH2_MSG_KEXGSS_ERROR); - packet_put_int(maj); - packet_put_int(min); - packet_put_cstring(errstr); - packet_put_cstring(""); - packet_send(); - packet_write_wait(); - /* XXX - We should probably log the error locally here */ - xfree(errstr); - } -} -#endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/libssh/common/key.c b/usr/src/cmd/ssh/libssh/common/key.c deleted file mode 100644 index 8ee2583d93..0000000000 --- a/usr/src/cmd/ssh/libssh/common/key.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * 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, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "includes.h" -RCSID("$OpenBSD: key.c,v 1.49 2002/09/09 14:54:14 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/evp.h> - -#include "xmalloc.h" -#include "key.h" -#include "rsa.h" -#include "ssh-dss.h" -#include "ssh-rsa.h" -#include "uuencode.h" -#include "buffer.h" -#include "bufaux.h" -#include "log.h" - -Key * -key_new(int type) -{ - Key *k; - RSA *rsa; - DSA *dsa; - k = xmalloc(sizeof(*k)); - k->type = type; - k->flags = 0; - k->dsa = NULL; - k->rsa = NULL; - switch (k->type) { - case KEY_RSA1: - case KEY_RSA: - if ((rsa = RSA_new()) == NULL) - fatal("key_new: RSA_new failed"); - if ((rsa->n = BN_new()) == NULL) - fatal("key_new: BN_new failed"); - if ((rsa->e = BN_new()) == NULL) - fatal("key_new: BN_new failed"); - k->rsa = rsa; - break; - case KEY_DSA: - if ((dsa = DSA_new()) == NULL) - fatal("key_new: DSA_new failed"); - if ((dsa->p = BN_new()) == NULL) - fatal("key_new: BN_new failed"); - if ((dsa->q = BN_new()) == NULL) - fatal("key_new: BN_new failed"); - if ((dsa->g = BN_new()) == NULL) - fatal("key_new: BN_new failed"); - if ((dsa->pub_key = BN_new()) == NULL) - fatal("key_new: BN_new failed"); - k->dsa = dsa; - break; - case KEY_UNSPEC: - break; - default: - fatal("key_new: bad key type %d", k->type); - break; - } - return k; -} - -Key * -key_new_private(int type) -{ - Key *k = key_new(type); - switch (k->type) { - case KEY_RSA1: - case KEY_RSA: - if ((k->rsa->d = BN_new()) == NULL) - fatal("key_new_private: BN_new failed"); - if ((k->rsa->iqmp = BN_new()) == NULL) - fatal("key_new_private: BN_new failed"); - if ((k->rsa->q = BN_new()) == NULL) - fatal("key_new_private: BN_new failed"); - if ((k->rsa->p = BN_new()) == NULL) - fatal("key_new_private: BN_new failed"); - if ((k->rsa->dmq1 = BN_new()) == NULL) - fatal("key_new_private: BN_new failed"); - if ((k->rsa->dmp1 = BN_new()) == NULL) - fatal("key_new_private: BN_new failed"); - break; - case KEY_DSA: - if ((k->dsa->priv_key = BN_new()) == NULL) - fatal("key_new_private: BN_new failed"); - break; - case KEY_UNSPEC: - break; - default: - break; - } - return k; -} - -void -key_free(Key *k) -{ - switch (k->type) { - case KEY_RSA1: - case KEY_RSA: - if (k->rsa != NULL) - RSA_free(k->rsa); - k->rsa = NULL; - break; - case KEY_DSA: - if (k->dsa != NULL) - DSA_free(k->dsa); - k->dsa = NULL; - break; - case KEY_UNSPEC: - break; - default: - fatal("key_free: bad key type %d", k->type); - break; - } - xfree(k); -} -int -key_equal(const Key *a, const Key *b) -{ - if (a == NULL || b == NULL || a->type != b->type) - return 0; - switch (a->type) { - case KEY_RSA1: - case KEY_RSA: - return a->rsa != NULL && b->rsa != NULL && - BN_cmp(a->rsa->e, b->rsa->e) == 0 && - BN_cmp(a->rsa->n, b->rsa->n) == 0; - break; - case KEY_DSA: - return a->dsa != NULL && b->dsa != NULL && - BN_cmp(a->dsa->p, b->dsa->p) == 0 && - BN_cmp(a->dsa->q, b->dsa->q) == 0 && - BN_cmp(a->dsa->g, b->dsa->g) == 0 && - BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; - break; - default: - fatal("key_equal: bad key type %d", a->type); - break; - } - return 0; -} - -static u_char * -key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) -{ - const EVP_MD *md = NULL; - EVP_MD_CTX ctx; - u_char *blob = NULL; - u_char *retval = NULL; - u_int len = 0; - int nlen, elen; - - *dgst_raw_length = 0; - - switch (dgst_type) { - case SSH_FP_MD5: - md = EVP_md5(); - break; - case SSH_FP_SHA1: - md = EVP_sha1(); - break; - default: - fatal("key_fingerprint_raw: bad digest type %d", - dgst_type); - } - switch (k->type) { - case KEY_RSA1: - nlen = BN_num_bytes(k->rsa->n); - elen = BN_num_bytes(k->rsa->e); - len = nlen + elen; - blob = xmalloc(len); - BN_bn2bin(k->rsa->n, blob); - BN_bn2bin(k->rsa->e, blob + nlen); - break; - case KEY_DSA: - case KEY_RSA: - key_to_blob(k, &blob, &len); - break; - case KEY_UNSPEC: - return retval; - break; - default: - fatal("key_fingerprint_raw: bad key type %d", k->type); - break; - } - if (blob != NULL) { - retval = xmalloc(EVP_MAX_MD_SIZE); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, blob, len); - EVP_DigestFinal(&ctx, retval, dgst_raw_length); - memset(blob, 0, len); - xfree(blob); - } else { - fatal("key_fingerprint_raw: blob is null"); - } - return retval; -} - -static char * -key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) -{ - char *retval; - int i; - - retval = xmalloc(dgst_raw_len * 3 + 1); - retval[0] = '\0'; - for (i = 0; i < dgst_raw_len; i++) { - char hex[4]; - snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); - strlcat(retval, hex, dgst_raw_len * 3); - } - retval[(dgst_raw_len * 3) - 1] = '\0'; - return retval; -} - -static char * -key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) -{ - char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; - char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', - 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; - u_int i, j = 0, rounds, seed = 1; - char *retval; - - rounds = (dgst_raw_len / 2) + 1; - retval = xmalloc(sizeof(char) * (rounds*6)); - retval[j++] = 'x'; - for (i = 0; i < rounds; i++) { - u_int idx0, idx1, idx2, idx3, idx4; - if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { - idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + - seed) % 6; - idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; - idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + - (seed / 6)) % 6; - retval[j++] = vowels[idx0]; - retval[j++] = consonants[idx1]; - retval[j++] = vowels[idx2]; - if ((i + 1) < rounds) { - idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; - idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; - retval[j++] = consonants[idx3]; - retval[j++] = '-'; - retval[j++] = consonants[idx4]; - seed = ((seed * 5) + - ((((u_int)(dgst_raw[2 * i])) * 7) + - ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; - } - } else { - idx0 = seed % 6; - idx1 = 16; - idx2 = seed / 6; - retval[j++] = vowels[idx0]; - retval[j++] = consonants[idx1]; - retval[j++] = vowels[idx2]; - } - } - retval[j++] = 'x'; - retval[j++] = '\0'; - return retval; -} - -char * -key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) -{ - char *retval = NULL; - u_char *dgst_raw; - u_int dgst_raw_len; - - dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); - if (!dgst_raw) - fatal("key_fingerprint: null from key_fingerprint_raw()"); - switch (dgst_rep) { - case SSH_FP_HEX: - retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); - break; - case SSH_FP_BUBBLEBABBLE: - retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); - break; - default: - fatal("key_fingerprint_ex: bad digest representation %d", - dgst_rep); - break; - } - memset(dgst_raw, 0, dgst_raw_len); - xfree(dgst_raw); - return retval; -} - -/* - * Reads a multiple-precision integer in decimal from the buffer, and advances - * the pointer. The integer must already be initialized. This function is - * permitted to modify the buffer. This leaves *cpp to point just beyond the - * last processed (and maybe modified) character. Note that this may modify - * the buffer containing the number. - */ -static int -read_bignum(char **cpp, BIGNUM * value) -{ - char *cp = *cpp; - int old; - - /* Skip any leading whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - - /* Check that it begins with a decimal digit. */ - if (*cp < '0' || *cp > '9') - return 0; - - /* Save starting position. */ - *cpp = cp; - - /* Move forward until all decimal digits skipped. */ - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - - /* Save the old terminating character, and replace it by \0. */ - old = *cp; - *cp = 0; - - /* Parse the number. */ - if (BN_dec2bn(&value, *cpp) == 0) - return 0; - - /* Restore old terminating character. */ - *cp = old; - - /* Move beyond the number and return success. */ - *cpp = cp; - return 1; -} - -static int -write_bignum(FILE *f, BIGNUM *num) -{ - char *buf = BN_bn2dec(num); - if (buf == NULL) { - error("write_bignum: BN_bn2dec() failed"); - return 0; - } - fprintf(f, " %s", buf); - OPENSSL_free(buf); - return 1; -} - -/* returns 1 ok, -1 error */ -int -key_read(Key *ret, char **cpp) -{ - Key *k; - int success = -1; - char *cp, *space; - int len, n, type; - u_int bits; - u_char *blob; - - cp = *cpp; - - switch (ret->type) { - case KEY_RSA1: - /* Get number of bits. */ - if (*cp < '0' || *cp > '9') - return -1; /* Bad bit count... */ - for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) - bits = 10 * bits + *cp - '0'; - if (bits == 0) - return -1; - *cpp = cp; - /* Get public exponent, public modulus. */ - if (!read_bignum(cpp, ret->rsa->e)) - return -1; - if (!read_bignum(cpp, ret->rsa->n)) - return -1; - success = 1; - break; - case KEY_UNSPEC: - case KEY_RSA: - case KEY_DSA: - space = strchr(cp, ' '); - if (space == NULL) { - debug3("key_read: no space"); - return -1; - } - *space = '\0'; - type = key_type_from_name(cp); - *space = ' '; - if (type == KEY_UNSPEC) { - debug3("key_read: no key found"); - return -1; - } - cp = space+1; - if (*cp == '\0') { - debug3("key_read: short string"); - return -1; - } - if (ret->type == KEY_UNSPEC) { - ret->type = type; - } else if (ret->type != type) { - /* is a key, but different type */ - debug3("key_read: type mismatch"); - return -1; - } - len = 2*strlen(cp); - blob = xmalloc(len); - n = uudecode(cp, blob, len); - if (n < 0) { - error("key_read: uudecode %s failed", cp); - xfree(blob); - return -1; - } - k = key_from_blob(blob, n); - xfree(blob); - if (k == NULL) { - error("key_read: key_from_blob %s failed", cp); - return -1; - } - if (k->type != type) { - error("key_read: type mismatch: encoding error"); - key_free(k); - return -1; - } -/*XXXX*/ - if (ret->type == KEY_RSA) { - if (ret->rsa != NULL) - RSA_free(ret->rsa); - ret->rsa = k->rsa; - k->rsa = NULL; - success = 1; -#ifdef DEBUG_PK - RSA_print_fp(stderr, ret->rsa, 8); -#endif - } else { - if (ret->dsa != NULL) - DSA_free(ret->dsa); - ret->dsa = k->dsa; - k->dsa = NULL; - success = 1; -#ifdef DEBUG_PK - DSA_print_fp(stderr, ret->dsa, 8); -#endif - } -/*XXXX*/ - key_free(k); - if (success != 1) - break; - /* advance cp: skip whitespace and data */ - while (*cp == ' ' || *cp == '\t') - cp++; - while (*cp != '\0' && *cp != ' ' && *cp != '\t') - cp++; - *cpp = cp; - break; - default: - fatal("key_read: bad key type: %d", ret->type); - break; - } - return success; -} - -int -key_write(const Key *key, FILE *f) -{ - int n, success = 0; - u_int len, bits = 0; - u_char *blob; - char *uu; - - if (key->type == KEY_RSA1 && key->rsa != NULL) { - /* size of modulus 'n' */ - bits = BN_num_bits(key->rsa->n); - fprintf(f, "%u", bits); - if (write_bignum(f, key->rsa->e) && - write_bignum(f, key->rsa->n)) { - success = 1; - } else { - error("key_write: failed for RSA key"); - } - } else if ((key->type == KEY_DSA && key->dsa != NULL) || - (key->type == KEY_RSA && key->rsa != NULL)) { - key_to_blob(key, &blob, &len); - uu = xmalloc(2*len); - n = uuencode(blob, len, uu, 2*len); - if (n > 0) { - fprintf(f, "%s %s", key_ssh_name(key), uu); - success = 1; - } - xfree(blob); - xfree(uu); - } - return success; -} - -char * -key_type(Key *k) -{ - switch (k->type) { - case KEY_RSA1: - return "RSA1"; - break; - case KEY_RSA: - return "RSA"; - break; - case KEY_DSA: - return "DSA"; - break; - } - return "unknown"; -} - -char * -key_ssh_name(const Key *k) -{ - switch (k->type) { - case KEY_RSA: - return "ssh-rsa"; - break; - case KEY_DSA: - return "ssh-dss"; - break; - } - return "ssh-unknown"; -} - -u_int -key_size(Key *k) -{ - switch (k->type) { - case KEY_RSA1: - case KEY_RSA: - return BN_num_bits(k->rsa->n); - break; - case KEY_DSA: - return BN_num_bits(k->dsa->p); - break; - } - return 0; -} - -static RSA * -rsa_generate_private_key(u_int bits) -{ - RSA *private; - private = RSA_generate_key(bits, 35, NULL, NULL); - if (private == NULL) - fatal("rsa_generate_private_key: key generation failed."); - return private; -} - -static DSA* -dsa_generate_private_key(u_int bits) -{ - DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); - if (private == NULL) - fatal("dsa_generate_private_key: DSA_generate_parameters failed"); - if (!DSA_generate_key(private)) - fatal("dsa_generate_private_key: DSA_generate_key failed."); - if (private == NULL) - fatal("dsa_generate_private_key: NULL."); - return private; -} - -Key * -key_generate(int type, u_int bits) -{ - Key *k = key_new(KEY_UNSPEC); - switch (type) { - case KEY_DSA: - k->dsa = dsa_generate_private_key(bits); - break; - case KEY_RSA: - case KEY_RSA1: - k->rsa = rsa_generate_private_key(bits); - break; - default: - fatal("key_generate: unknown type %d", type); - } - k->type = type; - return k; -} - -Key * -key_from_private(Key *k) -{ - Key *n = NULL; - switch (k->type) { - case KEY_DSA: - n = key_new(k->type); - BN_copy(n->dsa->p, k->dsa->p); - BN_copy(n->dsa->q, k->dsa->q); - BN_copy(n->dsa->g, k->dsa->g); - BN_copy(n->dsa->pub_key, k->dsa->pub_key); - break; - case KEY_RSA: - case KEY_RSA1: - n = key_new(k->type); - BN_copy(n->rsa->n, k->rsa->n); - BN_copy(n->rsa->e, k->rsa->e); - break; - default: - fatal("key_from_private: unknown type %d", k->type); - break; - } - return n; -} - -int -key_type_from_name(char *name) -{ - if (strcmp(name, "rsa1") == 0) { - return KEY_RSA1; - } else if (strcmp(name, "rsa") == 0) { - return KEY_RSA; - } else if (strcmp(name, "dsa") == 0) { - return KEY_DSA; - } else if (strcmp(name, "ssh-rsa") == 0) { - return KEY_RSA; - } else if (strcmp(name, "ssh-dss") == 0) { - return KEY_DSA; - } else if (strcmp(name, "null") == 0){ - return KEY_NULL; - } - debug2("key_type_from_name: unknown key type '%s'", name); - return KEY_UNSPEC; -} - -int -key_names_valid2(const char *names) -{ - char *s, *cp, *p; - - if (names == NULL || strcmp(names, "") == 0) - return 0; - s = cp = xstrdup(names); - for ((p = strsep(&cp, ",")); p && *p != '\0'; - (p = strsep(&cp, ","))) { - switch (key_type_from_name(p)) { - case KEY_RSA1: - case KEY_UNSPEC: - xfree(s); - return 0; - } - } - debug3("key names ok: [%s]", names); - xfree(s); - return 1; -} - -Key * -key_from_blob(u_char *blob, int blen) -{ - Buffer b; - char *ktype; - int rlen, type; - Key *key = NULL; - -#ifdef DEBUG_PK - dump_base64(stderr, blob, blen); -#endif - buffer_init(&b); - buffer_append(&b, blob, blen); - if ((ktype = buffer_get_string_ret(&b, NULL)) == NULL) { - error("key_from_blob: can't read key type"); - goto out; - } - - type = key_type_from_name(ktype); - - switch (type) { - case KEY_RSA: - key = key_new(type); - if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || - buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { - error("key_from_blob: can't read rsa key"); - key_free(key); - key = NULL; - goto out; - } -#ifdef DEBUG_PK - RSA_print_fp(stderr, key->rsa, 8); -#endif - break; - case KEY_DSA: - key = key_new(type); - if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || - buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || - buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || - buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { - error("key_from_blob: can't read dsa key"); - key_free(key); - key = NULL; - goto out; - } -#ifdef DEBUG_PK - DSA_print_fp(stderr, key->dsa, 8); -#endif - break; - case KEY_UNSPEC: - key = key_new(type); - break; - default: - error("key_from_blob: cannot handle type %s", ktype); - goto out; - } - rlen = buffer_len(&b); - if (key != NULL && rlen != 0) - error("key_from_blob: remaining bytes in key blob %d", rlen); - out: - if (ktype != NULL) - xfree(ktype); - buffer_free(&b); - return key; -} - -int -key_to_blob(const Key *key, u_char **blobp, u_int *lenp) -{ - Buffer b; - int len; - - if (key == NULL) { - error("key_to_blob: key == NULL"); - return 0; - } - buffer_init(&b); - switch (key->type) { - case KEY_DSA: - buffer_put_cstring(&b, key_ssh_name(key)); - buffer_put_bignum2(&b, key->dsa->p); - buffer_put_bignum2(&b, key->dsa->q); - buffer_put_bignum2(&b, key->dsa->g); - buffer_put_bignum2(&b, key->dsa->pub_key); - break; - case KEY_RSA: - buffer_put_cstring(&b, key_ssh_name(key)); - buffer_put_bignum2(&b, key->rsa->e); - buffer_put_bignum2(&b, key->rsa->n); - break; - default: - error("key_to_blob: unsupported key type %d", key->type); - buffer_free(&b); - return 0; - } - len = buffer_len(&b); - if (lenp != NULL) - *lenp = len; - if (blobp != NULL) { - *blobp = xmalloc(len); - memcpy(*blobp, buffer_ptr(&b), len); - } - memset(buffer_ptr(&b), 0, len); - buffer_free(&b); - return len; -} - -int -key_sign( - Key *key, - u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - switch (key->type) { - case KEY_DSA: - return ssh_dss_sign(key, sigp, lenp, data, datalen); - break; - case KEY_RSA: - return ssh_rsa_sign(key, sigp, lenp, data, datalen); - break; - default: - error("key_sign: illegal key type %d", key->type); - return -1; - break; - } -} - -/* - * key_verify returns 1 for a correct signature, 0 for an incorrect signature - * and -1 on error. - */ -int -key_verify( - Key *key, - u_char *signature, u_int signaturelen, - u_char *data, u_int datalen) -{ - if (signaturelen == 0) - return -1; - - switch (key->type) { - case KEY_DSA: - return ssh_dss_verify(key, signature, signaturelen, data, datalen); - break; - case KEY_RSA: - return ssh_rsa_verify(key, signature, signaturelen, data, datalen); - break; - default: - error("key_verify: illegal key type %d", key->type); - return -1; - break; - } -} - -/* Converts a private to a public key */ -Key * -key_demote(Key *k) -{ - Key *pk; - - pk = xmalloc(sizeof(*pk)); - pk->type = k->type; - pk->flags = k->flags; - pk->dsa = NULL; - pk->rsa = NULL; - - switch (k->type) { - case KEY_RSA1: - case KEY_RSA: - if ((pk->rsa = RSA_new()) == NULL) - fatal("key_demote: RSA_new failed"); - if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) - fatal("key_demote: BN_dup failed"); - if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) - fatal("key_demote: BN_dup failed"); - break; - case KEY_DSA: - if ((pk->dsa = DSA_new()) == NULL) - fatal("key_demote: DSA_new failed"); - if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) - fatal("key_demote: BN_dup failed"); - if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) - fatal("key_demote: BN_dup failed"); - if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) - fatal("key_demote: BN_dup failed"); - if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) - fatal("key_demote: BN_dup failed"); - break; - default: - fatal("key_free: bad key type %d", k->type); - break; - } - - return (pk); -} - -int -key_type_plain(int type) -{ - switch (type) { - case KEY_RSA_CERT_V00: - case KEY_RSA_CERT: - return KEY_RSA; - case KEY_DSA_CERT_V00: - case KEY_DSA_CERT: - return KEY_DSA; - case KEY_ECDSA_CERT: - return KEY_ECDSA; - default: - return type; - } -} diff --git a/usr/src/cmd/ssh/libssh/common/llib-lssh b/usr/src/cmd/ssh/libssh/common/llib-lssh deleted file mode 100644 index c44090abe6..0000000000 --- a/usr/src/cmd/ssh/libssh/common/llib-lssh +++ /dev/null @@ -1,130 +0,0 @@ -/* LINTLIBRARY */ -/* PROTOLIB1 */ - -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <includes.h> -#include <ssh.h> -#include <atomicio.h> -#include <auth.h> -#include <auth-pam.h> -#include <auth2-pam.h> -#include <authfd.h> -#include <authfile.h> -#include <auth-options.h> -#include <base64.h> -#include <bindresvport.h> -#include <bsd-arc4random.h> -#include <bsd-cray.h> -#include <bsd-cygwin_util.h> -#include <bsd-getpeereid.h> -#include <bsd-misc.h> -#include <bsd-snprintf.h> -#include <bsd-waitpid.h> -#include <bufaux.h> -#include <buffer.h> -#include <canohost.h> -#include <channels.h> -#include <cipher.h> -#include <clientloop.h> -#include <compat.h> -#include <compress.h> -#include <config.h> -#include <crc32.h> -#include <deattack.h> -#include <defines.h> -#include <dh.h> -#include <dirname.h> -#include <dispatch.h> -#include <entropy.h> -#include <fake-gai-errnos.h> -#include <fake-getaddrinfo.h> -#include <fake-getnameinfo.h> -#include <fake-socket.h> -#include <g11n.h> -#include <getcwd.h> -#include <getgrouplist.h> -#include <getopt.h> -#include <getput.h> -#include <glob.h> -#include <groupaccess.h> -#include <hostfile.h> -#include <inet_ntoa.h> -#include <inet_ntop.h> -#include <kex.h> -#include <key.h> -#include <log.h> -#include <loginrec.h> -#include <mac.h> -#include <match.h> -#include <misc.h> -#include <mktemp.h> -#include <mpaux.h> -#include <msg.h> -#include <myproposal.h> -#include <openbsd-compat.h> -#include <packet.h> -#include <pathnames.h> -#include <port-aix.h> -#include <port-irix.h> -#include <proxy-io.h> -#include <readconf.h> -#include <readpass.h> -#include <readpassphrase.h> -#include <realpath.h> -#include <rresvport.h> -#include <rsa.h> -#include <servconf.h> -#include <serverloop.h> -#include <session.h> -#include <setproctitle.h> -#include <sftp-common.h> -#include <sftp.h> -#include <sftp-client.h> -#include <sigact.h> -#include <ssh1.h> -#include <ssh2.h> -#include <sshconnect.h> -#include <ssh-dss.h> -#include <sshlogin.h> -#include <sshpty.h> -#include <ssh-rsa.h> -#include <sshtty.h> -#include <strlcat.h> -#include <strlcpy.h> -#include <strmode.h> -#include <sys-queue.h> -#include <sys-tree.h> -#include <tildexpand.h> -#include <uidswap.h> -#include <uuencode.h> -#include <version.h> -#include <xlist.h> -#include <xmalloc.h> -#include <xmmap.h> - -extern uid_t original_real_uid; -extern char *__progname; - diff --git a/usr/src/cmd/ssh/libssh/common/log.c b/usr/src/cmd/ssh/libssh/common/log.c deleted file mode 100644 index 79e4cace6e..0000000000 --- a/usr/src/cmd/ssh/libssh/common/log.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: log.c,v 1.24 2002/07/19 15:43:33 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "log.h" -#include "xmalloc.h" - -#include <atomic.h> -#include <syslog.h> - -static LogLevel log_level = SYSLOG_LEVEL_INFO; -static int log_on_stderr = 1; -static int log_facility = LOG_AUTH; -static char *argv0; - -extern char *__progname; - -static const char *log_txt_prefix = ""; - -/* textual representation of log-facilities/levels */ - -static struct { - const char *name; - SyslogFacility val; -} log_facilities[] = { - { "DAEMON", SYSLOG_FACILITY_DAEMON }, - { "USER", SYSLOG_FACILITY_USER }, - { "AUTH", SYSLOG_FACILITY_AUTH }, -#ifdef LOG_AUTHPRIV - { "AUTHPRIV", SYSLOG_FACILITY_AUTHPRIV }, -#endif - { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, - { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, - { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, - { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, - { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, - { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, - { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, - { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, - { NULL, SYSLOG_FACILITY_NOT_SET } -}; - -static struct { - const char *name; - LogLevel val; -} log_levels[] = -{ - { "QUIET", SYSLOG_LEVEL_QUIET }, - { "FATAL", SYSLOG_LEVEL_FATAL }, - { "ERROR", SYSLOG_LEVEL_ERROR }, - { "NOTICE", SYSLOG_LEVEL_NOTICE }, - { "INFO", SYSLOG_LEVEL_INFO }, - { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, - { "DEBUG", SYSLOG_LEVEL_DEBUG1 }, - { "DEBUG1", SYSLOG_LEVEL_DEBUG1 }, - { "DEBUG2", SYSLOG_LEVEL_DEBUG2 }, - { "DEBUG3", SYSLOG_LEVEL_DEBUG3 }, - { NULL, SYSLOG_LEVEL_NOT_SET } -}; - -SyslogFacility -log_facility_number(char *name) -{ - int i; - - if (name != NULL) - for (i = 0; log_facilities[i].name; i++) - if (strcasecmp(log_facilities[i].name, name) == 0) - return log_facilities[i].val; - return SYSLOG_FACILITY_NOT_SET; -} - -LogLevel -log_level_number(char *name) -{ - int i; - - if (name != NULL) - for (i = 0; log_levels[i].name; i++) - if (strcasecmp(log_levels[i].name, name) == 0) - return log_levels[i].val; - return SYSLOG_LEVEL_NOT_SET; -} - -void -set_log_txt_prefix(const char *txt) -{ - log_txt_prefix = txt; -} - -/* Error messages that should be logged. */ - -void -error(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_ERROR, fmt, args); - va_end(args); -} - -void -notice(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_NOTICE, fmt, args); - va_end(args); -} - -/* Log this message (information that usually should go to the log). */ - -void -log(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_INFO, fmt, args); - va_end(args); -} - -/* More detailed messages (information that does not need to go to the log). */ - -void -verbose(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); - va_end(args); -} - -/* Debugging messages that should not be logged during normal operation. */ - -void -debug(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_DEBUG1, fmt, args); - va_end(args); -} - -void -debug2(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_DEBUG2, fmt, args); - va_end(args); -} - -void -debug3(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_DEBUG3, fmt, args); - va_end(args); -} - -/* Fatal cleanup */ - -struct fatal_cleanup { - struct fatal_cleanup *next; - void (*proc) (void *); - void *context; -}; - -static struct fatal_cleanup *fatal_cleanups = NULL; - -/* Registers a cleanup function to be called by fatal() before exiting. */ - -void -fatal_add_cleanup(void (*proc) (void *), void *context) -{ - struct fatal_cleanup *cu; - - cu = xmalloc(sizeof(*cu)); - cu->proc = proc; - cu->context = context; - cu->next = fatal_cleanups; - fatal_cleanups = cu; -} - -/* Removes a cleanup function to be called at fatal(). */ - -void -fatal_remove_cleanup(void (*proc) (void *context), void *context) -{ - struct fatal_cleanup **cup, *cu; - - for (cup = &fatal_cleanups; *cup; cup = &cu->next) { - cu = *cup; - if (cu->proc == proc && cu->context == context) { - *cup = cu->next; - xfree(cu); - return; - } - } - debug3("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx", - (u_long) proc, (u_long) context); -} - -/* Remove all cleanups, to be called after fork() */ -void -fatal_remove_all_cleanups(void) -{ - struct fatal_cleanup *cu, *next_cu; - - for (cu = fatal_cleanups; cu; cu = next_cu) { - next_cu = cu->next; - xfree(cu); - } - - fatal_cleanups = NULL; -} - -/* Cleanup and exit. Make sure each cleanup is called only once. */ -void -fatal_cleanup(void) -{ - struct fatal_cleanup *cu, *next_cu; - static volatile u_int called = 0; - - if (atomic_cas_uint(&called, 0, 1) == 1) - exit(255); - /* Call cleanup functions. */ - for (cu = fatal_cleanups; cu; cu = next_cu) { - next_cu = cu->next; - debug("Calling cleanup 0x%lx(0x%lx)", - (u_long) cu->proc, (u_long) cu->context); - (*cu->proc) (cu->context); - } - exit(255); -} - - -/* - * Initialize the log. - */ - -void -log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) -{ - argv0 = av0; - - switch (level) { - case SYSLOG_LEVEL_QUIET: - case SYSLOG_LEVEL_FATAL: - case SYSLOG_LEVEL_ERROR: - case SYSLOG_LEVEL_NOTICE: - case SYSLOG_LEVEL_INFO: - case SYSLOG_LEVEL_VERBOSE: - case SYSLOG_LEVEL_DEBUG1: - case SYSLOG_LEVEL_DEBUG2: - case SYSLOG_LEVEL_DEBUG3: - log_level = level; - break; - default: - fprintf(stderr, "Unrecognized internal syslog level code %d\n", - (int) level); - exit(1); - } - - log_on_stderr = on_stderr; - if (on_stderr) - return; - - switch (facility) { - case SYSLOG_FACILITY_DAEMON: - log_facility = LOG_DAEMON; - break; - case SYSLOG_FACILITY_USER: - log_facility = LOG_USER; - break; - case SYSLOG_FACILITY_AUTH: - log_facility = LOG_AUTH; - break; -#ifdef LOG_AUTHPRIV - case SYSLOG_FACILITY_AUTHPRIV: - log_facility = LOG_AUTHPRIV; - break; -#endif - case SYSLOG_FACILITY_LOCAL0: - log_facility = LOG_LOCAL0; - break; - case SYSLOG_FACILITY_LOCAL1: - log_facility = LOG_LOCAL1; - break; - case SYSLOG_FACILITY_LOCAL2: - log_facility = LOG_LOCAL2; - break; - case SYSLOG_FACILITY_LOCAL3: - log_facility = LOG_LOCAL3; - break; - case SYSLOG_FACILITY_LOCAL4: - log_facility = LOG_LOCAL4; - break; - case SYSLOG_FACILITY_LOCAL5: - log_facility = LOG_LOCAL5; - break; - case SYSLOG_FACILITY_LOCAL6: - log_facility = LOG_LOCAL6; - break; - case SYSLOG_FACILITY_LOCAL7: - log_facility = LOG_LOCAL7; - break; - default: - fprintf(stderr, - "Unrecognized internal syslog facility code %d\n", - (int) facility); - exit(1); - } -} - -#define MSGBUFSIZ 1024 - -/* PRINTFLIKE2 */ -void -do_log(LogLevel level, const char *fmt, va_list args) -{ - char msgbuf[MSGBUFSIZ]; - char fmtbuf[MSGBUFSIZ]; - char *txt = NULL; - int pri = LOG_INFO; - int do_gettext = log_on_stderr; /* - * Localize user messages - not - * syslog()ed messages. - */ - - if (level > log_level) - return; - - switch (level) { - case SYSLOG_LEVEL_FATAL: - if (!log_on_stderr) - txt = "fatal"; - pri = LOG_CRIT; - break; - case SYSLOG_LEVEL_ERROR: - if (!log_on_stderr) - txt = "error"; - pri = LOG_ERR; - break; - case SYSLOG_LEVEL_NOTICE: - pri = LOG_NOTICE; - break; - case SYSLOG_LEVEL_INFO: - pri = LOG_INFO; - break; - case SYSLOG_LEVEL_VERBOSE: - pri = LOG_INFO; - break; - case SYSLOG_LEVEL_DEBUG1: - txt = "debug1"; - pri = LOG_DEBUG; - /* - * Don't localize debug messages - such are not intended - * for users but for support staff whose preferred - * language is unknown, therefore we default to the - * language used in the source code: English. - */ - do_gettext = 0; - break; - case SYSLOG_LEVEL_DEBUG2: - txt = "debug2"; - pri = LOG_DEBUG; - do_gettext = 0; /* Don't localize debug messages. */ - break; - case SYSLOG_LEVEL_DEBUG3: - txt = "debug3"; - pri = LOG_DEBUG; - do_gettext = 0; /* Don't localize debug messages. */ - break; - default: - txt = "internal error"; - pri = LOG_ERR; - break; - } - if (txt != NULL) { - snprintf(fmtbuf, sizeof(fmtbuf), "%s%s: %s", log_txt_prefix, - do_gettext ? gettext(txt) : txt, - do_gettext ? gettext(fmt) : fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); - } else { - vsnprintf(msgbuf, sizeof(msgbuf), - do_gettext ? gettext(fmt) : fmt, - args); - } - if (log_on_stderr) { - fprintf(stderr, "%s\r\n", msgbuf); - } else { - openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); - syslog(pri, "%.500s", msgbuf); - closelog(); - } -} diff --git a/usr/src/cmd/ssh/libssh/common/mac.c b/usr/src/cmd/ssh/libssh/common/mac.c deleted file mode 100644 index e25f5eb95d..0000000000 --- a/usr/src/cmd/ssh/libssh/common/mac.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: mac.c,v 1.5 2002/05/16 22:02:50 markus Exp $"); - -#include <openssl/hmac.h> - -#include "xmalloc.h" -#include "getput.h" -#include "log.h" -#include "cipher.h" -#include "kex.h" -#include "mac.h" -#include "misc.h" - -#define SSH_EVP 1 /* OpenSSL EVP-based MAC */ - -struct { - char *name; - int type; - const EVP_MD * (*mdfunc)(void); - int truncatebits; /* truncate digest if != 0 */ - int key_len; /* will be used if we have UMAC */ -} macs[] = { - { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1 }, - { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1 }, - { "hmac-md5", SSH_EVP, EVP_md5, 0, -1 }, - { "hmac-md5-96", SSH_EVP, EVP_md5, 96, -1 }, -#ifdef SOLARIS_SSH_ENABLE_RIPEMD160 - { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, -1 }, - { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, -1 }, -#endif /* SOLARIS_SSH_ENABLE_RIPEMD160 */ - { NULL, 0, NULL, 0, -1 } -}; - -static void -mac_setup_by_id(Mac *mac, int which) -{ - int evp_len; - mac->type = macs[which].type; - if (mac->type == SSH_EVP) { - mac->evp_md = (*macs[which].mdfunc)(); - if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) - fatal("mac %s len %d", mac->name, evp_len); - mac->key_len = mac->mac_len = (u_int)evp_len; - } else - fatal("wrong MAC type (%d)", mac->type); - if (macs[which].truncatebits != 0) - mac->mac_len = macs[which].truncatebits / 8; -} - -int -mac_setup(Mac *mac, char *name) -{ - int i; - - for (i = 0; macs[i].name; i++) { - if (strcmp(name, macs[i].name) == 0) { - if (mac != NULL) - mac_setup_by_id(mac, i); - debug2("mac_setup: found %s", name); - return (0); - } - } - debug2("mac_setup: unknown %s", name); - return (-1); -} - -int -mac_init(Mac *mac) -{ - if (mac->key == NULL) - fatal("mac_init: no key"); - switch (mac->type) { - case SSH_EVP: - if (mac->evp_md == NULL) - return -1; - HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md); - return 0; - default: - return -1; - } -} - -u_char * -mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) -{ - static u_char m[EVP_MAX_MD_SIZE]; - u_char b[4]; - - if (mac->mac_len > sizeof(m)) - fatal("mac_compute: mac too long %u %lu", - mac->mac_len, (u_long)sizeof(m)); - - switch (mac->type) { - case SSH_EVP: - put_u32(b, seqno); - /* reset HMAC context */ - HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); - HMAC_Update(&mac->evp_ctx, b, sizeof(b)); - HMAC_Update(&mac->evp_ctx, data, datalen); - HMAC_Final(&mac->evp_ctx, m, NULL); - break; - default: - fatal("mac_compute: unknown MAC type"); - } - - return (m); -} - -void -mac_clear(Mac *mac) -{ - if (mac->evp_md != NULL) - HMAC_cleanup(&mac->evp_ctx); - mac->evp_md = NULL; -} - -/* XXX copied from ciphers_valid */ -#define MAC_SEP "," -int -mac_valid(const char *names) -{ - char *maclist, *cp, *p; - - if (names == NULL || strcmp(names, "") == 0) - return (0); - maclist = cp = xstrdup(names); - for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; - (p = strsep(&cp, MAC_SEP))) { - if (mac_setup(NULL, p) < 0) { - debug("bad mac %s [%s]", p, names); - xfree(maclist); - return (0); - } else { - debug3("mac ok: %s [%s]", p, names); - } - } - debug3("macs ok: [%s]", names); - xfree(maclist); - return (1); -} diff --git a/usr/src/cmd/ssh/libssh/common/match.c b/usr/src/cmd/ssh/libssh/common/match.c deleted file mode 100644 index 4724d435e7..0000000000 --- a/usr/src/cmd/ssh/libssh/common/match.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * 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: match.c,v 1.19 2002/03/01 13:12:10 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "match.h" -#include "xmalloc.h" - -/* - * Returns true if the given string matches the pattern (which may contain ? - * and * as wildcards), and zero if it does not match. - */ - -int -match_pattern(const char *s, const char *pattern) -{ - for (;;) { - /* If at end of pattern, accept if also at end of string. */ - if (!*pattern) - return !*s; - - if (*pattern == '*') { - /* Skip the asterisk. */ - pattern++; - - /* If at end of pattern, accept immediately. */ - if (!*pattern) - return 1; - - /* If next character in pattern is known, optimize. */ - if (*pattern != '?' && *pattern != '*') { - /* - * Look instances of the next character in - * pattern, and try to match starting from - * those. - */ - for (; *s; s++) - if (*s == *pattern && - match_pattern(s + 1, pattern + 1)) - return 1; - /* Failed. */ - return 0; - } - /* - * Move ahead one character at a time and try to - * match at each position. - */ - for (; *s; s++) - if (match_pattern(s, pattern)) - return 1; - /* Failed. */ - return 0; - } - /* - * There must be at least one more character in the string. - * If we are at the end, fail. - */ - if (!*s) - return 0; - - /* Check if the next character of the string is acceptable. */ - if (*pattern != '?' && *pattern != *s) - return 0; - - /* Move to the next character, both in string and in pattern. */ - s++; - pattern++; - } - /* NOTREACHED */ -} - -/* - * Tries to match the string against the - * comma-separated sequence of subpatterns (each possibly preceded by ! to - * indicate negation). Returns -1 if negation matches, 1 if there is - * a positive match, 0 if there is no match at all. - */ - -int -match_pattern_list(const char *string, const char *pattern, u_int len, - int dolower) -{ - char sub[1024]; - int negated; - int got_positive; - u_int i, subi; - - got_positive = 0; - for (i = 0; i < len;) { - /* Check if the subpattern is negated. */ - if (pattern[i] == '!') { - negated = 1; - i++; - } else - negated = 0; - - /* - * Extract the subpattern up to a comma or end. Convert the - * subpattern to lowercase. - */ - for (subi = 0; - i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; - subi++, i++) - sub[subi] = dolower && isupper(pattern[i]) ? - tolower(pattern[i]) : pattern[i]; - /* If subpattern too long, return failure (no match). */ - if (subi >= sizeof(sub) - 1) - return 0; - - /* If the subpattern was terminated by a comma, skip the comma. */ - if (i < len && pattern[i] == ',') - i++; - - /* Null-terminate the subpattern. */ - sub[subi] = '\0'; - - /* Try to match the subpattern against the string. */ - if (match_pattern(string, sub)) { - if (negated) - return -1; /* Negative */ - else - got_positive = 1; /* Positive */ - } - } - - /* - * Return success if got a positive match. If there was a negative - * match, we have already returned -1 and never get here. - */ - return got_positive; -} - -/* - * 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 -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, u_int len) -{ - return match_pattern_list(host, pattern, len, 1); -} - -/* - * returns 0 if we get a negative match for the hostname or the ip - * or if we get no match at all. returns 1 otherwise. - */ -int -match_host_and_ip(const char *host, const char *ipaddr, - const char *patterns) -{ - int mhost, mip; - - /* negative ipaddr match */ - if ((mip = match_hostname(ipaddr, patterns, strlen(patterns))) == -1) - return 0; - /* negative hostname match */ - if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1) - return 0; - /* no match at all */ - if (mhost == 0 && mip == 0) - return 0; - return 1; -} - -/* - * match user, user@host_or_ip, user@host_or_ip_list against pattern - */ -int -match_user(const char *user, const char *host, const char *ipaddr, - const char *pattern) -{ - char *p, *pat; - int ret; - - if ((p = strchr(pattern,'@')) == NULL) - return match_pattern(user, pattern); - - pat = xstrdup(pattern); - p = strchr(pat, '@'); - *p++ = '\0'; - - if ((ret = match_pattern(user, pat)) == 1) - ret = match_host_and_ip(host, ipaddr, p); - xfree(pat); - - return ret; -} - -/* - * Returns first item from client-list that is also supported by server-list, - * caller must xfree() returned string. - */ -#define MAX_PROP 40 -#define SEP "," -char * -match_list(const char *client, const char *server, u_int *next) -{ - char *sproposals[MAX_PROP]; - char *c, *s, *p, *ret, *cp, *sp; - int i, j, nproposals; - - c = cp = xstrdup(client); - s = sp = xstrdup(server); - - for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0'; - (p = strsep(&sp, SEP)), i++) { - if (i < MAX_PROP) - sproposals[i] = p; - else - break; - } - nproposals = 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); - if (next != NULL) - *next = (cp == NULL) ? - strlen(c) : cp - c; - xfree(c); - xfree(s); - return ret; - } - } - } - if (next != NULL) - *next = strlen(c); - xfree(c); - xfree(s); - return NULL; -} diff --git a/usr/src/cmd/ssh/libssh/common/misc.c b/usr/src/cmd/ssh/libssh/common/misc.c deleted file mode 100644 index e73d3f364b..0000000000 --- a/usr/src/cmd/ssh/libssh/common/misc.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.19 2002/03/04 17:27:39 stevesk Exp $"); - -#include "misc.h" -#include "log.h" -#include "xmalloc.h" - -/* remove newline at end of string */ -char * -chop(char *s) -{ - char *t = s; - while (*t) { - if (*t == '\n' || *t == '\r') { - *t = '\0'; - return s; - } - t++; - } - return s; - -} - -/* set/unset filedescriptor to non-blocking */ -void -set_nonblock(int fd) -{ - int val; - - val = fcntl(fd, F_GETFL, 0); - if (val < 0) { - error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); - return; - } - if (val & O_NONBLOCK) { - debug2("fd %d is O_NONBLOCK", fd); - return; - } - debug("fd %d setting O_NONBLOCK", fd); - val |= O_NONBLOCK; - if (fcntl(fd, F_SETFL, val) == -1) - debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", - fd, strerror(errno)); -} - -void -unset_nonblock(int fd) -{ - int val; - - val = fcntl(fd, F_GETFL, 0); - if (val < 0) { - error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); - return; - } - if (!(val & O_NONBLOCK)) { - debug2("fd %d is not O_NONBLOCK", fd); - return; - } - debug("fd %d clearing O_NONBLOCK", fd); - val &= ~O_NONBLOCK; - if (fcntl(fd, F_SETFL, val) == -1) - debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", - fd, strerror(errno)); -} - -/* disable nagle on socket */ -void -set_nodelay(int fd) -{ - int opt; - socklen_t optlen; - - optlen = sizeof opt; - if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { - error("getsockopt TCP_NODELAY: %.100s", strerror(errno)); - return; - } - if (opt == 1) { - debug2("fd %d is TCP_NODELAY", fd); - return; - } - opt = 1; - debug("fd %d setting TCP_NODELAY", fd); - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) - error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); -} - -/* Characters considered whitespace in strsep calls. */ -#define WHITESPACE " \t\r\n" - -/* - * Function returns a pointer to the 1st token on the line. Such a token can - * be an empty string in the case of '*s' equal to " value". It changes the - * first whitespace token or '=' character after the 1st token to '\0'. Upon - * return it changes '*s' to point to the first character of the next token. - * That token may be an empty string if the 1st token was followed only by - * whitespace or it could be a NULL pointer if the line contained one token - * only. - */ -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); -} - -struct passwd * -pwcopy(struct passwd *pw) -{ - struct passwd *copy = xmalloc(sizeof(*copy)); - - memset(copy, 0, sizeof(*copy)); - copy->pw_name = xstrdup(pw->pw_name); - copy->pw_passwd = xstrdup(pw->pw_passwd); - copy->pw_gecos = xstrdup(pw->pw_gecos); - copy->pw_uid = pw->pw_uid; - copy->pw_gid = pw->pw_gid; -#ifdef HAVE_PW_EXPIRE_IN_PASSWD - copy->pw_expire = pw->pw_expire; -#endif -#ifdef HAVE_PW_CHANGE_IN_PASSWD - copy->pw_change = pw->pw_change; -#endif -#ifdef HAVE_PW_CLASS_IN_PASSWD - copy->pw_class = xstrdup(pw->pw_class); -#endif - copy->pw_dir = xstrdup(pw->pw_dir); - copy->pw_shell = xstrdup(pw->pw_shell); - return copy; -} - -void -pwfree(struct passwd **pw) -{ - struct passwd *p; - - if (pw == NULL || *pw == NULL) - return; - - p = *pw; - *pw = NULL; - - xfree(p->pw_name); - xfree(p->pw_passwd); - xfree(p->pw_gecos); -#ifdef HAVE_PW_CLASS_IN_PASSWD - xfree(p->pw_class); -#endif - xfree(p->pw_dir); - xfree(p->pw_shell); - xfree(p); -} - -/* - * Convert ASCII string to TCP/IP port number. - * Port must be >0 and <=65535. - * Return 0 if invalid. - */ -int -a2port(const char *s) -{ - long port; - char *endp; - - errno = 0; - port = strtol(s, &endp, 0); - if (s == endp || *endp != '\0' || - (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) || - port <= 0 || port > 65535) - return 0; - - return port; -} - -#define SECONDS 1 -#define MINUTES (SECONDS * 60) -#define HOURS (MINUTES * 60) -#define DAYS (HOURS * 24) -#define WEEKS (DAYS * 7) - -/* - * Convert a time string into seconds; format is - * a sequence of: - * time[qualifier] - * - * Valid time qualifiers are: - * <none> seconds - * s|S seconds - * m|M minutes - * h|H hours - * d|D days - * w|W weeks - * - * Examples: - * 90m 90 minutes - * 1h30m 90 minutes - * 2d 2 days - * 1w 1 week - * - * Return -1 if time string is invalid. - */ -long -convtime(const char *s) -{ - long total, secs; - const char *p; - char *endp; - - errno = 0; - total = 0; - p = s; - - if (p == NULL || *p == '\0') - return -1; - - while (*p) { - secs = strtol(p, &endp, 10); - if (p == endp || - (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || - secs < 0) - return -1; - - switch (*endp++) { - case '\0': - endp--; - break; - case 's': - case 'S': - break; - case 'm': - case 'M': - secs *= MINUTES; - break; - case 'h': - case 'H': - secs *= HOURS; - break; - case 'd': - case 'D': - secs *= DAYS; - break; - case 'w': - case 'W': - secs *= WEEKS; - break; - default: - return -1; - } - total += secs; - if (total < 0) - return -1; - p = endp; - } - - return total; -} - -/* - * Search for next delimiter between hostnames/addresses and ports. - * Argument may be modified (for termination). - * Returns *cp if parsing succeeds. - * *cp is set to the start of the next delimiter, if one was found. - * If this is the last field, *cp is set to NULL. - */ -char * -hpdelim(char **cp) -{ - char *s, *old; - - if (cp == NULL || *cp == NULL) - return NULL; - - old = s = *cp; - if (*s == '[') { - if ((s = strchr(s, ']')) == NULL) - return NULL; - else - s++; - } else if ((s = strpbrk(s, ":/")) == NULL) - s = *cp + strlen(*cp); /* skip to end (see first case below) */ - - switch (*s) { - case '\0': - *cp = NULL; /* no more fields*/ - break; - - case ':': - case '/': - *s = '\0'; /* terminate */ - *cp = s + 1; - break; - - default: - return NULL; - } - - return old; -} - -char * -cleanhostname(char *host) -{ - if (*host == '[' && host[strlen(host) - 1] == ']') { - host[strlen(host) - 1] = '\0'; - return (host + 1); - } else - return host; -} - -char * -colon(char *cp) -{ - int flag = 0; - - if (*cp == ':') /* Leading colon is part of file name. */ - return (0); - if (*cp == '[') - flag = 1; - - for (; *cp; ++cp) { - if (*cp == '@' && *(cp+1) == '[') - flag = 1; - if (*cp == ']' && *(cp+1) == ':' && flag) - return (cp+1); - if (*cp == ':' && !flag) - return (cp); - if (*cp == '/') - return (0); - } - return (0); -} - -/* function to assist building execv() arguments */ -/* PRINTFLIKE2 */ -void -addargs(arglist *args, char *fmt, ...) -{ - va_list ap; - char buf[1024]; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - if (args->list == NULL) { - args->nalloc = 32; - args->num = 0; - } else if (args->num+2 >= args->nalloc) - args->nalloc *= 2; - - args->list = xrealloc(args->list, args->nalloc * sizeof(char *)); - args->list[args->num++] = xstrdup(buf); - args->list[args->num] = NULL; -} - -void -replacearg(arglist *args, u_int which, char *fmt, ...) -{ - va_list ap; - char *cp; - int r; - - va_start(ap, fmt); - r = vasprintf(&cp, fmt, ap); - va_end(ap); - if (r == -1) - fatal("replacearg: argument too long"); - - if (which >= args->num) - fatal("replacearg: tried to replace invalid arg %d >= %d", - which, args->num); - xfree(args->list[which]); - args->list[which] = cp; -} - -void -freeargs(arglist *args) -{ - u_int i; - - if (args->list != NULL) { - for (i = 0; i < args->num; i++) - xfree(args->list[i]); - xfree(args->list); - args->nalloc = args->num = 0; - args->list = NULL; - } -} - -/* - * Expand a string with a set of %[char] escapes. A number of escapes may be - * specified as (char *escape_chars, char *replacement) pairs. The list must - * be terminated by a NULL escape_char. Returns replaced string in memory - * allocated by xmalloc. - */ -char * -percent_expand(const char *string, ...) -{ -#define EXPAND_MAX_KEYS 16 - struct { - const char *key; - const char *repl; - } keys[EXPAND_MAX_KEYS]; - u_int num_keys, i, j; - char buf[4096]; - va_list ap; - - /* Gather keys */ - va_start(ap, string); - for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { - keys[num_keys].key = va_arg(ap, char *); - if (keys[num_keys].key == NULL) - break; - keys[num_keys].repl = va_arg(ap, char *); - if (keys[num_keys].repl == NULL) - fatal("percent_expand: NULL replacement"); - } - va_end(ap); - - if (num_keys >= EXPAND_MAX_KEYS) - fatal("percent_expand: too many keys"); - - /* Expand string */ - *buf = '\0'; - for (i = 0; *string != '\0'; string++) { - if (*string != '%') { - append: - buf[i++] = *string; - if (i >= sizeof(buf)) - fatal("percent_expand: string too long"); - buf[i] = '\0'; - continue; - } - string++; - if (*string == '%') - goto append; - for (j = 0; j < num_keys; j++) { - if (strchr(keys[j].key, *string) != NULL) { - i = strlcat(buf, keys[j].repl, sizeof(buf)); - if (i >= sizeof(buf)) - fatal("percent_expand: string too long"); - break; - } - } - if (j >= num_keys) - fatal("percent_expand: unknown key %%%c", *string); - } - return (xstrdup(buf)); -#undef EXPAND_MAX_KEYS -} - -/* - * Ensure that file descriptors 0, 1 and 2 are open or directed to /dev/null, - * do not touch those that are already open. - */ -void -sanitise_stdfd(void) -{ - int nullfd, dupfd; - - if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { - fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno)); - exit(1); - } - while (++dupfd <= 2) { - /* Only clobber closed fds */ - if (fcntl(dupfd, F_GETFL, 0) >= 0) - continue; - if (dup2(nullfd, dupfd) == -1) { - fprintf(stderr, "dup2: %s", strerror(errno)); - exit(1); - } - } - if (nullfd > 2) - close(nullfd); -} - -char * -tohex(const void *vp, size_t l) -{ - const u_char *p = (const u_char *)vp; - char b[3], *r; - size_t i, hl; - - if (l > 65536) - return xstrdup("tohex: length > 65536"); - - hl = l * 2 + 1; - r = xcalloc(1, hl); - for (i = 0; i < l; i++) { - snprintf(b, sizeof(b), "%02x", p[i]); - strlcat(r, b, hl); - } - return (r); -} - -u_int64_t -get_u64(const void *vp) -{ - const u_char *p = (const u_char *)vp; - u_int64_t v; - - v = (u_int64_t)p[0] << 56; - v |= (u_int64_t)p[1] << 48; - v |= (u_int64_t)p[2] << 40; - v |= (u_int64_t)p[3] << 32; - v |= (u_int64_t)p[4] << 24; - v |= (u_int64_t)p[5] << 16; - v |= (u_int64_t)p[6] << 8; - v |= (u_int64_t)p[7]; - - return (v); -} - -u_int32_t -get_u32(const void *vp) -{ - const u_char *p = (const u_char *)vp; - u_int32_t v; - - v = (u_int32_t)p[0] << 24; - v |= (u_int32_t)p[1] << 16; - v |= (u_int32_t)p[2] << 8; - v |= (u_int32_t)p[3]; - - return (v); -} - -u_int16_t -get_u16(const void *vp) -{ - const u_char *p = (const u_char *)vp; - u_int16_t v; - - v = (u_int16_t)p[0] << 8; - v |= (u_int16_t)p[1]; - - return (v); -} - -void -put_u64(void *vp, u_int64_t v) -{ - u_char *p = (u_char *)vp; - - p[0] = (u_char)(v >> 56) & 0xff; - p[1] = (u_char)(v >> 48) & 0xff; - p[2] = (u_char)(v >> 40) & 0xff; - p[3] = (u_char)(v >> 32) & 0xff; - p[4] = (u_char)(v >> 24) & 0xff; - p[5] = (u_char)(v >> 16) & 0xff; - p[6] = (u_char)(v >> 8) & 0xff; - p[7] = (u_char)v & 0xff; -} - -void -put_u32(void *vp, u_int32_t v) -{ - u_char *p = (u_char *)vp; - - p[0] = (u_char)(v >> 24) & 0xff; - p[1] = (u_char)(v >> 16) & 0xff; - p[2] = (u_char)(v >> 8) & 0xff; - p[3] = (u_char)v & 0xff; -} - - -void -put_u16(void *vp, u_int16_t v) -{ - u_char *p = (u_char *)vp; - - p[0] = (u_char)(v >> 8) & 0xff; - p[1] = (u_char)v & 0xff; -} - -mysig_t -mysignal(int sig, mysig_t act) -{ -#ifdef HAVE_SIGACTION - struct sigaction sa, osa; - - if (sigaction(sig, NULL, &osa) == -1) - return (mysig_t) -1; - if (osa.sa_handler != act) { - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; -#if defined(SA_INTERRUPT) - if (sig == SIGALRM) - sa.sa_flags |= SA_INTERRUPT; -#endif - sa.sa_handler = act; - if (sigaction(sig, &sa, NULL) == -1) - return (mysig_t) -1; - } - return (osa.sa_handler); -#else - return (signal(sig, act)); -#endif -} - -/* - * Return true if argument is one of "yes", "true", "no" or "false". If - * 'active' is 0 than we are in a non-matching Host section of the - * configuration file so we check the syntax but will not set the value of - * '*option'. Otherwise we set its value if not already set. - */ -int -get_yes_no_flag(int *option, const char *arg, const char *filename, int linenum, - int active) -{ - int value = -1; - - if (arg == NULL || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) - value = 1; - else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) - value = 0; - - if (active && *option == -1 && value != -1) - *option = value; - - return (value != -1); -} - -/* - * Convert a string to lowercase. The string returned is an internally allocated - * one so the consumer of this function is not expected to change it or free it. - */ -char * -tolowercase(const char *s) -{ - int i, len; - static int lenret = 0; - static char *ret = NULL; - - /* allocate a new string if the old one it not long enough to store s */ - len = strlen(s) + 1; - if (len > lenret) { - if (ret != NULL) - xfree(ret); - ret = xmalloc(len); - lenret = len; - } - - /* process the string including the ending '\0' */ - for (i = 0; i < len; ++i) - ret[i] = tolower(s[i]); - - return (ret); -} diff --git a/usr/src/cmd/ssh/libssh/common/mpaux.c b/usr/src/cmd/ssh/libssh/common/mpaux.c deleted file mode 100644 index 1b77961b62..0000000000 --- a/usr/src/cmd/ssh/libssh/common/mpaux.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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". - */ - -#include "includes.h" -RCSID("$OpenBSD: mpaux.c,v 1.16 2001/02/08 19:30:52 itojun Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/bn.h> -#include "getput.h" -#include "xmalloc.h" - -#include <openssl/md5.h> - -#include "mpaux.h" - -void -compute_session_id(u_char session_id[16], - u_char cookie[8], - BIGNUM* host_key_n, - BIGNUM* session_key_n) -{ - u_int host_key_bytes = BN_num_bytes(host_key_n); - u_int session_key_bytes = BN_num_bytes(session_key_n); - u_int bytes = host_key_bytes + session_key_bytes; - u_char *buf = xmalloc(bytes); - MD5_CTX md; - - BN_bn2bin(host_key_n, buf); - BN_bn2bin(session_key_n, buf + host_key_bytes); - MD5_Init(&md); - MD5_Update(&md, buf, bytes); - MD5_Update(&md, cookie, 8); - MD5_Final(session_id, &md); - memset(buf, 0, bytes); - xfree(buf); -} diff --git a/usr/src/cmd/ssh/libssh/common/msg.c b/usr/src/cmd/ssh/libssh/common/msg.c deleted file mode 100644 index 26c5eeec61..0000000000 --- a/usr/src/cmd/ssh/libssh/common/msg.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2002 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: msg.c,v 1.4 2002/07/01 16:15:25 deraadt Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "buffer.h" -#include "getput.h" -#include "log.h" -#include "atomicio.h" -#include "msg.h" - -void -ssh_msg_send(int fd, u_char type, Buffer *m) -{ - u_char buf[5]; - u_int mlen = buffer_len(m); - - debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff); - - PUT_32BIT(buf, mlen + 1); - buf[4] = type; /* 1st byte of payload is mesg-type */ - if (atomicio(write, fd, buf, sizeof(buf)) != sizeof(buf)) - fatal("ssh_msg_send: write"); - if (atomicio(write, fd, buffer_ptr(m), mlen) != mlen) - fatal("ssh_msg_send: write"); -} - -int -ssh_msg_recv(int fd, Buffer *m) -{ - u_char buf[4]; - ssize_t res; - u_int msg_len; - - debug3("ssh_msg_recv entering"); - - res = atomicio(read, fd, buf, sizeof(buf)); - if (res != sizeof(buf)) { - if (res == 0) - return -1; - fatal("ssh_msg_recv: read: header %ld", (long)res); - } - msg_len = GET_32BIT(buf); - if (msg_len > 256 * 1024) - fatal("ssh_msg_recv: read: bad msg_len %u", msg_len); - buffer_clear(m); - buffer_append_space(m, msg_len); - res = atomicio(read, fd, buffer_ptr(m), msg_len); - if (res != msg_len) - fatal("ssh_msg_recv: read: %ld != msg_len", (long)res); - return 0; -} diff --git a/usr/src/cmd/ssh/libssh/common/nchan.c b/usr/src/cmd/ssh/libssh/common/nchan.c deleted file mode 100644 index 82a371af5b..0000000000 --- a/usr/src/cmd/ssh/libssh/common/nchan.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (c) 1999, 2000, 2001, 2002 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: nchan.c,v 1.47 2002/06/19 00:27:55 deraadt Exp $"); - -#include "ssh1.h" -#include "ssh2.h" -#include "buffer.h" -#include "packet.h" -#include "channels.h" -#include "compat.h" -#include "log.h" - -/* - * SSH Protocol 1.5 aka New Channel Protocol - * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. - * Written by Markus Friedl in October 1999 - * - * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the - * tear down of channels: - * - * 1.3: strict request-ack-protocol: - * CLOSE -> - * <- CLOSE_CONFIRM - * - * 1.5: uses variations of: - * IEOF -> - * <- OCLOSE - * <- IEOF - * OCLOSE -> - * i.e. both sides have to close the channel - * - * 2.0: the EOF messages are optional - * - * See the debugging output from 'ssh -v' and 'sshd -d' of - * ssh-1.2.27 as an example. - * - */ - -/* functions manipulating channel states */ -/* - * EVENTS update channel input/output states execute ACTIONS - */ -/* - * ACTIONS: should never update the channel states - */ -static void chan_send_ieof1(Channel *); -static void chan_send_oclose1(Channel *); -static void chan_send_close2(Channel *); -static void chan_send_eof2(Channel *); -static void chan_send_eow2(Channel *); - -/* helper */ -static void chan_shutdown_write(Channel *); -static void chan_shutdown_read(Channel *); - -static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; -static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; - -static void -chan_set_istate(Channel *c, u_int next) -{ - if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED) - fatal("chan_set_istate: bad state %d -> %d", c->istate, next); - debug("channel %d: input %s -> %s", c->self, istates[c->istate], - istates[next]); - c->istate = next; -} -static void -chan_set_ostate(Channel *c, u_int next) -{ - if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED) - fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next); - debug("channel %d: output %s -> %s", c->self, ostates[c->ostate], - ostates[next]); - c->ostate = next; -} - -/* - * SSH1 specific implementation of event functions - */ - -static void -chan_rcvd_oclose1(Channel *c) -{ - debug("channel %d: rcvd oclose", c->self); - switch (c->istate) { - case CHAN_INPUT_WAIT_OCLOSE: - chan_set_istate(c, CHAN_INPUT_CLOSED); - break; - case CHAN_INPUT_OPEN: - chan_shutdown_read(c); - chan_send_ieof1(c); - chan_set_istate(c, CHAN_INPUT_CLOSED); - break; - case CHAN_INPUT_WAIT_DRAIN: - /* both local read_failed and remote write_failed */ - chan_send_ieof1(c); - chan_set_istate(c, CHAN_INPUT_CLOSED); - break; - default: - error("channel %d: protocol error: rcvd_oclose for istate %d", - c->self, c->istate); - return; - } -} -void -chan_read_failed(Channel *c) -{ - debug("channel %d: read failed", c->self); - switch (c->istate) { - case CHAN_INPUT_OPEN: - chan_shutdown_read(c); - chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); - break; - default: - error("channel %d: chan_read_failed for istate %d", - c->self, c->istate); - break; - } -} -void -chan_ibuf_empty(Channel *c) -{ - debug("channel %d: ibuf empty", c->self); - if (buffer_len(&c->input)) { - error("channel %d: chan_ibuf_empty for non empty buffer", - c->self); - return; - } - switch (c->istate) { - case CHAN_INPUT_WAIT_DRAIN: - if (compat20) { - if (!(c->flags & CHAN_CLOSE_SENT)) - chan_send_eof2(c); - chan_set_istate(c, CHAN_INPUT_CLOSED); - } else { - chan_send_ieof1(c); - chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE); - } - break; - default: - error("channel %d: chan_ibuf_empty for istate %d", - c->self, c->istate); - break; - } -} -static void -chan_rcvd_ieof1(Channel *c) -{ - debug("channel %d: rcvd ieof", c->self); - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); - break; - case CHAN_OUTPUT_WAIT_IEOF: - chan_set_ostate(c, CHAN_OUTPUT_CLOSED); - break; - default: - error("channel %d: protocol error: rcvd_ieof for ostate %d", - c->self, c->ostate); - break; - } -} -static void -chan_write_failed1(Channel *c) -{ - debug("channel %d: write failed", c->self); - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - chan_shutdown_write(c); - chan_send_oclose1(c); - chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF); - break; - case CHAN_OUTPUT_WAIT_DRAIN: - chan_shutdown_write(c); - chan_send_oclose1(c); - chan_set_ostate(c, CHAN_OUTPUT_CLOSED); - break; - default: - error("channel %d: chan_write_failed for ostate %d", - c->self, c->ostate); - break; - } -} -void -chan_obuf_empty(Channel *c) -{ - debug("channel %d: obuf empty", c->self); - if (buffer_len(&c->output)) { - error("channel %d: chan_obuf_empty for non empty buffer", - c->self); - return; - } - switch (c->ostate) { - case CHAN_OUTPUT_WAIT_DRAIN: - chan_shutdown_write(c); - if (!compat20) - chan_send_oclose1(c); - chan_set_ostate(c, CHAN_OUTPUT_CLOSED); - break; - default: - error("channel %d: internal error: obuf_empty for ostate %d", - c->self, c->ostate); - break; - } -} -static void -chan_send_ieof1(Channel *c) -{ - debug("channel %d: send ieof", c->self); - switch (c->istate) { - case CHAN_INPUT_OPEN: - case CHAN_INPUT_WAIT_DRAIN: - packet_start(SSH_MSG_CHANNEL_INPUT_EOF); - packet_put_int(c->remote_id); - packet_send(); - break; - default: - error("channel %d: cannot send ieof for istate %d", - c->self, c->istate); - break; - } -} -static void -chan_send_oclose1(Channel *c) -{ - debug("channel %d: send oclose", c->self); - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - case CHAN_OUTPUT_WAIT_DRAIN: - buffer_clear(&c->output); - packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); - packet_put_int(c->remote_id); - packet_send(); - break; - default: - error("channel %d: cannot send oclose for ostate %d", - c->self, c->ostate); - break; - } -} - -/* - * the same for SSH2 - */ -static void -chan_rcvd_close2(Channel *c) -{ - debug("channel %d: rcvd close", c->self); - if (c->flags & CHAN_CLOSE_RCVD) - error("channel %d: protocol error: close rcvd twice", c->self); - c->flags |= CHAN_CLOSE_RCVD; - if (c->type == SSH_CHANNEL_LARVAL) { - /* tear down larval channels immediately */ - chan_set_ostate(c, CHAN_OUTPUT_CLOSED); - chan_set_istate(c, CHAN_INPUT_CLOSED); - return; - } - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - /* - * wait until a data from the channel is consumed if a CLOSE - * is received - */ - chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); - break; - } - switch (c->istate) { - case CHAN_INPUT_OPEN: - chan_shutdown_read(c); - chan_set_istate(c, CHAN_INPUT_CLOSED); - break; - case CHAN_INPUT_WAIT_DRAIN: - chan_send_eof2(c); - chan_set_istate(c, CHAN_INPUT_CLOSED); - break; - } -} -void -chan_rcvd_eow(Channel *c) -{ - debug2("channel %d: rcvd eow", c->self); - switch (c->istate) { - case CHAN_INPUT_OPEN: - chan_shutdown_read(c); - chan_set_istate(c, CHAN_INPUT_CLOSED); - break; - } -} -static void -chan_rcvd_eof2(Channel *c) -{ - debug("channel %d: rcvd eof", c->self); - c->flags |= CHAN_EOF_RCVD; - if (c->ostate == CHAN_OUTPUT_OPEN) - chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); -} -static void -chan_write_failed2(Channel *c) -{ - debug("channel %d: write failed", c->self); - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - case CHAN_OUTPUT_WAIT_DRAIN: - chan_shutdown_write(c); - if (strcmp(c->ctype, "session") == 0) - chan_send_eow2(c); - chan_set_ostate(c, CHAN_OUTPUT_CLOSED); - break; - default: - error("channel %d: chan_write_failed for ostate %d", - c->self, c->ostate); - break; - } -} -static void -chan_send_eof2(Channel *c) -{ - debug("channel %d: send eof", c->self); - switch (c->istate) { - case CHAN_INPUT_WAIT_DRAIN: - packet_start(SSH2_MSG_CHANNEL_EOF); - packet_put_int(c->remote_id); - packet_send(); - c->flags |= CHAN_EOF_SENT; - break; - default: - error("channel %d: cannot send eof for istate %d", - c->self, c->istate); - break; - } -} -static void -chan_send_close2(Channel *c) -{ - debug("channel %d: send close", c->self); - if (c->ostate != CHAN_OUTPUT_CLOSED || - c->istate != CHAN_INPUT_CLOSED) { - error("channel %d: cannot send close for istate/ostate %d/%d", - c->self, c->istate, c->ostate); - } else if (c->flags & CHAN_CLOSE_SENT) { - error("channel %d: already sent close", c->self); - } else { - packet_start(SSH2_MSG_CHANNEL_CLOSE); - packet_put_int(c->remote_id); - packet_send(); - c->flags |= CHAN_CLOSE_SENT; - } -} -static void -chan_send_eow2(Channel *c) -{ - debug2("channel %d: send eow", c->self); - if (c->ostate == CHAN_OUTPUT_CLOSED) { - error("channel %d: must not sent eow on closed output", - c->self); - return; - } - packet_start(SSH2_MSG_CHANNEL_REQUEST); - packet_put_int(c->remote_id); - packet_put_cstring("eow@openssh.com"); - packet_put_char(0); - packet_send(); -} - -/* shared */ - -void -chan_rcvd_ieof(Channel *c) -{ - if (compat20) - chan_rcvd_eof2(c); - else - chan_rcvd_ieof1(c); - if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && - buffer_len(&c->output) == 0 && - !CHANNEL_EFD_OUTPUT_ACTIVE(c)) - chan_obuf_empty(c); -} -void -chan_rcvd_oclose(Channel *c) -{ - if (compat20) - chan_rcvd_close2(c); - else - chan_rcvd_oclose1(c); -} -void -chan_write_failed(Channel *c) -{ - if (compat20) - chan_write_failed2(c); - else - chan_write_failed1(c); -} - -void -chan_mark_dead(Channel *c) -{ - c->type = SSH_CHANNEL_ZOMBIE; -} - -int -chan_is_dead(Channel *c, int send) -{ - if (c->type == SSH_CHANNEL_ZOMBIE) { - debug("channel %d: zombie", c->self); - return 1; - } - if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) - return 0; - if (!compat20) { - debug("channel %d: is dead", c->self); - return 1; - } - if ((datafellows & SSH_BUG_EXTEOF) && - c->extended_usage == CHAN_EXTENDED_WRITE && - c->efd != -1 && - buffer_len(&c->extended) > 0) { - debug2("channel %d: active efd: %d len %d", - c->self, c->efd, buffer_len(&c->extended)); - return 0; - } - if (!(c->flags & CHAN_CLOSE_SENT)) { - if (send) { - chan_send_close2(c); - } else { - /* channel would be dead if we sent a close */ - if (c->flags & CHAN_CLOSE_RCVD) { - debug("channel %d: almost dead", - c->self); - return 1; - } - } - } - if ((c->flags & CHAN_CLOSE_SENT) && - (c->flags & CHAN_CLOSE_RCVD)) { - debug("channel %d: is dead", c->self); - return 1; - } - return 0; -} - -/* helper */ -static void -chan_shutdown_write(Channel *c) -{ - buffer_clear(&c->output); - if (compat20 && c->type == SSH_CHANNEL_LARVAL) - return; - /* shutdown failure is allowed if write failed already */ - debug("channel %d: close_write", c->self); - if (c->sock != -1) { - if (shutdown(c->sock, SHUT_WR) < 0) - debug("channel %d: chan_shutdown_write: " - "shutdown() failed for fd%d: %.100s", - c->self, c->sock, strerror(errno)); - } else { - if (channel_close_fd(&c->wfd) < 0) - log("channel %d: chan_shutdown_write: " - "close() failed for fd%d: %.100s", - c->self, c->wfd, strerror(errno)); - } -} -static void -chan_shutdown_read(Channel *c) -{ - if (compat20 && c->type == SSH_CHANNEL_LARVAL) - return; - debug("channel %d: close_read", c->self); - if (c->sock != -1) { - /* - * shutdown(sock, SHUT_READ) may return ENOTCONN if the - * write side has been closed already. (bug on Linux) - * HP-UX may return ENOTCONN also. - */ - if (shutdown(c->sock, SHUT_RD) < 0 - && errno != ENOTCONN) - error("channel %d: chan_shutdown_read: " - "shutdown() failed for fd%d [i%d o%d]: %.100s", - c->self, c->sock, c->istate, c->ostate, - strerror(errno)); - } else { - if (channel_close_fd(&c->rfd) < 0) - log("channel %d: chan_shutdown_read: " - "close() failed for fd%d: %.100s", - c->self, c->rfd, strerror(errno)); - } -} diff --git a/usr/src/cmd/ssh/libssh/common/packet.c b/usr/src/cmd/ssh/libssh/common/packet.c deleted file mode 100644 index 1221db134a..0000000000 --- a/usr/src/cmd/ssh/libssh/common/packet.c +++ /dev/null @@ -1,1845 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* $OpenBSD: packet.c,v 1.148 2007/06/07 19:37:34 pvalchev Exp $ */ - -#include "includes.h" - -#include "sys-queue.h" -#include "xmalloc.h" -#include "buffer.h" -#include "packet.h" -#include "bufaux.h" -#include "crc32.h" -#include "getput.h" -#include "compress.h" -#include "deattack.h" -#include "channels.h" -#include "compat.h" -#include "ssh1.h" -#include "ssh2.h" -#include "cipher.h" -#include "kex.h" -#include "mac.h" -#include "log.h" -#include "canohost.h" -#include "misc.h" -#include "ssh.h" -#include "engine.h" - -/* PKCS#11 engine */ -ENGINE *e; - -#ifdef ALTPRIVSEP -static int packet_server = 0; -static int packet_monitor = 0; -#endif /* ALTPRIVSEP */ - -#ifdef PACKET_DEBUG -#define DBG(x) x -#else -#define DBG(x) -#endif - -static void packet_send2(void); - -/* - * This variable contains the file descriptors used for communicating with - * the other side. connection_in is used for reading; connection_out for - * writing. These can be the same descriptor, in which case it is assumed to - * be a socket. - */ -static int connection_in = -1; -static int connection_out = -1; - -/* Protocol flags for the remote side. */ -static u_int remote_protocol_flags = 0; - -/* Encryption context for receiving data. This is only used for decryption. */ -static CipherContext receive_context; - -/* Encryption context for sending data. This is only used for encryption. */ -static CipherContext send_context; - -/* Buffer for raw input data from the socket. */ -Buffer input; - -/* Buffer for raw output data going to the socket. */ -Buffer output; - -/* Buffer for the partial outgoing packet being constructed. */ -static Buffer outgoing_packet; - -/* Buffer for the incoming packet currently being processed. */ -static Buffer incoming_packet; - -/* Scratch buffer for packet compression/decompression. */ -static Buffer compression_buffer; -static int compression_buffer_ready = 0; - -/* Flag indicating whether packet compression/decompression is enabled. */ -static int packet_compression = 0; - -/* default maximum packet size */ -int max_packet_size = 32768; - -/* Flag indicating whether this module has been initialized. */ -static int initialized = 0; - -/* Set to true if the connection is interactive. */ -static int interactive_mode = 0; - -/* Session key information for Encryption and MAC */ -Newkeys *newkeys[MODE_MAX]; -static struct packet_state { - u_int32_t seqnr; - u_int32_t packets; - u_int64_t blocks; -} p_read, p_send; - -static u_int64_t max_blocks_in, max_blocks_out; -static u_int32_t rekey_limit; - -/* Session key for protocol v1 */ -static u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; -static u_int ssh1_keylen; - -/* roundup current message to extra_pad bytes */ -static u_char extra_pad = 0; - -struct packet { - TAILQ_ENTRY(packet) next; - u_char type; - Buffer payload; -}; -TAILQ_HEAD(, packet) outgoing; - -/* - * Part of what -f option and ~& escape sequence do in the client is that they - * will force it to daemonize itself. Due to the fork safety rules inherent in - * any PKCS#11 environment, if the engine is used we must do a key re-exchange - * before forking a child to negotiate the new keys. Those keys will be used to - * inicialize the new crypto contexts. This involves finishing the engine in the - * parent and reinitializing it again in both processes after fork() returns. - * This approach also leaves protocol 1 out since it doesn't support rekeying. - */ -int will_daemonize; - -#ifdef PACKET_DEBUG -/* This function dumps data onto stderr. This is for debugging only. */ -void -data_dump(void *data, u_int len) -{ - Buffer buf; - - buffer_init(&buf); - buffer_append(&buf, data, len); - buffer_dump(&buf); - buffer_free(&buf); -} -#endif - -/* - * Sets the descriptors used for communication. Disables encryption until - * packet_set_encryption_key is called. - */ -void -packet_set_connection(int fd_in, int fd_out) -{ - Cipher *none = cipher_by_name("none"); - - if (none == NULL) - fatal("packet_set_connection: cannot load cipher 'none'"); - connection_in = fd_in; - connection_out = fd_out; - cipher_init(&send_context, none, (unsigned char *) "", 0, NULL, 0, CIPHER_ENCRYPT); - cipher_init(&receive_context, none, (unsigned char *) "", 0, NULL, 0, CIPHER_DECRYPT); - newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; - if (!initialized) { - initialized = 1; - buffer_init(&input); - buffer_init(&output); - buffer_init(&outgoing_packet); - buffer_init(&incoming_packet); - TAILQ_INIT(&outgoing); - } else { - buffer_clear(&input); - buffer_clear(&output); - buffer_clear(&outgoing_packet); - buffer_clear(&incoming_packet); - } - - /* - * Prime the cache for get_remote_ipaddr() while we have a - * socket on which to do a getpeername(). - */ - (void) get_remote_ipaddr(); - - /* Kludge: arrange the close function to be called from fatal(). */ - fatal_add_cleanup((void (*) (void *)) packet_close, NULL); -} - -/* Returns 1 if remote host is connected via socket, 0 if not. */ - -int -packet_connection_is_on_socket(void) -{ - struct sockaddr_storage from, to; - socklen_t fromlen, tolen; - - /* filedescriptors in and out are the same, so it's a socket */ - if (connection_in != -1 && connection_in == connection_out) - return 1; - fromlen = sizeof(from); - memset(&from, 0, sizeof(from)); - if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0) - return 0; - tolen = sizeof(to); - memset(&to, 0, sizeof(to)); - if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0) - return 0; - if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) - return 0; - if (from.ss_family != AF_INET && from.ss_family != AF_INET6) - return 0; - return 1; -} - -/* returns 1 if connection is via ipv4 */ - -int -packet_connection_is_ipv4(void) -{ - struct sockaddr_storage to; - socklen_t tolen = sizeof(to); - - memset(&to, 0, sizeof(to)); - if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0) - return 0; - if (to.ss_family == AF_INET) - return 1; -#ifdef IPV4_IN_IPV6 - if (to.ss_family == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) - return 1; -#endif - return 0; -} - -/* Sets the connection into non-blocking mode. */ - -void -packet_set_nonblocking(void) -{ - /* Set the socket into non-blocking mode. */ - if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %.100s", strerror(errno)); - - if (connection_out != connection_in) { - if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %.100s", strerror(errno)); - } -} - -/* Returns the socket used for reading. */ - -int -packet_get_connection_in(void) -{ - return connection_in; -} - -/* Returns the descriptor used for writing. */ - -int -packet_get_connection_out(void) -{ - return connection_out; -} - -/* Closes the connection and clears and frees internal data structures. */ - -void -packet_close(void) -{ - if (!initialized) - return; - initialized = 0; - if (connection_in == connection_out) { - shutdown(connection_out, SHUT_RDWR); - close(connection_out); - } else { - close(connection_in); - close(connection_out); - } - buffer_free(&input); - buffer_free(&output); - buffer_free(&outgoing_packet); - buffer_free(&incoming_packet); - if (compression_buffer_ready) { - buffer_free(&compression_buffer); - buffer_compress_uninit(); - compression_buffer_ready = 0; - } - cipher_cleanup(&send_context); - cipher_cleanup(&receive_context); -} - -/* Sets remote side protocol flags. */ - -void -packet_set_protocol_flags(u_int protocol_flags) -{ - remote_protocol_flags = protocol_flags; -} - -/* Returns the remote protocol flags set earlier by the above function. */ - -u_int -packet_get_protocol_flags(void) -{ - return remote_protocol_flags; -} - -/* - * Starts packet compression from the next packet on in both directions. - * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. - */ - -static void -packet_init_compression(void) -{ - if (compression_buffer_ready == 1) - return; - compression_buffer_ready = 1; - buffer_init(&compression_buffer); -} - -void -packet_start_compression(int level) -{ -#ifdef ALTPRIVSEP - /* shouldn't happen! */ - if (packet_monitor) - fatal("INTERNAL ERROR: The monitor cannot compress."); -#endif /* ALTPRIVSEP */ - - if (packet_compression && !compat20) - fatal("Compression already enabled."); - packet_compression = 1; - packet_init_compression(); - buffer_compress_init_send(level); - buffer_compress_init_recv(); -} - -/* - * Causes any further packets to be encrypted using the given key. The same - * key is used for both sending and reception. However, both directions are - * encrypted independently of each other. - */ - -void -packet_set_encryption_key(const u_char *key, u_int keylen, - int number) -{ - Cipher *cipher = cipher_by_number(number); - - if (cipher == NULL) - fatal("packet_set_encryption_key: unknown cipher number %d", number); - if (keylen < 20) - fatal("packet_set_encryption_key: keylen too small: %d", keylen); - if (keylen > SSH_SESSION_KEY_LENGTH) - fatal("packet_set_encryption_key: keylen too big: %d", keylen); - memcpy(ssh1_key, key, keylen); - ssh1_keylen = keylen; - cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT); - cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT); -} - -u_int -packet_get_encryption_key(u_char *key) -{ - if (key == NULL) - return (ssh1_keylen); - memcpy(key, ssh1_key, ssh1_keylen); - return (ssh1_keylen); -} - -/* Start constructing a packet to send. */ -void -packet_start(u_char type) -{ - u_char buf[9]; - int len; - - DBG(debug("packet_start[%d]", type)); - len = compat20 ? 6 : 9; - memset(buf, 0, len - 1); - buf[len - 1] = type; - buffer_clear(&outgoing_packet); - buffer_append(&outgoing_packet, buf, len); -} - -/* Append payload. */ -void -packet_put_char(int value) -{ - char ch = value; - - buffer_append(&outgoing_packet, &ch, 1); -} - -void -packet_put_int(u_int value) -{ - buffer_put_int(&outgoing_packet, value); -} - -void -packet_put_string(const void *buf, u_int len) -{ - buffer_put_string(&outgoing_packet, buf, len); -} - -void -packet_put_cstring(const char *str) -{ - buffer_put_cstring(&outgoing_packet, str); -} - -void -packet_put_utf8_cstring(const char *str) -{ - if (datafellows & SSH_BUG_STRING_ENCODING) - buffer_put_cstring(&outgoing_packet, str); - else - buffer_put_utf8_cstring(&outgoing_packet, str); -} - -void -packet_put_utf8_string(const char *str, uint_t len) -{ - if (datafellows & SSH_BUG_STRING_ENCODING) - buffer_put_string(&outgoing_packet, str, len); - else - buffer_put_utf8_string(&outgoing_packet, str, len); -} - -void -packet_put_raw(const void *buf, u_int len) -{ - buffer_append(&outgoing_packet, buf, len); -} - -void -packet_put_bignum(BIGNUM * value) -{ - buffer_put_bignum(&outgoing_packet, value); -} - -void -packet_put_bignum2(BIGNUM * value) -{ - buffer_put_bignum2(&outgoing_packet, value); -} - -/* - * Finalizes and sends the packet. If the encryption key has been set, - * encrypts the packet before sending. - */ - -static void -packet_send1(void) -{ - u_char buf[8], *cp; - int i, padding, len; - u_int checksum; - u_int32_t rnd = 0; - - /* - * If using packet compression, compress the payload of the outgoing - * packet. - */ - if (packet_compression) { - buffer_clear(&compression_buffer); - /* Skip padding. */ - buffer_consume(&outgoing_packet, 8); - /* padding */ - buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); - buffer_compress(&outgoing_packet, &compression_buffer); - buffer_clear(&outgoing_packet); - buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), - buffer_len(&compression_buffer)); - } - /* Compute packet length without padding (add checksum, remove padding). */ - len = buffer_len(&outgoing_packet) + 4 - 8; - - /* Insert padding. Initialized to zero in packet_start1() */ - padding = 8 - len % 8; - if (!send_context.plaintext) { - cp = buffer_ptr(&outgoing_packet); - for (i = 0; i < padding; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cp[7 - i] = rnd & 0xff; - rnd >>= 8; - } - } - buffer_consume(&outgoing_packet, 8 - padding); - - /* Add check bytes. */ - checksum = ssh_crc32(buffer_ptr(&outgoing_packet), - buffer_len(&outgoing_packet)); - PUT_32BIT(buf, checksum); - buffer_append(&outgoing_packet, buf, 4); - -#ifdef PACKET_DEBUG - fprintf(stderr, "packet_send plain: "); - buffer_dump(&outgoing_packet); -#endif - - /* Append to output. */ - PUT_32BIT(buf, len); - buffer_append(&output, buf, 4); - cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); - cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), - buffer_len(&outgoing_packet)); - -#ifdef PACKET_DEBUG - debug("encrypted output queue now contains (%d bytes):\n", - buffer_len(&output)); - buffer_dump(&output); -#endif - - buffer_clear(&outgoing_packet); - - /* - * Note that the packet is now only buffered in output. It won\'t be - * actually sent until packet_write_wait or packet_write_poll is - * called. - */ -} - -void -set_newkeys(int mode) -{ - Enc *enc; - Mac *mac; - Comp *comp; - CipherContext *cc; - u_int64_t *max_blocks; - int crypt_type; - - debug2("set_newkeys: mode %d", mode); - - if (mode == MODE_OUT) { - cc = &send_context; - crypt_type = CIPHER_ENCRYPT; - p_send.packets = p_send.blocks = 0; - max_blocks = &max_blocks_out; - } else { - cc = &receive_context; - crypt_type = CIPHER_DECRYPT; - p_read.packets = p_read.blocks = 0; - max_blocks = &max_blocks_in; - } - - debug("set_newkeys: setting new keys for '%s' mode", - mode == MODE_IN ? "in" : "out"); - - if (newkeys[mode] != NULL) { - cipher_cleanup(cc); - free_keys(newkeys[mode]); - } - - newkeys[mode] = kex_get_newkeys(mode); - if (newkeys[mode] == NULL) - fatal("newkeys: no keys for mode %d", mode); - enc = &newkeys[mode]->enc; - mac = &newkeys[mode]->mac; - comp = &newkeys[mode]->comp; - if (mac_init(mac) == 0) - mac->enabled = 1; -#ifdef PACKET_DEBUG - debug("new encryption key:\n"); - data_dump(enc->key, enc->key_len); - debug("new encryption IV:\n"); - data_dump(enc->iv, enc->block_size); - debug("new MAC key:\n"); - data_dump(mac->key, mac->key_len); -#endif - cipher_init(cc, enc->cipher, enc->key, enc->key_len, - enc->iv, enc->block_size, crypt_type); - /* Deleting the keys does not gain extra security */ - /* memset(enc->iv, 0, enc->block_size); - memset(enc->key, 0, enc->key_len); */ - if (comp->type != 0 && comp->enabled == 0) { - packet_init_compression(); - if (mode == MODE_OUT) - buffer_compress_init_send(6); - else - buffer_compress_init_recv(); - comp->enabled = 1; - } - - /* - * In accordance to the RFCs listed below we enforce the key - * re-exchange for: - * - * - every 1GB of transmitted data if the selected cipher block size - * is less than 16 bytes (3DES, Blowfish) - * - every 2^(2*B) cipher blocks transmitted (B is block size in bytes) - * if the cipher block size is greater than or equal to 16 bytes (AES) - * - and we never send more than 2^32 SSH packets using the same keys. - * The recommendation of 2^31 packets is not enforced here but in - * packet_need_rekeying(). There is also a hard check in - * packet_send2_wrapped() that we don't send more than 2^32 packets. - * - * Note that if the SSH_BUG_NOREKEY compatibility flag is set then no - * automatic rekeying is performed nor do we enforce the 3rd rule. - * This means that we can be always forced by the opposite side to never - * initiate automatic key re-exchange. This might change in the future. - * - * The RekeyLimit option keyword may only enforce more frequent key - * renegotiation, never less. For more information on key renegotiation, - * see: - * - * - RFC 4253 (SSH Transport Layer Protocol), section "9. Key - * Re-Exchange" - * - RFC 4344 (SSH Transport Layer Encryption Modes), sections "3. - * Rekeying" and "6.1 Rekeying Considerations" - */ - if (enc->block_size >= 16) - *max_blocks = (u_int64_t)1 << (enc->block_size * 2); - else - *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; - - if (rekey_limit) - *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size); -} - -void -free_keys(Newkeys *keys) -{ - Enc *enc; - Mac *mac; - Comp *comp; - - enc = &keys->enc; - mac = &keys->mac; - comp = &keys->comp; - xfree(enc->name); - xfree(enc->iv); - xfree(enc->key); - - memset(mac->key, 0, mac->key_len); - xfree(mac->key); - xfree(mac->name); - mac_clear(mac); - - xfree(comp->name); - xfree(keys); -} - -/* - * Process SSH2_MSG_NEWKEYS message. If we are using the engine we must have - * both SSH2_MSG_NEWKEYS processed before we can finish the engine, fork, and - * reinitialize the crypto contexts. We can't fork before processing the 2nd - * message otherwise we couldn't encrypt/decrypt that message at all - note that - * parent's PKCS#11 sessions are useless after the fork and we must process - * both SSH2_MSG_NEWKEYS messages using the old keys. - */ -void -process_newkeys(int mode) -{ - /* this function is for the client only */ - if (packet_is_server() != 0) - return; - - if (will_daemonize == FIRST_NEWKEYS_PROCESSED) { - debug3("both SSH2_MSG_NEWKEYS processed, will daemonize now"); - cipher_cleanup(&send_context); - cipher_cleanup(&receive_context); - pkcs11_engine_finish(e); - if (daemon(1, 1) < 0) { - fatal("daemon() failed: %.200s", - strerror(errno)); - } - e = pkcs11_engine_load(e != NULL ? 1 : 0); - - set_newkeys(MODE_OUT); - set_newkeys(MODE_IN); - will_daemonize = SECOND_NEWKEYS_PROCESSED; - packet_send2(); - } else { - if (will_daemonize == DAEMONIZING_REQUESTED) - will_daemonize = FIRST_NEWKEYS_PROCESSED; - else - set_newkeys(mode); - } -} - -/* - * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) - */ -static void -packet_send2_wrapped(void) -{ - u_char type, *cp, *macbuf = NULL; - u_char padlen, pad; - u_int packet_length = 0; - u_int i, len; - u_int32_t rnd = 0; - Enc *enc = NULL; - Mac *mac = NULL; - Comp *comp = NULL; - int block_size; - - if (newkeys[MODE_OUT] != NULL) { - enc = &newkeys[MODE_OUT]->enc; - mac = &newkeys[MODE_OUT]->mac; - comp = &newkeys[MODE_OUT]->comp; - } - block_size = enc ? enc->block_size : 8; - - cp = buffer_ptr(&outgoing_packet); - type = cp[5]; - -#ifdef PACKET_DEBUG - debug("plain output packet to be processed (%d bytes):\n", - buffer_len(&outgoing_packet)); - buffer_dump(&outgoing_packet); -#endif - - if (comp && comp->enabled) { - len = buffer_len(&outgoing_packet); - /* skip header, compress only payload */ - buffer_consume(&outgoing_packet, 5); - buffer_clear(&compression_buffer); - buffer_compress(&outgoing_packet, &compression_buffer); - buffer_clear(&outgoing_packet); - buffer_append(&outgoing_packet, "\0\0\0\0\0", 5); - buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), - buffer_len(&compression_buffer)); - DBG(debug("compression: raw %d compressed %d", len, - buffer_len(&outgoing_packet))); - } - - /* sizeof (packet_len + pad_len + payload) */ - len = buffer_len(&outgoing_packet); - - /* - * calc size of padding, alloc space, get random data, - * minimum padding is 4 bytes - */ - padlen = block_size - (len % block_size); - if (padlen < 4) - padlen += block_size; - if (extra_pad) { - /* will wrap if extra_pad+padlen > 255 */ - extra_pad = roundup(extra_pad, block_size); - pad = extra_pad - ((len + padlen) % extra_pad); - debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", - pad, len, padlen, extra_pad); - padlen += pad; - extra_pad = 0; - } - cp = buffer_append_space(&outgoing_packet, padlen); - if (enc && !send_context.plaintext) { - /* random padding */ - for (i = 0; i < padlen; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cp[i] = rnd & 0xff; - rnd >>= 8; - } - } else { - /* clear padding */ - memset(cp, 0, padlen); - } - /* packet_length includes payload, padding and padding length field */ - packet_length = buffer_len(&outgoing_packet) - 4; - cp = buffer_ptr(&outgoing_packet); - PUT_32BIT(cp, packet_length); - cp[4] = padlen; - DBG(debug("will send %d bytes (includes padlen %d)", - packet_length + 4, padlen)); - - /* compute MAC over seqnr and packet(length fields, payload, padding) */ - if (mac && mac->enabled) { - macbuf = mac_compute(mac, p_send.seqnr, - buffer_ptr(&outgoing_packet), - buffer_len(&outgoing_packet)); - DBG(debug("done calc MAC out #%d", p_send.seqnr)); - } - /* encrypt packet and append to output buffer. */ - cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); - cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), - buffer_len(&outgoing_packet)); - /* append unencrypted MAC */ - if (mac && mac->enabled) - buffer_append(&output, (char *)macbuf, mac->mac_len); -#ifdef PACKET_DEBUG - debug("encrypted output queue now contains (%d bytes):\n", - buffer_len(&output)); - buffer_dump(&output); -#endif - /* increment sequence number for outgoing packets */ - if (++p_send.seqnr == 0) - log("outgoing seqnr wraps around"); - - /* - * RFC 4344: 3.1. First Rekeying Recommendation - * - * "Because of possible information leakage through the MAC tag after a - * key exchange, .... an SSH implementation SHOULD NOT send more than - * 2**32 packets before rekeying again." - * - * The code below is a hard check so that we are sure we don't go across - * the suggestion. However, since the largest cipher block size we have - * (AES) is 16 bytes we can't reach 2^32 SSH packets encrypted with the - * same key while performing periodic rekeying. - */ - if (++p_send.packets == 0) - if (!(datafellows & SSH_BUG_NOREKEY)) - fatal("too many packets encrypted with same key"); - p_send.blocks += (packet_length + 4) / block_size; - buffer_clear(&outgoing_packet); - - if (type == SSH2_MSG_NEWKEYS) { - /* - * set_newkeys(MODE_OUT) in the client. Note that in the - * unprivileged child, set_newkeys() for MODE_OUT are set after - * SSH2_MSG_NEWKEYS is read from the monitor and forwarded to - * the client side. - */ - process_newkeys(MODE_OUT); - } -} - -/* - * Packets we deal with here are plain until we encrypt them in - * packet_send2_wrapped(). - * - * As already mentioned in a comment at process_newkeys() function we must not - * fork() until both SSH2_MSG_NEWKEYS packets were processed. Until this is done - * we must queue all packets so that they can be encrypted with the new keys and - * then sent to the other side. However, what can happen here is that we get - * SSH2_MSG_NEWKEYS after we sent it. In that situation we must call - * packet_send2() anyway to empty the queue, and set the rekey flag to the - * finished state. If we didn't do that we would just hang and enqueue data. - */ -static void -packet_send2(void) -{ - static int rekeying = 0; - struct packet *p; - u_char type, *cp; - - if (will_daemonize != SECOND_NEWKEYS_PROCESSED) { - cp = buffer_ptr(&outgoing_packet); - type = cp[5]; - - /* during rekeying we can only send key exchange messages */ - if (rekeying) { - if (!((type >= SSH2_MSG_TRANSPORT_MIN) && - (type <= SSH2_MSG_TRANSPORT_MAX))) { - debug("enqueue a plain packet because rekex in " - "progress [type %u]", type); - p = xmalloc(sizeof(*p)); - p->type = type; - memcpy(&p->payload, &outgoing_packet, sizeof(Buffer)); - buffer_init(&outgoing_packet); - TAILQ_INSERT_TAIL(&outgoing, p, next); - return; - } - } - - /* rekeying starts with sending KEXINIT */ - if (type == SSH2_MSG_KEXINIT) - rekeying = 1; - - packet_send2_wrapped(); - } - - /* after rekex is done we can process the queue of plain packets */ - if (will_daemonize == SECOND_NEWKEYS_PROCESSED || - (will_daemonize == NOT_DAEMONIZING && type == SSH2_MSG_NEWKEYS)) { - rekeying = 0; - will_daemonize = NOT_DAEMONIZING; - while ((p = TAILQ_FIRST(&outgoing)) != NULL) { - type = p->type; - debug("dequeuing a plain packet since rekex is over " - "[type %u]", type); - buffer_free(&outgoing_packet); - memcpy(&outgoing_packet, &p->payload, sizeof(Buffer)); - TAILQ_REMOVE(&outgoing, p, next); - xfree(p); - packet_send2_wrapped(); - } - } -} - -void -packet_send(void) -{ - if (compat20) - packet_send2(); - else - packet_send1(); - DBG(debug("packet_send done")); -} - -/* - * Waits until a packet has been received, and returns its type. Note that - * no other data is processed until this returns, so this function should not - * be used during the interactive session. - * - * The function is also used in the monitor to read the authentication context - * in aps_read_auth_context() via packet_read_seqnr(), before the monitor enters - * aps_monitor_loop() and starts using the process_input() function. - */ -int -packet_read_seqnr(u_int32_t *seqnr_p) -{ - int type, len; - fd_set *setp; - char buf[8192]; - DBG(debug("packet_read()")); - - setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) * - sizeof(fd_mask)); - - /* Since we are blocking, ensure that all written packets have been sent. */ - packet_write_wait(); - - /* Stay in the loop until we have received a complete packet. */ - for (;;) { - /* Try to read a packet from the buffer. */ - type = packet_read_poll_seqnr(seqnr_p); - if (!compat20 && ( - type == SSH_SMSG_SUCCESS - || type == SSH_SMSG_FAILURE - || type == SSH_CMSG_EOF - || type == SSH_CMSG_EXIT_CONFIRMATION)) - packet_check_eom(); - /* If we got a packet, return it. */ - if (type != SSH_MSG_NONE) { - xfree(setp); - return type; - } - /* - * Otherwise, wait for some data to arrive, add it to the - * buffer, and try again. - */ - memset(setp, 0, howmany(connection_in + 1, NFDBITS) * - sizeof(fd_mask)); - FD_SET(connection_in, setp); - - /* Wait for some data to arrive. */ - while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && - (errno == EAGAIN || errno == EINTR)) - ; - - /* Read data from the socket. */ - len = read(connection_in, buf, sizeof(buf)); - if (len == 0) { - if (packet_connection_is_on_socket()) - log("Connection closed by %.200s", - get_remote_ipaddr()); - else - debug("child closed the communication pipe " - "before user auth was finished"); - fatal_cleanup(); - } - if (len < 0) { - if (packet_connection_is_on_socket()) - fatal("Read from socket failed: %.100s", - strerror(errno)); - else - fatal("Read from communication pipe failed: " - "%.100s", strerror(errno)); - } - /* Append it to the buffer. */ - packet_process_incoming(buf, len); - } - /* NOTREACHED */ -} - -int -packet_read(void) -{ - return packet_read_seqnr(NULL); -} - -/* - * Waits until a packet has been received, verifies that its type matches - * that given, and gives a fatal error and exits if there is a mismatch. - */ - -void -packet_read_expect(int expected_type) -{ - int type; - - type = packet_read(); - if (type != expected_type) - packet_disconnect("Protocol error: expected packet type %d, got %d", - expected_type, type); -} - -/* Checks if a full packet is available in the data received so far via - * packet_process_incoming. If so, reads the packet; otherwise returns - * SSH_MSG_NONE. This does not wait for data from the connection. - * - * SSH_MSG_DISCONNECT is handled specially here. Also, - * SSH_MSG_IGNORE messages are skipped by this function and are never returned - * to higher levels. - */ - -static int -packet_read_poll1(void) -{ - u_int len, padded_len; - u_char *cp, type; - u_int checksum, stored_checksum; - - /* Check if input size is less than minimum packet size. */ - if (buffer_len(&input) < 4 + 8) - return SSH_MSG_NONE; - /* Get length of incoming packet. */ - cp = buffer_ptr(&input); - len = GET_32BIT(cp); - if (len < 1 + 2 + 2 || len > 256 * 1024) - packet_disconnect("Bad packet length %d.", len); - padded_len = (len + 8) & ~7; - - /* Check if the packet has been entirely received. */ - if (buffer_len(&input) < 4 + padded_len) - return SSH_MSG_NONE; - - /* The entire packet is in buffer. */ - - /* Consume packet length. */ - buffer_consume(&input, 4); - - /* - * Cryptographic attack detector for ssh - * (C)1998 CORE-SDI, Buenos Aires Argentina - * Ariel Futoransky(futo@core-sdi.com) - */ - if (!receive_context.plaintext) { - switch (detect_attack(buffer_ptr(&input), padded_len, NULL)) { - case DEATTACK_DETECTED: - packet_disconnect("crc32 compensation attack: " - "network attack detected"); - break; - case DEATTACK_DOS_DETECTED: - packet_disconnect("deattack denial of " - "service detected"); - break; - } - } - - /* Decrypt data to incoming_packet. */ - buffer_clear(&incoming_packet); - cp = buffer_append_space(&incoming_packet, padded_len); - cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len); - - buffer_consume(&input, padded_len); - -#ifdef PACKET_DEBUG - debug("read_poll plain/full:\n"); - buffer_dump(&incoming_packet); -#endif - - /* Compute packet checksum. */ - checksum = ssh_crc32(buffer_ptr(&incoming_packet), - buffer_len(&incoming_packet) - 4); - - /* Skip padding. */ - buffer_consume(&incoming_packet, 8 - len % 8); - - /* Test check bytes. */ - if (len != buffer_len(&incoming_packet)) - packet_disconnect("packet_read_poll1: len %d != buffer_len %d.", - len, buffer_len(&incoming_packet)); - - cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4; - stored_checksum = GET_32BIT(cp); - if (checksum != stored_checksum) - packet_disconnect("Corrupted check bytes on input."); - buffer_consume_end(&incoming_packet, 4); - - if (packet_compression) { - buffer_clear(&compression_buffer); - buffer_uncompress(&incoming_packet, &compression_buffer); - buffer_clear(&incoming_packet); - buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), - buffer_len(&compression_buffer)); - } - type = buffer_get_char(&incoming_packet); - return type; -} - -static int -packet_read_poll2(u_int32_t *seqnr_p) -{ - static u_int packet_length = 0; - u_int padlen, need; - u_char *macbuf, *cp, type; - int maclen, block_size; - Enc *enc = NULL; - Mac *mac = NULL; - Comp *comp = NULL; - - if (newkeys[MODE_IN] != NULL) { - enc = &newkeys[MODE_IN]->enc; - mac = &newkeys[MODE_IN]->mac; - comp = &newkeys[MODE_IN]->comp; - } - maclen = mac && mac->enabled ? mac->mac_len : 0; - block_size = enc ? enc->block_size : 8; - - if (packet_length == 0) { - /* - * check if input size is less than the cipher block size, - * decrypt first block and extract length of incoming packet - */ - if (buffer_len(&input) < block_size) - return SSH_MSG_NONE; -#ifdef PACKET_DEBUG - debug("encrypted data we have in read queue (%d bytes):\n", - buffer_len(&input)); - buffer_dump(&input); -#endif - buffer_clear(&incoming_packet); - cp = buffer_append_space(&incoming_packet, block_size); - cipher_crypt(&receive_context, cp, buffer_ptr(&input), - block_size); - cp = buffer_ptr(&incoming_packet); - packet_length = GET_32BIT(cp); - if (packet_length < 1 + 4 || packet_length > 256 * 1024) { - packet_disconnect("Bad packet length."); - } - DBG(debug("input: packet len %u", packet_length + 4)); - buffer_consume(&input, block_size); - } - /* we have a partial packet of block_size bytes */ - need = 4 + packet_length - block_size; - DBG(debug("partial packet %d, still need %d, maclen %d", block_size, - need, maclen)); - if (need % block_size != 0) - packet_disconnect("Bad packet length."); - /* - * check if the entire packet has been received and - * decrypt into incoming_packet - */ - if (buffer_len(&input) < need + maclen) - return SSH_MSG_NONE; -#ifdef PACKET_DEBUG - debug("in read_poll, the encrypted input queue now contains " - "(%d bytes):\n", buffer_len(&input)); - buffer_dump(&input); -#endif - cp = buffer_append_space(&incoming_packet, need); - cipher_crypt(&receive_context, cp, buffer_ptr(&input), need); - buffer_consume(&input, need); - /* - * compute MAC over seqnr and packet, - * increment sequence number for incoming packet - */ - if (mac && mac->enabled) { - macbuf = mac_compute(mac, p_read.seqnr, - buffer_ptr(&incoming_packet), - buffer_len(&incoming_packet)); - if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) - packet_disconnect("Corrupted MAC on input."); - DBG(debug("MAC #%d ok", p_read.seqnr)); - buffer_consume(&input, mac->mac_len); - } - if (seqnr_p != NULL) - *seqnr_p = p_read.seqnr; - if (++p_read.seqnr == 0) - log("incoming seqnr wraps around"); - - /* see above for the comment on "First Rekeying Recommendation" */ - if (++p_read.packets == 0) - if (!(datafellows & SSH_BUG_NOREKEY)) - fatal("too many packets with same key"); - p_read.blocks += (packet_length + 4) / block_size; - - /* get padlen */ - cp = buffer_ptr(&incoming_packet); - padlen = cp[4]; - DBG(debug("input: padlen %d", padlen)); - if (padlen < 4) - packet_disconnect("Corrupted padlen %d on input.", padlen); - - /* skip packet size + padlen, discard padding */ - buffer_consume(&incoming_packet, 4 + 1); - buffer_consume_end(&incoming_packet, padlen); - - DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet))); - if (comp && comp->enabled) { - buffer_clear(&compression_buffer); - buffer_uncompress(&incoming_packet, &compression_buffer); - buffer_clear(&incoming_packet); - buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), - buffer_len(&compression_buffer)); - DBG(debug("input: len after de-compress %d", - buffer_len(&incoming_packet))); - } - /* - * get packet type, implies consume. - * return length of payload (without type field) - */ - type = buffer_get_char(&incoming_packet); - if (type == SSH2_MSG_NEWKEYS) { - /* - * set_newkeys(MODE_IN) in the client because it doesn't have a - * dispatch function for SSH2_MSG_NEWKEYS in contrast to the - * server processes. Note that in the unprivileged child, - * set_newkeys() for MODE_IN are set in dispatch function - * altprivsep_rekey() after SSH2_MSG_NEWKEYS packet is received - * from the client. - */ - process_newkeys(MODE_IN); - } - -#ifdef PACKET_DEBUG - debug("decrypted input packet [type %d]:\n", type); - buffer_dump(&incoming_packet); -#endif - /* reset for next packet */ - packet_length = 0; - return type; -} - -/* - * This tries to read a packet from the buffer of received data. Note that it - * doesn't read() anything from the network socket. - */ -int -packet_read_poll_seqnr(u_int32_t *seqnr_p) -{ - u_int reason, seqnr; - u_char type; - char *msg; - - for (;;) { - if (compat20) { - type = packet_read_poll2(seqnr_p); - DBG(debug("received packet type %d", type)); - switch (type) { - case SSH2_MSG_IGNORE: - break; - case SSH2_MSG_DEBUG: - packet_get_char(); - msg = packet_get_utf8_string(NULL); - msg = g11n_filter_string(msg); - debug("Remote: %.900s", msg); - xfree(msg); - msg = packet_get_string(NULL); - xfree(msg); - break; - case SSH2_MSG_DISCONNECT: - reason = packet_get_int(); - msg = packet_get_utf8_string(NULL); - msg = g11n_filter_string(msg); - log("Received disconnect from %s: %u: %.400s", - get_remote_ipaddr(), reason, msg); - xfree(msg); - fatal_cleanup(); - break; - case SSH2_MSG_UNIMPLEMENTED: - seqnr = packet_get_int(); - debug("Received SSH2_MSG_UNIMPLEMENTED for %u", - seqnr); - break; - default: - return type; - break; - } - } else { - type = packet_read_poll1(); - DBG(debug("received packet type %d", type)); - switch (type) { - case SSH_MSG_IGNORE: - break; - case SSH_MSG_DEBUG: - msg = packet_get_string(NULL); - debug("Remote: %.900s", msg); - xfree(msg); - break; - case SSH_MSG_DISCONNECT: - msg = packet_get_string(NULL); - log("Received disconnect from %s: %.400s", - get_remote_ipaddr(), msg); - fatal_cleanup(); - xfree(msg); - break; - default: - return type; - break; - } - } - } -} - -int -packet_read_poll(void) -{ - return packet_read_poll_seqnr(NULL); -} - -/* - * Buffers the given amount of input characters. This is intended to be used - * together with packet_read_poll. - */ - -void -packet_process_incoming(const char *buf, u_int len) -{ - buffer_append(&input, buf, len); -} - -/* Returns a character from the packet. */ - -u_int -packet_get_char(void) -{ - char ch; - - buffer_get(&incoming_packet, &ch, 1); - return (u_char) ch; -} - -/* Returns an integer from the packet data. */ - -u_int -packet_get_int(void) -{ - return buffer_get_int(&incoming_packet); -} - -/* - * Returns an arbitrary precision integer from the packet data. The integer - * must have been initialized before this call. - */ - -void -packet_get_bignum(BIGNUM * value) -{ - buffer_get_bignum(&incoming_packet, value); -} - -void -packet_get_bignum2(BIGNUM * value) -{ - buffer_get_bignum2(&incoming_packet, value); -} - -void * -packet_get_raw(u_int *length_ptr) -{ - u_int bytes = buffer_len(&incoming_packet); - - if (length_ptr != NULL) - *length_ptr = bytes; - return buffer_ptr(&incoming_packet); -} - -int -packet_remaining(void) -{ - return buffer_len(&incoming_packet); -} - -/* - * Returns a string from the packet data. The string is allocated using - * xmalloc; it is the responsibility of the calling program to free it when - * no longer needed. The length_ptr argument may be NULL, or point to an - * integer into which the length of the string is stored. - */ - -void * -packet_get_string(u_int *length_ptr) -{ - return buffer_get_string(&incoming_packet, length_ptr); -} - -char * -packet_get_utf8_string(uint_t *length_ptr) -{ - if (datafellows & SSH_BUG_STRING_ENCODING) - return (buffer_get_string(&incoming_packet, length_ptr)); - else - return (buffer_get_utf8_string(&incoming_packet, length_ptr)); -} - -/* - * Sends a diagnostic message from the server to the client. This message - * can be sent at any time (but not while constructing another message). The - * message is printed immediately, but only if the client is being executed - * in verbose mode. These messages are primarily intended to ease debugging - * authentication problems. The length of the formatted message must not - * exceed 1024 bytes. This will automatically call packet_write_wait. - */ - -void -packet_send_debug(const char *fmt,...) -{ - char buf[1024]; - va_list args; - - if (compat20 && (datafellows & SSH_BUG_DEBUG)) - return; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), gettext(fmt), args); - va_end(args); - -#ifdef ALTPRIVSEP - /* shouldn't happen */ - if (packet_monitor) { - debug("packet_send_debug: %s", buf); - return; - } -#endif /* ALTPRIVSEP */ - - if (compat20) { - packet_start(SSH2_MSG_DEBUG); - packet_put_char(0); /* bool: always display */ - packet_put_utf8_cstring(buf); - packet_put_cstring(""); - } else { - packet_start(SSH_MSG_DEBUG); - packet_put_cstring(buf); - } - packet_send(); - packet_write_wait(); -} - -/* - * Logs the error plus constructs and sends a disconnect packet, closes the - * connection, and exits. This function never returns. The error message - * should not contain a newline. The length of the formatted message must - * not exceed 1024 bytes. - */ - -void -packet_disconnect(const char *fmt,...) -{ - char buf[1024]; - va_list args; - static int disconnecting = 0; - - if (disconnecting) /* Guard against recursive invocations. */ - fatal("packet_disconnect called recursively."); - disconnecting = 1; - - /* - * Format the message. Note that the caller must make sure the - * message is of limited size. - */ - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - -#ifdef ALTPRIVSEP - /* - * If we packet_disconnect() in the monitor the fatal cleanups will take - * care of the child. See main() in sshd.c. We don't send the packet - * disconnect message here because: a) the child might not be looking - * for it and b) because we don't really know if the child is compat20 - * or not as we lost that information when packet_set_monitor() was - * called. - */ - if (packet_monitor) - goto close_stuff; -#endif /* ALTPRIVSEP */ - - /* Send the disconnect message to the other side, and wait for it to get sent. */ - if (compat20) { - packet_start(SSH2_MSG_DISCONNECT); - packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); - packet_put_utf8_cstring(buf); - packet_put_cstring(""); - } else { - packet_start(SSH_MSG_DISCONNECT); - packet_put_cstring(buf); - } - packet_send(); - packet_write_wait(); - -#ifdef ALTPRIVSEP -close_stuff: -#endif /* ALTPRIVSEP */ - /* Stop listening for connections. */ - channel_close_all(); - - /* Close the connection. */ - packet_close(); - - /* Display the error locally and exit. */ - log("Disconnecting: %.100s", buf); - fatal_cleanup(); -} - -/* Checks if there is any buffered output, and tries to write some of the output. */ - -void -packet_write_poll(void) -{ - int len = buffer_len(&output); - - if (len > 0) { - len = write(connection_out, buffer_ptr(&output), len); - if (len <= 0) { - if (errno == EAGAIN) - return; - else - fatal("Write failed: %.100s", strerror(errno)); - } -#ifdef PACKET_DEBUG - debug("in packet_write_poll, %d bytes just sent to the " - "remote side", len); -#endif - buffer_consume(&output, len); - } -} - -/* - * Calls packet_write_poll repeatedly until all pending output data has been - * written. - */ - -void -packet_write_wait(void) -{ - fd_set *setp; - - setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) * - sizeof(fd_mask)); - packet_write_poll(); - while (packet_have_data_to_write()) { - memset(setp, 0, howmany(connection_out + 1, NFDBITS) * - sizeof(fd_mask)); - FD_SET(connection_out, setp); - while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && - (errno == EAGAIN || errno == EINTR)) - ; - packet_write_poll(); - } - xfree(setp); -} - -/* Returns true if there is buffered data to write to the connection. */ - -int -packet_have_data_to_write(void) -{ - return buffer_len(&output) != 0; -} - -/* Returns true if there is not too much data to write to the connection. */ - -int -packet_not_very_much_data_to_write(void) -{ - if (interactive_mode) - return buffer_len(&output) < 16384; - else - return buffer_len(&output) < 128 * 1024; -} - -/* Informs that the current session is interactive. Sets IP flags for that. */ - -void -packet_set_interactive(int interactive) -{ - static int called = 0; -#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) - int lowdelay = IPTOS_LOWDELAY; - int throughput = IPTOS_THROUGHPUT; -#endif - - if (called) - return; - called = 1; - - /* Record that we are in interactive mode. */ - interactive_mode = interactive; - - /* Only set socket options if using a socket. */ - if (!packet_connection_is_on_socket()) - return; - /* - * IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only - */ - if (interactive) { - /* - * Set IP options for an interactive connection. Use - * IPTOS_LOWDELAY and TCP_NODELAY. - */ -#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) - if (packet_connection_is_ipv4()) { - if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, - &lowdelay, sizeof(lowdelay)) < 0) - error("setsockopt IPTOS_LOWDELAY: %.100s", - strerror(errno)); - } -#endif - set_nodelay(connection_in); - } -#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) - else if (packet_connection_is_ipv4()) { - /* - * Set IP options for a non-interactive connection. Use - * IPTOS_THROUGHPUT. - */ - if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &throughput, - sizeof(throughput)) < 0) - error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno)); - } -#endif -} - -/* Returns true if the current connection is interactive. */ - -int -packet_is_interactive(void) -{ - return interactive_mode; -} - -int -packet_set_maxsize(int s) -{ - static int called = 0; - - if (called) { - log("packet_set_maxsize: called twice: old %d new %d", - max_packet_size, s); - return -1; - } - if (s < 4 * 1024 || s > 1024 * 1024) { - log("packet_set_maxsize: bad size %d", s); - return -1; - } - called = 1; - debug("packet_set_maxsize: setting to %d", s); - max_packet_size = s; - return s; -} - -/* roundup current message to pad bytes */ -void -packet_add_padding(u_char pad) -{ - extra_pad = pad; -} - -/* - * 9.2. Ignored Data Message - * - * byte SSH_MSG_IGNORE - * string data - * - * All implementations MUST understand (and ignore) this message at any - * time (after receiving the protocol version). No implementation is - * required to send them. This message can be used as an additional - * protection measure against advanced traffic analysis techniques. - */ -void -packet_send_ignore(int nbytes) -{ - u_int32_t rnd = 0; - int i; - -#ifdef ALTPRIVSEP - /* shouldn't happen -- see packet_set_monitor() */ - if (packet_monitor) - return; -#endif /* ALTPRIVSEP */ - - packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); - packet_put_int(nbytes); - for (i = 0; i < nbytes; i++) { - if (i % 4 == 0) - rnd = arc4random(); - packet_put_char((u_char)rnd & 0xff); - rnd >>= 8; - } -} - -#define MAX_PACKETS (1U<<31) -int -packet_need_rekeying(void) -{ - if (datafellows & SSH_BUG_NOREKEY) - return 0; - return - (p_send.packets > MAX_PACKETS) || - (p_read.packets > MAX_PACKETS) || - (max_blocks_out && (p_send.blocks > max_blocks_out)) || - (max_blocks_in && (p_read.blocks > max_blocks_in)); -} - -void -packet_set_rekey_limit(u_int32_t bytes) -{ - rekey_limit = bytes; -} - -#ifdef ALTPRIVSEP -void -packet_set_server(void) -{ - packet_server = 1; -} - -int -packet_is_server(void) -{ - return (packet_server); -} - -void -packet_set_monitor(int pipe) -{ - int dup_fd; - - packet_server = 1; - packet_monitor = 1; - - /* - * Awful hack follows. - * - * For SSHv1 the monitor does not process any SSHv1 packets, only - * ALTPRIVSEP packets. We take advantage of that here to keep changes - * to packet.c to a minimum by using the SSHv2 binary packet protocol, - * with cipher "none," mac "none" and compression alg "none," as the - * basis for the monitor protocol. And so to force packet.c to treat - * packets as SSHv2 we force compat20 == 1 here. - * - * For completeness and to help future developers catch this we also - * force compat20 == 1 in the monitor loop, in serverloop.c. - */ - compat20 = 1; - - /* - * NOTE: Assumptions below! - * - * - lots of packet.c code assumes that (connection_in == - * connection_out) -> connection is socket - * - * - packet_close() does not shutdown() the connection fildes - * if connection_in != connection_out - * - * - other code assumes the connection is a socket if - * connection_in == connection_out - */ - - if ((dup_fd = dup(pipe)) < 0) - fatal("Monitor failed to start: %s", strerror(errno)); - - /* - * make sure that the monitor's child's socket is not shutdown(3SOCKET) - * when we packet_close(). Setting connection_out to -1 will take care - * of that. - */ - if (packet_connection_is_on_socket()) - connection_out = -1; - - /* - * Now clean up the state related to the server socket. As a side - * effect, we also clean up existing cipher contexts that were - * initialized with 'none' cipher in packet_set_connection(). That - * function was called in the child server process shortly after the - * master SSH process forked. However, all of that is reinialized again - * by another packet_set_connection() call right below. - */ - packet_close(); - - /* - * Now make the monitor pipe look like the ssh connection which means - * that connection_in and connection_out will be set to the - * communication pipe descriptors. - */ - packet_set_connection(pipe, dup_fd); -} - -/* - * We temporarily need to set connection_in and connection_out descriptors so - * that we can make use of existing code that gets the IP address and hostname - * of the peer to write a login/logout record. It's not nice but we would have - * to change more code when implementing the PKCS#11 engine support. - */ -void -packet_set_fds(int fd, int restore) -{ - static int stored_fd; - - if (stored_fd == 0 && restore == 0) { - debug3("packet_set_fds: saving %d, installing %d", - connection_in, fd); - stored_fd = connection_in; - /* we don't have a socket in inetd mode */ - if (fd != -1) - connection_in = connection_out = fd; - return; - } - - if (restore == 1) { - debug3("restoring %d to connection_in/out", stored_fd); - connection_in = connection_out = stored_fd; - } -} - -int -packet_is_monitor(void) -{ - return (packet_monitor); -} -#endif /* ALTPRIVSEP */ diff --git a/usr/src/cmd/ssh/libssh/common/progressmeter.c b/usr/src/cmd/ssh/libssh/common/progressmeter.c deleted file mode 100644 index 65d28fb596..0000000000 --- a/usr/src/cmd/ssh/libssh/common/progressmeter.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2003 Nils Nordman. 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. - */ - -/* $OpenBSD: progressmeter.c,v 1.37 2006/08/03 03:34:42 deraadt Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/uio.h> - -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include "progressmeter.h" -#include "atomicio.h" -#include "misc.h" - -#define DEFAULT_WINSIZE 80 -#define MAX_WINSIZE 512 -#define PADDING 1 /* padding between the progress indicators */ -#define UPDATE_INTERVAL 1 /* update the progress meter every second */ -#define STALL_TIME 5 /* we're stalled after this many seconds */ - -/* determines whether we can output to the terminal */ -static int can_output(void); - -/* formats and inserts the specified size into the given buffer */ -static void format_size(char *, int, off_t); -static void format_rate(char *, int, off_t); - -/* window resizing */ -static void sig_winch(int); -static void setscreensize(void); - -/* updates the progressmeter to reflect the current state of the transfer */ -void refresh_progress_meter(void); - -/* signal handler for updating the progress meter */ -static void update_progress_meter(int); - -static time_t start; /* start progress */ -static time_t last_update; /* last progress update */ -static char *file; /* name of the file being transferred */ -static off_t end_pos; /* ending position of transfer */ -static off_t cur_pos; /* transfer position as of last refresh */ -static volatile off_t *counter; /* progress counter */ -static long stalled; /* how long we have been stalled */ -static int bytes_per_second; /* current speed in bytes per second */ -static int win_size; /* terminal window size */ -static volatile sig_atomic_t win_resized; /* for window resizing */ - -/* units for format_size */ -static const char unit[] = " KMGT"; - -static int -can_output(void) -{ - return (getpgrp() == tcgetpgrp(STDOUT_FILENO)); -} - -static void -format_rate(char *buf, int size, off_t bytes) -{ - int i; - - bytes *= 100; - for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) - bytes = (bytes + 512) / 1024; - if (i == 0) { - i++; - bytes = (bytes + 512) / 1024; - } - snprintf(buf, size, "%3lld.%1lld%c%s", - (long long) (bytes + 5) / 100, - (long long) (bytes + 5) / 10 % 10, - unit[i], - i ? "B" : " "); -} - -static void -format_size(char *buf, int size, off_t bytes) -{ - int i; - - for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) - bytes = (bytes + 512) / 1024; - snprintf(buf, size, "%4lld%c%s", - (long long) bytes, - unit[i], - i ? "B" : " "); -} - -void -refresh_progress_meter(void) -{ - char buf[MAX_WINSIZE + 1]; - time_t now; - off_t transferred; - double elapsed; - int percent; - off_t bytes_left; - int cur_speed; - int hours, minutes, seconds; - int i, len; - int file_len; - - transferred = *counter - cur_pos; - cur_pos = *counter; - now = time(NULL); - bytes_left = end_pos - cur_pos; - - if (bytes_left > 0) - elapsed = now - last_update; - else { - elapsed = now - start; - /* Calculate true total speed when done */ - transferred = end_pos; - bytes_per_second = 0; - } - - /* calculate speed */ - if (elapsed != 0) - cur_speed = (int)(transferred / elapsed); - else - cur_speed = transferred; - -#define AGE_FACTOR 0.9 - if (bytes_per_second != 0) { - bytes_per_second = (int)((bytes_per_second * AGE_FACTOR) + - (cur_speed * (1.0 - AGE_FACTOR))); - } else - bytes_per_second = cur_speed; - - /* filename */ - buf[0] = '\0'; - file_len = win_size - 35; - if (file_len > 0) { - len = snprintf(buf, file_len + 1, "\r%s", file); - if (len < 0) - len = 0; - if (len >= file_len + 1) - len = file_len; - for (i = len; i < file_len; i++) - buf[i] = ' '; - buf[file_len] = '\0'; - } - - /* percent of transfer done */ - if (end_pos != 0) - percent = (int)(((float)cur_pos / end_pos) * 100); - else - percent = 100; - snprintf(buf + strlen(buf), win_size - strlen(buf), - " %3d%% ", percent); - - /* amount transferred */ - format_size(buf + strlen(buf), win_size - strlen(buf), - cur_pos); - strlcat(buf, " ", win_size); - - /* bandwidth usage */ - format_rate(buf + strlen(buf), win_size - strlen(buf), - (off_t)bytes_per_second); - strlcat(buf, "/s ", win_size); - - /* ETA */ - if (!transferred) - stalled += elapsed; - else - stalled = 0; - - if (stalled >= STALL_TIME) - strlcat(buf, "- stalled -", win_size); - else if (bytes_per_second == 0 && bytes_left) - strlcat(buf, " --:-- ETA", win_size); - else { - if (bytes_left > 0) - seconds = bytes_left / bytes_per_second; - else - seconds = (int)elapsed; - - hours = seconds / 3600; - seconds -= hours * 3600; - minutes = seconds / 60; - seconds -= minutes * 60; - - if (hours != 0) - snprintf(buf + strlen(buf), win_size - strlen(buf), - "%d:%02d:%02d", hours, minutes, seconds); - else - snprintf(buf + strlen(buf), win_size - strlen(buf), - " %02d:%02d", minutes, seconds); - - if (bytes_left > 0) - strlcat(buf, " ETA", win_size); - else - strlcat(buf, " ", win_size); - } - - atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); - last_update = now; -} - -/*ARGSUSED*/ -static void -update_progress_meter(int ignore) -{ - int save_errno; - - save_errno = errno; - - if (win_resized) { - setscreensize(); - win_resized = 0; - } - if (can_output()) - refresh_progress_meter(); - - signal(SIGALRM, update_progress_meter); - alarm(UPDATE_INTERVAL); - errno = save_errno; -} - -void -start_progress_meter(char *f, off_t filesize, off_t *ctr) -{ - start = last_update = time(NULL); - file = f; - end_pos = filesize; - cur_pos = 0; - counter = ctr; - stalled = 0; - bytes_per_second = 0; - - setscreensize(); - if (can_output()) - refresh_progress_meter(); - - signal(SIGALRM, update_progress_meter); - signal(SIGWINCH, sig_winch); - alarm(UPDATE_INTERVAL); -} - -void -stop_progress_meter(void) -{ - alarm(0); - - if (!can_output()) - return; - - /* Ensure we complete the progress */ - if (cur_pos != end_pos) - refresh_progress_meter(); - - atomicio(vwrite, STDOUT_FILENO, "\n", 1); -} - -/*ARGSUSED*/ -static void -sig_winch(int sig) -{ - win_resized = 1; -} - -static void -setscreensize(void) -{ - struct winsize winsize; - - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 && - winsize.ws_col != 0) { - if (winsize.ws_col > MAX_WINSIZE) - win_size = MAX_WINSIZE; - else - win_size = winsize.ws_col; - } else - win_size = DEFAULT_WINSIZE; - win_size += 1; /* trailing \0 */ -} diff --git a/usr/src/cmd/ssh/libssh/common/proxy-io.c b/usr/src/cmd/ssh/libssh/common/proxy-io.c deleted file mode 100644 index c025f28f0a..0000000000 --- a/usr/src/cmd/ssh/libssh/common/proxy-io.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <unistd.h> -#include "proxy-io.h" - -int -proxy_read_write_loop(int readfd, int writefd) -{ - int rbytes, bytes_to_write, bytes_written; - char readbuf[BUFFER_SIZ]; - char *ptr; - - rbytes = read(readfd, readbuf, sizeof (readbuf)); - - if (rbytes > 0) { - bytes_to_write = rbytes; - ptr = readbuf; - while (bytes_to_write > 0) { - if ((bytes_written = - write(writefd, ptr, bytes_to_write)) < 0) { - perror("write"); - return (0); - } - bytes_to_write -= bytes_written; - ptr += bytes_written; - } - } else if (rbytes <= 0) { - return (0); - } - /* Read and write successful */ - return (1); -} diff --git a/usr/src/cmd/ssh/libssh/common/radix.c b/usr/src/cmd/ssh/libssh/common/radix.c deleted file mode 100644 index 4200f71b3b..0000000000 --- a/usr/src/cmd/ssh/libssh/common/radix.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 1999 Dug Song. All rights reserved. - * Copyright (c) 2002 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 "uuencode.h" - -RCSID("$OpenBSD: radix.c,v 1.22 2002/09/09 14:54:15 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef AFS -#include <krb.h> - -#include <radix.h> -#include "bufaux.h" - -int -creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen) -{ - Buffer b; - int ret; - - buffer_init(&b); - - buffer_put_char(&b, 1); /* version */ - - buffer_append(&b, creds->service, strlen(creds->service)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->instance, strlen(creds->instance)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->realm, strlen(creds->realm)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->pname, strlen(creds->pname)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->pinst, strlen(creds->pinst)); - buffer_put_char(&b, '\0'); - - /* Null string to repeat the realm. */ - buffer_put_char(&b, '\0'); - - buffer_put_int(&b, creds->issue_date); - buffer_put_int(&b, krb_life_to_time(creds->issue_date, - creds->lifetime)); - buffer_append(&b, creds->session, sizeof(creds->session)); - buffer_put_short(&b, creds->kvno); - - /* 32 bit size + data */ - buffer_put_string(&b, creds->ticket_st.dat, creds->ticket_st.length); - - ret = uuencode(buffer_ptr(&b), buffer_len(&b), (char *)buf, buflen); - - buffer_free(&b); - return ret; -} - -#define GETSTRING(b, t, tlen) \ - do { \ - int i, found = 0; \ - for (i = 0; i < tlen; i++) { \ - if (buffer_len(b) == 0) \ - goto done; \ - t[i] = buffer_get_char(b); \ - if (t[i] == '\0') { \ - found = 1; \ - break; \ - } \ - } \ - if (!found) \ - goto done; \ - } while(0) - -int -radix_to_creds(const char *buf, CREDENTIALS *creds) -{ - Buffer b; - u_char *space; - char c, version, *p; - u_int endTime, len; - int blen, ret; - - ret = 0; - blen = strlen(buf); - - /* sanity check for size */ - if (blen > 8192) - return 0; - - buffer_init(&b); - space = buffer_append_space(&b, blen); - - /* check version and length! */ - len = uudecode(buf, space, blen); - if (len < 1) - goto done; - - version = buffer_get_char(&b); - - GETSTRING(&b, creds->service, sizeof creds->service); - GETSTRING(&b, creds->instance, sizeof creds->instance); - GETSTRING(&b, creds->realm, sizeof creds->realm); - GETSTRING(&b, creds->pname, sizeof creds->pname); - GETSTRING(&b, creds->pinst, sizeof creds->pinst); - - if (buffer_len(&b) == 0) - goto done; - - /* Ignore possibly different realm. */ - while (buffer_len(&b) > 0 && (c = buffer_get_char(&b)) != '\0') - ; - - if (buffer_len(&b) == 0) - goto done; - - creds->issue_date = buffer_get_int(&b); - - endTime = buffer_get_int(&b); - creds->lifetime = krb_time_to_life(creds->issue_date, endTime); - - len = buffer_len(&b); - if (len < sizeof(creds->session)) - goto done; - memcpy(&creds->session, buffer_ptr(&b), sizeof(creds->session)); - buffer_consume(&b, sizeof(creds->session)); - - creds->kvno = buffer_get_short(&b); - - p = buffer_get_string(&b, &len); - if (len < 0 || len > sizeof(creds->ticket_st.dat)) - goto done; - memcpy(&creds->ticket_st.dat, p, len); - creds->ticket_st.length = len; - - ret = 1; -done: - buffer_free(&b); - return ret; -} -#endif /* AFS */ diff --git a/usr/src/cmd/ssh/libssh/common/readconf.c b/usr/src/cmd/ssh/libssh/common/readconf.c deleted file mode 100644 index b1e7f89c7a..0000000000 --- a/usr/src/cmd/ssh/libssh/common/readconf.c +++ /dev/null @@ -1,1276 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * Copyright 2013 Joyent, Inc. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $"); - -#include "ssh.h" -#include "xmalloc.h" -#include "compat.h" -#include "cipher.h" -#include "pathnames.h" -#include "log.h" -#include "readconf.h" -#include "match.h" -#include "misc.h" -#include "kex.h" -#include "mac.h" - -/* Format of the configuration file: - - # Configuration data is parsed as follows: - # 1. command line options - # 2. user-specific file - # 3. system-wide file - # Any configuration value is only changed the first time it is set. - # Thus, host-specific definitions should be at the beginning of the - # configuration file, and defaults at the end. - - # Host-specific declarations. These may override anything above. A single - # host may match multiple declarations; these are processed in the order - # that they are given in. - - Host *.ngs.fi ngs.fi - User foo - - Host fake.com - HostName another.host.name.real.org - User blaah - Port 34289 - ForwardX11 no - ForwardAgent no - - Host books.com - RemoteForward 9999 shadows.cs.hut.fi:9999 - Cipher 3des - - Host fascist.blob.com - Port 23123 - User tylonen - RhostsAuthentication no - PasswordAuthentication no - - Host puukko.hut.fi - User t35124p - ProxyCommand ssh-proxy %h %p - - Host *.fr - PublicKeyAuthentication no - - Host *.su - Cipher none - PasswordAuthentication no - - # Defaults for various options - Host * - ForwardAgent no - ForwardX11 no - RhostsAuthentication yes - PasswordAuthentication yes - RSAAuthentication yes - RhostsRSAAuthentication yes - StrictHostKeyChecking yes - KeepAlives no - IdentityFile ~/.ssh/identity - Port 22 - EscapeChar ~ - -*/ - -/* Keyword tokens. */ - -typedef enum { - oBadOption, - oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts, - oRhostsAuthentication, - oPasswordAuthentication, oRSAAuthentication, - oChallengeResponseAuthentication, oXAuthLocation, -#if defined(KRB4) || defined(KRB5) - oKerberosAuthentication, -#endif -#ifdef GSSAPI - oGssKeyEx, oGssAuthentication, oGssDelegateCreds, -#ifdef GSI - oGssGlobusDelegateLimitedCreds, -#endif /* GSI */ -#endif /* GSSAPI */ -#if defined(AFS) || defined(KRB5) - oKerberosTgtPassing, -#endif -#ifdef AFS - oAFSTokenPassing, -#endif - oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, - oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, - oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, - oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, - oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, - oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, - oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, - oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, - oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, - oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, - oClearAllForwardings, oNoHostAuthenticationForLocalhost, - oFallBackToRsh, oUseRsh, oConnectTimeout, oHashKnownHosts, - oServerAliveInterval, oServerAliveCountMax, oDisableBanner, - oIgnoreIfUnknown, oRekeyLimit, oUseOpenSSLEngine, - oDeprecated -} OpCodes; - -/* Textual representations of the tokens. */ - -static struct { - const char *name; - OpCodes opcode; -} keywords[] = { - { "forwardagent", oForwardAgent }, - { "forwardx11", oForwardX11 }, - { "forwardx11trusted", oForwardX11Trusted }, - { "xauthlocation", oXAuthLocation }, - { "gatewayports", oGatewayPorts }, - { "useprivilegedport", oUsePrivilegedPort }, - { "rhostsauthentication", oRhostsAuthentication }, - { "passwordauthentication", oPasswordAuthentication }, - { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, - { "kbdinteractivedevices", oKbdInteractiveDevices }, - { "rsaauthentication", oRSAAuthentication }, - { "pubkeyauthentication", oPubkeyAuthentication }, - { "dsaauthentication", oPubkeyAuthentication }, /* alias */ - { "rhostsrsaauthentication", oRhostsRSAAuthentication }, - { "hostbasedauthentication", oHostbasedAuthentication }, - { "challengeresponseauthentication", oChallengeResponseAuthentication }, - { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ - { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ -#if defined(KRB4) || defined(KRB5) - { "kerberosauthentication", oKerberosAuthentication }, -#endif -#ifdef GSSAPI - { "gssapikeyexchange", oGssKeyEx }, - { "gssapiauthentication", oGssAuthentication }, - { "gssapidelegatecredentials", oGssDelegateCreds }, - { "gsskeyex", oGssKeyEx }, /* alias */ - { "gssauthentication", oGssAuthentication }, /* alias */ - { "gssdelegatecreds", oGssDelegateCreds }, /* alias */ -#ifdef GSI - /* For backwards compatability with old 1.2.27 client code */ - { "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */ - { "forwardgssapiglobuslimitedproxy", oGssGlobusDelegateLimitedCreds }, -#endif /* GSI */ -#endif /* GSSAPI */ -#if defined(AFS) || defined(KRB5) - { "kerberostgtpassing", oKerberosTgtPassing }, -#endif -#ifdef AFS - { "afstokenpassing", oAFSTokenPassing }, -#endif - { "fallbacktorsh", oFallBackToRsh }, - { "usersh", oUseRsh }, - { "identityfile", oIdentityFile }, - { "identityfile2", oIdentityFile }, /* alias */ - { "hostname", oHostName }, - { "hostkeyalias", oHostKeyAlias }, - { "proxycommand", oProxyCommand }, - { "port", oPort }, - { "cipher", oCipher }, - { "ciphers", oCiphers }, - { "macs", oMacs }, - { "protocol", oProtocol }, - { "remoteforward", oRemoteForward }, - { "localforward", oLocalForward }, - { "user", oUser }, - { "host", oHost }, - { "escapechar", oEscapeChar }, - { "globalknownhostsfile", oGlobalKnownHostsFile }, - { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */ - { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, - { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ - { "connectionattempts", oConnectionAttempts }, - { "batchmode", oBatchMode }, - { "checkhostip", oCheckHostIP }, - { "stricthostkeychecking", oStrictHostKeyChecking }, - { "compression", oCompression }, - { "compressionlevel", oCompressionLevel }, - { "tcpkeepalive", oKeepAlives }, - { "keepalive", oKeepAlives }, /* obsolete */ - { "numberofpasswordprompts", oNumberOfPasswordPrompts }, - { "loglevel", oLogLevel }, - { "dynamicforward", oDynamicForward }, - { "preferredauthentications", oPreferredAuthentications }, - { "hostkeyalgorithms", oHostKeyAlgorithms }, - { "bindaddress", oBindAddress }, - { "smartcarddevice", oSmartcardDevice }, - { "clearallforwardings", oClearAllForwardings }, - { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, - { "rekeylimit", oRekeyLimit }, - { "connecttimeout", oConnectTimeout }, - { "serveraliveinterval", oServerAliveInterval }, - { "serveralivecountmax", oServerAliveCountMax }, - { "disablebanner", oDisableBanner }, - { "hashknownhosts", oHashKnownHosts }, - { "ignoreifunknown", oIgnoreIfUnknown }, - { "useopensslengine", oUseOpenSSLEngine }, - { NULL, oBadOption } -}; - -/* - * Adds a local TCP/IP port forward to options. Never returns if there is an - * error. - */ - -void -add_local_forward(Options *options, const Forward *newfwd) -{ - Forward *fwd; -#ifndef NO_IPPORT_RESERVED_CONCEPT - extern uid_t original_real_uid; - if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0) - fatal("Privileged ports can only be forwarded by root."); -#endif - if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) - fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); - fwd = &options->local_forwards[options->num_local_forwards++]; - - fwd->listen_host = (newfwd->listen_host == NULL) ? - NULL : xstrdup(newfwd->listen_host); - fwd->listen_port = newfwd->listen_port; - fwd->connect_host = xstrdup(newfwd->connect_host); - fwd->connect_port = newfwd->connect_port; -} - -/* - * Adds a remote TCP/IP port forward to options. Never returns if there is - * an error. - */ - -void -add_remote_forward(Options *options, const Forward *newfwd) -{ - Forward *fwd; - if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) - fatal("Too many remote forwards (max %d).", - SSH_MAX_FORWARDS_PER_DIRECTION); - fwd = &options->remote_forwards[options->num_remote_forwards++]; - - fwd->listen_host = (newfwd->listen_host == NULL) ? - NULL : xstrdup(newfwd->listen_host); - fwd->listen_port = newfwd->listen_port; - fwd->connect_host = xstrdup(newfwd->connect_host); - fwd->connect_port = newfwd->connect_port; -} - -static void -clear_forwardings(Options *options) -{ - int i; - - for (i = 0; i < options->num_local_forwards; i++) { - if (options->local_forwards[i].listen_host != NULL) - xfree(options->local_forwards[i].listen_host); - xfree(options->local_forwards[i].connect_host); - } - options->num_local_forwards = 0; - for (i = 0; i < options->num_remote_forwards; i++) { - if (options->remote_forwards[i].listen_host != NULL) - xfree(options->remote_forwards[i].listen_host); - xfree(options->remote_forwards[i].connect_host); - } - options->num_remote_forwards = 0; -} - -/* - * Returns the number of the token pointed to by cp or oBadOption. - */ - -static OpCodes -parse_token(const char *cp, const char *filename, int linenum) -{ - u_int i; - - for (i = 0; keywords[i].name; i++) - if (strcasecmp(cp, keywords[i].name) == 0) - return keywords[i].opcode; - - debug("%s: line %d: unknown configuration option: %s", - filename, linenum, cp); - return oBadOption; -} - -/* - * Processes a single option line as used in the configuration files. This - * only sets those values that have not already been set. - */ - -int -process_config_line(Options *options, const char *host, - char *line, const char *filename, int linenum, - int *activep) -{ - char *s, *string, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; - int opcode, *intptr, value, scale, i; - long long orig, val64; - StoredOption *so; - Forward fwd; - - 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 == NULL || !*keyword || *keyword == '\n' || *keyword == '#') - return 0; - - opcode = parse_token(keyword, filename, linenum); - - switch (opcode) { - case oBadOption: - if (options->unknown_opts_num == MAX_UNKNOWN_OPTIONS) { - error("we can't have more than %d unknown options:", - MAX_UNKNOWN_OPTIONS); - for (i = 0; i < MAX_UNKNOWN_OPTIONS; ++i) { - so = &options->unknown_opts[i]; - error("%s:%d:%s", - so->filename, so->linenum, so->keyword); - xfree(so->keyword); - xfree(so->filename); - } - fatal("too many unknown options found, can't continue"); - } - - /* unknown options will be processed later */ - so = &options->unknown_opts[options->unknown_opts_num]; - so->keyword = xstrdup(keyword); - so->filename = xstrdup(filename); - so->linenum = linenum; - options->unknown_opts_num++; - return (0); - - /* NOTREACHED */ - case oConnectTimeout: - intptr = &options->connection_timeout; -parse_time: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%s line %d: missing time value.", - filename, linenum); - if ((value = convtime(arg)) == -1) - fatal("%s line %d: invalid time value.", - filename, linenum); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case oForwardAgent: - intptr = &options->forward_agent; -parse_flag: - 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(arg, "yes") == 0 || strcmp(arg, "true") == 0) - value = 1; - else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) - value = 0; - else - fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case oForwardX11: - intptr = &options->forward_x11; - goto parse_flag; - - case oForwardX11Trusted: - intptr = &options->forward_x11_trusted; - goto parse_flag; - - case oGatewayPorts: - intptr = &options->gateway_ports; - goto parse_flag; - - case oUsePrivilegedPort: - intptr = &options->use_privileged_port; - goto parse_flag; - - case oRhostsAuthentication: - intptr = &options->rhosts_authentication; - goto parse_flag; - - case oPasswordAuthentication: - intptr = &options->password_authentication; - goto parse_flag; - - case oKbdInteractiveAuthentication: - intptr = &options->kbd_interactive_authentication; - goto parse_flag; - - case oKbdInteractiveDevices: - charptr = &options->kbd_interactive_devices; - goto parse_string; - - case oPubkeyAuthentication: - intptr = &options->pubkey_authentication; - goto parse_flag; - - case oRSAAuthentication: - intptr = &options->rsa_authentication; - goto parse_flag; - - case oRhostsRSAAuthentication: - intptr = &options->rhosts_rsa_authentication; - goto parse_flag; - - case oHostbasedAuthentication: - intptr = &options->hostbased_authentication; - goto parse_flag; - - case oChallengeResponseAuthentication: - intptr = &options->challenge_response_authentication; - goto parse_flag; -#if defined(KRB4) || defined(KRB5) - case oKerberosAuthentication: - intptr = &options->kerberos_authentication; - goto parse_flag; -#endif -#ifdef GSSAPI - case oGssKeyEx: - intptr = &options->gss_keyex; - goto parse_flag; - - case oGssAuthentication: - intptr = &options->gss_authentication; - goto parse_flag; - - case oGssDelegateCreds: - intptr = &options->gss_deleg_creds; - goto parse_flag; - -#ifdef GSI - case oGssGlobusDelegateLimitedCreds: - intptr = &options->gss_globus_deleg_limited_proxy; - goto parse_flag; -#endif /* GSI */ - -#endif /* GSSAPI */ - -#if defined(AFS) || defined(KRB5) - case oKerberosTgtPassing: - intptr = &options->kerberos_tgt_passing; - goto parse_flag; -#endif -#ifdef AFS - case oAFSTokenPassing: - intptr = &options->afs_token_passing; - goto parse_flag; -#endif - case oFallBackToRsh: - intptr = &options->fallback_to_rsh; - goto parse_flag; - - case oUseRsh: - intptr = &options->use_rsh; - goto parse_flag; - - case oBatchMode: - intptr = &options->batch_mode; - goto parse_flag; - - case oCheckHostIP: - intptr = &options->check_host_ip; - goto parse_flag; - - case oStrictHostKeyChecking: - intptr = &options->strict_host_key_checking; - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing yes/no/ask argument.", - filename, linenum); - value = 0; /* To avoid compiler warning... */ - if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) - value = 1; - else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) - value = 0; - else if (strcmp(arg, "ask") == 0) - value = 2; - else - fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case oCompression: - intptr = &options->compression; - goto parse_flag; - - case oKeepAlives: - intptr = &options->keepalives; - goto parse_flag; - - case oNoHostAuthenticationForLocalhost: - intptr = &options->no_host_authentication_for_localhost; - goto parse_flag; - - case oNumberOfPasswordPrompts: - intptr = &options->number_of_password_prompts; - goto parse_int; - - case oCompressionLevel: - intptr = &options->compression_level; - goto parse_int; - - case oRekeyLimit: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (arg[0] < '0' || arg[0] > '9') - fatal("%.200s line %d: Bad number.", filename, linenum); - orig = val64 = strtoll(arg, &endofnumber, 10); - if (arg == endofnumber) - fatal("%.200s line %d: Bad number.", filename, linenum); - switch (toupper(*endofnumber)) { - case '\0': - scale = 1; - break; - case 'K': - scale = 1<<10; - break; - case 'M': - scale = 1<<20; - break; - case 'G': - scale = 1<<30; - break; - default: - fatal("%.200s line %d: Invalid RekeyLimit suffix", - filename, linenum); - } - val64 *= scale; - /* detect integer wrap and too-large limits */ - if ((val64 / scale) != orig || val64 > UINT_MAX) - fatal("%.200s line %d: RekeyLimit too large", - filename, linenum); - if (val64 < 16) - fatal("%.200s line %d: RekeyLimit too small", - filename, linenum); - if (*activep && options->rekey_limit == -1) - options->rekey_limit = (u_int32_t)val64; - break; - - case oIdentityFile: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (*activep) { - intptr = &options->num_identity_files; - if (*intptr >= SSH_MAX_IDENTITY_FILES) - fatal("%.200s line %d: Too many identity files specified (max %d).", - filename, linenum, SSH_MAX_IDENTITY_FILES); - charptr = &options->identity_files[*intptr]; - *charptr = xstrdup(arg); - *intptr = *intptr + 1; - } - break; - - case oXAuthLocation: - charptr=&options->xauth_location; - goto parse_string; - - case oUser: - charptr = &options->user; -parse_string: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (*activep && *charptr == NULL) - *charptr = xstrdup(arg); - break; - - case oGlobalKnownHostsFile: - charptr = &options->system_hostfile; - goto parse_string; - - case oUserKnownHostsFile: - charptr = &options->user_hostfile; - goto parse_string; - - case oGlobalKnownHostsFile2: - charptr = &options->system_hostfile2; - goto parse_string; - - case oUserKnownHostsFile2: - charptr = &options->user_hostfile2; - goto parse_string; - - case oHostName: - charptr = &options->hostname; - goto parse_string; - - case oHostKeyAlias: - charptr = &options->host_key_alias; - goto parse_string; - - case oPreferredAuthentications: - charptr = &options->preferred_authentications; - goto parse_string; - - case oBindAddress: - charptr = &options->bind_address; - goto parse_string; - - case oSmartcardDevice: - charptr = &options->smartcard_device; - goto parse_string; - - case oProxyCommand: - charptr = &options->proxy_command; - string = xstrdup(""); - while ((arg = strdelim(&s)) != NULL && *arg != '\0') { - string = xrealloc(string, strlen(string) + strlen(arg) + 2); - strcat(string, " "); - strcat(string, arg); - } - if (*activep && *charptr == NULL) - *charptr = string; - else - xfree(string); - return 0; - - case oPort: - intptr = &options->port; -parse_int: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (arg[0] < '0' || arg[0] > '9') - fatal("%.200s line %d: Bad number.", filename, linenum); - - /* Octal, decimal, or hex format? */ - value = strtol(arg, &endofnumber, 0); - if (arg == endofnumber) - fatal("%.200s line %d: Bad number.", filename, linenum); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case oConnectionAttempts: - intptr = &options->connection_attempts; - goto parse_int; - - case oCipher: - intptr = &options->cipher; - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - value = cipher_number(arg); - if (value == -1) - fatal("%.200s line %d: Bad cipher '%s'.", - filename, linenum, arg ? arg : "<NONE>"); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case oCiphers: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (!ciphers_valid(arg)) - fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", - filename, linenum, arg ? arg : "<NONE>"); - if (*activep && options->ciphers == NULL) - options->ciphers = xstrdup(arg); - break; - - case oMacs: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (!mac_valid(arg)) - fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", - filename, linenum, arg ? arg : "<NONE>"); - if (*activep && options->macs == NULL) - options->macs = xstrdup(arg); - break; - - case oHostKeyAlgorithms: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (!key_names_valid2(arg)) - fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", - filename, linenum, arg ? arg : "<NONE>"); - if (*activep && options->hostkeyalgorithms == NULL) - options->hostkeyalgorithms = xstrdup(arg); - break; - - case oProtocol: - intptr = &options->protocol; - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - value = proto_spec(arg); - if (value == SSH_PROTO_UNKNOWN) - fatal("%.200s line %d: Bad protocol spec '%s'.", - filename, linenum, arg ? arg : "<NONE>"); - if (*activep && *intptr == SSH_PROTO_UNKNOWN) - *intptr = value; - break; - - case oLogLevel: - intptr = (int *) &options->log_level; - arg = strdelim(&s); - value = log_level_number(arg); - if (value == SYSLOG_LEVEL_NOT_SET) - fatal("%.200s line %d: unsupported log level '%s'", - filename, linenum, arg ? arg : "<NONE>"); - if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET) - *intptr = (LogLevel) value; - break; - - case oLocalForward: - case oRemoteForward: - arg = strdelim(&s); - if (arg == NULL || *arg == '\0') - fatal("%.200s line %d: Missing port argument.", - filename, linenum); - arg2 = strdelim(&s); - if (arg2 == NULL || *arg2 == '\0') - fatal("%.200s line %d: Missing target argument.", - filename, linenum); - - /* construct a string for parse_forward */ - snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); - - if (parse_forward(1, &fwd, fwdarg) == 0) - fatal("%.200s line %d: Bad forwarding specification.", - filename, linenum); - - if (*activep) { - if (opcode == oLocalForward) - add_local_forward(options, &fwd); - else if (opcode == oRemoteForward) - add_remote_forward(options, &fwd); - } - break; - - case oDynamicForward: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing port argument.", - filename, linenum); - - if (parse_forward(0, &fwd, arg) == 0) { - fatal("%.200s line %d: Bad dynamic forwarding specification.", - filename, linenum); - } - - if (*activep) { - fwd.connect_host = "socks"; - add_local_forward(options, &fwd); - } - break; - - case oClearAllForwardings: - intptr = &options->clear_forwardings; - goto parse_flag; - - case oHost: - *activep = 0; - 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 strdelim is done. */ - return 0; - - case oEscapeChar: - intptr = &options->escape_char; - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (arg[0] == '^' && arg[2] == 0 && - (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) - value = (u_char) arg[1] & 31; - else if (strlen(arg) == 1) - value = (u_char) arg[0]; - else if (strcmp(arg, "none") == 0) - value = SSH_ESCAPECHAR_NONE; - else { - fatal("%.200s line %d: Bad escape character.", - filename, linenum); - /* NOTREACHED */ - value = 0; /* Avoid compiler warning. */ - } - if (*activep && *intptr == -1) - *intptr = value; - break; - - case oServerAliveInterval: - intptr = &options->server_alive_interval; - goto parse_time; - - case oServerAliveCountMax: - intptr = &options->server_alive_count_max; - goto parse_int; - - case oHashKnownHosts: - intptr = &options->hash_known_hosts; - goto parse_flag; - - case oDisableBanner: - arg = strdelim(&s); - if (get_yes_no_flag(&options->disable_banner, arg, filename, - linenum, *activep) == 1) - break; - - if (strcmp(arg, "in-exec-mode") == 0) - options->disable_banner = SSH_NO_BANNER_IN_EXEC_MODE; - else - fatal("%.200s line %d: Bad yes/no/in-exec-mode " - "argument.", filename, linenum); - break; - - case oIgnoreIfUnknown: - charptr = &options->ignore_if_unknown; - goto parse_string; - - case oUseOpenSSLEngine: - intptr = &options->use_openssl_engine; - goto parse_flag; - - case oDeprecated: - debug("%s line %d: Deprecated option \"%s\"", - filename, linenum, keyword); - return 0; - - default: - fatal("process_config_line: Unimplemented opcode %d", opcode); - } - - /* Check that there is no garbage at end of line. */ - if ((arg = strdelim(&s)) != NULL && *arg != '\0') { - fatal("%.200s line %d: garbage at end of line; \"%.200s\".", - filename, linenum, arg); - } - return 0; -} - - -/* - * Reads the config file and modifies the options accordingly. Options - * should already be initialized before this call. This never returns if - * there is an error. If the file does not exist, this returns 0. - */ - -int -read_config_file(const char *filename, const char *host, Options *options) -{ - FILE *f; - char line[1024]; - int active, linenum; - - /* Open the file. */ - f = fopen(filename, "r"); - if (!f) - return 0; - - debug("Reading configuration data %.200s", filename); - - /* - * Mark that we are now processing the options. This flag is turned - * on/off by Host specifications. - */ - active = 1; - linenum = 0; - while (fgets(line, sizeof(line), f)) { - /* Update line number counter. */ - linenum++; - process_config_line(options, host, line, filename, linenum, &active); - } - fclose(f); - return 1; -} - -/* - * Initializes options to special values that indicate that they have not yet - * been set. Read_config_file will only set options with this value. Options - * are processed in the following order: command line, user config file, - * system config file. Last, fill_default_options is called. - */ - -void -initialize_options(Options * options) -{ - memset(options, 'X', sizeof(*options)); - options->forward_agent = -1; - options->forward_x11 = -1; - options->forward_x11_trusted = -1; - options->xauth_location = NULL; - options->gateway_ports = -1; - options->use_privileged_port = -1; - options->rhosts_authentication = -1; - options->rsa_authentication = -1; - options->pubkey_authentication = -1; - options->challenge_response_authentication = -1; -#ifdef GSSAPI - options->gss_keyex = -1; - options->gss_authentication = -1; - options->gss_deleg_creds = -1; -#ifdef GSI - options->gss_globus_deleg_limited_proxy = -1; -#endif /* GSI */ -#endif /* GSSAPI */ - -#if defined(KRB4) || defined(KRB5) - options->kerberos_authentication = -1; -#endif -#if defined(AFS) || defined(KRB5) - options->kerberos_tgt_passing = -1; -#endif -#ifdef AFS - options->afs_token_passing = -1; -#endif - options->password_authentication = -1; - options->kbd_interactive_authentication = -1; - options->kbd_interactive_devices = NULL; - options->rhosts_rsa_authentication = -1; - options->hostbased_authentication = -1; - options->batch_mode = -1; - options->check_host_ip = -1; - options->strict_host_key_checking = -1; - options->compression = -1; - options->keepalives = -1; - options->compression_level = -1; - options->port = -1; - options->connection_attempts = -1; - options->connection_timeout = -1; - options->number_of_password_prompts = -1; - options->cipher = -1; - options->ciphers = NULL; - options->macs = NULL; - options->hostkeyalgorithms = NULL; - options->protocol = SSH_PROTO_UNKNOWN; - options->num_identity_files = 0; - options->hostname = NULL; - options->host_key_alias = NULL; - options->proxy_command = NULL; - options->user = NULL; - options->escape_char = -1; - options->system_hostfile = NULL; - options->user_hostfile = NULL; - options->system_hostfile2 = NULL; - options->user_hostfile2 = NULL; - options->num_local_forwards = 0; - options->num_remote_forwards = 0; - options->clear_forwardings = -1; - options->log_level = SYSLOG_LEVEL_NOT_SET; - options->preferred_authentications = NULL; - options->bind_address = NULL; - options->smartcard_device = NULL; - options->no_host_authentication_for_localhost = -1; - options->rekey_limit = -1; - options->fallback_to_rsh = -1; - options->use_rsh = -1; - options->server_alive_interval = -1; - options->server_alive_count_max = -1; - options->hash_known_hosts = -1; - options->ignore_if_unknown = NULL; - options->unknown_opts_num = 0; - options->disable_banner = -1; - options->use_openssl_engine = -1; -} - -/* - * Called after processing other sources of option data, this fills those - * options for which no value has been specified with their default values. - */ - -void -fill_default_options(Options * options) -{ - int len; - - if (options->forward_agent == -1) - options->forward_agent = 0; - if (options->forward_x11 == -1) - options->forward_x11 = 0; - /* - * Unlike OpenSSH, we keep backward compatibility for '-X' option - * which means that X11 forwarding is trusted by default. - */ - if (options->forward_x11_trusted == -1) - options->forward_x11_trusted = 1; - if (options->xauth_location == NULL) - options->xauth_location = _PATH_XAUTH; - if (options->gateway_ports == -1) - options->gateway_ports = 0; - if (options->use_privileged_port == -1) - options->use_privileged_port = 0; - if (options->rhosts_authentication == -1) - options->rhosts_authentication = 0; - if (options->rsa_authentication == -1) - options->rsa_authentication = 1; - if (options->pubkey_authentication == -1) - options->pubkey_authentication = 1; - if (options->challenge_response_authentication == -1) - options->challenge_response_authentication = 1; -#ifdef GSSAPI - if (options->gss_keyex == -1) - options->gss_keyex = 1; - if (options->gss_authentication == -1) - options->gss_authentication = 1; - if (options->gss_deleg_creds == -1) - options->gss_deleg_creds = 0; -#ifdef GSI - if (options->gss_globus_deleg_limited_proxy == -1) - options->gss_globus_deleg_limited_proxy = 0; -#endif /* GSI */ -#endif /* GSSAPI */ -#if defined(KRB4) || defined(KRB5) - if (options->kerberos_authentication == -1) - options->kerberos_authentication = 1; -#endif -#if defined(AFS) || defined(KRB5) - if (options->kerberos_tgt_passing == -1) - options->kerberos_tgt_passing = 1; -#endif -#ifdef AFS - if (options->afs_token_passing == -1) - options->afs_token_passing = 1; -#endif - if (options->password_authentication == -1) - options->password_authentication = 1; - if (options->kbd_interactive_authentication == -1) - options->kbd_interactive_authentication = 1; - if (options->rhosts_rsa_authentication == -1) - options->rhosts_rsa_authentication = 0; - if (options->hostbased_authentication == -1) - options->hostbased_authentication = 0; - if (options->batch_mode == -1) - options->batch_mode = 0; - if (options->check_host_ip == -1) - options->check_host_ip = 1; - if (options->strict_host_key_checking == -1) - options->strict_host_key_checking = 2; /* 2 is default */ - if (options->compression == -1) - options->compression = 0; - if (options->keepalives == -1) - options->keepalives = 1; - if (options->compression_level == -1) - options->compression_level = 6; - if (options->port == -1) - options->port = 0; /* Filled in ssh_connect. */ - if (options->connection_attempts == -1) - options->connection_attempts = 1; - if (options->number_of_password_prompts == -1) - options->number_of_password_prompts = 3; - /* Selected in ssh_login(). */ - if (options->cipher == -1) - options->cipher = SSH_CIPHER_NOT_SET; - /* options->ciphers, default set in myproposals.h */ - /* options->macs, default set in myproposals.h */ - /* options->hostkeyalgorithms, default set in myproposals.h */ - if (options->protocol == SSH_PROTO_UNKNOWN) - options->protocol = SSH_PROTO_1|SSH_PROTO_2; - if (options->num_identity_files == 0) { - if (options->protocol & SSH_PROTO_1) { - len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; - options->identity_files[options->num_identity_files] = - xmalloc(len); - snprintf(options->identity_files[options->num_identity_files++], - len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); - } - if (options->protocol & SSH_PROTO_2) { - len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; - options->identity_files[options->num_identity_files] = - xmalloc(len); - snprintf(options->identity_files[options->num_identity_files++], - len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); - - len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; - options->identity_files[options->num_identity_files] = - xmalloc(len); - snprintf(options->identity_files[options->num_identity_files++], - len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); - } - } - if (options->escape_char == -1) - options->escape_char = '~'; - if (options->system_hostfile == NULL) - options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; - if (options->user_hostfile == NULL) - options->user_hostfile = _PATH_SSH_USER_HOSTFILE; - if (options->system_hostfile2 == NULL) - options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; - if (options->user_hostfile2 == NULL) - options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; - if (options->log_level == SYSLOG_LEVEL_NOT_SET) - options->log_level = SYSLOG_LEVEL_INFO; - if (options->clear_forwardings == 1) - clear_forwardings(options); - if (options->no_host_authentication_for_localhost == -1) - options->no_host_authentication_for_localhost = 0; - if (options->rekey_limit == -1) - options->rekey_limit = 0; - if (options->fallback_to_rsh == -1) - options->fallback_to_rsh = 0; - if (options->use_rsh == -1) - options->use_rsh = 0; - if (options->server_alive_interval == -1) - options->server_alive_interval = 0; - if (options->server_alive_count_max == -1) - options->server_alive_count_max = 3; - if (options->hash_known_hosts == -1) - options->hash_known_hosts = 0; - if (options->disable_banner == -1) - options->disable_banner = 0; - if (options->use_openssl_engine == -1) - options->use_openssl_engine = 1; - /* options->proxy_command should not be set by default */ - /* options->user will be set in the main program if appropriate */ - /* options->hostname will be set in the main program if appropriate */ - /* options->host_key_alias should not be set by default */ - /* options->preferred_authentications will be set in ssh */ - /* options->ignore_if_unknown should not be set by default */ -} - -/* - * Parses a string containing a port forwarding specification of one of the - * two forms, short or long: - * - * [listenhost:]listenport - * [listenhost:]listenport:connecthost:connectport - * - * short forwarding specification is used for dynamic port forwarding and for - * port forwarding cancelation in process_cmdline(). The function returns number - * of arguments parsed or zero on any error. - */ -int -parse_forward(int long_form, Forward *fwd, const char *fwdspec) -{ - int i; - char *p, *cp, *fwdarg[5]; - - memset(fwd, '\0', sizeof(*fwd)); - - cp = p = xstrdup(fwdspec); - - /* skip leading spaces */ - while (isspace(*cp)) - cp++; - - for (i = 0; i < 5; ++i) - if ((fwdarg[i] = hpdelim(&cp)) == NULL) - break; - - if ((long_form == 0 && i > 2) || (long_form == 1 && i < 3) || (i == 5)) - goto fail_free; - - switch (i) { - case 0: - goto fail_free; - - case 1: - fwd->listen_host = NULL; - fwd->listen_port = a2port(fwdarg[0]); - break; - - case 2: - fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); - fwd->listen_port = a2port(fwdarg[1]); - break; - - case 3: - fwd->listen_host = NULL; - fwd->listen_port = a2port(fwdarg[0]); - fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); - fwd->connect_port = a2port(fwdarg[2]); - break; - - case 4: - fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); - fwd->listen_port = a2port(fwdarg[1]); - fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); - fwd->connect_port = a2port(fwdarg[3]); - break; - } - - if (fwd->listen_port == 0 || (fwd->connect_port == 0 && i > 2)) - goto fail_free; - - xfree(p); - return (i); - -fail_free: - if (p != NULL) - xfree(p); - if (fwd->connect_host != NULL) - xfree(fwd->connect_host); - if (fwd->listen_host != NULL) - xfree(fwd->listen_host); - return (0); -} - -/* - * Process previously stored unknown options. When this function is called we - * already have IgnoreIfUnknown set so finally we can decide whether each - * unknown option is to be ignored or not. - */ -void -process_unknown_options(Options *options) -{ - StoredOption *so; - int m, i, bad_options = 0; - - /* if there is no unknown option we are done */ - if (options->unknown_opts_num == 0) - return; - - /* - * Now go through the list of unknown options and report any one that - * is not explicitly listed in IgnoreIfUnknown option. If at least one - * such as that is found it's a show stopper. - */ - for (i = 0; i < options->unknown_opts_num; ++i) { - so = &options->unknown_opts[i]; - if (options->ignore_if_unknown == NULL) - m = 0; - else - m = match_pattern_list(tolowercase(so->keyword), - options->ignore_if_unknown, - strlen(options->ignore_if_unknown), 1); - if (m == 1) { - debug("%s: line %d: ignoring unknown option: %s", - so->filename, so->linenum, so->keyword); - } - else { - error("%s: line %d: unknown configuration option: %s", - so->filename, so->linenum, so->keyword); - bad_options++; - } - xfree(so->keyword); - xfree(so->filename); - } - - /* exit if we found at least one unignored unknown option */ - if (bad_options > 0) - fatal("terminating, %d bad configuration option(s)", - bad_options); -} diff --git a/usr/src/cmd/ssh/libssh/common/readpass.c b/usr/src/cmd/ssh/libssh/common/readpass.c deleted file mode 100644 index fa1f1a4982..0000000000 --- a/usr/src/cmd/ssh/libssh/common/readpass.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: readpass.c,v 1.27 2002/03/26 15:58:46 markus Exp $"); - -#include "xmalloc.h" -#include "readpass.h" -#include "pathnames.h" -#include "log.h" -#include "ssh.h" -#include <langinfo.h> - -static char * -ssh_askpass(char *askpass, const char *msg) -{ - pid_t pid; - size_t len; - char *pass; - int p[2], status, ret; - char buf[1024]; - - if (fflush(stdout) != 0) - error("ssh_askpass: fflush: %s", strerror(errno)); - if (askpass == NULL) - fatal("internal error: askpass undefined"); - if (pipe(p) < 0) { - error("ssh_askpass: pipe: %s", strerror(errno)); - return xstrdup(""); - } - if ((pid = fork()) < 0) { - error("ssh_askpass: fork: %s", strerror(errno)); - return xstrdup(""); - } - if (pid == 0) { - seteuid(getuid()); - setuid(getuid()); - close(p[0]); - if (dup2(p[1], STDOUT_FILENO) < 0) - fatal("ssh_askpass: dup2: %s", strerror(errno)); - execlp(askpass, askpass, msg, (char *) 0); - fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); - } - close(p[1]); - - len = ret = 0; - do { - ret = read(p[0], buf + len, sizeof(buf) - 1 - len); - if (ret == -1 && errno == EINTR) - continue; - if (ret <= 0) - break; - len += ret; - } while (sizeof(buf) - 1 - len > 0); - buf[len] = '\0'; - - close(p[0]); - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - break; - - buf[strcspn(buf, "\r\n")] = '\0'; - pass = xstrdup(buf); - memset(buf, 0, sizeof(buf)); - return pass; -} - -/* - * Reads a passphrase from /dev/tty with echo turned off/on. Returns the - * passphrase (allocated with xmalloc). Exits if EOF is encountered. If - * RP_ALLOW_STDIN is set, the passphrase will be read from stdin if no - * tty is available - */ -char * -read_passphrase(const char *prompt, int flags) -{ - char *askpass = NULL, *ret, buf[1024]; - int rppflags, use_askpass = 0, ttyfd; - - rppflags = (flags & RP_ECHO) ? RPP_ECHO_ON : RPP_ECHO_OFF; - if (flags & RP_ALLOW_STDIN) { - if (!isatty(STDIN_FILENO)) - use_askpass = 1; - } else { - rppflags |= RPP_REQUIRE_TTY; - ttyfd = open(_PATH_TTY, O_RDWR); - if (ttyfd >= 0) - close(ttyfd); - else - use_askpass = 1; - } - - if (use_askpass && getenv("DISPLAY")) { - if (getenv(SSH_ASKPASS_ENV)) - askpass = getenv(SSH_ASKPASS_ENV); - else - askpass = _PATH_SSH_ASKPASS_DEFAULT; - return ssh_askpass(askpass, prompt); - } - - if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL) { - if (flags & RP_ALLOW_EOF) - return NULL; - return xstrdup(""); - } - - ret = xstrdup(buf); - memset(buf, 'x', sizeof buf); - return ret; -} - -int -ask_permission(const char *fmt, ...) -{ - va_list args; - char *p, prompt[1024]; - int allowed = 0; - char *yeschar = nl_langinfo(YESSTR); - - va_start(args, fmt); - vsnprintf(prompt, sizeof(prompt), fmt, args); - va_end(args); - - p = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF); - if (p != NULL) { - /* - * Accept empty responses and responses consisting - * of the word "yes" as affirmative. - */ - if (*p == '\0' || *p == '\n' || - strncasecmp(p, yeschar, 1) == 0) - allowed = 1; - xfree(p); - } - - return (allowed); -} diff --git a/usr/src/cmd/ssh/libssh/common/rsa.c b/usr/src/cmd/ssh/libssh/common/rsa.c deleted file mode 100644 index f24a44a770..0000000000 --- a/usr/src/cmd/ssh/libssh/common/rsa.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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) 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. - * - * - * Description of the RSA algorithm can be found e.g. from the following - * sources: - * - * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. - * - * Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to - * Computer Security. Prentice-Hall, 1989. - * - * Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill, - * 1994. - * - * R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications - * System and Method. US Patent 4,405,829, 1983. - * - * Hans Riesel: Prime Numbers and Computer Methods for Factorization. - * Birkhauser, 1994. - * - * 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: - * - * [gone - had to be deleted - what a pity] - */ - -#include "includes.h" -RCSID("$OpenBSD: rsa.c,v 1.24 2001/12/27 18:22:16 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "rsa.h" -#include "log.h" -#include "xmalloc.h" - -void -rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) -{ - u_char *inbuf, *outbuf; - int len, ilen, olen; - - if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) - fatal("rsa_public_encrypt() exponent too small or not odd"); - - olen = BN_num_bytes(key->n); - outbuf = xmalloc(olen); - - ilen = BN_num_bytes(in); - inbuf = xmalloc(ilen); - BN_bn2bin(in, inbuf); - - if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, - RSA_PKCS1_PADDING)) <= 0) - fatal("rsa_public_encrypt() failed"); - - BN_bin2bn(outbuf, len, out); - - memset(outbuf, 0, olen); - memset(inbuf, 0, ilen); - xfree(outbuf); - xfree(inbuf); -} - -int -rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) -{ - u_char *inbuf, *outbuf; - int len, ilen, olen; - - olen = BN_num_bytes(key->n); - outbuf = xmalloc(olen); - - ilen = BN_num_bytes(in); - inbuf = xmalloc(ilen); - BN_bn2bin(in, inbuf); - - if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, - RSA_PKCS1_PADDING)) <= 0) { - error("rsa_private_decrypt() failed"); - } else { - BN_bin2bn(outbuf, len, out); - } - memset(outbuf, 0, olen); - memset(inbuf, 0, ilen); - xfree(outbuf); - xfree(inbuf); - return len; -} - -/* calculate p-1 and q-1 */ -void -rsa_generate_additional_parameters(RSA *rsa) -{ - BIGNUM *aux; - BN_CTX *ctx; - - if ((aux = BN_new()) == NULL) - fatal("rsa_generate_additional_parameters: BN_new failed"); - if ((ctx = BN_CTX_new()) == NULL) - fatal("rsa_generate_additional_parameters: BN_CTX_new failed"); - - 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); -} - diff --git a/usr/src/cmd/ssh/libssh/common/sftp-common.c b/usr/src/cmd/ssh/libssh/common/sftp-common.c deleted file mode 100644 index ead9e2406f..0000000000 --- a/usr/src/cmd/ssh/libssh/common/sftp-common.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * Copyright (c) 2001 Damien Miller. 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. - */ - -/* $OpenBSD: sftp-common.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> - -#include <grp.h> -#include <pwd.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <stdarg.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "log.h" - -#include "sftp.h" -#include "sftp-common.h" - -/* Clear contents of attributes structure */ -void -attrib_clear(Attrib *a) -{ - a->flags = 0; - a->size = 0; - a->uid = 0; - a->gid = 0; - a->perm = 0; - a->atime = 0; - a->mtime = 0; -} - -/* Convert from struct stat to filexfer attribs */ -void -stat_to_attrib(const struct stat *st, Attrib *a) -{ - attrib_clear(a); - a->flags = 0; - a->flags |= SSH2_FILEXFER_ATTR_SIZE; - a->size = st->st_size; - a->flags |= SSH2_FILEXFER_ATTR_UIDGID; - a->uid = st->st_uid; - a->gid = st->st_gid; - a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; - a->perm = st->st_mode; - a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME; - a->atime = st->st_atime; - a->mtime = st->st_mtime; -} - -/* Convert from filexfer attribs to struct stat */ -void -attrib_to_stat(const Attrib *a, struct stat *st) -{ - memset(st, 0, sizeof(*st)); - - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) - st->st_size = a->size; - if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { - st->st_uid = a->uid; - st->st_gid = a->gid; - } - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) - st->st_mode = a->perm; - if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { - st->st_atime = a->atime; - st->st_mtime = a->mtime; - } -} - -/* Decode attributes in buffer */ -Attrib * -decode_attrib(Buffer *b) -{ - static Attrib a; - - attrib_clear(&a); - a.flags = buffer_get_int(b); - if (a.flags & SSH2_FILEXFER_ATTR_SIZE) - a.size = buffer_get_int64(b); - if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { - a.uid = buffer_get_int(b); - a.gid = buffer_get_int(b); - } - if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) - a.perm = buffer_get_int(b); - if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { - a.atime = buffer_get_int(b); - a.mtime = buffer_get_int(b); - } - /* vendor-specific extensions */ - if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) { - char *type, *data; - int i, count; - - count = buffer_get_int(b); - for (i = 0; i < count; i++) { - type = buffer_get_string(b, NULL); - data = buffer_get_string(b, NULL); - debug3("Got file attribute \"%s\"", type); - xfree(type); - xfree(data); - } - } - return &a; -} - -/* Encode attributes to buffer */ -void -encode_attrib(Buffer *b, const Attrib *a) -{ - buffer_put_int(b, a->flags); - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) - buffer_put_int64(b, a->size); - if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { - buffer_put_int(b, a->uid); - buffer_put_int(b, a->gid); - } - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) - buffer_put_int(b, a->perm); - if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { - buffer_put_int(b, a->atime); - buffer_put_int(b, a->mtime); - } -} - -/* Convert from SSH2_FX_ status to text error message */ -const char * -fx2txt(int status) -{ - switch (status) { - case SSH2_FX_OK: - return(gettext("No error")); - case SSH2_FX_EOF: - return(gettext("End of file")); - case SSH2_FX_NO_SUCH_FILE: - return(gettext("No such file or directory")); - case SSH2_FX_PERMISSION_DENIED: - return(gettext("Permission denied")); - case SSH2_FX_FAILURE: - return(gettext("Failure")); - case SSH2_FX_BAD_MESSAGE: - return(gettext("Bad message")); - case SSH2_FX_NO_CONNECTION: - return(gettext("No connection")); - case SSH2_FX_CONNECTION_LOST: - return(gettext("Connection lost")); - case SSH2_FX_OP_UNSUPPORTED: - return(gettext("Operation unsupported")); - default: - return(gettext("Unknown status")); - } - /* NOTREACHED */ -} - -/* - * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh - */ -char * -ls_file(const char *name, const struct stat *st, int remote) -{ - int ulen, glen, sz = 0; - struct passwd *pw; - struct group *gr; - struct tm *ltime = localtime(&st->st_mtime); - char *user, *group; - char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; - - strmode(st->st_mode, mode); - if (!remote && (pw = getpwuid(st->st_uid)) != NULL) { - user = pw->pw_name; - } else { - snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid); - user = ubuf; - } - if (!remote && (gr = getgrgid(st->st_gid)) != NULL) { - group = gr->gr_name; - } else { - snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid); - group = gbuf; - } - if (ltime != NULL) { - if (time(NULL) - st->st_mtime < (365*24*60*60)/2) - sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime); - else - sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime); - } - if (sz == 0) - tbuf[0] = '\0'; - ulen = MAX(strlen(user), 8); - glen = MAX(strlen(group), 8); - snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, - (u_int)st->st_nlink, ulen, user, glen, group, - (unsigned long long)st->st_size, tbuf, name); - return xstrdup(buf); -} diff --git a/usr/src/cmd/ssh/libssh/common/ssh-dss.c b/usr/src/cmd/ssh/libssh/common/ssh-dss.c deleted file mode 100644 index f73a91672f..0000000000 --- a/usr/src/cmd/ssh/libssh/common/ssh-dss.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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-dss.c,v 1.17 2002/07/04 10:41:47 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/bn.h> -#include <openssl/evp.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "compat.h" -#include "log.h" -#include "key.h" -#include "ssh-dss.h" - -#define INTBLOB_LEN 20 -#define SIGBLOB_LEN (2*INTBLOB_LEN) - -int -ssh_dss_sign(Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - DSA_SIG *sig; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN]; - u_int rlen, slen, len, dlen; - Buffer b; - - if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { - error("ssh_dss_sign: no DSA key"); - return -1; - } - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); - - sig = DSA_do_sign(digest, dlen, key->dsa); - memset(digest, 'd', sizeof(digest)); - - if (sig == NULL) { - error("ssh_dss_sign: sign failed"); - return -1; - } - - rlen = BN_num_bytes(sig->r); - slen = BN_num_bytes(sig->s); - if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { - error("bad sig size %u %u", rlen, slen); - DSA_SIG_free(sig); - return -1; - } - memset(sigblob, 0, SIGBLOB_LEN); - BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); - BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); - DSA_SIG_free(sig); - - if (datafellows & SSH_BUG_SIGBLOB) { - if (lenp != NULL) - *lenp = SIGBLOB_LEN; - if (sigp != NULL) { - *sigp = xmalloc(SIGBLOB_LEN); - memcpy(*sigp, sigblob, SIGBLOB_LEN); - } - } else { - /* ietf-drafts */ - buffer_init(&b); - buffer_put_cstring(&b, "ssh-dss"); - buffer_put_string(&b, sigblob, SIGBLOB_LEN); - len = buffer_len(&b); - if (lenp != NULL) - *lenp = len; - if (sigp != NULL) { - *sigp = xmalloc(len); - memcpy(*sigp, buffer_ptr(&b), len); - } - buffer_free(&b); - } - return 0; -} -int -ssh_dss_verify(Key *key, u_char *signature, u_int signaturelen, - u_char *data, u_int datalen) -{ - DSA_SIG *sig; - const EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE], *sigblob; - u_int len, dlen; - int rlen, ret; - Buffer b; - - if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { - error("ssh_dss_verify: no DSA key"); - return -1; - } - - /* fetch signature */ - if (datafellows & SSH_BUG_SIGBLOB) { - sigblob = signature; - len = signaturelen; - } else { - /* ietf-drafts */ - char *ktype; - buffer_init(&b); - buffer_append(&b, signature, signaturelen); - ktype = buffer_get_string(&b, NULL); - if (strcmp("ssh-dss", ktype) != 0) { - error("ssh_dss_verify: cannot handle type %s", ktype); - buffer_free(&b); - xfree(ktype); - return -1; - } - xfree(ktype); - sigblob = buffer_get_string(&b, &len); - rlen = buffer_len(&b); - buffer_free(&b); - if (rlen != 0) { - error("ssh_dss_verify: " - "remaining bytes in signature %d", rlen); - xfree(sigblob); - return -1; - } - } - - if (len != SIGBLOB_LEN) { - fatal("bad sigbloblen %u != SIGBLOB_LEN", len); - } - - /* parse signature */ - if ((sig = DSA_SIG_new()) == NULL) - fatal("ssh_dss_verify: DSA_SIG_new failed"); - if ((sig->r = BN_new()) == NULL) - fatal("ssh_dss_verify: BN_new failed"); - if ((sig->s = BN_new()) == NULL) - fatal("ssh_dss_verify: BN_new failed"); - BN_bin2bn(sigblob, INTBLOB_LEN, sig->r); - BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s); - - if (!(datafellows & SSH_BUG_SIGBLOB)) { - memset(sigblob, 0, len); - xfree(sigblob); - } - - /* sha1 the data */ - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); - - ret = DSA_do_verify(digest, dlen, sig, key->dsa); - memset(digest, 'd', sizeof(digest)); - - DSA_SIG_free(sig); - - debug("ssh_dss_verify: signature %s", - ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); - return ret; -} diff --git a/usr/src/cmd/ssh/libssh/common/ssh-gss.c b/usr/src/cmd/ssh/libssh/common/ssh-gss.c deleted file mode 100644 index 37aeb04873..0000000000 --- a/usr/src/cmd/ssh/libssh/common/ssh-gss.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" - -#ifdef GSSAPI - -#include "ssh.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "packet.h" -#include "compat.h" -#include <openssl/evp.h> -#include "cipher.h" -#include "kex.h" -#include "log.h" -#include "compat.h" -#include "xlist.h" - -#include <netdb.h> - -#include "ssh-gss.h" - -#ifdef HAVE_GSS_OID_TO_MECH -#include <gssapi/gssapi_ext.h> -#endif /* HAVE_GSS_OID_TO_MECH */ - -typedef struct { - char *encoded; - gss_OID oid; -} ssh_gss_kex_mapping; - -static ssh_gss_kex_mapping **gss_enc2oid = NULL; - -static void ssh_gssapi_encode_oid_for_kex(const gss_OID oid, char **enc_name); -static char *ssh_gssapi_make_kexalgs_list(gss_OID_set mechs, - const char *old_kexalgs); - -/* - * Populate gss_enc2oid table and return list of kexnames. - * - * If called with both mechs == GSS_C_NULL_OID_SET and kexname_list == NULL - * then cached gss_enc2oid table is cleaned up. - */ -void -ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, char **kexname_list) -{ - ssh_gss_kex_mapping **new_gss_enc2oid, **p; - Buffer buf; - char *enc_name; - int i; - - if (kexname_list != NULL) - *kexname_list = NULL; /* default to failed */ - - if (mechs != GSS_C_NULL_OID_SET || kexname_list == NULL) { - /* Cleanup gss_enc2oid table */ - for (p = gss_enc2oid; p != NULL && *p != NULL; p++) { - if ((*p)->encoded) - xfree((*p)->encoded); - ssh_gssapi_release_oid(&(*p)->oid); - xfree(*p); - } - if (gss_enc2oid) - xfree(gss_enc2oid); - } - - if (mechs == GSS_C_NULL_OID_SET && kexname_list == NULL) - return; /* nothing left to do */ - - if (mechs) { - gss_OID mech; - /* Populate gss_enc2oid table */ - new_gss_enc2oid = xmalloc(sizeof (ssh_gss_kex_mapping *) * - (mechs->count + 1)); - memset(new_gss_enc2oid, 0, - sizeof (ssh_gss_kex_mapping *) * (mechs->count + 1)); - - for (i = 0; i < mechs->count; i++) { - mech = &mechs->elements[i]; - ssh_gssapi_encode_oid_for_kex((const gss_OID)mech, - &enc_name); - - if (!enc_name) - continue; - - new_gss_enc2oid[i] = - xmalloc(sizeof (ssh_gss_kex_mapping)); - (new_gss_enc2oid[i])->encoded = enc_name; - (new_gss_enc2oid[i])->oid = - ssh_gssapi_dup_oid(&mechs->elements[i]); - } - - /* Do this last to avoid run-ins with fatal_cleanups */ - gss_enc2oid = new_gss_enc2oid; - } - - if (!kexname_list) - return; /* nothing left to do */ - - /* Make kex name list */ - buffer_init(&buf); - for (p = gss_enc2oid; p && *p; p++) { - buffer_put_char(&buf, ','); - buffer_append(&buf, (*p)->encoded, strlen((*p)->encoded)); - } - - if (buffer_len(&buf) == 0) { - buffer_free(&buf); - return; - } - - buffer_consume(&buf, 1); /* consume leading ',' */ - buffer_put_char(&buf, '\0'); - - *kexname_list = xstrdup(buffer_ptr(&buf)); - buffer_free(&buf); -} - -void -ssh_gssapi_mech_oid_to_kexname(const gss_OID mech, char **kexname) -{ - ssh_gss_kex_mapping **p; - - if (mech == GSS_C_NULL_OID || !kexname) - return; - - *kexname = NULL; /* default to not found */ - if (gss_enc2oid) { - for (p = gss_enc2oid; p && *p; p++) { - if (mech->length == (*p)->oid->length && - memcmp(mech->elements, (*p)->oid->elements, - mech->length) == 0) - *kexname = xstrdup((*p)->encoded); - } - } - - if (*kexname) - return; /* found */ - - ssh_gssapi_encode_oid_for_kex(mech, kexname); -} - -void -ssh_gssapi_oid_of_kexname(const char *kexname, gss_OID *mech) -{ - ssh_gss_kex_mapping **p; - - if (!mech || !kexname || !*kexname) - return; - - *mech = GSS_C_NULL_OID; /* default to not found */ - - if (!gss_enc2oid) - return; - - for (p = gss_enc2oid; p && *p; p++) { - if (strcmp(kexname, (*p)->encoded) == 0) { - *mech = (*p)->oid; - return; - } - } -} - -static -void -ssh_gssapi_encode_oid_for_kex(const gss_OID oid, char **enc_name) -{ - Buffer buf; - OM_uint32 oidlen; - uint_t enclen; - const EVP_MD *evp_md = EVP_md5(); - EVP_MD_CTX md; - uchar_t digest[EVP_MAX_MD_SIZE]; - char *encoded; - - if (oid == GSS_C_NULL_OID || !enc_name) - return; - - *enc_name = NULL; - - oidlen = oid->length; - - /* No GSS mechs have OIDs as long as 128 -- simplify DER encoding */ - if (oidlen > 128) - return; /* fail gracefully */ - - /* - * NOTE: If we need to support SSH_BUG_GSSAPI_BER this is where - * we'd do it. - * - * That means using "Se3H81ismmOC3OE+FwYCiQ==" for the Kerberos - * V mech and "N3+k7/4wGxHyuP8Yxi4RhA==" for the GSI mech. Ick. - */ - - buffer_init(&buf); - - /* UNIVERSAL class tag for OBJECT IDENTIFIER */ - buffer_put_char(&buf, 0x06); - buffer_put_char(&buf, oidlen); /* one octet DER length -- see above */ - - /* OID elements */ - buffer_append(&buf, oid->elements, oidlen); - - /* Make digest */ - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&buf), buffer_len(&buf)); - EVP_DigestFinal(&md, digest, NULL); - buffer_free(&buf); - - /* Base 64 encoding */ - encoded = xmalloc(EVP_MD_size(evp_md)*2); - enclen = __b64_ntop(digest, EVP_MD_size(evp_md), - encoded, EVP_MD_size(evp_md) * 2); - buffer_init(&buf); - buffer_append(&buf, KEX_GSS_SHA1, sizeof (KEX_GSS_SHA1) - 1); - buffer_append(&buf, encoded, enclen); - buffer_put_char(&buf, '\0'); - - debug2("GSS-API Mechanism encoded as %s", encoded); - xfree(encoded); - - *enc_name = xstrdup(buffer_ptr(&buf)); - buffer_free(&buf); -} - -static char * -ssh_gssapi_make_kexalgs_list(gss_OID_set mechs, const char *old_kexalgs) -{ - char *gss_kexalgs, *new_kexalgs; - int len; - - if (mechs == GSS_C_NULL_OID_SET) - return (xstrdup(old_kexalgs)); /* never null */ - - ssh_gssapi_mech_oids_to_kexnames(mechs, &gss_kexalgs); - - if (gss_kexalgs == NULL || *gss_kexalgs == '\0') - return (xstrdup(old_kexalgs)); /* never null */ - - if (old_kexalgs == NULL || *old_kexalgs == '\0') - return (gss_kexalgs); - - len = strlen(old_kexalgs) + strlen(gss_kexalgs) + 2; - new_kexalgs = xmalloc(len); - (void) snprintf(new_kexalgs, len, "%s,%s", gss_kexalgs, old_kexalgs); - xfree(gss_kexalgs); - - return (new_kexalgs); -} - -void -ssh_gssapi_modify_kex(Kex *kex, gss_OID_set mechs, char **proposal) -{ - char *kexalgs, *orig_kexalgs, *p; - char **hostalg, *orig_hostalgs, *new_hostalgs; - char **hostalgs; - gss_OID_set dup_mechs; - OM_uint32 maj, min; - int i; - - if (kex == NULL || proposal == NULL || - proposal[PROPOSAL_KEX_ALGS] == NULL) { - fatal("INTERNAL ERROR (%s)", __func__); - } - - orig_hostalgs = proposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; - - if (kex->mechs == GSS_C_NULL_OID_SET && mechs == GSS_C_NULL_OID_SET) - return; /* didn't offer GSS last time, not offering now */ - - if (kex->mechs == GSS_C_NULL_OID_SET || mechs == GSS_C_NULL_OID_SET) - goto mod_offer; /* didn't offer last time or not offering now */ - - /* Check if mechs is congruent to kex->mechs (last offered) */ - if (kex->mechs->count == mechs->count) { - int present, matches = 0; - - for (i = 0; i < mechs->count; i++) { - maj = gss_test_oid_set_member(&min, - &kex->mechs->elements[i], mechs, &present); - - if (GSS_ERROR(maj)) { - mechs = GSS_C_NULL_OID_SET; - break; - } - - matches += (present) ? 1 : 0; - } - - if (matches == kex->mechs->count) - return; /* no change in offer from last time */ - } - -mod_offer: - /* - * Remove previously offered mechs from PROPOSAL_KEX_ALGS proposal - * - * ASSUMPTION: GSS-API kex algs always go in front, so removing - * them is a matter of skipping them. - */ - p = kexalgs = orig_kexalgs = proposal[PROPOSAL_KEX_ALGS]; - while (p != NULL && *p != '\0' && - strncmp(p, KEX_GSS_SHA1, strlen(KEX_GSS_SHA1)) == 0) { - - if ((p = strchr(p, ',')) == NULL) - break; - p++; - kexalgs = p; - - } - kexalgs = proposal[PROPOSAL_KEX_ALGS] = xstrdup(kexalgs); - xfree(orig_kexalgs); - - (void) gss_release_oid_set(&min, &kex->mechs); /* ok if !kex->mechs */ - - /* Not offering GSS kex algorithms now -> all done */ - if (mechs == GSS_C_NULL_OID_SET) - return; - - /* Remember mechs we're offering */ - maj = gss_create_empty_oid_set(&min, &dup_mechs); - if (GSS_ERROR(maj)) - return; - for (i = 0; i < mechs->count; i++) { - maj = gss_add_oid_set_member(&min, &mechs->elements[i], - &dup_mechs); - - if (GSS_ERROR(maj)) { - (void) gss_release_oid_set(&min, &dup_mechs); - return; - } - } - - /* Add mechs to kex algorithms ... */ - proposal[PROPOSAL_KEX_ALGS] = ssh_gssapi_make_kexalgs_list(mechs, - kexalgs); - xfree(kexalgs); - kex->mechs = dup_mechs; /* remember what we offer now */ - - /* - * ... and add null host key alg, if it wasn't there before, but - * not if we're the server and we have other host key algs to - * offer. - * - * NOTE: Never remove "null" host key alg once added. - */ - if (orig_hostalgs == NULL || *orig_hostalgs == '\0') { - proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); - } else if (!kex->server) { - hostalgs = xsplit(orig_hostalgs, ','); - for (hostalg = hostalgs; *hostalg != NULL; hostalg++) { - if (strcmp(*hostalg, "null") == 0) { - xfree_split_list(hostalgs); - return; - } - } - xfree_split_list(hostalgs); - - if (kex->mechs != GSS_C_NULL_OID_SET) { - int len; - - len = strlen(orig_hostalgs) + sizeof (",null"); - new_hostalgs = xmalloc(len); - (void) snprintf(new_hostalgs, len, "%s,null", - orig_hostalgs); - proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = new_hostalgs; - } - - xfree(orig_hostalgs); - } -} - -/* - * Yes, we harcode OIDs for some things, for now it's all we can do. - * - * We have to reference particular mechanisms due to lack of generality - * in the GSS-API in several areas: authorization, mapping principal - * names to usernames, "storing" delegated credentials, and discovering - * whether a mechanism is a pseudo-mechanism that negotiates mechanisms. - * - * Even if they were in some header file or if __gss_mech_to_oid() - * and/or __gss_oid_to_mech() were standard we'd still have to hardcode - * the mechanism names, and since the mechanisms have no standard names - * other than their OIDs it's actually worse [less portable] to hardcode - * names than OIDs, so we hardcode OIDs. - * - * SPNEGO is a difficult problem though -- it MUST NOT be used in SSHv2, - * but that's true of all possible pseudo-mechanisms that can perform - * mechanism negotiation, and SPNEGO could have new OIDs in the future. - * Ideally we could query each mechanism for its feature set and then - * ignore any mechanisms that negotiate mechanisms, but, alas, there's - * no interface to do that. - * - * In the future, if the necessary generic GSS interfaces for the issues - * listed above are made available (even if they differ by platform, as - * we can expect authorization interfaces will), then we can stop - * referencing specific mechanism OIDs here. - */ -int -ssh_gssapi_is_spnego(gss_OID oid) -{ - return (oid->length == 6 && - memcmp("\053\006\001\005\005\002", oid->elements, 6) == 0); -} - -int -ssh_gssapi_is_krb5(gss_OID oid) -{ - return (oid->length == 9 && - memcmp("\x2A\x86\x48\x86\xF7\x12\x01\x02\x02", - oid->elements, 9) == 0); -} - -int -ssh_gssapi_is_dh(gss_OID oid) -{ - return (oid->length == 9 && - memcmp("\053\006\004\001\052\002\032\002\005", - oid->elements, 9) == 0); -} - -int -ssh_gssapi_is_gsi(gss_OID oid) -{ - return (oid->length == 9 && - memcmp("\x2B\x06\x01\x04\x01\x9B\x50\x01\x01", - oid->elements, 9) == 0); -} - -const char * -ssh_gssapi_oid_to_name(gss_OID oid) -{ -#ifdef HAVE_GSS_OID_TO_MECH - return (__gss_oid_to_mech(oid)); -#else - if (ssh_gssapi_is_krb5(oid)) - return ("Kerberos"); - if (ssh_gssapi_is_gsi(oid)) - return ("GSI"); - return ("(unknown)"); -#endif /* HAVE_GSS_OID_TO_MECH */ -} - -char * -ssh_gssapi_oid_to_str(gss_OID oid) -{ -#ifdef HAVE_GSS_OID_TO_STR - gss_buffer_desc str_buf; - char *str; - OM_uint32 maj, min; - - maj = gss_oid_to_str(&min, oid, &str_buf); - - if (GSS_ERROR(maj)) - return (xstrdup("<gss_oid_to_str() failed>")); - - str = xmalloc(str_buf.length + 1); - memset(str, 0, str_buf.length + 1); - strlcpy(str, str_buf.value, str_buf.length + 1); - (void) gss_release_buffer(&min, &str_buf); - - return (str); -#else - return (xstrdup("<gss_oid_to_str() unsupported>")); -#endif /* HAVE_GSS_OID_TO_STR */ -} - -/* Check that the OID in a data stream matches that in the context */ -int -ssh_gssapi_check_mech_oid(Gssctxt *ctx, void *data, size_t len) -{ - - return (ctx != NULL && ctx->desired_mech != GSS_C_NULL_OID && - ctx->desired_mech->length == len && - memcmp(ctx->desired_mech->elements, data, len) == 0); -} - -/* Set the contexts OID from a data stream */ -void -ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) -{ - if (ctx->actual_mech != GSS_C_NULL_OID) { - xfree(ctx->actual_mech->elements); - xfree(ctx->actual_mech); - } - ctx->actual_mech = xmalloc(sizeof (gss_OID_desc)); - ctx->actual_mech->length = len; - ctx->actual_mech->elements = xmalloc(len); - memcpy(ctx->actual_mech->elements, data, len); -} - -/* Set the contexts OID */ -void -ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) -{ - ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length); -} - -/* All this effort to report an error ... */ - -void -ssh_gssapi_error(Gssctxt *ctxt, const char *where) -{ - char *errmsg = ssh_gssapi_last_error(ctxt, NULL, NULL); - - if (where != NULL) - debug("GSS-API error while %s: %s", where, errmsg); - else - debug("GSS-API error: %s", errmsg); - - /* ssh_gssapi_last_error() can't return NULL */ - xfree(errmsg); -} - -char * -ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status, - OM_uint32 *minor_status) -{ - OM_uint32 lmin, more; - OM_uint32 maj, min; - gss_OID mech = GSS_C_NULL_OID; - gss_buffer_desc msg; - Buffer b; - char *ret; - - buffer_init(&b); - - if (ctxt) { - /* Get status codes from the Gssctxt */ - maj = ctxt->major; - min = ctxt->minor; - /* Output them if desired */ - if (major_status) - *major_status = maj; - if (minor_status) - *minor_status = min; - /* Get mechanism for minor status display */ - mech = (ctxt->actual_mech != GSS_C_NULL_OID) ? - ctxt->actual_mech : ctxt->desired_mech; - } else if (major_status && minor_status) { - maj = *major_status; - min = *major_status; - } else { - maj = GSS_S_COMPLETE; - min = 0; - } - - more = 0; - /* The GSSAPI error */ - do { - gss_display_status(&lmin, maj, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &more, &msg); - - buffer_append(&b, msg.value, msg.length); - buffer_put_char(&b, '\n'); - gss_release_buffer(&lmin, &msg); - } while (more != 0); - - /* The mechanism specific error */ - do { - /* - * If mech == GSS_C_NULL_OID we may get the default - * mechanism, whatever that is, and that may not be - * useful. - */ - gss_display_status(&lmin, min, GSS_C_MECH_CODE, mech, &more, - &msg); - - buffer_append(&b, msg.value, msg.length); - buffer_put_char(&b, '\n'); - - gss_release_buffer(&lmin, &msg); - } while (more != 0); - - buffer_put_char(&b, '\0'); - ret = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - - return (ret); -} - -/* - * Initialise our GSSAPI context. We use this opaque structure to contain all - * of the data which both the client and server need to persist across - * {accept,init}_sec_context calls, so that when we do it from the userauth - * stuff life is a little easier - */ -void -ssh_gssapi_build_ctx(Gssctxt **ctx, int client, gss_OID mech) -{ - Gssctxt *newctx; - - - newctx = (Gssctxt*)xmalloc(sizeof (Gssctxt)); - memset(newctx, 0, sizeof (Gssctxt)); - - - newctx->local = client; - newctx->desired_mech = ssh_gssapi_dup_oid(mech); - - /* This happens to be redundant given the memset() above */ - newctx->major = GSS_S_COMPLETE; - newctx->context = GSS_C_NO_CONTEXT; - newctx->actual_mech = GSS_C_NULL_OID; - newctx->desired_name = GSS_C_NO_NAME; - newctx->src_name = GSS_C_NO_NAME; - newctx->dst_name = GSS_C_NO_NAME; - newctx->creds = GSS_C_NO_CREDENTIAL; - newctx->deleg_creds = GSS_C_NO_CREDENTIAL; - - newctx->default_creds = (*ctx != NULL) ? (*ctx)->default_creds : 0; - - ssh_gssapi_delete_ctx(ctx); - - *ctx = newctx; -} - -gss_OID -ssh_gssapi_dup_oid(gss_OID oid) -{ - gss_OID new_oid; - - new_oid = xmalloc(sizeof (gss_OID_desc)); - - new_oid->elements = xmalloc(oid->length); - new_oid->length = oid->length; - memcpy(new_oid->elements, oid->elements, oid->length); - - return (new_oid); -} - -gss_OID -ssh_gssapi_make_oid(size_t length, void *elements) -{ - gss_OID_desc oid; - - oid.length = length; - oid.elements = elements; - - return (ssh_gssapi_dup_oid(&oid)); -} - -void -ssh_gssapi_release_oid(gss_OID *oid) -{ - OM_uint32 min; - - if (oid && *oid == GSS_C_NULL_OID) - return; - (void) gss_release_oid(&min, oid); - - if (*oid == GSS_C_NULL_OID) - return; /* libgss did own this gss_OID and released it */ - - xfree((*oid)->elements); - xfree(*oid); - *oid = GSS_C_NULL_OID; -} - -struct gss_name { - gss_OID name_type; - gss_buffer_t external_name; - gss_OID mech_type; - void *mech_name; -}; - -/* Delete our context, providing it has been built correctly */ -void -ssh_gssapi_delete_ctx(Gssctxt **ctx) -{ - OM_uint32 ms; - - if ((*ctx) == NULL) - return; - - if ((*ctx)->context != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER); -#if 0 - /* XXX */ - if ((*ctx)->desired_mech != GSS_C_NULL_OID) - ssh_gssapi_release_oid(&(*ctx)->desired_mech); -#endif - if ((*ctx)->actual_mech != GSS_C_NULL_OID) - (void) ssh_gssapi_release_oid(&(*ctx)->actual_mech); - if ((*ctx)->desired_name != GSS_C_NO_NAME) - gss_release_name(&ms, &(*ctx)->desired_name); -#if 0 - if ((*ctx)->src_name != GSS_C_NO_NAME) - gss_release_name(&ms, &(*ctx)->src_name); -#endif - if ((*ctx)->dst_name != GSS_C_NO_NAME) - gss_release_name(&ms, &(*ctx)->dst_name); - if ((*ctx)->creds != GSS_C_NO_CREDENTIAL) - gss_release_cred(&ms, &(*ctx)->creds); - if ((*ctx)->deleg_creds != GSS_C_NO_CREDENTIAL) - gss_release_cred(&ms, &(*ctx)->deleg_creds); - - xfree(*ctx); - *ctx = NULL; -} - -/* Create a GSS hostbased service principal name for a given server hostname */ -int -ssh_gssapi_import_name(Gssctxt *ctx, const char *server_host) -{ - gss_buffer_desc name_buf; - int ret; - - /* Build target principal */ - name_buf.length = strlen(SSH_GSS_HOSTBASED_SERVICE) + - strlen(server_host) + 1; /* +1 for '@' */ - name_buf.value = xmalloc(name_buf.length + 1); /* +1 for NUL */ - ret = snprintf(name_buf.value, name_buf.length + 1, "%s@%s", - SSH_GSS_HOSTBASED_SERVICE, server_host); - - debug3("%s: snprintf() returned %d, expected %d", __func__, ret, - name_buf.length); - - ctx->major = gss_import_name(&ctx->minor, &name_buf, - GSS_C_NT_HOSTBASED_SERVICE, &ctx->desired_name); - - if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, "calling GSS_Import_name()"); - return (0); - } - - xfree(name_buf.value); - - return (1); -} - -OM_uint32 -ssh_gssapi_get_mic(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) -{ - - ctx->major = gss_get_mic(&ctx->minor, ctx->context, - GSS_C_QOP_DEFAULT, buffer, hash); - if (GSS_ERROR(ctx->major)) - ssh_gssapi_error(ctx, "while getting MIC"); - return (ctx->major); -} - -OM_uint32 -ssh_gssapi_verify_mic(Gssctxt *ctx, gss_buffer_desc *buffer, - gss_buffer_desc *hash) -{ - gss_qop_t qop; - - ctx->major = gss_verify_mic(&ctx->minor, ctx->context, buffer, - hash, &qop); - if (GSS_ERROR(ctx->major)) - ssh_gssapi_error(ctx, "while verifying MIC"); - return (ctx->major); -} -#endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/libssh/common/ssh-rsa.c b/usr/src/cmd/ssh/libssh/common/ssh-rsa.c deleted file mode 100644 index bc89d41da1..0000000000 --- a/usr/src/cmd/ssh/libssh/common/ssh-rsa.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * 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-rsa.c,v 1.26 2002/08/27 17:13:56 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/evp.h> -#include <openssl/err.h> - -#include "xmalloc.h" -#include "log.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "ssh-rsa.h" -#include "compat.h" -#include "ssh.h" - -static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int , RSA *); - -/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ -int -ssh_rsa_sign(Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - const EVP_MD *evp_md; - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE], *sig; - u_int slen, dlen, len; - int ok, nid; - Buffer b; - - if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) { - error("ssh_rsa_sign: no RSA key"); - return -1; - } - nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; - if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { - error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid); - return -1; - } - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); - - slen = RSA_size(key->rsa); - sig = xmalloc(slen); - - ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa); - memset(digest, 'd', sizeof(digest)); - - if (ok != 1) { - int ecode = ERR_get_error(); - error("ssh_rsa_sign: RSA_sign failed: %s", - ERR_error_string(ecode, NULL)); - xfree(sig); - return -1; - } - if (len < slen) { - u_int diff = slen - len; - debug("slen %u > len %u", slen, len); - memmove(sig + diff, sig, len); - memset(sig, 0, diff); - } else if (len > slen) { - error("ssh_rsa_sign: slen %u slen2 %u", slen, len); - xfree(sig); - return -1; - } - /* encode signature */ - buffer_init(&b); - buffer_put_cstring(&b, "ssh-rsa"); - buffer_put_string(&b, sig, slen); - len = buffer_len(&b); - if (lenp != NULL) - *lenp = len; - if (sigp != NULL) { - *sigp = xmalloc(len); - memcpy(*sigp, buffer_ptr(&b), len); - } - buffer_free(&b); - memset(sig, 's', slen); - xfree(sig); - - return 0; -} - -int -ssh_rsa_verify(Key *key, u_char *signature, u_int signaturelen, - u_char *data, u_int datalen) -{ - Buffer b; - const EVP_MD *evp_md; - EVP_MD_CTX md; - char *ktype; - u_char digest[EVP_MAX_MD_SIZE], *sigblob; - u_int len, dlen, modlen; - int rlen, ret, nid; - - if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) { - error("ssh_rsa_verify: no RSA key"); - return -1; - } - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits", - BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); - return -1; - } - buffer_init(&b); - buffer_append(&b, signature, signaturelen); - ktype = buffer_get_string(&b, NULL); - if (strcmp("ssh-rsa", ktype) != 0) { - error("ssh_rsa_verify: cannot handle type %s", ktype); - buffer_free(&b); - xfree(ktype); - return -1; - } - xfree(ktype); - sigblob = buffer_get_string(&b, &len); - rlen = buffer_len(&b); - buffer_free(&b); - if (rlen != 0) { - error("ssh_rsa_verify: remaining bytes in signature %d", rlen); - xfree(sigblob); - return -1; - } - /* RSA_verify expects a signature of RSA_size */ - modlen = RSA_size(key->rsa); - if (len > modlen) { - error("ssh_rsa_verify: len %u > modlen %u", len, modlen); - xfree(sigblob); - return -1; - } else if (len < modlen) { - u_int diff = modlen - len; - debug("ssh_rsa_verify: add padding: modlen %u > len %u", - modlen, len); - sigblob = xrealloc(sigblob, modlen); - memmove(sigblob + diff, sigblob, len); - memset(sigblob, 0, diff); - len = modlen; - } - nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; - if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { - error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid); - xfree(sigblob); - return -1; - } - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, &dlen); - - ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa); - memset(digest, 'd', sizeof(digest)); - memset(sigblob, 's', len); - xfree(sigblob); - debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : ""); - return ret; -} - -/* - * See: - * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn - */ -/* - * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) - * oiw(14) secsig(3) algorithms(2) 26 } - */ -static const u_char id_sha1[] = { - 0x30, 0x21, /* type Sequence, length 0x21 (33) */ - 0x30, 0x09, /* type Sequence, length 0x09 */ - 0x06, 0x05, /* type OID, length 0x05 */ - 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ - 0x05, 0x00, /* NULL */ - 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ -}; -/* - * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) - * rsadsi(113549) digestAlgorithm(2) 5 } - */ -static const u_char id_md5[] = { - 0x30, 0x20, /* type Sequence, length 0x20 (32) */ - 0x30, 0x0c, /* type Sequence, length 0x09 */ - 0x06, 0x08, /* type OID, length 0x05 */ - 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */ - 0x05, 0x00, /* NULL */ - 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */ -}; - -static int -openssh_RSA_verify(int type, u_char *hash, u_int hashlen, - u_char *sigbuf, u_int siglen, RSA *rsa) -{ - u_int ret, rsasize, oidlen = 0, hlen = 0; - int len; - const u_char *oid = NULL; - u_char *decrypted = NULL; - - ret = 0; - switch (type) { - case NID_sha1: - oid = id_sha1; - oidlen = sizeof(id_sha1); - hlen = 20; - break; - case NID_md5: - oid = id_md5; - oidlen = sizeof(id_md5); - hlen = 16; - break; - default: - goto done; - break; - } - if (hashlen != hlen) { - error("bad hashlen"); - goto done; - } - rsasize = RSA_size(rsa); - if (siglen == 0 || siglen > rsasize) { - error("bad siglen"); - goto done; - } - decrypted = xmalloc(rsasize); - if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, - RSA_PKCS1_PADDING)) < 0) { - error("RSA_public_decrypt failed: %s", - ERR_error_string(ERR_get_error(), NULL)); - goto done; - } - if (len != hlen + oidlen) { - error("bad decrypted len: %d != %d + %d", len, hlen, oidlen); - goto done; - } - if (memcmp(decrypted, oid, oidlen) != 0) { - error("oid mismatch"); - goto done; - } - if (memcmp(decrypted + oidlen, hash, hlen) != 0) { - error("hash mismatch"); - goto done; - } - ret = 1; -done: - if (decrypted) - xfree(decrypted); - return ret; -} diff --git a/usr/src/cmd/ssh/libssh/common/tildexpand.c b/usr/src/cmd/ssh/libssh/common/tildexpand.c deleted file mode 100644 index 5fcd07ebe6..0000000000 --- a/usr/src/cmd/ssh/libssh/common/tildexpand.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: tildexpand.c,v 1.13 2002/06/23 03:25:50 deraadt Exp $"); - -#include <libgen.h> - -#include "xmalloc.h" -#include "log.h" -#include "tildexpand.h" - -/* - * Expands tildes in the file name. Returns data allocated by xmalloc. - * Warning: this calls getpw*. - */ -char * -tilde_expand_filename(const char *filename, uid_t my_uid) -{ - const char *cp; - uint_t userlen; - char *expanded; - struct passwd *pw; - char *pw_dir; - char user[100]; - int len; - - /* Return immediately if no tilde. */ - if (filename[0] != '~') - return (xstrdup(filename)); - - /* Skip the tilde. */ - filename++; - - /* Find where the username ends. */ - cp = strchr(filename, '/'); - if (cp) - userlen = cp - filename; /* Something after username. */ - else - userlen = strlen(filename); /* Nothing after username. */ - - /* This is the ~/xyz case with no ~username specification. */ - if (userlen == 0) - pw = getpwuid(my_uid); - else { - /* Tilde refers to someone elses home directory. */ - if (userlen > sizeof (user) - 1) - fatal("User name after tilde too long."); - memcpy(user, filename, userlen); - user[userlen] = 0; - pw = getpwnam(user); - } - - /* Use the HOME variable now. */ - if (pw == NULL) { - debug("User account's password entry not found, trying to use " - "the HOME variable."); - if ((pw_dir = getenv("HOME")) == NULL) { - fatal("User account's password entry not found and " - "the HOME variable not set."); - } - } else { - pw_dir = pw->pw_dir; - } - - /* If referring to someones home directory, return it now. */ - if (cp == NULL) { - /* Only home directory specified */ - return (xstrdup(pw_dir)); - } - - /* Build a path combining the specified directory and path. */ - len = strlen(pw_dir) + strlen(cp + 1) + 2; - if (len > MAXPATHLEN) - fatal("Home directory too long (%d > %d)", len - 1, - MAXPATHLEN - 1); - - expanded = xmalloc(len); - snprintf(expanded, len, "%s%s%s", pw_dir, - strcmp(pw_dir, "/") ? "/" : "", cp + 1); - return (expanded); -} diff --git a/usr/src/cmd/ssh/libssh/common/ttymodes.c b/usr/src/cmd/ssh/libssh/common/ttymodes.c deleted file mode 100644 index b20ab34ff3..0000000000 --- a/usr/src/cmd/ssh/libssh/common/ttymodes.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * 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". - */ - -/* - * SSH2 tty modes support by Kevin Steves. - * Copyright (c) 2001 Kevin Steves. 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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * 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. - */ - -#include "includes.h" -RCSID("$OpenBSD: ttymodes.c,v 1.18 2002/06/19 00:27:55 deraadt Exp $"); - -#include "packet.h" -#include "log.h" -#include "ssh1.h" -#include "compat.h" -#include "buffer.h" -#include "bufaux.h" - -#define TTY_OP_END 0 -/* - * uint32 (u_int) follows speed in SSH1 and SSH2 - */ -#define TTY_OP_ISPEED_PROTO1 192 -#define TTY_OP_OSPEED_PROTO1 193 -#define TTY_OP_ISPEED_PROTO2 128 -#define TTY_OP_OSPEED_PROTO2 129 - -/* - * Converts POSIX speed_t to a baud rate. The values of the - * constants for speed_t are not themselves portable. - */ -static int -speed_to_baud(speed_t speed) -{ - switch (speed) { - case B0: - return 0; - case B50: - return 50; - case B75: - return 75; - case B110: - return 110; - case B134: - return 134; - case B150: - return 150; - case B200: - return 200; - case B300: - return 300; - case B600: - return 600; - case B1200: - return 1200; - case B1800: - return 1800; - case B2400: - return 2400; - case B4800: - return 4800; - case B9600: - return 9600; - -#ifdef B19200 - case B19200: - return 19200; -#else /* B19200 */ -#ifdef EXTA - case EXTA: - return 19200; -#endif /* EXTA */ -#endif /* B19200 */ - -#ifdef B38400 - case B38400: - return 38400; -#else /* B38400 */ -#ifdef EXTB - case EXTB: - return 38400; -#endif /* EXTB */ -#endif /* B38400 */ - -#ifdef B7200 - case B7200: - return 7200; -#endif /* B7200 */ -#ifdef B14400 - case B14400: - return 14400; -#endif /* B14400 */ -#ifdef B28800 - case B28800: - return 28800; -#endif /* B28800 */ -#ifdef B57600 - case B57600: - return 57600; -#endif /* B57600 */ -#ifdef B76800 - case B76800: - return 76800; -#endif /* B76800 */ -#ifdef B115200 - case B115200: - return 115200; -#endif /* B115200 */ -#ifdef B230400 - case B230400: - return 230400; -#endif /* B230400 */ -#ifdef B460800 - case B460800: - return 460800; -#endif /* B460800 */ -#ifdef B921600 - case B921600: - return 921600; -#endif /* B921600 */ - default: - return 9600; - } -} - -/* - * Converts a numeric baud rate to a POSIX speed_t. - */ -static speed_t -baud_to_speed(int baud) -{ - switch (baud) { - case 0: - return B0; - case 50: - return B50; - case 75: - return B75; - case 110: - return B110; - case 134: - return B134; - case 150: - return B150; - case 200: - return B200; - case 300: - return B300; - case 600: - return B600; - case 1200: - return B1200; - case 1800: - return B1800; - case 2400: - return B2400; - case 4800: - return B4800; - case 9600: - return B9600; - -#ifdef B19200 - case 19200: - return B19200; -#else /* B19200 */ -#ifdef EXTA - case 19200: - return EXTA; -#endif /* EXTA */ -#endif /* B19200 */ - -#ifdef B38400 - case 38400: - return B38400; -#else /* B38400 */ -#ifdef EXTB - case 38400: - return EXTB; -#endif /* EXTB */ -#endif /* B38400 */ - -#ifdef B7200 - case 7200: - return B7200; -#endif /* B7200 */ -#ifdef B14400 - case 14400: - return B14400; -#endif /* B14400 */ -#ifdef B28800 - case 28800: - return B28800; -#endif /* B28800 */ -#ifdef B57600 - case 57600: - return B57600; -#endif /* B57600 */ -#ifdef B76800 - case 76800: - return B76800; -#endif /* B76800 */ -#ifdef B115200 - case 115200: - return B115200; -#endif /* B115200 */ -#ifdef B230400 - case 230400: - return B230400; -#endif /* B230400 */ -#ifdef B460800 - case 460800: - return B460800; -#endif /* B460800 */ -#ifdef B921600 - case 921600: - return B921600; -#endif /* B921600 */ - default: - return B9600; - } -} - -/* - * Encodes terminal modes for the terminal referenced by fd - * or tiop in a portable manner, and appends the modes to a packet - * being constructed. - */ -void -tty_make_modes(int fd, struct termios *tiop) -{ - struct termios tio; - int baud; - Buffer buf; - int tty_op_ospeed, tty_op_ispeed; - void (*put_arg)(Buffer *, u_int); - - buffer_init(&buf); - if (compat20) { - tty_op_ospeed = TTY_OP_OSPEED_PROTO2; - tty_op_ispeed = TTY_OP_ISPEED_PROTO2; - put_arg = buffer_put_int; - } else { - tty_op_ospeed = TTY_OP_OSPEED_PROTO1; - tty_op_ispeed = TTY_OP_ISPEED_PROTO1; - put_arg = (void (*)(Buffer *, u_int)) buffer_put_char; - } - - if (tiop == NULL) { - if (tcgetattr(fd, &tio) == -1) { - log("tcgetattr: %.100s", strerror(errno)); - goto end; - } - } else - tio = *tiop; - - /* Store input and output baud rates. */ - baud = speed_to_baud(cfgetospeed(&tio)); - debug3("tty_make_modes: ospeed %d", baud); - buffer_put_char(&buf, tty_op_ospeed); - buffer_put_int(&buf, baud); - baud = speed_to_baud(cfgetispeed(&tio)); - debug3("tty_make_modes: ispeed %d", baud); - buffer_put_char(&buf, tty_op_ispeed); - buffer_put_int(&buf, baud); - - /* Store values of mode flags. */ -#define TTYCHAR(NAME, OP) \ - debug3("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \ - buffer_put_char(&buf, OP); \ - put_arg(&buf, tio.c_cc[NAME]); - -#define TTYMODE(NAME, FIELD, OP) \ - debug3("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \ - buffer_put_char(&buf, OP); \ - put_arg(&buf, ((tio.FIELD & NAME) != 0)); - -#include "ttymodes.h" - -#undef TTYCHAR -#undef TTYMODE - -end: - /* Mark end of mode data. */ - buffer_put_char(&buf, TTY_OP_END); - if (compat20) - packet_put_string(buffer_ptr(&buf), buffer_len(&buf)); - else - packet_put_raw(buffer_ptr(&buf), buffer_len(&buf)); - buffer_free(&buf); -} - -/* - * Decodes terminal modes for the terminal referenced by fd in a portable - * manner from a packet being read. - */ -void -tty_parse_modes(int fd, int *n_bytes_ptr) -{ - struct termios tio; - int opcode, baud; - int n_bytes = 0; - int failure = 0; - u_int (*get_arg)(void); - int arg, arg_size; - - if (compat20) { - *n_bytes_ptr = packet_get_int(); - debug3("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr); - if (*n_bytes_ptr == 0) - return; - get_arg = packet_get_int; - arg_size = 4; - } else { - get_arg = packet_get_char; - arg_size = 1; - } - - /* - * Get old attributes for the terminal. We will modify these - * flags. I am hoping that if there are any machine-specific - * modes, they will initially have reasonable values. - */ - if (tcgetattr(fd, &tio) == -1) { - log("tcgetattr: %.100s", strerror(errno)); - failure = -1; - } - - for (;;) { - n_bytes += 1; - opcode = packet_get_char(); - switch (opcode) { - case TTY_OP_END: - goto set; - - /* XXX: future conflict possible */ - case TTY_OP_ISPEED_PROTO1: - case TTY_OP_ISPEED_PROTO2: - n_bytes += 4; - baud = packet_get_int(); - debug3("tty_parse_modes: ispeed %d", baud); - if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1) - error("cfsetispeed failed for %d", baud); - break; - - /* XXX: future conflict possible */ - case TTY_OP_OSPEED_PROTO1: - case TTY_OP_OSPEED_PROTO2: - n_bytes += 4; - baud = packet_get_int(); - debug3("tty_parse_modes: ospeed %d", baud); - if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1) - error("cfsetospeed failed for %d", baud); - break; - -#define TTYCHAR(NAME, OP) \ - case OP: \ - n_bytes += arg_size; \ - tio.c_cc[NAME] = get_arg(); \ - debug3("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \ - break; -#define TTYMODE(NAME, FIELD, OP) \ - case OP: \ - n_bytes += arg_size; \ - if ((arg = get_arg())) \ - tio.FIELD |= NAME; \ - else \ - tio.FIELD &= ~NAME; \ - debug3("tty_parse_modes: %d %d", OP, arg); \ - break; - -#include "ttymodes.h" - -#undef TTYCHAR -#undef TTYMODE - - default: - debug("Ignoring unsupported tty mode opcode %d (0x%x)", - opcode, opcode); - if (!compat20) { - /* - * SSH1: - * Opcodes 1 to 127 are defined to have - * a one-byte argument. - * Opcodes 128 to 159 are defined to have - * an integer argument. - */ - if (opcode > 0 && opcode < 128) { - n_bytes += 1; - (void) packet_get_char(); - break; - } else if (opcode >= 128 && opcode < 160) { - n_bytes += 4; - (void) packet_get_int(); - break; - } else { - /* - * It is a truly undefined opcode (160 to 255). - * We have no idea about its arguments. So we - * must stop parsing. Note that some data may be - * left in the packet; hopefully there is nothing - * more coming after the mode data. - */ - log("parse_tty_modes: unknown opcode %d", opcode); - goto set; - } - } else { - /* - * SSH2: - * Opcodes 1 to 159 are defined to have - * a uint32 argument. - * Opcodes 160 to 255 are undefined and - * cause parsing to stop. - */ - if (opcode > 0 && opcode < 160) { - n_bytes += 4; - (void) packet_get_int(); - break; - } else { - log("parse_tty_modes: unknown opcode %d", opcode); - goto set; - } - } - } - } - -set: - if (*n_bytes_ptr != n_bytes) { - *n_bytes_ptr = n_bytes; - log("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", - *n_bytes_ptr, n_bytes); - return; /* Don't process bytes passed */ - } - if (failure == -1) - return; /* Packet parsed ok but tcgetattr() failed */ - - /* Set the new modes for the terminal. */ - if (tcsetattr(fd, TCSANOW, &tio) == -1) - log("Setting tty modes failed: %.100s", strerror(errno)); -} diff --git a/usr/src/cmd/ssh/libssh/common/uidswap.c b/usr/src/cmd/ssh/libssh/common/uidswap.c deleted file mode 100644 index 942b22a749..0000000000 --- a/usr/src/cmd/ssh/libssh/common/uidswap.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: uidswap.c,v 1.23 2002/07/15 17:15:31 stevesk Exp $"); - -#include <priv.h> - -#include "log.h" -#include "uidswap.h" -#include "buffer.h" -#include "servconf.h" - -/* - * Note: all these functions must work in all of the following cases: - * 1. euid=0, ruid=0 - * 2. euid=0, ruid!=0 - * 3. euid!=0, ruid!=0 - * Additionally, they must work regardless of whether the system has - * POSIX saved uids or not. - */ - -#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS) -/* Lets assume that posix saved ids also work with seteuid, even though that - is not part of the posix specification. */ -#define SAVED_IDS_WORK -/* Saved effective uid. */ -static uid_t saved_euid = 0; -static gid_t saved_egid = 0; -#endif - -/* Saved effective uid. */ -static int privileged = 0; -static int temporarily_use_uid_effective = 0; -static int ngroups_max = -1; -static gid_t *saved_egroups, *user_groups; -static int saved_egroupslen = -1, user_groupslen = -1; - -/* - * Temporarily changes to the given uid. If the effective user - * id is not root, this does nothing. This call cannot be nested. - */ -void -temporarily_use_uid(struct passwd *pw) -{ - /* Save the current euid, and egroups. */ -#ifdef SAVED_IDS_WORK - saved_euid = geteuid(); - saved_egid = getegid(); - debug("temporarily_use_uid: %u/%u (e=%u/%u)", - (u_int)pw->pw_uid, (u_int)pw->pw_gid, - (u_int)saved_euid, (u_int)saved_egid); - if (saved_euid != 0) { - privileged = 0; - return; - } -#else - if (geteuid() != 0) { - privileged = 0; - return; - } -#endif /* SAVED_IDS_WORK */ - - privileged = 1; - temporarily_use_uid_effective = 1; - - if (ngroups_max < 0) { - ngroups_max = sysconf(_SC_NGROUPS_MAX); - saved_egroups = malloc(ngroups_max * sizeof (gid_t)); - user_groups = malloc(ngroups_max * sizeof (gid_t)); - if (saved_egroups == NULL || user_groups == NULL) - fatal("malloc(gid array): %.100s", strerror(errno)); - } - - saved_egroupslen = getgroups(ngroups_max, saved_egroups); - if (saved_egroupslen < 0) - fatal("getgroups: %.100s", strerror(errno)); - - /* set and save the user's groups */ - if (user_groupslen == -1) { - if (initgroups(pw->pw_name, pw->pw_gid) < 0) - fatal("initgroups: %s: %.100s", pw->pw_name, - strerror(errno)); - user_groupslen = getgroups(ngroups_max, user_groups); - if (user_groupslen < 0) - fatal("getgroups: %.100s", strerror(errno)); - } - /* Set the effective uid to the given (unprivileged) uid. */ - if (setgroups(user_groupslen, user_groups) < 0) - fatal("setgroups: %.100s", strerror(errno)); -#ifdef SAVED_IDS_WORK - /* Set saved gid and set real gid */ - if (setregid(pw->pw_gid, -1) == -1) - debug("setregid(%u, -1): %.100s", (uint_t)pw->pw_gid, strerror(errno)); - /* Set saved uid and set real uid */ - if (setreuid(pw->pw_uid, -1) == -1) - debug("setreuid(%u, -1): %.100s", (uint_t)pw->pw_uid, strerror(errno)); -#else - /* Propagate the privileged gid to all of our gids. */ - if (setgid(getegid()) < 0) - debug("setgid %u: %.100s", (u_int) getegid(), strerror(errno)); - /* Propagate the privileged uid to all of our uids. */ - if (setuid(geteuid()) < 0) - debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno)); -#endif /* SAVED_IDS_WORK */ - /* Set effective gid */ - if (setegid(pw->pw_gid) == -1) - fatal("setegid %u: %.100s", (u_int)pw->pw_uid, - strerror(errno)); - /* Set effective uid */ - if (seteuid(pw->pw_uid) == -1) - fatal("seteuid %u: %.100s", (u_int)pw->pw_uid, - strerror(errno)); - /* - * If saved set ids work then - * - * ruid == euid == pw->pw_uid - * saved uid = previous euid - * rgid == egid == pw->pw_gid - * saved gid = previous egid - */ -} - -/* - * Restores to the original (privileged) uid. - */ -void -restore_uid(void) -{ - /* it's a no-op unless privileged */ - if (!privileged) { - debug("restore_uid: (unprivileged)"); - return; - } - if (!temporarily_use_uid_effective) - fatal("restore_uid: temporarily_use_uid not effective"); - -#ifdef SAVED_IDS_WORK - debug("restore_uid: %u/%u", (u_int)saved_euid, (u_int)saved_egid); - /* Set the effective uid back to the saved privileged uid. */ - if (seteuid(saved_euid) < 0) - fatal("seteuid %u: %.100s", (u_int)saved_euid, strerror(errno)); - if (setuid(saved_euid) < 0) - fatal("setuid %u: %.100s", (u_int)saved_euid, strerror(errno)); - if (setegid(saved_egid) < 0) - fatal("setegid %u: %.100s", (u_int)saved_egid, strerror(errno)); - if (setgid(saved_egid) < 0) - fatal("setgid %u: %.100s", (u_int)saved_egid, strerror(errno)); -#else /* SAVED_IDS_WORK */ - /* - * We are unable to restore the real uid to its unprivileged value. - * Propagate the real uid (usually more privileged) to effective uid - * as well. - */ - setuid(getuid()); - setgid(getgid()); -#endif /* SAVED_IDS_WORK */ - - if (setgroups(saved_egroupslen, saved_egroups) < 0) - fatal("setgroups: %.100s", strerror(errno)); - temporarily_use_uid_effective = 0; -} - -/* - * Permanently sets all uids to the given uid. This cannot be called while - * temporarily_use_uid is effective. Note that when the ChrootDirectory option - * is in use we keep a few privileges so that we can call chroot(2) later while - * already running under UIDs of a connecting user. - */ -void -permanently_set_uid(struct passwd *pw, char *chroot_directory) -{ - priv_set_t *pset; - - if (temporarily_use_uid_effective) - fatal("%s: temporarily_use_uid effective", __func__); - - debug("%s: %u/%u", __func__, (u_int)pw->pw_uid, (u_int)pw->pw_gid); - - if (initgroups(pw->pw_name, pw->pw_gid) < 0) - fatal("initgroups: %s: %.100s", pw->pw_name, - strerror(errno)); - - if (setgid(pw->pw_gid) < 0) - fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); - - /* - * If root is connecting we are done now. Note that we must have called - * setgid() in case that the SSH server was run under a group other than - * root. - */ - if (pw->pw_uid == 0) - return; - - /* - * This means we will keep all privileges after the UID change. - */ - if (setpflags(PRIV_AWARE, 1) != 0) - fatal("setpflags: %s", strerror(errno)); - - /* Now we are running under UID of the user. */ - if (setuid(pw->pw_uid) < 0) - fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); - - /* - * We will run with the privileges from the Inheritable set as - * we would have after exec(2) if we had stayed in NPA mode - * before setuid(2) call (see privileges(5), user_attr(4), and - * pam_unix_cred(5)). We want to run with P = E = I, with I as - * set by pam_unix_cred(5). We also add PRIV_PROC_CHROOT, - * obviously, and then PRIV_PROC_FORK and PRIV_PROC_EXEC, since - * those two might have been removed from the I set. Note that - * we are expected to finish the login process without them in - * the I set, the important thing is that those not be passed on - * to a shell or a subsystem later if they were not set in - * pam_unix_cred(5). - */ - if ((pset = priv_allocset()) == NULL) - fatal("priv_allocset: %s", strerror(errno)); - if (getppriv(PRIV_INHERITABLE, pset) != 0) - fatal("getppriv: %s", strerror(errno)); - - /* We do not need PRIV_PROC_CHROOT unless chroot()ing. */ - if (chroot_requested(chroot_directory) && - priv_addset(pset, PRIV_PROC_CHROOT) == -1) { - fatal("%s: priv_addset failed", __func__); - } - - if (priv_addset(pset, PRIV_PROC_FORK) == -1 || - priv_addset(pset, PRIV_PROC_EXEC) == -1) { - fatal("%s: priv_addset failed", __func__); - } - - /* Set only P; this will also set E. */ - if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) == -1) - fatal("setppriv: %s", strerror(errno)); - - /* We don't need the PA flag anymore. */ - if (setpflags(PRIV_AWARE, 0) == -1) - fatal("setpflags: %s", strerror(errno)); - - priv_freeset(pset); -} diff --git a/usr/src/cmd/ssh/libssh/common/uuencode.c b/usr/src/cmd/ssh/libssh/common/uuencode.c deleted file mode 100644 index 432f5c4369..0000000000 --- a/usr/src/cmd/ssh/libssh/common/uuencode.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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: uuencode.c,v 1.16 2002/09/09 14:54:15 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "xmalloc.h" -#include "uuencode.h" - -int -uuencode(u_char *src, u_int srclength, - char *target, size_t targsize) -{ - return __b64_ntop(src, srclength, target, targsize); -} - -int -uudecode(const char *src, u_char *target, size_t targsize) -{ - int len; - char *encoded, *p; - - /* copy the 'readonly' source */ - encoded = xstrdup(src); - /* skip whitespace and data */ - for (p = encoded; *p == ' ' || *p == '\t'; p++) - ; - for (; *p != '\0' && *p != ' ' && *p != '\t'; p++) - ; - /* and remove trailing whitespace because __b64_pton needs this */ - *p = '\0'; - len = __b64_pton((u_char *) encoded, target, targsize); - xfree(encoded); - return len; -} - -void -dump_base64(FILE *fp, u_char *data, u_int len) -{ - char *buf = xmalloc(2*len); - int i, n; - - n = uuencode(data, len, buf, 2*len); - for (i = 0; i < n; i++) { - fprintf(fp, "%c", buf[i]); - if (i % 70 == 69) - fprintf(fp, "\n"); - } - if (i % 70 != 69) - fprintf(fp, "\n"); - xfree(buf); -} diff --git a/usr/src/cmd/ssh/libssh/common/xlist.c b/usr/src/cmd/ssh/libssh/common/xlist.c deleted file mode 100644 index c44e420eeb..0000000000 --- a/usr/src/cmd/ssh/libssh/common/xlist.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <strings.h> -#include "xmalloc.h" -#include "xlist.h" - -char ** -xsplit(char *list, char sep) -{ - char **a; - char *p, *q; - uint_t n = 0; - - for (n = 0, p = list; p && *p; ) { - while (p && *p && *p == sep) - p++; - if (!*p) - break; - n++; - p = strchr(p, sep); - } - a = (char **)xmalloc(sizeof (char *) * (n + 2)); - for (n = 0, p = list; p && *p; ) { - while (*p == sep) - p++; - if (!*p) - break; - q = strchr(p, sep); - if (!q) - q = p + strlen(p); - a[n] = (char *)xmalloc((q - p + 2)); - (void) strncpy(a[n], p, q - p); - a[n][q - p] = '\0'; - n++; - if (!*q) - break; - p = q + 1; - } - a[n] = NULL; - return (a); -} - -void -xfree_split_list(char **list) -{ - char **p; - for (p = list; p && *p; p++) { - xfree(*p); - } - xfree(list); -} - -char * -xjoin(char **alist, char sep) -{ - char **p; - char *list; - char sep_str[2]; - uint_t n; - - for (n = 1, p = alist; p && *p; p++) { - if (!*p || !**p) - continue; - n += strlen(*p) + 1; - } - list = (char *)xmalloc(n); - *list = '\0'; - - sep_str[0] = sep; - sep_str[1] = '\0'; - for (p = alist; p && *p; p++) { - if (!*p || !**p) - continue; - if (*list != '\0') - (void) strlcat(list, sep_str, n); - (void) strlcat(list, *p, n); - } - return (list); -} diff --git a/usr/src/cmd/ssh/libssh/common/xmalloc.c b/usr/src/cmd/ssh/libssh/common/xmalloc.c deleted file mode 100644 index b9ae011d3c..0000000000 --- a/usr/src/cmd/ssh/libssh/common/xmalloc.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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("$OpenBSD: xmalloc.c,v 1.16 2001/07/23 18:21:46 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "xmalloc.h" -#include "log.h" - -void * -xmalloc(size_t size) -{ - void *ptr; - - if (size == 0) - fatal("xmalloc: zero size"); - ptr = malloc(size); - if (ptr == NULL) - fatal("xmalloc: out of memory (allocating %lu bytes)", (u_long) size); - return ptr; -} - -void * -xcalloc(size_t nmemb, size_t size) -{ - void *ptr; - - if (size == 0 || nmemb == 0) - fatal("xcalloc: zero size"); - if (SIZE_T_MAX / nmemb < size) - fatal("xcalloc: nmemb * size > SIZE_T_MAX"); - ptr = calloc(nmemb, size); - if (ptr == NULL) - fatal("xcalloc: out of memory (allocating %lu bytes)", - (u_long)(size * nmemb)); - return ptr; -} - -void * -xrealloc(void *ptr, size_t new_size) -{ - void *new_ptr; - - if (new_size == 0) - fatal("xrealloc: zero size"); - if (ptr == NULL) - new_ptr = malloc(new_size); - else - new_ptr = realloc(ptr, new_size); - if (new_ptr == NULL) - fatal("xrealloc: out of memory (new_size %lu bytes)", (u_long) new_size); - return new_ptr; -} - -void -xfree(void *ptr) -{ - if (ptr == NULL) - fatal("xfree: NULL pointer given as argument"); - free(ptr); -} - -char * -xstrdup(const char *str) -{ - size_t len; - char *cp; - - len = strlen(str) + 1; - cp = xmalloc(len); - strlcpy(cp, str, len); - return cp; -} diff --git a/usr/src/cmd/ssh/libssh/i386/Makefile b/usr/src/cmd/ssh/libssh/i386/Makefile deleted file mode 100644 index fde6250470..0000000000 --- a/usr/src/cmd/ssh/libssh/i386/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all diff --git a/usr/src/cmd/ssh/libssh/sparc/Makefile b/usr/src/cmd/ssh/libssh/sparc/Makefile deleted file mode 100644 index fde6250470..0000000000 --- a/usr/src/cmd/ssh/libssh/sparc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all diff --git a/usr/src/cmd/ssh/req.flg b/usr/src/cmd/ssh/req.flg deleted file mode 100644 index f02f86c7fe..0000000000 --- a/usr/src/cmd/ssh/req.flg +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#pragma ident "%Z%%M% %I% %E% SMI" - -echo_file usr/src/lib/Makefile.lib -echo_file usr/src/lib/Makefile.targ -echo_file usr/src/cmd/Makefile.cmd diff --git a/usr/src/cmd/ssh/scp/Makefile b/usr/src/cmd/ssh/scp/Makefile deleted file mode 100644 index 0d0bf4f6c9..0000000000 --- a/usr/src/cmd/ssh/scp/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# -# cmd/ssh/scp/Makefile - -PROG= scp - -OBJS = \ - scp.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -install: all $(ROOTPROG) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/scp/scp.c b/usr/src/cmd/ssh/scp/scp.c deleted file mode 100644 index 2759d952c5..0000000000 --- a/usr/src/cmd/ssh/scp/scp.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * 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.) - * - * 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. - * - * 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. - * - */ - -#include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.91 2002/06/19 00:27:55 deraadt Exp $"); - -#include "xmalloc.h" -#include "atomicio.h" -#include "pathnames.h" -#include "log.h" -#include "misc.h" - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - -/* For progressmeter() -- number of seconds before xfer considered "stalled" */ -#define STALLTIME 5 -/* alarm() interval for updating progress meter */ -#define PROGRESSTIME 1 - -/* Visual statistics about files as they are transferred. */ -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); - -/* Struct for addargs */ -arglist args; - -/* Time a transfer started. */ -static struct timeval start; - -/* Number of bytes of current file transferred so far. */ -volatile off_t statbytes; - -/* Total size of current file. */ -off_t totalbytes = 0; - -/* Name of current file being transferred. */ -char *curfile; - -/* This is set to non-zero to enable verbose mode. */ -int verbose_mode = 0; - -/* This is set to zero if the progressmeter is not desired. */ -int showprogress = 1; - -/* This is the program to execute for the secured connection. ("ssh" or -S) */ -char *ssh_program = _PATH_SSH_PROGRAM; - -/* This is used to store the pid of ssh_program */ -static pid_t do_cmd_pid = -1; - -static void -killchild(int signo) -{ - if (do_cmd_pid > 1) { - kill(do_cmd_pid, signo ? signo : SIGTERM); - waitpid(do_cmd_pid, NULL, 0); - } - - if (signo) - _exit(1); - exit(1); -} - -/* - * Run a command via fork(2)/exec(2). This can be a local-to-local copy via - * cp(1) or one side of a remote-to-remote copy. We must not use system(3) here - * because we don't want filenames to go through a command expansion in the - * underlying shell. Note that the user can create a filename that is a piece of - * shell code itself and this must not be executed. - */ -static int -do_local_cmd(arglist *a) -{ - uint_t i; - int status; - pid_t pid; - - if (a->num == 0) - fatal("do_local_cmd: no arguments"); - - if (verbose_mode) { - fprintf(stderr, gettext("Executing:")); - for (i = 0; i < a->num; i++) - fprintf(stderr, " %s", a->list[i]); - fprintf(stderr, "\n"); - } - if ((pid = fork()) == -1) - fatal("do_local_cmd: fork: %s", strerror(errno)); - - if (pid == 0) { - execvp(a->list[0], a->list); - perror(a->list[0]); - exit(1); - } - - do_cmd_pid = pid; - signal(SIGTERM, killchild); - signal(SIGINT, killchild); - signal(SIGHUP, killchild); - - while (waitpid(pid, &status, 0) == -1) - if (errno != EINTR) - fatal("do_local_cmd: waitpid: %s", strerror(errno)); - - do_cmd_pid = -1; - - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - return (-1); - - return (0); -} - -/* - * This function executes the given command as the specified user on the - * given host. This returns < 0 if execution fails, and >= 0 otherwise. This - * assigns the input and output file descriptors on success. - */ - -int -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, - gettext("Executing: program %s host %s, " - "user %s, command %s\n"), - ssh_program, host, - remuser ? remuser : gettext("(unspecified)"), cmd); - - /* - * Reserve two descriptors so that the real pipes won't get - * descriptors 0 and 1 because that will screw up dup2 below. - */ - pipe(reserved); - - /* Create a socket pair for communicating with ssh. */ - if (pipe(pin) < 0) - fatal("pipe: %s", strerror(errno)); - if (pipe(pout) < 0) - fatal("pipe: %s", strerror(errno)); - - /* Free the reserved descriptors. */ - close(reserved[0]); - close(reserved[1]); - - /* For a child to execute the command on the remote host using ssh. */ - if ((do_cmd_pid = fork()) == 0) { - /* Child. */ - close(pin[1]); - close(pout[0]); - dup2(pin[0], 0); - dup2(pout[1], 1); - close(pin[0]); - close(pout[1]); - - args.list[0] = ssh_program; - if (remuser != NULL) - addargs(&args, "-l%s", remuser); - addargs(&args, "%s", host); - addargs(&args, "%s", cmd); - - execvp(ssh_program, args.list); - perror(ssh_program); - exit(1); - } else if (do_cmd_pid == (pid_t)-1) { - /* fork() failed */ - fatal("fork: %s", strerror(errno)); - } - - /* Parent. Close the other side, and return the local side. */ - close(pin[0]); - *fdout = pin[1]; - close(pout[1]); - *fdin = pout[0]; - return (0); -} - -typedef struct { - int cnt; - char *buf; -} BUF; - -BUF *allocbuf(BUF *, int, int); -void lostconn(int); -void nospace(void); -int okname(char *); -void run_err(const char *, ...); -void verifydir(char *); - -struct passwd *pwd; -uid_t userid; -int errs, remin, remout; -int pflag, iamremote, iamrecursive, targetshouldbedirectory; - -#define CMDNEEDS 64 -char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ - -int response(void); -void rsource(char *, struct stat *); -void sink(int, char *[]); -void source(int, char *[]); -void tolocal(int, char *[]); -void toremote(char *, int, char *[]); -void usage(void); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - int ch, fflag, tflag, status; - char *targ; - extern char *optarg; - extern int optind; - - __progname = get_progname(argv[0]); - - g11n_setlocale(LC_ALL, ""); - - args.list = NULL; - addargs(&args, "ssh"); /* overwritten with ssh_program */ - addargs(&args, "-x"); - addargs(&args, "-oForwardAgent no"); - addargs(&args, "-oClearAllForwardings yes"); - - fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:F:")) != -1) - switch (ch) { - /* User-visible flags. */ - case '4': - case '6': - case 'C': - addargs(&args, "-%c", ch); - break; - case 'o': - case 'c': - case 'i': - case 'F': - addargs(&args, "-%c%s", ch, optarg); - break; - case 'P': - addargs(&args, "-p%s", optarg); - break; - case 'B': - addargs(&args, "-oBatchmode yes"); - break; - case 'p': - pflag = 1; - break; - case 'r': - iamrecursive = 1; - break; - case 'S': - ssh_program = xstrdup(optarg); - break; - case 'v': - addargs(&args, "-v"); - verbose_mode = 1; - break; - case 'q': - showprogress = 0; - break; - - /* Server options. */ - case 'd': - targetshouldbedirectory = 1; - break; - case 'f': /* "from" */ - iamremote = 1; - fflag = 1; - break; - case 't': /* "to" */ - iamremote = 1; - tflag = 1; -#ifdef HAVE_CYGWIN - setmode(0, O_BINARY); -#endif - break; - default: - usage(); - } - argc -= optind; - argv += optind; - - if ((pwd = getpwuid(userid = getuid())) == NULL) - fatal("unknown user %d", (int)userid); - - if (!isatty(STDERR_FILENO)) - showprogress = 0; - - remin = STDIN_FILENO; - remout = STDOUT_FILENO; - - if (fflag) { - /* Follow "protocol", send data. */ - (void) response(); - source(argc, argv); - exit(errs != 0); - } - if (tflag) { - /* Receive data. */ - sink(argc, argv); - exit(errs != 0); - } - if (argc < 2) - usage(); - if (argc > 2) - targetshouldbedirectory = 1; - - remin = remout = -1; - do_cmd_pid = (pid_t)-1; - - /* Command to be executed on remote system using "ssh". */ - (void) snprintf(cmd, sizeof (cmd), "scp%s%s%s%s", - verbose_mode ? " -v" : "", - iamrecursive ? " -r" : "", pflag ? " -p" : "", - targetshouldbedirectory ? " -d" : ""); - - (void) signal(SIGPIPE, lostconn); - - if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ - toremote(targ, argc, argv); - else { - if (targetshouldbedirectory) - verifydir(argv[argc - 1]); - tolocal(argc, argv); /* Dest is local host. */ - } - /* - * Finally check the exit status of the ssh process, if one was forked - * and no error has occurred yet - */ - if (do_cmd_pid != (pid_t)-1 && errs == 0) { - if (remin != -1) { - (void) close(remin); - } - if (remout != -1) { - (void) close(remout); - } - if (waitpid(do_cmd_pid, &status, 0) == -1) { - errs = 1; - } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - errs = 1; - } - } - - return (errs != 0); -} - -void -toremote(targ, argc, argv) - char *targ, *argv[]; - int argc; -{ - int i, len; - char *bp, *host, *src, *suser, *thost, *tuser, *arg; - arglist alist; - - memset(&alist, '\0', sizeof (alist)); - alist.list = NULL; - - *targ++ = 0; - if (*targ == 0) - targ = "."; - - arg = xstrdup(argv[argc - 1]); - if ((thost = strchr(arg, '@'))) { - /* user@host */ - *thost++ = 0; - tuser = arg; - if (*tuser == '\0') - tuser = NULL; - else if (!okname(tuser)) - exit(1); - } else { - thost = arg; - tuser = NULL; - } - - if (tuser != NULL && !okname(tuser)) { - xfree(arg); - return; - } - - for (i = 0; i < argc - 1; i++) { - src = colon(argv[i]); - if (src) { /* remote to remote */ - freeargs(&alist); - addargs(&alist, "%s", ssh_program); - if (verbose_mode) - addargs(&alist, "-v"); - addargs(&alist, "-x"); - addargs(&alist, "-oClearAllForwardings yes"); - addargs(&alist, "-n"); - - *src++ = 0; - if (*src == 0) - src = "."; - host = strchr(argv[i], '@'); - - if (host) { - *host++ = 0; - host = cleanhostname(host); - suser = argv[i]; - if (*suser == '\0') - suser = pwd->pw_name; - else if (!okname(suser)) - continue; - addargs(&alist, "-l"); - addargs(&alist, "%s", suser); - } else { - host = cleanhostname(argv[i]); - } - addargs(&alist, "%s", host); - addargs(&alist, "%s", cmd); - addargs(&alist, "%s", src); - addargs(&alist, "%s%s%s:%s", - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); - if (do_local_cmd(&alist) != 0) - errs = 1; - } else { /* local to remote */ - if (remin == -1) { - len = strlen(targ) + CMDNEEDS + 20; - bp = xmalloc(len); - (void) snprintf(bp, len, "%s -t %s", cmd, targ); - host = cleanhostname(thost); - if (do_cmd(host, tuser, bp, &remin, - &remout, argc) < 0) - exit(1); - if (response() < 0) - exit(1); - (void) xfree(bp); - } - source(1, argv + i); - } - } -} - -void -tolocal(argc, argv) - int argc; - char *argv[]; -{ - int i, len; - char *bp, *host, *src, *suser; - arglist alist; - - memset(&alist, '\0', sizeof (alist)); - alist.list = NULL; - - for (i = 0; i < argc - 1; i++) { - if (!(src = colon(argv[i]))) { /* Local to local. */ - freeargs(&alist); - addargs(&alist, "%s", _PATH_CP); - if (iamrecursive) - addargs(&alist, "-r"); - if (pflag) - addargs(&alist, "-p"); - addargs(&alist, "%s", argv[i]); - addargs(&alist, "%s", argv[argc-1]); - if (do_local_cmd(&alist)) - ++errs; - continue; - } - *src++ = 0; - if (*src == 0) - src = "."; - if ((host = strchr(argv[i], '@')) == NULL) { - host = argv[i]; - suser = NULL; - } else { - *host++ = 0; - suser = argv[i]; - if (*suser == '\0') - suser = pwd->pw_name; - else if (!okname(suser)) - continue; - } - host = cleanhostname(host); - len = strlen(src) + CMDNEEDS + 20; - bp = xmalloc(len); - (void) snprintf(bp, len, "%s -f %s", cmd, src); - if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { - (void) xfree(bp); - ++errs; - continue; - } - xfree(bp); - sink(1, argv + argc - 1); - (void) close(remin); - remin = remout = -1; - } -} - -void -source(argc, argv) - int argc; - char *argv[]; -{ - struct stat stb; - static BUF buffer; - BUF *bp; - off_t i, amt, result; - int fd, haderr, indx; - char *last, *name, buf[2048]; - int len; - - for (indx = 0; indx < argc; ++indx) { - name = argv[indx]; - statbytes = 0; - len = strlen(name); - while (len > 1 && name[len-1] == '/') - name[--len] = '\0'; - if (strchr(name, '\n') != NULL) { - run_err("%s: skipping, filename contains a newline", - name); - goto next; - } - if ((fd = open(name, O_RDONLY, 0)) < 0) - goto syserr; - if (fstat(fd, &stb) < 0) { -syserr: run_err("%s: %s", name, strerror(errno)); - goto next; - } - switch (stb.st_mode & S_IFMT) { - case S_IFREG: - break; - case S_IFDIR: - if (iamrecursive) { - rsource(name, &stb); - goto next; - } - /* FALLTHROUGH */ - default: - run_err("%s: not a regular file", name); - goto next; - } - if ((last = strrchr(name, '/')) == NULL) - last = name; - else - ++last; - curfile = last; - if (pflag) { - /* - * Make it compatible with possible future - * versions expecting microseconds. - */ - (void) snprintf(buf, sizeof (buf), "T%lu 0 %lu 0\n", - (ulong_t)stb.st_mtime, - (ulong_t)stb.st_atime); - (void) atomicio(write, remout, buf, strlen(buf)); - if (response() < 0) - goto next; - } -#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) -#ifdef HAVE_LONG_LONG_INT - snprintf(buf, sizeof (buf), "C%04o %lld %s\n", - (uint_t)(stb.st_mode & FILEMODEMASK), - (long long)stb.st_size, last); -#else - /* XXX: Handle integer overflow? */ - snprintf(buf, sizeof (buf), "C%04o %lu %s\n", - (uint_t)(stb.st_mode & FILEMODEMASK), - (ulong_t)stb.st_size, last); -#endif - if (verbose_mode) { - fprintf(stderr, gettext("Sending file modes: %s"), buf); - fflush(stderr); - } - (void) atomicio(write, remout, buf, strlen(buf)); - if (response() < 0) - goto next; - if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { -next: (void) close(fd); - continue; - } - if (showprogress) { - totalbytes = stb.st_size; - progressmeter(-1); - } - /* Keep writing after an error so that we stay sync'd up. */ - for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { - amt = bp->cnt; - if (i + amt > stb.st_size) - amt = stb.st_size - i; - if (!haderr) { - result = atomicio(read, fd, bp->buf, amt); - if (result != amt) - haderr = result >= 0 ? EIO : errno; - } - if (haderr) - (void) atomicio(write, remout, bp->buf, amt); - else { - result = atomicio(write, remout, bp->buf, amt); - if (result != amt) - haderr = result >= 0 ? EIO : errno; - statbytes += result; - } - } - if (showprogress) - progressmeter(1); - - if (close(fd) < 0 && !haderr) - haderr = errno; - if (!haderr) - (void) atomicio(write, remout, "", 1); - else - run_err("%s: %s", name, strerror(haderr)); - (void) response(); - } -} - -void -rsource(name, statp) - char *name; - struct stat *statp; -{ - DIR *dirp; - struct dirent *dp; - char *last, *vect[1], path[1100]; - - if (!(dirp = opendir(name))) { - run_err("%s: %s", name, strerror(errno)); - return; - } - last = strrchr(name, '/'); - if (last == 0) - last = name; - else - last++; - if (pflag) { - (void) snprintf(path, sizeof (path), "T%lu 0 %lu 0\n", - (ulong_t)statp->st_mtime, - (ulong_t)statp->st_atime); - (void) atomicio(write, remout, path, strlen(path)); - if (response() < 0) { - closedir(dirp); - return; - } - } - (void) snprintf(path, sizeof (path), "D%04o %d %.1024s\n", - (uint_t)(statp->st_mode & FILEMODEMASK), 0, last); - if (verbose_mode) - fprintf(stderr, gettext("Entering directory: %s"), path); - (void) atomicio(write, remout, path, strlen(path)); - if (response() < 0) { - closedir(dirp); - return; - } - while ((dp = readdir(dirp)) != NULL) { - if (dp->d_ino == 0) - continue; - if ((strcmp(dp->d_name, ".") == 0) || - (strcmp(dp->d_name, "..") == 0)) - continue; - if (strlen(name) + 1 + strlen(dp->d_name) >= - sizeof (path) - 1) { - run_err("%s/%s: name too long", name, dp->d_name); - continue; - } - (void) snprintf(path, sizeof (path), "%s/%s", name, dp->d_name); - vect[0] = path; - source(1, vect); - } - (void) closedir(dirp); - (void) atomicio(write, remout, "E\n", 2); - (void) response(); -} - -void -sink(argc, argv) - int argc; - char *argv[]; -{ - static BUF buffer; - struct stat stb; - enum { - YES, NO, DISPLAYED - } wrerr; - BUF *bp; - off_t i, j; - int amt, count, exists, first, mask, mode, ofd, omode; - off_t size; - int setimes, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; - struct timeval tv[2]; - -#define atime tv[0] -#define mtime tv[1] -#define SCREWUP(str) { why = str; goto screwup; } - - setimes = targisdir = 0; - mask = umask(0); - if (!pflag) - (void) umask(mask); - if (argc != 1) { - run_err("ambiguous target"); - exit(1); - } - targ = *argv; - if (targetshouldbedirectory) - verifydir(targ); - - (void) atomicio(write, remout, "", 1); - if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) - targisdir = 1; - for (first = 1; ; first = 0) { - cp = buf; - if (atomicio(read, remin, cp, 1) <= 0) - return; - if (*cp++ == '\n') - SCREWUP("unexpected <newline>") - do { - if (atomicio(read, remin, &ch, sizeof (ch)) != - sizeof (ch)) - SCREWUP("lost connection") - *cp++ = ch; - } while (cp < &buf[sizeof (buf) - 1] && ch != '\n'); - *cp = 0; - - if (buf[0] == '\01' || buf[0] == '\02') { - if (iamremote == 0) - (void) atomicio(write, STDERR_FILENO, - buf + 1, strlen(buf + 1)); - if (buf[0] == '\02') - exit(1); - ++errs; - continue; - } - if (buf[0] == 'E') { - (void) atomicio(write, remout, "", 1); - return; - } - if (ch == '\n') - *--cp = 0; - - cp = buf; - if (*cp == 'T') { - setimes++; - cp++; - mtime.tv_sec = strtol(cp, &cp, 10); - if (!cp || *cp++ != ' ') - SCREWUP("mtime.sec not delimited") - mtime.tv_usec = strtol(cp, &cp, 10); - if (!cp || *cp++ != ' ') - SCREWUP("mtime.usec not delimited") - atime.tv_sec = strtol(cp, &cp, 10); - if (!cp || *cp++ != ' ') - SCREWUP("atime.sec not delimited") - atime.tv_usec = strtol(cp, &cp, 10); - if (!cp || *cp++ != '\0') - SCREWUP("atime.usec not delimited") - (void) atomicio(write, remout, "", 1); - continue; - } - if (*cp != 'C' && *cp != 'D') { - /* - * Check for the case "rcp remote:foo\* local:bar". - * In this case, the line "No match." can be returned - * by the shell before the rcp command on the remote is - * executed so the ^Aerror_message convention isn't - * followed. - */ - if (first) { - run_err("%s", cp); - exit(1); - } - SCREWUP("expected control record") - } - mode = 0; - for (++cp; cp < buf + 5; cp++) { - if (*cp < '0' || *cp > '7') - SCREWUP("bad mode") - mode = (mode << 3) | (*cp - '0'); - } - if (*cp++ != ' ') - SCREWUP("mode not delimited") - - for (size = 0; isdigit(*cp); ) - size = size * 10 + (*cp++ - '0'); - if (*cp++ != ' ') - SCREWUP("size not delimited") - if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { - run_err("error: unexpected filename: %s", cp); - exit(1); - } - if (targisdir) { - static char *namebuf; - static int cursize; - size_t need; - - need = strlen(targ) + strlen(cp) + 250; - if (need > cursize) { - if (namebuf) - xfree(namebuf); - namebuf = xmalloc(need); - cursize = need; - } - (void) snprintf(namebuf, need, "%s%s%s", targ, - strcmp(targ, "/") ? "/" : "", cp); - np = namebuf; - } else - np = targ; - curfile = cp; - exists = stat(np, &stb) == 0; - if (buf[0] == 'D') { - int mod_flag = pflag; - if (!iamrecursive) - SCREWUP("received directory without -r"); - if (exists) { - if (!S_ISDIR(stb.st_mode)) { - errno = ENOTDIR; - goto bad; - } - if (pflag) - (void) chmod(np, mode); - } else { - /* - * Handle copying from a read-only - * directory - */ - mod_flag = 1; - if (mkdir(np, mode | S_IRWXU) < 0) - goto bad; - } - vect[0] = xstrdup(np); - sink(1, vect); - if (setimes) { - setimes = 0; - if (utimes(vect[0], tv) < 0) - run_err("%s: set times: %s", - vect[0], strerror(errno)); - } - if (mod_flag) - (void) chmod(vect[0], mode); - if (vect[0]) - xfree(vect[0]); - continue; - } - omode = mode; - mode |= S_IWRITE; - if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { -bad: run_err("%s: %s", np, strerror(errno)); - continue; - } - (void) atomicio(write, remout, "", 1); - if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { - (void) close(ofd); - continue; - } - wrerr = NO; - - if (showprogress) { - totalbytes = size; - progressmeter(-1); - } - statbytes = 0; - for (i = 0; i < size; i += bp->cnt) { - amt = bp->cnt; - cp = bp->buf; - if (i + amt > size) - amt = size - i; - count = amt; - do { - j = read(remin, cp, amt); - if (j == -1 && (errno == EINTR || - errno == EAGAIN)) { - continue; - } else if (j <= 0) { - run_err("%s", j ? strerror(errno) : - "dropped connection"); - exit(1); - } - amt -= j; - cp += j; - statbytes += j; - } while (amt > 0); - /* Keep reading so we stay sync'd up. */ - if (wrerr == NO) { - j = atomicio(write, ofd, bp->buf, - count); - if (j != count) { - wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; - } - } - } - if (showprogress) - progressmeter(1); - if (ftruncate(ofd, size)) { - run_err("%s: truncate: %s", np, strerror(errno)); - wrerr = DISPLAYED; - } - if (pflag) { - if (exists || omode != mode) -#ifdef HAVE_FCHMOD - if (fchmod(ofd, omode)) { -#else /* HAVE_FCHMOD */ - if (chmod(np, omode)) { -#endif /* HAVE_FCHMOD */ - run_err("%s: set mode: %s", - np, strerror(errno)); - wrerr = DISPLAYED; - } - } else { - if (!exists && omode != mode) -#ifdef HAVE_FCHMOD - if (fchmod(ofd, omode & ~mask)) { -#else /* HAVE_FCHMOD */ - if (chmod(np, omode & ~mask)) { -#endif /* HAVE_FCHMOD */ - run_err("%s: set mode: %s", - np, strerror(errno)); - wrerr = DISPLAYED; - } - } - if (close(ofd) == -1) { - wrerr = YES; - wrerrno = errno; - } - (void) response(); - if (setimes && wrerr == NO) { - setimes = 0; - if (utimes(np, tv) < 0) { - run_err("%s: set times: %s", - np, strerror(errno)); - wrerr = DISPLAYED; - } - } - switch (wrerr) { - case YES: - run_err("%s: %s", np, strerror(wrerrno)); - break; - case NO: - (void) atomicio(write, remout, "", 1); - break; - case DISPLAYED: - break; - } - } -screwup: - run_err("protocol error: %s", why); - exit(1); -} - -int -response(void) -{ - char ch, *cp, resp, rbuf[2048]; - - if (atomicio(read, remin, &resp, sizeof (resp)) != sizeof (resp)) - lostconn(0); - - cp = rbuf; - switch (resp) { - case 0: /* ok */ - return (0); - default: - *cp++ = resp; - /* FALLTHROUGH */ - case 1: /* error, followed by error msg */ - case 2: /* fatal error, "" */ - do { - if (atomicio(read, remin, &ch, sizeof (ch)) != - sizeof (ch)) - lostconn(0); - *cp++ = ch; - } while (cp < &rbuf[sizeof (rbuf) - 1] && ch != '\n'); - - if (!iamremote) - (void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf); - ++errs; - if (resp == 1) - return (-1); - exit(1); - } - /* NOTREACHED */ -} - -void -usage(void) -{ - (void) fprintf(stderr, - gettext( - "Usage: scp [-pqrvBC46] [-F config] [-S program] [-P port]\n" - " [-c cipher] [-i identity] [-o option]\n" - " [[user@]host1:]file1 [...] " - "[[user@]host2:]file2\n")); - exit(1); -} - -/* PRINTFLIKE1 */ -void -run_err(const char *fmt, ...) -{ - static FILE *fp; - va_list ap; - - ++errs; - - if (!iamremote) { - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); - } - - if (fp == NULL && !(fp = fdopen(remout, "w"))) - return; - - (void) fprintf(fp, "%c", 0x01); - (void) fprintf(fp, "scp: "); - va_start(ap, fmt); - (void) vfprintf(fp, fmt, ap); - va_end(ap); - (void) fprintf(fp, "\n"); - (void) fflush(fp); - -} - -void -verifydir(cp) - char *cp; -{ - struct stat stb; - - if (!stat(cp, &stb)) { - if (S_ISDIR(stb.st_mode)) - return; - errno = ENOTDIR; - } - run_err("%s: %s", cp, strerror(errno)); - exit(1); -} - -int -okname(cp0) - char *cp0; -{ - int c; - char *cp; - - cp = cp0; - do { - c = (int)*cp; - if (c & 0200) - goto bad; - if (!isalpha(c) && !isdigit(c)) { - switch (c) { - case '\'': - case '"': - case '`': - case ' ': - case '#': - goto bad; - default: - break; - } - } - } while (*++cp); - return (1); - -bad: fprintf(stderr, gettext("%s: invalid user name\n"), cp0); - return (0); -} - -BUF * -allocbuf(bp, fd, blksize) - BUF *bp; - int fd, blksize; -{ - size_t size; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - struct stat stb; - - if (fstat(fd, &stb) < 0) { - run_err("fstat: %s", strerror(errno)); - return (0); - } - if (stb.st_blksize == 0) - size = blksize; - else - size = blksize + (stb.st_blksize - blksize % stb.st_blksize) % - stb.st_blksize; -#else /* HAVE_STRUCT_STAT_ST_BLKSIZE */ - size = blksize; -#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ - if (bp->cnt >= size) - return (bp); - if (bp->buf == NULL) - bp->buf = xmalloc(size); - else - bp->buf = xrealloc(bp->buf, size); - memset(bp->buf, 0, size); - bp->cnt = size; - return (bp); -} - -void -lostconn(signo) - int signo; -{ - if (!iamremote) - write(STDERR_FILENO, "lost connection\n", 16); - if (signo) - _exit(1); - else - exit(1); -} - -static void -updateprogressmeter(int ignore) -{ - int save_errno = errno; - - progressmeter(0); - signal(SIGALRM, updateprogressmeter); - alarm(PROGRESSTIME); - errno = save_errno; -} - -static int -foregroundproc(void) -{ - static pid_t pgrp = -1; - int ctty_pgrp; - - if (pgrp == -1) - pgrp = getpgrp(); - -#ifdef HAVE_TCGETPGRP - return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 && - ctty_pgrp == pgrp); -#else - return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && - ctty_pgrp == pgrp)); -#endif -} - -void -progressmeter(int flag) -{ - static const char prefixes[] = " KMGTP"; - static struct timeval lastupdate; - static off_t lastsize; - struct timeval now, td, wait; - off_t cursize, abbrevsize; - double elapsed; - int ratio, barlength, i, remaining; - char buf[512]; - - if (flag == -1) { - (void) gettimeofday(&start, (struct timezone *)0); - lastupdate = start; - lastsize = 0; - } - if (foregroundproc() == 0) - return; - - (void) gettimeofday(&now, (struct timezone *)0); - cursize = statbytes; - if (totalbytes != 0) { - ratio = (int)(100.0 * cursize / totalbytes); - ratio = MAX(ratio, 0); - ratio = MIN(ratio, 100); - } else - ratio = 100; - - snprintf(buf, sizeof (buf), "\r%-20.20s %3d%% ", curfile, ratio); - - barlength = getttywidth() - 51; - if (barlength > 0) { - i = barlength * ratio / 100; - snprintf(buf + strlen(buf), sizeof (buf) - strlen(buf), - "|%.*s%*s|", i, - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************", - barlength - i, ""); - } - i = 0; - abbrevsize = cursize; - while (abbrevsize >= 100000 && i < strlen(prefixes) - 1) { - i++; - abbrevsize >>= 10; - } - snprintf(buf + strlen(buf), sizeof (buf) - strlen(buf), " %5lu %c%c ", - (unsigned long) abbrevsize, prefixes[i], - prefixes[i] == ' ' ? ' ' : 'B'); - - timersub(&now, &lastupdate, &wait); - if (cursize > lastsize) { - lastupdate = now; - lastsize = cursize; - if (wait.tv_sec >= STALLTIME) { - start.tv_sec += wait.tv_sec; - start.tv_usec += wait.tv_usec; - } - wait.tv_sec = 0; - } - timersub(&now, &start, &td); - elapsed = td.tv_sec + (td.tv_usec / 1000000.0); - - if (flag != 1 && - (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes)) { - snprintf(buf + strlen(buf), sizeof (buf) - strlen(buf), - " --:-- ETA"); - } else if (wait.tv_sec >= STALLTIME) { - snprintf(buf + strlen(buf), sizeof (buf) - strlen(buf), - " - stalled -"); - } else { - if (flag != 1) - remaining = (int)(totalbytes / (statbytes / elapsed) - - elapsed); - else - remaining = (int)elapsed; - - i = remaining / 3600; - if (i) - snprintf(buf + strlen(buf), sizeof (buf) - strlen(buf), - "%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" : " "); - } - atomicio(write, fileno(stdout), buf, strlen(buf)); - - if (flag == -1) { - mysignal(SIGALRM, updateprogressmeter); - alarm(PROGRESSTIME); - } else if (flag == 1) { - alarm(0); - atomicio(write, fileno(stdout), "\n", 1); - statbytes = 0; - } -} - -int -getttywidth(void) -{ - struct winsize winsize; - - if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1) - return (winsize.ws_col ? winsize.ws_col : 80); - else - return (80); -} diff --git a/usr/src/cmd/ssh/sftp-server/Makefile b/usr/src/cmd/ssh/sftp-server/Makefile deleted file mode 100644 index f49dde54ee..0000000000 --- a/usr/src/cmd/ssh/sftp-server/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/sftp-server/Makefile - -PROG = sftp-server - -OBJS = sftp-server.o sftp-server-main.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto - -POFILE_DIR = .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -install: all $(ROOTLIBSSHPROG) $(ROOTLIBSSH) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/sftp-server/sftp-server-main.c b/usr/src/cmd/ssh/sftp-server/sftp-server-main.c deleted file mode 100644 index 7b604b7cdc..0000000000 --- a/usr/src/cmd/ssh/sftp-server/sftp-server-main.c +++ /dev/null @@ -1,51 +0,0 @@ -/* $OpenBSD: sftp-server-main.c,v 1.4 2009/02/21 19:32:04 tobias Exp $ */ -/* - * Copyright (c) 2008 Markus Friedl. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include <sys/types.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdio.h> -#include <unistd.h> - -#include "log.h" -#include "sftp.h" -#include "misc.h" - -/* defined in sftp-server.c */ -extern struct passwd *pw; -extern char *client_addr; - -void cleanup_exit(int i); - -int -main(int argc, char **argv) -{ - struct passwd *user_pw; - - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - - if ((user_pw = getpwuid(getuid())) == NULL) { - fprintf(stderr, "No user found for uid %lu\n", - (ulong_t)getuid()); - return (1); - } - - return (sftp_server_main(argc, argv, user_pw)); -} diff --git a/usr/src/cmd/ssh/sftp-server/sftp-server.c b/usr/src/cmd/ssh/sftp-server/sftp-server.c deleted file mode 100644 index 030ed79ac2..0000000000 --- a/usr/src/cmd/ssh/sftp-server/sftp-server.c +++ /dev/null @@ -1,1364 +0,0 @@ -/* - * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* $OpenBSD: sftp-server.c,v 1.71 2007/01/03 07:22:36 stevesk Exp $ */ - -#include "includes.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -#endif - -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <pwd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <pwd.h> -#include <time.h> -#include <unistd.h> -#include <stdarg.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "log.h" -#include "misc.h" -#include "uidswap.h" - -#include "sftp.h" -#include "sftp-common.h" - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - -/* helper */ -#define get_int64() buffer_get_int64(&iqueue); -#define get_int() buffer_get_int(&iqueue); -#define get_string(lenp) buffer_get_string(&iqueue, lenp); - -void cleanup_exit(int i); - -/* Our verbosity */ -LogLevel log_level = SYSLOG_LEVEL_ERROR; - -/* Our client */ -struct passwd *pw = NULL; -char *client_addr = NULL; - -/* input and output queue */ -Buffer iqueue; -Buffer oqueue; - -/* Version of client */ -int version; - -/* portable attributes, etc. */ - -typedef struct Stat Stat; - -struct Stat { - char *name; - char *long_name; - Attrib attrib; -}; - -static int -errno_to_portable(int unixerrno) -{ - int ret = 0; - - switch (unixerrno) { - case 0: - ret = SSH2_FX_OK; - break; - case ENOENT: - case ENOTDIR: - case EBADF: - case ELOOP: - ret = SSH2_FX_NO_SUCH_FILE; - break; - case EPERM: - case EACCES: - case EFAULT: - ret = SSH2_FX_PERMISSION_DENIED; - break; - case ENAMETOOLONG: - case EINVAL: - ret = SSH2_FX_BAD_MESSAGE; - break; - default: - ret = SSH2_FX_FAILURE; - break; - } - return ret; -} - -static int -flags_from_portable(int pflags) -{ - int flags = 0; - - if ((pflags & SSH2_FXF_READ) && - (pflags & SSH2_FXF_WRITE)) { - flags = O_RDWR; - } else if (pflags & SSH2_FXF_READ) { - flags = O_RDONLY; - } else if (pflags & SSH2_FXF_WRITE) { - flags = O_WRONLY; - } - if (pflags & SSH2_FXF_CREAT) - flags |= O_CREAT; - if (pflags & SSH2_FXF_TRUNC) - flags |= O_TRUNC; - if (pflags & SSH2_FXF_EXCL) - flags |= O_EXCL; - return flags; -} - -static const char * -string_from_portable(int pflags) -{ - static char ret[128]; - - *ret = '\0'; - -#define PAPPEND(str) { \ - if (*ret != '\0') \ - strlcat(ret, ",", sizeof(ret)); \ - strlcat(ret, str, sizeof(ret)); \ - } - - if (pflags & SSH2_FXF_READ) - PAPPEND("READ") - if (pflags & SSH2_FXF_WRITE) - PAPPEND("WRITE") - if (pflags & SSH2_FXF_CREAT) - PAPPEND("CREATE") - if (pflags & SSH2_FXF_TRUNC) - PAPPEND("TRUNCATE") - if (pflags & SSH2_FXF_EXCL) - PAPPEND("EXCL") - - return ret; -} - -static Attrib * -get_attrib(void) -{ - return decode_attrib(&iqueue); -} - -/* handle handles */ - -typedef struct Handle Handle; -struct Handle { - int use; - DIR *dirp; - int fd; - char *name; - u_int64_t bytes_read, bytes_write; -}; - -enum { - HANDLE_UNUSED, - HANDLE_DIR, - HANDLE_FILE -}; - -Handle handles[100]; - -static void -handle_init(void) -{ - u_int i; - - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) - handles[i].use = HANDLE_UNUSED; -} - -static int -handle_new(int use, const char *name, int fd, DIR *dirp) -{ - u_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 = xstrdup(name); - handles[i].bytes_read = handles[i].bytes_write = 0; - return i; - } - } - return -1; -} - -static int -handle_is_ok(int i, int type) -{ - return i >= 0 && (u_int)i < sizeof(handles)/sizeof(Handle) && - handles[i].use == type; -} - -static int -handle_to_string(int handle, char **stringp, int *hlenp) -{ - if (stringp == NULL || hlenp == NULL) - return -1; - *stringp = xmalloc(sizeof(int32_t)); - put_u32(*stringp, handle); - *hlenp = sizeof(int32_t); - return 0; -} - -static int -handle_from_string(const char *handle, u_int hlen) -{ - int val; - - if (hlen != sizeof(int32_t)) - return -1; - val = get_u32(handle); - if (handle_is_ok(val, HANDLE_FILE) || - handle_is_ok(val, HANDLE_DIR)) - return val; - return -1; -} - -static 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; -} - -static DIR * -handle_to_dir(int handle) -{ - if (handle_is_ok(handle, HANDLE_DIR)) - return handles[handle].dirp; - return NULL; -} - -static int -handle_to_fd(int handle) -{ - if (handle_is_ok(handle, HANDLE_FILE)) - return handles[handle].fd; - return -1; -} - -static void -handle_update_read(int handle, ssize_t bytes) -{ - if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0) - handles[handle].bytes_read += bytes; -} - -static void -handle_update_write(int handle, ssize_t bytes) -{ - if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0) - handles[handle].bytes_write += bytes; -} - -static u_int64_t -handle_bytes_read(int handle) -{ - if (handle_is_ok(handle, HANDLE_FILE)) - return (handles[handle].bytes_read); - return 0; -} - -static u_int64_t -handle_bytes_write(int handle) -{ - if (handle_is_ok(handle, HANDLE_FILE)) - return (handles[handle].bytes_write); - return 0; -} - -static 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; - xfree(handles[handle].name); - } else if (handle_is_ok(handle, HANDLE_DIR)) { - ret = closedir(handles[handle].dirp); - handles[handle].use = HANDLE_UNUSED; - xfree(handles[handle].name); - } else { - errno = ENOENT; - } - return ret; -} - -static void -handle_log_close(int handle, char *emsg) -{ - if (handle_is_ok(handle, HANDLE_FILE)) { - log("%s%sclose \"%s\" bytes read %llu written %llu", - emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", - handle_to_name(handle), - (unsigned long long)handle_bytes_read(handle), - (unsigned long long)handle_bytes_write(handle)); - } else { - log("%s%sclosedir \"%s\"", - emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", - handle_to_name(handle)); - } -} - -static void -handle_log_exit(void) -{ - u_int i; - - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) - if (handles[i].use != HANDLE_UNUSED) - handle_log_close(i, "forced"); -} - -static int -get_handle(void) -{ - char *handle; - int val = -1; - u_int hlen; - - handle = get_string(&hlen); - if (hlen < 256) - val = handle_from_string(handle, hlen); - xfree(handle); - return val; -} - -/* send replies */ - -static void -send_msg(Buffer *m) -{ - int mlen = buffer_len(m); - - buffer_put_int(&oqueue, mlen); - buffer_append(&oqueue, buffer_ptr(m), mlen); - buffer_consume(m, mlen); -} - -static const char * -status_to_message(u_int32_t status) -{ - const char *status_messages[] = { - "Success", /* SSH_FX_OK */ - "End of file", /* SSH_FX_EOF */ - "No such file", /* SSH_FX_NO_SUCH_FILE */ - "Permission denied", /* SSH_FX_PERMISSION_DENIED */ - "Failure", /* SSH_FX_FAILURE */ - "Bad message", /* SSH_FX_BAD_MESSAGE */ - "No connection", /* SSH_FX_NO_CONNECTION */ - "Connection lost", /* SSH_FX_CONNECTION_LOST */ - "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */ - "Unknown error" /* Others */ - }; - return (status_messages[MIN(status,SSH2_FX_MAX)]); -} - -static void -send_status(u_int32_t id, u_int32_t status) -{ - Buffer msg; - - debug3("request %u: sent status %u", id, status); - if (log_level > SYSLOG_LEVEL_VERBOSE || - (status != SSH2_FX_OK && status != SSH2_FX_EOF)) - log("sent status %s", status_to_message(status)); - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_STATUS); - buffer_put_int(&msg, id); - buffer_put_int(&msg, status); - if (version >= 3) { - buffer_put_cstring(&msg, status_to_message(status)); - buffer_put_cstring(&msg, ""); - } - send_msg(&msg); - buffer_free(&msg); -} -static void -send_data_or_handle(char type, u_int32_t id, const 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); -} - -static void -send_data(u_int32_t id, const char *data, int dlen) -{ - debug("request %u: sent data len %d", id, dlen); - send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); -} - -static void -send_handle(u_int32_t id, int handle) -{ - char *string; - int hlen; - - handle_to_string(handle, &string, &hlen); - debug("request %u: sent handle handle %d", id, handle); - send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen); - xfree(string); -} - -static void -send_names(u_int32_t id, int count, const Stat *stats) -{ - Buffer msg; - int i; - - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_NAME); - buffer_put_int(&msg, id); - buffer_put_int(&msg, count); - debug("request %u: sent names 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); -} - -static void -send_attrib(u_int32_t id, const Attrib *a) -{ - Buffer msg; - - debug("request %u: sent attrib have 0x%x", id, a->flags); - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_ATTRS); - buffer_put_int(&msg, id); - encode_attrib(&msg, a); - send_msg(&msg); - buffer_free(&msg); -} - -/* parse incoming */ - -static void -process_init(void) -{ - Buffer msg; - - version = get_int(); - verbose("received client version %d", version); - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_VERSION); - buffer_put_int(&msg, SSH2_FILEXFER_VERSION); - send_msg(&msg); - buffer_free(&msg); -} - -static void -process_open(void) -{ - u_int32_t id, pflags; - Attrib *a; - char *name; - int handle, fd, flags, mode, status = SSH2_FX_FAILURE; - - id = get_int(); - name = get_string(NULL); - pflags = get_int(); /* portable flags */ - debug3("request %u: open flags %d", id, pflags); - a = get_attrib(); - flags = flags_from_portable(pflags); - mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; - log("open \"%s\" flags %s mode 0%o", - name, string_from_portable(pflags), mode); - fd = open(name, flags, mode); - if (fd < 0) { - status = errno_to_portable(errno); - } else { - handle = handle_new(HANDLE_FILE, name, fd, NULL); - if (handle < 0) { - close(fd); - } else { - send_handle(id, handle); - status = SSH2_FX_OK; - } - } - if (status != SSH2_FX_OK) - send_status(id, status); - xfree(name); -} - -static void -process_close(void) -{ - u_int32_t id; - int handle, ret, status = SSH2_FX_FAILURE; - - id = get_int(); - handle = get_handle(); - debug3("request %u: close handle %u", id, handle); - handle_log_close(handle, NULL); - ret = handle_close(handle); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - send_status(id, status); -} - -static void -process_read(void) -{ - char buf[64*1024]; - u_int32_t id, len; - int handle, fd, ret, status = SSH2_FX_FAILURE; - u_int64_t off; - - id = get_int(); - handle = get_handle(); - off = get_int64(); - len = get_int(); - - debug("request %u: read \"%s\" (handle %d) off %llu len %d", - id, handle_to_name(handle), handle, (unsigned long long)off, len); - if (len > sizeof buf) { - len = sizeof buf; - debug2("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 = SSH2_FX_EOF; - } else { - send_data(id, buf, ret); - status = SSH2_FX_OK; - handle_update_read(handle, ret); - } - } - } - if (status != SSH2_FX_OK) - send_status(id, status); -} - -static void -process_write(void) -{ - u_int32_t id; - u_int64_t off; - u_int len; - int handle, fd, ret, status = SSH2_FX_FAILURE; - char *data; - - id = get_int(); - handle = get_handle(); - off = get_int64(); - data = get_string(&len); - - debug("request %u: write \"%s\" (handle %d) off %llu len %d", - id, handle_to_name(handle), handle, (unsigned long long)off, len); - fd = handle_to_fd(handle); - if (fd >= 0) { - if (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 < 0) { - error("process_write: write failed"); - status = errno_to_portable(errno); - } else if ((size_t)ret == len) { - status = SSH2_FX_OK; - handle_update_write(handle, ret); - } else { - debug2("nothing at all written"); - } - } - } - send_status(id, status); - xfree(data); -} - -static void -process_do_stat(int do_lstat) -{ - Attrib a; - struct stat st; - u_int32_t id; - char *name; - int ret, status = SSH2_FX_FAILURE; - - id = get_int(); - name = get_string(NULL); - debug3("request %u: %sstat", id, do_lstat ? "l" : ""); - verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); - ret = do_lstat ? lstat(name, &st) : stat(name, &st); - if (ret < 0) { - status = errno_to_portable(errno); - } else { - stat_to_attrib(&st, &a); - send_attrib(id, &a); - status = SSH2_FX_OK; - } - if (status != SSH2_FX_OK) - send_status(id, status); - xfree(name); -} - -static void -process_stat(void) -{ - process_do_stat(0); -} - -static void -process_lstat(void) -{ - process_do_stat(1); -} - -static void -process_fstat(void) -{ - Attrib a; - struct stat st; - u_int32_t id; - int fd, ret, handle, status = SSH2_FX_FAILURE; - - id = get_int(); - handle = get_handle(); - debug("request %u: fstat \"%s\" (handle %u)", - id, handle_to_name(handle), handle); - fd = handle_to_fd(handle); - if (fd >= 0) { - ret = fstat(fd, &st); - if (ret < 0) { - status = errno_to_portable(errno); - } else { - stat_to_attrib(&st, &a); - send_attrib(id, &a); - status = SSH2_FX_OK; - } - } - if (status != SSH2_FX_OK) - send_status(id, status); -} - -static struct timeval * -attrib_to_tv(const 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; -} - -static void -process_setstat(void) -{ - Attrib *a; - u_int32_t id; - char *name; - int status = SSH2_FX_OK, ret; - - id = get_int(); - name = get_string(NULL); - a = get_attrib(); - debug("request %u: setstat name \"%s\"", id, name); - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { - log("set \"%s\" size %llu", - name, (unsigned long long)a->size); - ret = truncate(name, a->size); - if (ret == -1) - status = errno_to_portable(errno); - } - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { - log("set \"%s\" mode %04o", name, a->perm); - ret = chmod(name, a->perm & 07777); - if (ret == -1) - status = errno_to_portable(errno); - } - if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { - char buf[64]; - time_t t = a->mtime; - - strftime(buf, sizeof(buf), "%Y" "%m%d-%H:%M:%S", - localtime(&t)); - log("set \"%s\" modtime %s", name, buf); - ret = utimes(name, attrib_to_tv(a)); - if (ret == -1) - status = errno_to_portable(errno); - } - if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { - log("set \"%s\" owner %lu group %lu", name, - (u_long)a->uid, (u_long)a->gid); - ret = chown(name, a->uid, a->gid); - if (ret == -1) - status = errno_to_portable(errno); - } - send_status(id, status); - xfree(name); -} - -static void -process_fsetstat(void) -{ - Attrib *a; - u_int32_t id; - int handle, fd, ret; - int status = SSH2_FX_OK; - - id = get_int(); - handle = get_handle(); - a = get_attrib(); - debug("request %u: fsetstat handle %d", id, handle); - fd = handle_to_fd(handle); - if (fd < 0) { - status = SSH2_FX_FAILURE; - } else { - char *name = handle_to_name(handle); - - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { - log("set \"%s\" size %llu", - name, (unsigned long long)a->size); - ret = ftruncate(fd, a->size); - if (ret == -1) - status = errno_to_portable(errno); - } - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { - log("set \"%s\" mode %04o", name, a->perm); -#ifdef HAVE_FCHMOD - ret = fchmod(fd, a->perm & 07777); -#else - ret = chmod(name, a->perm & 07777); -#endif - if (ret == -1) - status = errno_to_portable(errno); - } - if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { - char buf[64]; - time_t t = a->mtime; - - strftime(buf, sizeof(buf), "%Y" "%m%d-%H:%M:%S", - localtime(&t)); - log("set \"%s\" modtime %s", name, buf); -#ifdef HAVE_FUTIMES - ret = futimes(fd, attrib_to_tv(a)); -#else - ret = utimes(name, attrib_to_tv(a)); -#endif - if (ret == -1) - status = errno_to_portable(errno); - } - if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { - log("set \"%s\" owner %lu group %lu", name, - (u_long)a->uid, (u_long)a->gid); -#ifdef HAVE_FCHOWN - ret = fchown(fd, a->uid, a->gid); -#else - ret = chown(name, a->uid, a->gid); -#endif - if (ret == -1) - status = errno_to_portable(errno); - } - } - send_status(id, status); -} - -static void -process_opendir(void) -{ - DIR *dirp = NULL; - char *path; - int handle, status = SSH2_FX_FAILURE; - u_int32_t id; - - id = get_int(); - path = get_string(NULL); - debug3("request %u: opendir", id); - log("opendir \"%s\"", path); - dirp = opendir(path); - if (dirp == NULL) { - status = errno_to_portable(errno); - } else { - handle = handle_new(HANDLE_DIR, path, 0, dirp); - if (handle < 0) { - closedir(dirp); - } else { - send_handle(id, handle); - status = SSH2_FX_OK; - } - - } - if (status != SSH2_FX_OK) - send_status(id, status); - xfree(path); -} - -static void -process_readdir(void) -{ - DIR *dirp; - struct dirent *dp; - char *path; - int handle; - u_int32_t id; - - id = get_int(); - handle = get_handle(); - debug("request %u: readdir \"%s\" (handle %d)", id, - handle_to_name(handle), handle); - dirp = handle_to_dir(handle); - path = handle_to_name(handle); - if (dirp == NULL || path == NULL) { - send_status(id, SSH2_FX_FAILURE); - } else { - struct stat st; - char pathname[MAXPATHLEN]; - Stat *stats; - int nstats = 10, count = 0, i; - - stats = xcalloc(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%s", path, - strcmp(path, "/") ? "/" : "", dp->d_name); - if (lstat(pathname, &st) < 0) - continue; - stat_to_attrib(&st, &(stats[count].attrib)); - stats[count].name = xstrdup(dp->d_name); - stats[count].long_name = ls_file(dp->d_name, &st, 0); - count++; - /* send up to 100 entries in one message */ - /* XXX check packet size instead */ - if (count == 100) - break; - } - if (count > 0) { - send_names(id, count, stats); - for (i = 0; i < count; i++) { - xfree(stats[i].name); - xfree(stats[i].long_name); - } - } else { - send_status(id, SSH2_FX_EOF); - } - xfree(stats); - } -} - -static void -process_remove(void) -{ - char *name; - u_int32_t id; - int status = SSH2_FX_FAILURE; - int ret; - - id = get_int(); - name = get_string(NULL); - debug3("request %u: remove", id); - log("remove name \"%s\"", name); - ret = unlink(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - send_status(id, status); - xfree(name); -} - -static void -process_mkdir(void) -{ - Attrib *a; - u_int32_t id; - char *name; - int ret, mode, status = SSH2_FX_FAILURE; - - id = get_int(); - name = get_string(NULL); - a = get_attrib(); - mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? - a->perm & 0777 : 0777; - debug3("request %u: mkdir", id); - log("mkdir name \"%s\" mode 0%o", name, mode); - ret = mkdir(name, mode); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - send_status(id, status); - xfree(name); -} - -static void -process_rmdir(void) -{ - u_int32_t id; - char *name; - int ret, status; - - id = get_int(); - name = get_string(NULL); - debug3("request %u: rmdir", id); - log("rmdir name \"%s\"", name); - ret = rmdir(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - send_status(id, status); - xfree(name); -} - -static void -process_realpath(void) -{ - char resolvedname[MAXPATHLEN]; - u_int32_t id; - char *path; - - id = get_int(); - path = get_string(NULL); - if (path[0] == '\0') { - xfree(path); - path = xstrdup("."); - } - debug3("request %u: realpath", id); - verbose("realpath \"%s\"", 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); -} - -static void -process_rename(void) -{ - u_int32_t id; - char *oldpath, *newpath; - int status; - struct stat sb; - - id = get_int(); - oldpath = get_string(NULL); - newpath = get_string(NULL); - debug3("request %u: rename", id); - log("rename old \"%s\" new \"%s\"", oldpath, newpath); - status = SSH2_FX_FAILURE; - if (lstat(oldpath, &sb) == -1) - status = errno_to_portable(errno); - else if (S_ISREG(sb.st_mode)) { - /* Race-free rename of regular files */ - if (link(oldpath, newpath) == -1) { - if (errno == EOPNOTSUPP -#ifdef LINK_OPNOTSUPP_ERRNO - || errno == LINK_OPNOTSUPP_ERRNO -#endif - ) { - struct stat st; - - /* - * fs doesn't support links, so fall back to - * stat+rename. This is racy. - */ - if (stat(newpath, &st) == -1) { - if (rename(oldpath, newpath) == -1) - status = - errno_to_portable(errno); - else - status = SSH2_FX_OK; - } - } else { - status = errno_to_portable(errno); - } - } else if (unlink(oldpath) == -1) { - status = errno_to_portable(errno); - /* clean spare link */ - unlink(newpath); - } else - status = SSH2_FX_OK; - } else if (stat(newpath, &sb) == -1) { - if (rename(oldpath, newpath) == -1) - status = errno_to_portable(errno); - else - status = SSH2_FX_OK; - } - send_status(id, status); - xfree(oldpath); - xfree(newpath); -} - -static void -process_readlink(void) -{ - u_int32_t id; - int len; - char buf[MAXPATHLEN]; - char *path; - - id = get_int(); - path = get_string(NULL); - debug3("request %u: readlink", id); - verbose("readlink \"%s\"", path); - if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) - send_status(id, errno_to_portable(errno)); - else { - Stat s; - - buf[len] = '\0'; - attrib_clear(&s.attrib); - s.name = s.long_name = buf; - send_names(id, 1, &s); - } - xfree(path); -} - -static void -process_symlink(void) -{ - u_int32_t id; - char *oldpath, *newpath; - int ret, status; - - id = get_int(); - oldpath = get_string(NULL); - newpath = get_string(NULL); - debug3("request %u: symlink", id); - log("symlink old \"%s\" new \"%s\"", oldpath, newpath); - /* this will fail if 'newpath' exists */ - ret = symlink(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - send_status(id, status); - xfree(oldpath); - xfree(newpath); -} - -static void -process_extended(void) -{ - u_int32_t id; - char *request; - - id = get_int(); - request = get_string(NULL); - send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ - xfree(request); -} - -/* stolen from ssh-agent */ - -static void -process(void) -{ - u_int msg_len; - u_int buf_len; - u_int consumed; - u_int type; - u_char *cp; - - buf_len = buffer_len(&iqueue); - if (buf_len < 5) - return; /* Incomplete message. */ - cp = buffer_ptr(&iqueue); - msg_len = get_u32(cp); - if (msg_len > SFTP_MAX_MSG_LENGTH) { - error("bad message from %s local user %s", - client_addr, pw->pw_name); - cleanup_exit(11); - } - if (buf_len < msg_len + 4) - return; - buffer_consume(&iqueue, 4); - buf_len -= 4; - type = buffer_get_char(&iqueue); - switch (type) { - case SSH2_FXP_INIT: - process_init(); - break; - case SSH2_FXP_OPEN: - process_open(); - break; - case SSH2_FXP_CLOSE: - process_close(); - break; - case SSH2_FXP_READ: - process_read(); - break; - case SSH2_FXP_WRITE: - process_write(); - break; - case SSH2_FXP_LSTAT: - process_lstat(); - break; - case SSH2_FXP_FSTAT: - process_fstat(); - break; - case SSH2_FXP_SETSTAT: - process_setstat(); - break; - case SSH2_FXP_FSETSTAT: - process_fsetstat(); - break; - case SSH2_FXP_OPENDIR: - process_opendir(); - break; - case SSH2_FXP_READDIR: - process_readdir(); - break; - case SSH2_FXP_REMOVE: - process_remove(); - break; - case SSH2_FXP_MKDIR: - process_mkdir(); - break; - case SSH2_FXP_RMDIR: - process_rmdir(); - break; - case SSH2_FXP_REALPATH: - process_realpath(); - break; - case SSH2_FXP_STAT: - process_stat(); - break; - case SSH2_FXP_RENAME: - process_rename(); - break; - case SSH2_FXP_READLINK: - process_readlink(); - break; - case SSH2_FXP_SYMLINK: - process_symlink(); - break; - case SSH2_FXP_EXTENDED: - process_extended(); - break; - default: - error("Unknown message %d", type); - break; - } - /* discard the remaining bytes from the current packet */ - if (buf_len < buffer_len(&iqueue)) - fatal("iqueue grew unexpectedly"); - consumed = buf_len - buffer_len(&iqueue); - if (msg_len < consumed) - fatal("msg_len %d < consumed %d", msg_len, consumed); - if (msg_len > consumed) - buffer_consume(&iqueue, msg_len - consumed); -} - -/* - * Cleanup handler that logs active handles upon normal exit. Not static since - * sftp-server-main.c file needs that as well. - */ -void -cleanup_exit(int i) -{ - if (pw != NULL && client_addr != NULL) { - handle_log_exit(); - log("session closed for local user %s from [%s]", - pw->pw_name, client_addr); - } - _exit(i); -} - -static void -usage(void) -{ - fprintf(stderr, - "Usage: %s [-he] [-l log_level] [-f log_facility]\n", __progname); - exit(1); -} - -int -sftp_server_main(int argc, char **argv, struct passwd *user_pw) -{ - fd_set *rset, *wset; - int in, out, max, ch, skipargs = 0, log_stderr = 0; - ssize_t len, olen, set_size; - SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; - char *cp, buf[4*4096]; - - extern char *optarg; - - __progname = get_progname(argv[0]); - - (void) g11n_setlocale(LC_ALL, ""); - - log_init(__progname, log_level, log_facility, log_stderr); - - while (!skipargs && (ch = getopt(argc, argv, "C:f:l:che")) != -1) { - switch (ch) { - case 'c': - /* - * Ignore all arguments if we are invoked as a - * shell using "sftp-server -c command" - */ - skipargs = 1; - break; - case 'e': - log_stderr = 1; - break; - case 'l': - log_level = log_level_number(optarg); - if (log_level == SYSLOG_LEVEL_NOT_SET) - error("Invalid log level \"%s\"", optarg); - break; - case 'f': - log_facility = log_facility_number(optarg); - if (log_facility == SYSLOG_FACILITY_NOT_SET) - error("Invalid log facility \"%s\"", optarg); - break; - case 'h': - default: - usage(); - } - } - - log_init(__progname, log_level, log_facility, log_stderr); - - if ((cp = getenv("SSH_CONNECTION")) != NULL) { - client_addr = xstrdup(cp); - if ((cp = strchr(client_addr, ' ')) == NULL) - fatal("Malformed SSH_CONNECTION variable: \"%s\"", - getenv("SSH_CONNECTION")); - *cp = '\0'; - } else - client_addr = xstrdup("UNKNOWN"); - - pw = pwcopy(user_pw); - - log("session opened for local user %s from [%s]", - pw->pw_name, client_addr); - - handle_init(); - - in = dup(STDIN_FILENO); - out = dup(STDOUT_FILENO); - -#ifdef HAVE_CYGWIN - setmode(in, O_BINARY); - setmode(out, O_BINARY); -#endif - - max = 0; - if (in > max) - max = in; - if (out > max) - max = out; - - buffer_init(&iqueue); - buffer_init(&oqueue); - - set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); - rset = (fd_set *)xmalloc(set_size); - wset = (fd_set *)xmalloc(set_size); - - for (;;) { - memset(rset, 0, set_size); - memset(wset, 0, set_size); - - /* - * Ensure that we can read a full buffer and handle - * the worst-case length packet it can generate, - * otherwise apply backpressure by stopping reads. - */ - if (buffer_check_alloc(&iqueue, sizeof(buf)) && - buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH)) - FD_SET(in, rset); - - olen = buffer_len(&oqueue); - if (olen > 0) - FD_SET(out, wset); - - if (select(max+1, rset, wset, NULL, NULL) < 0) { - if (errno == EINTR) - continue; - error("select: %s", strerror(errno)); - cleanup_exit(2); - } - - /* copy stdin to iqueue */ - if (FD_ISSET(in, rset)) { - len = read(in, buf, sizeof buf); - if (len == 0) { - debug("read eof"); - cleanup_exit(0); - } else if (len < 0) { - error("read: %s", strerror(errno)); - cleanup_exit(1); - } else { - buffer_append(&iqueue, buf, len); - } - } - /* send oqueue to stdout */ - if (FD_ISSET(out, wset)) { - len = write(out, buffer_ptr(&oqueue), olen); - if (len < 0) { - error("write: %s", strerror(errno)); - cleanup_exit(1); - } else { - buffer_consume(&oqueue, len); - } - } - - /* - * Process requests from client if we can fit the results - * into the output buffer, otherwise stop processing input - * and let the output queue drain. - */ - if (buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH)) - process(); - } - - /* NOTREACHED */ - return (0); -} diff --git a/usr/src/cmd/ssh/sftp/Makefile b/usr/src/cmd/ssh/sftp/Makefile deleted file mode 100644 index f3c0ea7a75..0000000000 --- a/usr/src/cmd/ssh/sftp/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/sftp/Makefile - -PROG = sftp - -OBJS = \ - sftp.o \ - sftp-client.o \ - sftp-glob.o - -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto -ltecla - -POFILE_DIR = .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -install: all $(ROOTPROG) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/sftp/sftp-client.c b/usr/src/cmd/ssh/sftp/sftp-client.c deleted file mode 100644 index f194ccaf2b..0000000000 --- a/usr/src/cmd/ssh/sftp/sftp-client.c +++ /dev/null @@ -1,1184 +0,0 @@ -/* - * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* $OpenBSD: sftp-client.c,v 1.76 2007/01/22 11:32:50 djm Exp $ */ - -/* XXX: memleaks */ -/* XXX: signed vs unsigned */ -/* XXX: remove all logging, only return status codes */ -/* XXX: copy between two remote sites */ - -#include "includes.h" - -#include <sys/types.h> -#include <sys/param.h> -#include "sys-queue.h" -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -#endif -#include <sys/uio.h> - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "log.h" -#include "atomicio.h" -#include "progressmeter.h" -#include "misc.h" - -#include "sftp.h" -#include "sftp-common.h" -#include "sftp-client.h" - -extern volatile sig_atomic_t interrupted; -extern int showprogress; - -/* Minimum amount of data to read at a time */ -#define MIN_READ_SIZE 512 - -struct sftp_conn { - int fd_in; - int fd_out; - u_int transfer_buflen; - u_int num_requests; - u_int version; - u_int msg_id; -}; - -static void -send_msg(int fd, Buffer *m) -{ - char mlen[4]; - struct iovec iov[2]; - - if (buffer_len(m) > SFTP_MAX_MSG_LENGTH) - fatal("Outbound message too long %u", buffer_len(m)); - - /* Send length first */ - put_u32(mlen, buffer_len(m)); - iov[0].iov_base = mlen; - iov[0].iov_len = sizeof(mlen); - iov[1].iov_base = buffer_ptr(m); - iov[1].iov_len = buffer_len(m); - - if (atomiciov(writev, fd, iov, 2) != buffer_len(m) + sizeof(mlen)) - fatal("Couldn't send packet: %s", strerror(errno)); - - buffer_clear(m); -} - -static void -get_msg(int fd, Buffer *m) -{ - u_int msg_len; - - buffer_append_space(m, 4); - if (atomicio(read, fd, buffer_ptr(m), 4) != 4) { - if (errno == EPIPE) - fatal("Connection closed"); - else - fatal("Couldn't read packet: %s", strerror(errno)); - } - - msg_len = buffer_get_int(m); - if (msg_len > SFTP_MAX_MSG_LENGTH) - fatal("Received message too long %u", msg_len); - - buffer_append_space(m, msg_len); - if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) { - if (errno == EPIPE) - fatal("Connection closed"); - else - fatal("Read packet: %s", strerror(errno)); - } -} - -static void -send_string_request(int fd, u_int id, u_int code, char *s, - u_int len) -{ - Buffer msg; - - buffer_init(&msg); - buffer_put_char(&msg, code); - buffer_put_int(&msg, id); - buffer_put_string(&msg, s, len); - send_msg(fd, &msg); - debug3("Sent message fd %d T:%u I:%u", fd, code, id); - buffer_free(&msg); -} - -static void -send_string_attrs_request(int fd, u_int id, u_int code, char *s, - u_int len, Attrib *a) -{ - Buffer msg; - - buffer_init(&msg); - buffer_put_char(&msg, code); - buffer_put_int(&msg, id); - buffer_put_string(&msg, s, len); - encode_attrib(&msg, a); - send_msg(fd, &msg); - debug3("Sent message fd %d T:%u I:%u", fd, code, id); - buffer_free(&msg); -} - -static u_int -get_status(int fd, u_int expected_id) -{ - Buffer msg; - u_int type, id, status; - - buffer_init(&msg); - get_msg(fd, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); - - if (id != expected_id) - fatal("ID mismatch (%u != %u)", id, expected_id); - if (type != SSH2_FXP_STATUS) - fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u", - SSH2_FXP_STATUS, type); - - status = buffer_get_int(&msg); - buffer_free(&msg); - - debug3("SSH2_FXP_STATUS %u", status); - - return(status); -} - -static char * -get_handle(int fd, u_int expected_id, u_int *len) -{ - Buffer msg; - u_int type, id; - char *handle; - - buffer_init(&msg); - get_msg(fd, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); - - if (id != expected_id) - fatal("ID mismatch (%u != %u)", id, expected_id); - if (type == SSH2_FXP_STATUS) { - int status = buffer_get_int(&msg); - - error("Couldn't get handle: %s", fx2txt(status)); - buffer_free(&msg); - return(NULL); - } else if (type != SSH2_FXP_HANDLE) - fatal("Expected SSH2_FXP_HANDLE(%u) packet, got %u", - SSH2_FXP_HANDLE, type); - - handle = buffer_get_string(&msg, len); - buffer_free(&msg); - - return(handle); -} - -static Attrib * -get_decode_stat(int fd, u_int expected_id, int quiet) -{ - Buffer msg; - u_int type, id; - Attrib *a; - - buffer_init(&msg); - get_msg(fd, &msg); - - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); - - debug3("Received stat reply T:%u I:%u", type, id); - if (id != expected_id) - fatal("ID mismatch (%u != %u)", id, expected_id); - if (type == SSH2_FXP_STATUS) { - int status = buffer_get_int(&msg); - - if (quiet) - debug("Couldn't stat remote file: %s", fx2txt(status)); - else - error("Couldn't stat remote file: %s", fx2txt(status)); - buffer_free(&msg); - return(NULL); - } else if (type != SSH2_FXP_ATTRS) { - fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u", - SSH2_FXP_ATTRS, type); - } - a = decode_attrib(&msg); - buffer_free(&msg); - - return(a); -} - -struct sftp_conn * -do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) -{ - u_int type; - int version; - Buffer msg; - struct sftp_conn *ret; - - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_INIT); - buffer_put_int(&msg, SSH2_FILEXFER_VERSION); - send_msg(fd_out, &msg); - - buffer_clear(&msg); - - get_msg(fd_in, &msg); - - /* Expecting a VERSION reply */ - if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) { - error("Invalid packet back from SSH2_FXP_INIT (type %u)", - type); - buffer_free(&msg); - return(NULL); - } - version = buffer_get_int(&msg); - - debug2("Remote version: %d", version); - - /* Check for extensions */ - while (buffer_len(&msg) > 0) { - char *name = buffer_get_string(&msg, NULL); - char *value = buffer_get_string(&msg, NULL); - - debug2("Init extension: \"%s\"", name); - xfree(name); - xfree(value); - } - - buffer_free(&msg); - - ret = xmalloc(sizeof(*ret)); - ret->fd_in = fd_in; - ret->fd_out = fd_out; - ret->transfer_buflen = transfer_buflen; - ret->num_requests = num_requests; - ret->version = version; - ret->msg_id = 1; - - /* Some filexfer v.0 servers don't support large packets */ - if (version == 0) - ret->transfer_buflen = MIN(ret->transfer_buflen, 20480); - - return(ret); -} - -u_int -sftp_proto_version(struct sftp_conn *conn) -{ - return(conn->version); -} - -int -do_close(struct sftp_conn *conn, char *handle, u_int handle_len) -{ - u_int id, status; - Buffer msg; - - buffer_init(&msg); - - id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_CLOSE); - buffer_put_int(&msg, id); - buffer_put_string(&msg, handle, handle_len); - send_msg(conn->fd_out, &msg); - debug3("Sent message SSH2_FXP_CLOSE I:%u", id); - - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't close file: %s", fx2txt(status)); - - buffer_free(&msg); - - return(status); -} - - -static int -do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, - SFTP_DIRENT ***dir) -{ - Buffer msg; - u_int count, type, id, handle_len, i, expected_id, ents = 0; - char *handle; - - id = conn->msg_id++; - - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_OPENDIR); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, path); - send_msg(conn->fd_out, &msg); - - buffer_clear(&msg); - - handle = get_handle(conn->fd_in, id, &handle_len); - if (handle == NULL) - return(-1); - - if (dir) { - ents = 0; - *dir = xmalloc(sizeof(**dir)); - (*dir)[0] = NULL; - } - - for (; !interrupted;) { - id = expected_id = conn->msg_id++; - - debug3("Sending SSH2_FXP_READDIR I:%u", id); - - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_READDIR); - buffer_put_int(&msg, id); - buffer_put_string(&msg, handle, handle_len); - send_msg(conn->fd_out, &msg); - - buffer_clear(&msg); - - get_msg(conn->fd_in, &msg); - - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); - - debug3("Received reply T:%u I:%u", type, id); - - if (id != expected_id) - fatal("ID mismatch (%u != %u)", id, expected_id); - - if (type == SSH2_FXP_STATUS) { - int status = buffer_get_int(&msg); - - debug3("Received SSH2_FXP_STATUS %d", status); - - if (status == SSH2_FX_EOF) { - break; - } else { - error("Couldn't read directory: %s", - fx2txt(status)); - do_close(conn, handle, handle_len); - xfree(handle); - return(status); - } - } else if (type != SSH2_FXP_NAME) - fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", - SSH2_FXP_NAME, type); - - count = buffer_get_int(&msg); - if (count == 0) - break; - debug3("Received %d SSH2_FXP_NAME responses", count); - for (i = 0; i < count; i++) { - char *filename, *longname; - Attrib *a; - - filename = buffer_get_string(&msg, NULL); - longname = buffer_get_string(&msg, NULL); - a = decode_attrib(&msg); - - if (printflag) - printf("%s\n", longname); - - if (dir) { - *dir = xrealloc(*dir, (ents + 2) * sizeof(**dir)); - (*dir)[ents] = xmalloc(sizeof(***dir)); - (*dir)[ents]->filename = xstrdup(filename); - (*dir)[ents]->longname = xstrdup(longname); - memcpy(&(*dir)[ents]->a, a, sizeof(*a)); - (*dir)[++ents] = NULL; - } - - xfree(filename); - xfree(longname); - } - } - - buffer_free(&msg); - do_close(conn, handle, handle_len); - xfree(handle); - - /* Don't return partial matches on interrupt */ - if (interrupted && dir != NULL && *dir != NULL) { - free_sftp_dirents(*dir); - *dir = xmalloc(sizeof(**dir)); - **dir = NULL; - } - - return(0); -} - -int -do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir) -{ - return(do_lsreaddir(conn, path, 0, dir)); -} - -void free_sftp_dirents(SFTP_DIRENT **s) -{ - int i; - - for (i = 0; s[i]; i++) { - xfree(s[i]->filename); - xfree(s[i]->longname); - xfree(s[i]); - } - xfree(s); -} - -int -do_rm(struct sftp_conn *conn, char *path) -{ - u_int status, id; - - debug2("Sending SSH2_FXP_REMOVE \"%s\"", path); - - id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path, - strlen(path)); - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't delete file: %s", fx2txt(status)); - return(status); -} - -int -do_mkdir(struct sftp_conn *conn, char *path, Attrib *a) -{ - u_int status, id; - - id = conn->msg_id++; - send_string_attrs_request(conn->fd_out, id, SSH2_FXP_MKDIR, path, - strlen(path), a); - - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't create directory: %s", fx2txt(status)); - - return(status); -} - -int -do_rmdir(struct sftp_conn *conn, char *path) -{ - u_int status, id; - - id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_RMDIR, path, - strlen(path)); - - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't remove directory: %s", fx2txt(status)); - - return(status); -} - -Attrib * -do_stat(struct sftp_conn *conn, char *path, int quiet) -{ - u_int id; - - id = conn->msg_id++; - - send_string_request(conn->fd_out, id, - conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT, - path, strlen(path)); - - return(get_decode_stat(conn->fd_in, id, quiet)); -} - -Attrib * -do_lstat(struct sftp_conn *conn, char *path, int quiet) -{ - u_int id; - - if (conn->version == 0) { - if (quiet) - debug("Server version does not support lstat operation"); - else - log("Server version does not support lstat operation"); - return(do_stat(conn, path, quiet)); - } - - id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_LSTAT, path, - strlen(path)); - - return(get_decode_stat(conn->fd_in, id, quiet)); -} - -/* this is never used so hush the lint */ -#if 0 -Attrib * -do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) -{ - u_int id; - - id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_FSTAT, handle, - handle_len); - - return(get_decode_stat(conn->fd_in, id, quiet)); -} -#endif - -int -do_setstat(struct sftp_conn *conn, char *path, Attrib *a) -{ - u_int status, id; - - id = conn->msg_id++; - send_string_attrs_request(conn->fd_out, id, SSH2_FXP_SETSTAT, path, - strlen(path), a); - - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't setstat on \"%s\": %s", path, - fx2txt(status)); - - return(status); -} - -int -do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, - Attrib *a) -{ - u_int status, id; - - id = conn->msg_id++; - send_string_attrs_request(conn->fd_out, id, SSH2_FXP_FSETSTAT, handle, - handle_len, a); - - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't fsetstat: %s", fx2txt(status)); - - return(status); -} - -char * -do_realpath(struct sftp_conn *conn, char *path) -{ - Buffer msg; - u_int type, expected_id, count, id; - char *filename, *longname; - /* LINTED */ - Attrib *a; - - expected_id = id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_REALPATH, path, - strlen(path)); - - buffer_init(&msg); - - get_msg(conn->fd_in, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); - - if (id != expected_id) - fatal("ID mismatch (%u != %u)", id, expected_id); - - if (type == SSH2_FXP_STATUS) { - u_int status = buffer_get_int(&msg); - - error("Couldn't canonicalise: %s", fx2txt(status)); - return(NULL); - } else if (type != SSH2_FXP_NAME) - fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", - SSH2_FXP_NAME, type); - - count = buffer_get_int(&msg); - if (count != 1) - fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); - - filename = buffer_get_string(&msg, NULL); - longname = buffer_get_string(&msg, NULL); - a = decode_attrib(&msg); - - debug3("SSH_FXP_REALPATH %s -> %s", path, filename); - - xfree(longname); - - buffer_free(&msg); - - return(filename); -} - -int -do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) -{ - Buffer msg; - u_int status, id; - - buffer_init(&msg); - - /* Send rename request */ - id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_RENAME); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, oldpath); - buffer_put_cstring(&msg, newpath); - send_msg(conn->fd_out, &msg); - debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath, - newpath); - buffer_free(&msg); - - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, - newpath, fx2txt(status)); - - return(status); -} - -int -do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) -{ - Buffer msg; - u_int status, id; - - if (conn->version < 3) { - error("This server does not support the symlink operation"); - return(SSH2_FX_OP_UNSUPPORTED); - } - - buffer_init(&msg); - - /* Send symlink request */ - id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_SYMLINK); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, oldpath); - buffer_put_cstring(&msg, newpath); - send_msg(conn->fd_out, &msg); - debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, - newpath); - buffer_free(&msg); - - status = get_status(conn->fd_in, id); - if (status != SSH2_FX_OK) - error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath, - newpath, fx2txt(status)); - - return(status); -} - -/* this is never used so hush the lint */ -#if 0 -char * -do_readlink(struct sftp_conn *conn, char *path) -{ - Buffer msg; - u_int type, expected_id, count, id; - char *filename, *longname; - Attrib *a; - - expected_id = id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_READLINK, path, - strlen(path)); - - buffer_init(&msg); - - get_msg(conn->fd_in, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); - - if (id != expected_id) - fatal("ID mismatch (%u != %u)", id, expected_id); - - if (type == SSH2_FXP_STATUS) { - u_int status = buffer_get_int(&msg); - - error("Couldn't readlink: %s", fx2txt(status)); - return(NULL); - } else if (type != SSH2_FXP_NAME) - fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", - SSH2_FXP_NAME, type); - - count = buffer_get_int(&msg); - if (count != 1) - fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); - - filename = buffer_get_string(&msg, NULL); - longname = buffer_get_string(&msg, NULL); - a = decode_attrib(&msg); - - debug3("SSH_FXP_READLINK %s -> %s", path, filename); - - xfree(longname); - - buffer_free(&msg); - - return(filename); -} -#endif - -static void -send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, - char *handle, u_int handle_len) -{ - Buffer msg; - - buffer_init(&msg); - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_READ); - buffer_put_int(&msg, id); - buffer_put_string(&msg, handle, handle_len); - buffer_put_int64(&msg, offset); - buffer_put_int(&msg, len); - send_msg(fd_out, &msg); - buffer_free(&msg); -} - -int -do_download(struct sftp_conn *conn, char *remote_path, char *local_path, - int pflag) -{ - Attrib junk, *a; - Buffer msg; - char *handle; - int local_fd, status = 0, write_error; - int read_error, write_errno; - u_int64_t offset, size; - u_int handle_len, mode, type, id, buflen, num_req, max_req; - off_t progress_counter; - struct request { - u_int id; - u_int len; - u_int64_t offset; - TAILQ_ENTRY(request) tq; - }; - TAILQ_HEAD(reqhead, request) requests; - struct request *req; - - TAILQ_INIT(&requests); - - a = do_stat(conn, remote_path, 0); - if (a == NULL) - return(-1); - - /* Do not preserve set[ug]id here, as we do not preserve ownership */ - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) - mode = a->perm & 0777; - else - mode = 0666; - - if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && - (!S_ISREG(a->perm))) { - error("Cannot download non-regular file: %s", remote_path); - return(-1); - } - - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) - size = a->size; - else - size = 0; - - buflen = conn->transfer_buflen; - buffer_init(&msg); - - /* Send open request */ - id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_OPEN); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, remote_path); - buffer_put_int(&msg, SSH2_FXF_READ); - attrib_clear(&junk); /* Send empty attributes */ - encode_attrib(&msg, &junk); - send_msg(conn->fd_out, &msg); - debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); - - handle = get_handle(conn->fd_in, id, &handle_len); - if (handle == NULL) { - buffer_free(&msg); - return(-1); - } - - local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, - mode | S_IWRITE); - if (local_fd == -1) { - error("Couldn't open local file \"%s\" for writing: %s", - local_path, strerror(errno)); - buffer_free(&msg); - xfree(handle); - return(-1); - } - - /* Read from remote and write to local */ - write_error = read_error = write_errno = num_req = offset = 0; - max_req = 1; - progress_counter = 0; - - if (showprogress && size != 0) - start_progress_meter(remote_path, size, &progress_counter); - - while (num_req > 0 || max_req > 0) { - char *data; - u_int len; - - /* - * Simulate EOF on interrupt: stop sending new requests and - * allow outstanding requests to drain gracefully - */ - if (interrupted) { - if (num_req == 0) /* If we haven't started yet... */ - break; - max_req = 0; - } - - /* Send some more requests */ - while (num_req < max_req) { - debug3("Request range %llu -> %llu (%d/%d)", - (unsigned long long)offset, - (unsigned long long)offset + buflen - 1, - num_req, max_req); - req = xmalloc(sizeof(*req)); - req->id = conn->msg_id++; - req->len = buflen; - req->offset = offset; - offset += buflen; - num_req++; - TAILQ_INSERT_TAIL(&requests, req, tq); - send_read_request(conn->fd_out, req->id, req->offset, - req->len, handle, handle_len); - } - - buffer_clear(&msg); - get_msg(conn->fd_in, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); - debug3("Received reply T:%u I:%u R:%d", type, id, max_req); - - /* Find the request in our queue */ - for (req = TAILQ_FIRST(&requests); - req != NULL && req->id != id; - req = TAILQ_NEXT(req, tq)) - ; - if (req == NULL) - fatal("Unexpected reply %u", id); - - switch (type) { - case SSH2_FXP_STATUS: - status = buffer_get_int(&msg); - if (status != SSH2_FX_EOF) - read_error = 1; - max_req = 0; - TAILQ_REMOVE(&requests, req, tq); - xfree(req); - num_req--; - break; - case SSH2_FXP_DATA: - data = buffer_get_string(&msg, &len); - debug3("Received data %llu -> %llu", - (unsigned long long)req->offset, - (unsigned long long)req->offset + len - 1); - if (len > req->len) - fatal("Received more data than asked for " - "%u > %u", len, req->len); - if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || - atomicio(vwrite, local_fd, data, len) != len) && - !write_error) { - write_errno = errno; - write_error = 1; - max_req = 0; - } - progress_counter += len; - xfree(data); - - if (len == req->len) { - TAILQ_REMOVE(&requests, req, tq); - xfree(req); - num_req--; - } else { - /* Resend the request for the missing data */ - debug3("Short data block, re-requesting " - "%llu -> %llu (%2d)", - (unsigned long long)req->offset + len, - (unsigned long long)req->offset + - req->len - 1, num_req); - req->id = conn->msg_id++; - req->len -= len; - req->offset += len; - send_read_request(conn->fd_out, req->id, - req->offset, req->len, handle, handle_len); - /* Reduce the request size */ - if (len < buflen) - buflen = MAX(MIN_READ_SIZE, len); - } - if (max_req > 0) { /* max_req = 0 iff EOF received */ - if (size > 0 && offset > size) { - /* Only one request at a time - * after the expected EOF */ - debug3("Finish at %llu (%2d)", - (unsigned long long)offset, - num_req); - max_req = 1; - } else if (max_req <= conn->num_requests) { - ++max_req; - } - } - break; - default: - fatal("Expected SSH2_FXP_DATA(%u) packet, got %u", - SSH2_FXP_DATA, type); - } - } - - if (showprogress && size) - stop_progress_meter(); - - /* Sanity check */ - if (TAILQ_FIRST(&requests) != NULL) - fatal("Transfer complete, but requests still in queue"); - - if (read_error) { - error("Couldn't read from remote file \"%s\" : %s", - remote_path, fx2txt(status)); - do_close(conn, handle, handle_len); - } else if (write_error) { - error("Couldn't write to \"%s\": %s", local_path, - strerror(write_errno)); - status = -1; - do_close(conn, handle, handle_len); - } else { - status = do_close(conn, handle, handle_len); - - /* Override umask and utimes if asked */ -#ifdef HAVE_FCHMOD - if (pflag && fchmod(local_fd, mode) == -1) -#else - if (pflag && chmod(local_path, mode) == -1) -#endif /* HAVE_FCHMOD */ - error("Couldn't set mode on \"%s\": %s", local_path, - strerror(errno)); - if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { - struct timeval tv[2]; - tv[0].tv_sec = a->atime; - tv[1].tv_sec = a->mtime; - tv[0].tv_usec = tv[1].tv_usec = 0; - if (utimes(local_path, tv) == -1) - error("Can't set times on \"%s\": %s", - local_path, strerror(errno)); - } - } - close(local_fd); - buffer_free(&msg); - xfree(handle); - - return(status); -} - -int -do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, - int pflag) -{ - int local_fd, status; - u_int handle_len, id, type; - u_int64_t offset; - char *handle, *data; - Buffer msg; - struct stat sb; - Attrib a; - u_int32_t startid; - u_int32_t ackid; - struct outstanding_ack { - u_int id; - u_int len; - u_int64_t offset; - TAILQ_ENTRY(outstanding_ack) tq; - }; - TAILQ_HEAD(ackhead, outstanding_ack) acks; - struct outstanding_ack *ack = NULL; - - TAILQ_INIT(&acks); - - if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { - error("Couldn't open local file \"%s\" for reading: %s", - local_path, strerror(errno)); - return(-1); - } - if (fstat(local_fd, &sb) == -1) { - error("Couldn't fstat local file \"%s\": %s", - local_path, strerror(errno)); - close(local_fd); - return(-1); - } - if (!S_ISREG(sb.st_mode)) { - error("%s is not a regular file", local_path); - close(local_fd); - return(-1); - } - stat_to_attrib(&sb, &a); - - a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; - a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; - a.perm &= 0777; - if (!pflag) - a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; - - buffer_init(&msg); - - /* Send open request */ - id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_OPEN); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, remote_path); - buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC); - encode_attrib(&msg, &a); - send_msg(conn->fd_out, &msg); - debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); - - buffer_clear(&msg); - - handle = get_handle(conn->fd_in, id, &handle_len); - if (handle == NULL) { - close(local_fd); - buffer_free(&msg); - return(-1); - } - - startid = ackid = id + 1; - data = xmalloc(conn->transfer_buflen); - - /* Read from local and write to remote */ - offset = 0; - if (showprogress) - start_progress_meter(local_path, sb.st_size, (off_t *)&offset); - - for (;;) { - int len; - - /* - * Can't use atomicio here because it returns 0 on EOF, - * thus losing the last block of the file. - * Simulate an EOF on interrupt, allowing ACKs from the - * server to drain. - */ - if (interrupted) - len = 0; - else do - len = read(local_fd, data, conn->transfer_buflen); - while ((len == -1) && (errno == EINTR || errno == EAGAIN)); - - if (len == -1) - fatal("Couldn't read from \"%s\": %s", local_path, - strerror(errno)); - - if (len != 0) { - ack = xmalloc(sizeof(*ack)); - ack->id = ++id; - ack->offset = offset; - ack->len = len; - TAILQ_INSERT_TAIL(&acks, ack, tq); - - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_WRITE); - buffer_put_int(&msg, ack->id); - buffer_put_string(&msg, handle, handle_len); - buffer_put_int64(&msg, offset); - buffer_put_string(&msg, data, len); - send_msg(conn->fd_out, &msg); - debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", - id, (unsigned long long)offset, len); - } else if (TAILQ_FIRST(&acks) == NULL) - break; - - if (ack == NULL) - fatal("Unexpected ACK %u", id); - - if (id == startid || len == 0 || - id - ackid >= conn->num_requests) { - u_int r_id; - - buffer_clear(&msg); - get_msg(conn->fd_in, &msg); - type = buffer_get_char(&msg); - r_id = buffer_get_int(&msg); - - if (type != SSH2_FXP_STATUS) - fatal("Expected SSH2_FXP_STATUS(%d) packet, " - "got %d", SSH2_FXP_STATUS, type); - - status = buffer_get_int(&msg); - debug3("SSH2_FXP_STATUS %d", status); - - /* Find the request in our queue */ - for (ack = TAILQ_FIRST(&acks); - ack != NULL && ack->id != r_id; - ack = TAILQ_NEXT(ack, tq)) - ; - if (ack == NULL) - fatal("Can't find request for ID %u", r_id); - TAILQ_REMOVE(&acks, ack, tq); - - if (status != SSH2_FX_OK) { - error("Couldn't write to remote file \"%s\": %s", - remote_path, fx2txt(status)); - if (showprogress) - stop_progress_meter(); - do_close(conn, handle, handle_len); - close(local_fd); - xfree(data); - xfree(ack); - status = -1; - goto done; - } - debug3("In write loop, ack for %u %u bytes at %llu", - ack->id, ack->len, (unsigned long long)ack->offset); - ++ackid; - xfree(ack); - } - offset += len; - } - if (showprogress) - stop_progress_meter(); - xfree(data); - - if (close(local_fd) == -1) { - error("Couldn't close local file \"%s\": %s", local_path, - strerror(errno)); - do_close(conn, handle, handle_len); - status = -1; - goto done; - } - - /* Override umask and utimes if asked */ - if (pflag) - do_fsetstat(conn, handle, handle_len, &a); - - status = do_close(conn, handle, handle_len); - -done: - xfree(handle); - buffer_free(&msg); - return(status); -} diff --git a/usr/src/cmd/ssh/sftp/sftp-glob.c b/usr/src/cmd/ssh/sftp/sftp-glob.c deleted file mode 100644 index 626e80922a..0000000000 --- a/usr/src/cmd/ssh/sftp/sftp-glob.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* $OpenBSD: sftp-glob.c,v 1.22 2006/08/03 03:34:42 deraadt Exp $ */ - -#include "includes.h" - -#include <sys/types.h> -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif - -#include <dirent.h> -#include <string.h> - -#include "xmalloc.h" -#include "sftp.h" -#include "buffer.h" -#include "sftp-common.h" -#include "sftp-client.h" - -int remote_glob(struct sftp_conn *, const char *, int, - int (*)(const char *, int), glob_t *); - -struct SFTP_OPENDIR { - SFTP_DIRENT **dir; - int offset; -}; - -static struct { - struct sftp_conn *conn; -} cur; - -static void * -fudge_opendir(const char *path) -{ - struct SFTP_OPENDIR *r; - - r = xmalloc(sizeof(*r)); - - if (do_readdir(cur.conn, (char *)path, &r->dir)) { - xfree(r); - return(NULL); - } - - r->offset = 0; - - return((void *)r); -} - -static struct dirent * -fudge_readdir(struct SFTP_OPENDIR *od) -{ - /* Solaris needs sizeof(dirent) + path length (see below) */ - static union { - char buf_chars[sizeof (struct dirent) + MAXPATHLEN]; - struct dirent buf_dirent; - } buf; - struct dirent *ret = &buf.buf_dirent; -#ifdef __GNU_LIBRARY__ - static int inum = 1; -#endif /* __GNU_LIBRARY__ */ - - if (od->dir[od->offset] == NULL) - return(NULL); - - memset(buf.buf_chars, 0, sizeof (buf.buf_chars)); - - /* - * Solaris defines dirent->d_name as a one byte array and expects - * you to hack around it. - */ -#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME - strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN); -#else - strlcpy(ret->d_name, od->dir[od->offset++]->filename, - sizeof(ret->d_name)); -#endif -#ifdef __GNU_LIBRARY__ - /* - * Idiot glibc uses extensions to struct dirent for readdir with - * ALTDIRFUNCs. Not that this is documented anywhere but the - * source... Fake an inode number to appease it. - */ - ret->d_ino = inum++; - if (!inum) - inum = 1; -#endif /* __GNU_LIBRARY__ */ - - return(ret); -} - -static void -fudge_closedir(struct SFTP_OPENDIR *od) -{ - free_sftp_dirents(od->dir); - xfree(od); -} - -static int -fudge_lstat(const char *path, struct stat *st) -{ - Attrib *a; - - if (!(a = do_lstat(cur.conn, (char *)path, 0))) - return(-1); - - attrib_to_stat(a, st); - - return(0); -} - -static int -fudge_stat(const char *path, struct stat *st) -{ - Attrib *a; - - if (!(a = do_stat(cur.conn, (char *)path, 0))) - return(-1); - - attrib_to_stat(a, st); - - return(0); -} - -int -remote_glob(struct sftp_conn *conn, const char *pattern, int flags, - int (*errfunc)(const char *, int), glob_t *pglob) -{ - pglob->gl_opendir = fudge_opendir; - pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; - pglob->gl_closedir = (void (*)(void *))fudge_closedir; - pglob->gl_lstat = fudge_lstat; - pglob->gl_stat = fudge_stat; - - memset(&cur, 0, sizeof(cur)); - cur.conn = conn; - - return(glob(pattern, flags|GLOB_LIMIT|GLOB_ALTDIRFUNC, errfunc, pglob)); -} diff --git a/usr/src/cmd/ssh/sftp/sftp.c b/usr/src/cmd/ssh/sftp/sftp.c deleted file mode 100644 index 10b971f02c..0000000000 --- a/usr/src/cmd/ssh/sftp/sftp.c +++ /dev/null @@ -1,1690 +0,0 @@ -/* - * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* $OpenBSD: sftp.c,v 1.96 2007/01/03 04:09:15 stevesk Exp $ */ - -#include "includes.h" - -#include <sys/types.h> -#include <sys/ioctl.h> -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/wait.h> - -#include <errno.h> - -#ifdef HAVE_PATHS_H -# include <paths.h> -#endif - -#ifdef USE_LIBEDIT -#include <histedit.h> -#else -#ifdef USE_LIBTECLA -#include <libtecla.h> -#define MAX_LINE_LEN 2048 -#define MAX_CMD_HIST 10000 -#endif /* USE_LIBTECLA */ -#endif /* USE_LIBEDIT */ - -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> - -#include "xmalloc.h" -#include "log.h" -#include "pathnames.h" -#include "misc.h" - -#include "sftp.h" -#include "buffer.h" -#include "sftp-common.h" -#include "sftp-client.h" - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - - -/* File to read commands from */ -FILE* infile; - -/* Are we in batchfile mode? */ -int batchmode = 0; - -/* Size of buffer used when copying files */ -size_t copy_buffer_len = 32768; - -/* Number of concurrent outstanding requests */ -size_t num_requests = 16; - -/* PID of ssh transport process */ -static pid_t sshpid = -1; - -/* This is set to 0 if the progressmeter is not desired. */ -int showprogress = 1; - -/* SIGINT received during command processing */ -volatile sig_atomic_t interrupted = 0; - -/* I wish qsort() took a separate ctx for the comparison function...*/ -int sort_flag; - -int remote_glob(struct sftp_conn *, const char *, int, - int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ - -/* Separators for interactive commands */ -#define WHITESPACE " \t\r\n" - -/* ls flags */ -#define LS_LONG_VIEW 0x01 /* Full view ala ls -l */ -#define LS_SHORT_VIEW 0x02 /* Single row view ala ls -1 */ -#define LS_NUMERIC_VIEW 0x04 /* Long view with numeric uid/gid */ -#define LS_NAME_SORT 0x08 /* Sort by name (default) */ -#define LS_TIME_SORT 0x10 /* Sort by mtime */ -#define LS_SIZE_SORT 0x20 /* Sort by file size */ -#define LS_REVERSE_SORT 0x40 /* Reverse sort order */ -#define LS_SHOW_ALL 0x80 /* Don't skip filenames starting with '.' */ - -#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW) -#define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) - -/* Commands for interactive mode */ -#define I_CHDIR 1 -#define I_CHGRP 2 -#define I_CHMOD 3 -#define I_CHOWN 4 -#define I_GET 5 -#define I_HELP 6 -#define I_LCHDIR 7 -#define I_LLS 8 -#define I_LMKDIR 9 -#define I_LPWD 10 -#define I_LS 11 -#define I_LUMASK 12 -#define I_MKDIR 13 -#define I_PUT 14 -#define I_PWD 15 -#define I_QUIT 16 -#define I_RENAME 17 -#define I_RM 18 -#define I_RMDIR 19 -#define I_SHELL 20 -#define I_SYMLINK 21 -#define I_VERSION 22 -#define I_PROGRESS 23 - -struct CMD { - const char *c; - const int n; -}; - -static const struct CMD cmds[] = { - { "bye", I_QUIT }, - { "cd", I_CHDIR }, - { "chdir", I_CHDIR }, - { "chgrp", I_CHGRP }, - { "chmod", I_CHMOD }, - { "chown", I_CHOWN }, - { "dir", I_LS }, - { "exit", I_QUIT }, - { "get", I_GET }, - { "mget", I_GET }, - { "help", I_HELP }, - { "lcd", I_LCHDIR }, - { "lchdir", I_LCHDIR }, - { "lls", I_LLS }, - { "lmkdir", I_LMKDIR }, - { "ln", I_SYMLINK }, - { "lpwd", I_LPWD }, - { "ls", I_LS }, - { "lumask", I_LUMASK }, - { "mkdir", I_MKDIR }, - { "progress", I_PROGRESS }, - { "put", I_PUT }, - { "mput", I_PUT }, - { "pwd", I_PWD }, - { "quit", I_QUIT }, - { "rename", I_RENAME }, - { "rm", I_RM }, - { "rmdir", I_RMDIR }, - { "symlink", I_SYMLINK }, - { "version", I_VERSION }, - { "!", I_SHELL }, - { "?", I_HELP }, - { NULL, -1} -}; - -int interactive_loop(int fd_in, int fd_out, char *file1, char *file2); - -/* ARGSUSED */ -static void -killchild(int signo) -{ - if (sshpid > 1) { - kill(sshpid, SIGTERM); - waitpid(sshpid, NULL, 0); - } - - _exit(1); -} - -/* ARGSUSED */ -static void -cmd_interrupt(int signo) -{ - const char msg[] = "\rInterrupt \n"; - int olderrno = errno; - - write(STDERR_FILENO, msg, sizeof(msg) - 1); - interrupted = 1; - errno = olderrno; -} - -static void -help(void) -{ - printf(gettext("Available commands:\n" - "cd path Change remote directory to 'path'\n" - "lcd path Change local directory to 'path'\n" - "chgrp grp path Change group of file 'path' to 'grp'\n" - "chmod mode path Change permissions of file 'path' to 'mode'\n" - "chown own path Change owner of file 'path' to 'own'\n" - "help Display this help text\n" - "get remote-path [local-path] Download file\n" - "lls [ls-options [path]] Display local directory listing\n" - "ln oldpath newpath Symlink remote file\n" - "lmkdir path Create local directory\n" - "lpwd Print local working directory\n" - "ls [path] Display remote directory listing\n" - "lumask umask Set local umask to 'umask'\n" - "mkdir path Create remote directory\n" - "progress Toggle display of progress meter\n" - "put local-path [remote-path] Upload file\n" - "pwd Display remote working directory\n" - "exit Quit sftp\n" - "quit Quit sftp\n" - "rename oldpath newpath Rename remote file\n" - "rmdir path Remove remote directory\n" - "rm path Delete remote file\n" - "symlink oldpath newpath Symlink remote file\n" - "version Show SFTP version\n" - "!command Execute 'command' in local shell\n" - "! Escape to local shell\n" - "? Synonym for help\n")); -} - -static void -local_do_shell(const char *args) -{ - int status; - char *shell; - pid_t pid; - - if (!*args) - args = NULL; - - if ((shell = getenv("SHELL")) == NULL) - shell = _PATH_BSHELL; - - if ((pid = fork()) == -1) - fatal("Couldn't fork: %s", strerror(errno)); - - if (pid == 0) { - /* XXX: child has pipe fds to ssh subproc open - issue? */ - if (args) { - debug3("Executing %s -c \"%s\"", shell, args); - execl(shell, shell, "-c", args, (char *)NULL); - } else { - debug3("Executing %s", shell); - execl(shell, shell, (char *)NULL); - } - fprintf(stderr, gettext("Couldn't execute \"%s\": %s\n"), shell, - strerror(errno)); - _exit(1); - } - while (waitpid(pid, &status, 0) == -1) - if (errno != EINTR) - fatal("Couldn't wait for child: %s", strerror(errno)); - if (!WIFEXITED(status)) - error("Shell exited abnormally"); - else if (WEXITSTATUS(status)) - error("Shell exited with status %d", WEXITSTATUS(status)); -} - -static void -local_do_ls(const char *args) -{ - if (!args || !*args) - local_do_shell(_PATH_LS); - else { - int len = strlen(_PATH_LS " ") + strlen(args) + 1; - char *buf = xmalloc(len); - - /* XXX: quoting - rip quoting code from ftp? */ - snprintf(buf, len, _PATH_LS " %s", args); - local_do_shell(buf); - xfree(buf); - } -} - -/* Strip one path (usually the pwd) from the start of another */ -static char * -path_strip(char *path, char *strip) -{ - size_t len; - - if (strip == NULL) - return (xstrdup(path)); - - len = strlen(strip); - if (strncmp(path, strip, len) == 0) { - if (strip[len - 1] != '/' && path[len] == '/') - len++; - return (xstrdup(path + len)); - } - - return (xstrdup(path)); -} - -static char * -path_append(char *p1, char *p2) -{ - char *ret; - size_t len = strlen(p1) + strlen(p2) + 2; - - ret = xmalloc(len); - strlcpy(ret, p1, len); - if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/') - strlcat(ret, "/", len); - strlcat(ret, p2, len); - - return(ret); -} - -static char * -make_absolute(char *p, char *pwd) -{ - char *abs_str; - - /* Derelativise */ - if (p && p[0] != '/') { - abs_str = path_append(pwd, p); - xfree(p); - return(abs_str); - } else - return(p); -} - -static int -infer_path(const char *p, char **ifp) -{ - char *cp; - - cp = strrchr(p, '/'); - if (cp == NULL) { - *ifp = xstrdup(p); - return(0); - } - - if (!cp[1]) { - error("Invalid path"); - return(-1); - } - - *ifp = xstrdup(cp + 1); - return(0); -} - -static int -parse_getput_flags(const char **cpp, int *pflag) -{ - const char *cp = *cpp; - - /* Check for flags */ - if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) { - switch (cp[1]) { - case 'p': - case 'P': - *pflag = 1; - break; - default: - error("Invalid flag -%c", cp[1]); - return(-1); - } - cp += 2; - *cpp = cp + strspn(cp, WHITESPACE); - } - - return(0); -} - -static int -parse_ls_flags(const char **cpp, int *lflag) -{ - const char *cp = *cpp; - - /* Defaults */ - *lflag = LS_NAME_SORT; - - /* Check for flags */ - if (cp++[0] == '-') { - for (; strchr(WHITESPACE, *cp) == NULL; cp++) { - switch (*cp) { - case 'l': - *lflag &= ~VIEW_FLAGS; - *lflag |= LS_LONG_VIEW; - break; - case '1': - *lflag &= ~VIEW_FLAGS; - *lflag |= LS_SHORT_VIEW; - break; - case 'n': - *lflag &= ~VIEW_FLAGS; - *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; - break; - case 'S': - *lflag &= ~SORT_FLAGS; - *lflag |= LS_SIZE_SORT; - break; - case 't': - *lflag &= ~SORT_FLAGS; - *lflag |= LS_TIME_SORT; - break; - case 'r': - *lflag |= LS_REVERSE_SORT; - break; - case 'f': - *lflag &= ~SORT_FLAGS; - break; - case 'a': - *lflag |= LS_SHOW_ALL; - break; - default: - error("Invalid flag -%c", *cp); - return(-1); - } - } - *cpp = cp + strspn(cp, WHITESPACE); - } - - return(0); -} - -static int -get_pathname(const char **cpp, char **path) -{ - const char *cp = *cpp, *end; - char quot; - u_int i, j; - - cp += strspn(cp, WHITESPACE); - if (!*cp) { - *cpp = cp; - *path = NULL; - return (0); - } - - *path = xmalloc(strlen(cp) + 1); - - /* Check for quoted filenames */ - if (*cp == '\"' || *cp == '\'') { - quot = *cp++; - - /* Search for terminating quote, unescape some chars */ - for (i = j = 0; i <= strlen(cp); i++) { - if (cp[i] == quot) { /* Found quote */ - i++; - (*path)[j] = '\0'; - break; - } - if (cp[i] == '\0') { /* End of string */ - error("Unterminated quote"); - goto fail; - } - if (cp[i] == '\\') { /* Escaped characters */ - i++; - if (cp[i] != '\'' && cp[i] != '\"' && - cp[i] != '\\') { - error("Bad escaped character '\\%c'", - cp[i]); - goto fail; - } - } - (*path)[j++] = cp[i]; - } - - if (j == 0) { - error("Empty quotes"); - goto fail; - } - *cpp = cp + i + strspn(cp + i, WHITESPACE); - } else { - /* Read to end of filename */ - end = strpbrk(cp, WHITESPACE); - if (end == NULL) - end = strchr(cp, '\0'); - *cpp = end + strspn(end, WHITESPACE); - - memcpy(*path, cp, end - cp); - (*path)[end - cp] = '\0'; - } - return (0); - - fail: - xfree(*path); - *path = NULL; - return (-1); -} - -static int -is_dir(char *path) -{ - struct stat sb; - - /* XXX: report errors? */ - if (stat(path, &sb) == -1) - return(0); - - return(S_ISDIR(sb.st_mode)); -} - -static int -is_reg(char *path) -{ - struct stat sb; - - if (stat(path, &sb) == -1) - fatal("stat %s: %s", path, strerror(errno)); - - return(S_ISREG(sb.st_mode)); -} - -static int -remote_is_dir(struct sftp_conn *conn, char *path) -{ - Attrib *a; - - /* XXX: report errors? */ - if ((a = do_stat(conn, path, 1)) == NULL) - return(0); - if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) - return(0); - return(S_ISDIR(a->perm)); -} - -static int -process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) -{ - char *abs_src = NULL; - char *abs_dst = NULL; - char *tmp; - glob_t g; - int err = 0; - int i; - - abs_src = xstrdup(src); - abs_src = make_absolute(abs_src, pwd); - - memset(&g, 0, sizeof(g)); - debug3("Looking up %s", abs_src); - if (remote_glob(conn, abs_src, 0, NULL, &g)) { - error("File \"%s\" not found.", abs_src); - err = -1; - goto out; - } - - /* If multiple matches, dst must be a directory or unspecified */ - if (g.gl_matchc > 1 && dst && !is_dir(dst)) { - error("Multiple files match, but \"%s\" is not a directory", - dst); - err = -1; - goto out; - } - - for (i = 0; g.gl_pathv[i] && !interrupted; i++) { - if (infer_path(g.gl_pathv[i], &tmp)) { - err = -1; - goto out; - } - - if (g.gl_matchc == 1 && dst) { - /* If directory specified, append filename */ - xfree(tmp); - if (is_dir(dst)) { - if (infer_path(g.gl_pathv[0], &tmp)) { - err = 1; - goto out; - } - abs_dst = path_append(dst, tmp); - xfree(tmp); - } else - abs_dst = xstrdup(dst); - } else if (dst) { - abs_dst = path_append(dst, tmp); - xfree(tmp); - } else - abs_dst = tmp; - - printf(gettext("Fetching %s to %s\n"), g.gl_pathv[i], abs_dst); - if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1) - err = -1; - xfree(abs_dst); - abs_dst = NULL; - } - -out: - xfree(abs_src); - globfree(&g); - return(err); -} - -static int -process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) -{ - char *tmp_dst = NULL; - char *abs_dst = NULL; - char *tmp; - glob_t g; - int err = 0; - int i; - - if (dst) { - tmp_dst = xstrdup(dst); - tmp_dst = make_absolute(tmp_dst, pwd); - } - - memset(&g, 0, sizeof(g)); - debug3("Looking up %s", src); - if (glob(src, GLOB_LIMIT, NULL, &g)) { - error("File \"%s\" not found.", src); - err = -1; - goto out; - } - - /* If multiple matches, dst may be directory or unspecified */ - if (g.gl_matchc > 1 && tmp_dst && !remote_is_dir(conn, tmp_dst)) { - error("Multiple files match, but \"%s\" is not a directory", - tmp_dst); - err = -1; - goto out; - } - - for (i = 0; g.gl_pathv[i] && !interrupted; i++) { - if (!is_reg(g.gl_pathv[i])) { - error("skipping non-regular file %s", - g.gl_pathv[i]); - continue; - } - if (infer_path(g.gl_pathv[i], &tmp)) { - err = -1; - goto out; - } - - if (g.gl_matchc == 1 && tmp_dst) { - /* If directory specified, append filename */ - if (remote_is_dir(conn, tmp_dst)) { - if (infer_path(g.gl_pathv[0], &tmp)) { - err = 1; - goto out; - } - abs_dst = path_append(tmp_dst, tmp); - xfree(tmp); - } else - abs_dst = xstrdup(tmp_dst); - - } else if (tmp_dst) { - abs_dst = path_append(tmp_dst, tmp); - xfree(tmp); - } else - abs_dst = make_absolute(tmp, pwd); - - printf(gettext("Uploading %s to %s\n"), g.gl_pathv[i], abs_dst); - if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1) - err = -1; - } - -out: - if (abs_dst) - xfree(abs_dst); - if (tmp_dst) - xfree(tmp_dst); - globfree(&g); - return(err); -} - -static int -sdirent_comp(const void *aa, const void *bb) -{ - SFTP_DIRENT *a = *(SFTP_DIRENT **)aa; - SFTP_DIRENT *b = *(SFTP_DIRENT **)bb; - int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1; - -#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1)) - if (sort_flag & LS_NAME_SORT) - return (rmul * strcmp(a->filename, b->filename)); - else if (sort_flag & LS_TIME_SORT) - return (rmul * NCMP(a->a.mtime, b->a.mtime)); - else if (sort_flag & LS_SIZE_SORT) - return (rmul * NCMP(a->a.size, b->a.size)); - - fatal("Unknown ls sort type"); - - /* NOTREACHED */ - return (0); -} - -/* sftp ls.1 replacement for directories */ -static int -do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) -{ - int n; - u_int c = 1, colspace = 0, columns = 1; - SFTP_DIRENT **d; - - if ((n = do_readdir(conn, path, &d)) != 0) - return (n); - - if (!(lflag & LS_SHORT_VIEW)) { - u_int m = 0, width = 80; - struct winsize ws; - char *tmp; - - /* Count entries for sort and find longest filename */ - for (n = 0; d[n] != NULL; n++) { - if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL)) - m = MAX(m, strlen(d[n]->filename)); - } - - /* Add any subpath that also needs to be counted */ - tmp = path_strip(path, strip_path); - m += strlen(tmp); - xfree(tmp); - - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) - width = ws.ws_col; - - columns = width / (m + 2); - columns = MAX(columns, 1); - colspace = width / columns; - colspace = MIN(colspace, width); - } - - if (lflag & SORT_FLAGS) { - for (n = 0; d[n] != NULL; n++) - ; /* count entries */ - sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT); - qsort(d, n, sizeof(*d), sdirent_comp); - } - - for (n = 0; d[n] != NULL && !interrupted; n++) { - char *tmp, *fname; - - if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL)) - continue; - - tmp = path_append(path, d[n]->filename); - fname = path_strip(tmp, strip_path); - xfree(tmp); - - if (lflag & LS_LONG_VIEW) { - if (lflag & LS_NUMERIC_VIEW) { - char *lname; - struct stat sb; - - memset(&sb, 0, sizeof(sb)); - attrib_to_stat(&d[n]->a, &sb); - lname = ls_file(fname, &sb, 1); - printf("%s\n", lname); - xfree(lname); - } else - printf("%s\n", d[n]->longname); - } else { - printf("%-*s", colspace, fname); - if (c >= columns) { - printf("\n"); - c = 1; - } else - c++; - } - - xfree(fname); - } - - if (!(lflag & LS_LONG_VIEW) && (c != 1)) - printf("\n"); - - free_sftp_dirents(d); - return (0); -} - -/* sftp ls.1 replacement which handles path globs */ -static int -do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, - int lflag) -{ - glob_t g; - u_int i, c = 1, colspace = 0, columns = 1; - Attrib *a = NULL; - - memset(&g, 0, sizeof(g)); - - if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE, - NULL, &g) || (g.gl_pathc && !g.gl_matchc)) { - if (g.gl_pathc) - globfree(&g); - error("Can't ls: \"%s\" not found", path); - return (-1); - } - - if (interrupted) - goto out; - - /* - * If the glob returns a single match and it is a directory, - * then just list its contents. - */ - if (g.gl_matchc == 1) { - if ((a = do_lstat(conn, g.gl_pathv[0], 1)) == NULL) { - globfree(&g); - return (-1); - } - if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && - S_ISDIR(a->perm)) { - int err; - - err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag); - globfree(&g); - return (err); - } - } - - if (!(lflag & LS_SHORT_VIEW)) { - u_int m = 0, width = 80; - struct winsize ws; - - /* Count entries for sort and find longest filename */ - for (i = 0; g.gl_pathv[i]; i++) - m = MAX(m, strlen(g.gl_pathv[i])); - - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) - width = ws.ws_col; - - columns = width / (m + 2); - columns = MAX(columns, 1); - colspace = width / columns; - } - - for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) { - char *fname; - - fname = path_strip(g.gl_pathv[i], strip_path); - - if (lflag & LS_LONG_VIEW) { - char *lname; - struct stat sb; - - /* - * XXX: this is slow - 1 roundtrip per path - * A solution to this is to fork glob() and - * build a sftp specific version which keeps the - * attribs (which currently get thrown away) - * that the server returns as well as the filenames. - */ - memset(&sb, 0, sizeof(sb)); - if (a == NULL) - a = do_lstat(conn, g.gl_pathv[i], 1); - if (a != NULL) - attrib_to_stat(a, &sb); - lname = ls_file(fname, &sb, 1); - printf("%s\n", lname); - xfree(lname); - } else { - printf("%-*s", colspace, fname); - if (c >= columns) { - printf("\n"); - c = 1; - } else - c++; - } - xfree(fname); - } - - if (!(lflag & LS_LONG_VIEW) && (c != 1)) - printf("\n"); - - out: - if (g.gl_pathc) - globfree(&g); - - return (0); -} - -static int -parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, - unsigned long *n_arg, char **path1, char **path2) -{ - const char *cmd, *cp = *cpp; - char *cp2; - int base = 0; - long l; - int i, cmdnum; - - /* Skip leading whitespace */ - cp = cp + strspn(cp, WHITESPACE); - - /* Ignore blank lines and lines which begin with comment '#' char */ - if (*cp == '\0' || *cp == '#') - return (0); - - /* Check for leading '-' (disable error processing) */ - *iflag = 0; - if (*cp == '-') { - *iflag = 1; - cp++; - } - - /* Figure out which command we have */ - for (i = 0; cmds[i].c; i++) { - int cmdlen = strlen(cmds[i].c); - - /* Check for command followed by whitespace */ - if (!strncasecmp(cp, cmds[i].c, cmdlen) && - strchr(WHITESPACE, cp[cmdlen])) { - cp += cmdlen; - cp = cp + strspn(cp, WHITESPACE); - break; - } - } - cmdnum = cmds[i].n; - cmd = cmds[i].c; - - /* Special case */ - if (*cp == '!') { - cp++; - cmdnum = I_SHELL; - } else if (cmdnum == -1) { - error("Invalid command."); - return (-1); - } - - /* Get arguments and parse flags */ - *lflag = *pflag = *n_arg = 0; - *path1 = *path2 = NULL; - switch (cmdnum) { - case I_GET: - case I_PUT: - if (parse_getput_flags(&cp, pflag)) - return(-1); - /* Get first pathname (mandatory) */ - if (get_pathname(&cp, path1)) - return(-1); - if (*path1 == NULL) { - error("You must specify at least one path after a " - "%s command.", cmd); - return(-1); - } - /* Try to get second pathname (optional) */ - if (get_pathname(&cp, path2)) - return(-1); - break; - case I_RENAME: - case I_SYMLINK: - if (get_pathname(&cp, path1)) - return(-1); - if (get_pathname(&cp, path2)) - return(-1); - if (!*path1 || !*path2) { - error("You must specify two paths after a %s " - "command.", cmd); - return(-1); - } - break; - case I_RM: - case I_MKDIR: - case I_RMDIR: - case I_CHDIR: - case I_LCHDIR: - case I_LMKDIR: - /* Get pathname (mandatory) */ - if (get_pathname(&cp, path1)) - return(-1); - if (*path1 == NULL) { - error("You must specify a path after a %s command.", - cmd); - return(-1); - } - break; - case I_LS: - if (parse_ls_flags(&cp, lflag)) - return(-1); - /* Path is optional */ - if (get_pathname(&cp, path1)) - return(-1); - break; - case I_LLS: - case I_SHELL: - /* Uses the rest of the line */ - break; - case I_LUMASK: - base = 8; - /* FALLTHRU */ - case I_CHMOD: - base = 8; - /* FALLTHRU */ - case I_CHOWN: - case I_CHGRP: - /* Get numeric arg (mandatory) */ - errno = 0; - l = strtol(cp, &cp2, base); - if (cp2 == cp || ((l == LONG_MIN || l == LONG_MAX) && - errno == ERANGE) || l < 0) { - error("You must supply a numeric argument " - "to the %s command.", cmd); - return(-1); - } - cp = cp2; - *n_arg = l; - if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp)) - break; - if (cmdnum == I_LUMASK || !strchr(WHITESPACE, *cp)) { - error("You must supply a numeric argument " - "to the %s command.", cmd); - return(-1); - } - cp += strspn(cp, WHITESPACE); - - /* Get pathname (mandatory) */ - if (get_pathname(&cp, path1)) - return(-1); - if (*path1 == NULL) { - error("You must specify a path after a %s command.", - cmd); - return(-1); - } - break; - case I_QUIT: - case I_PWD: - case I_LPWD: - case I_HELP: - case I_VERSION: - case I_PROGRESS: - break; - default: - fatal("Command not implemented"); - } - - *cpp = cp; - return(cmdnum); -} - -static int -parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, - int err_abort) -{ - char *path1, *path2, *tmp; - int pflag, lflag, iflag, cmdnum, i; - unsigned long n_arg; - Attrib a, *aa; - char path_buf[MAXPATHLEN]; - int err = 0; - glob_t g; - - path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, - &path1, &path2); - - if (iflag != 0) - err_abort = 0; - - memset(&g, 0, sizeof(g)); - - /* Perform command */ - switch (cmdnum) { - case 0: - /* Blank line */ - break; - case -1: - /* Unrecognized command */ - err = -1; - break; - case I_GET: - err = process_get(conn, path1, path2, *pwd, pflag); - break; - case I_PUT: - err = process_put(conn, path1, path2, *pwd, pflag); - break; - case I_RENAME: - path1 = make_absolute(path1, *pwd); - path2 = make_absolute(path2, *pwd); - err = do_rename(conn, path1, path2); - break; - case I_SYMLINK: - path2 = make_absolute(path2, *pwd); - err = do_symlink(conn, path1, path2); - break; - case I_RM: - path1 = make_absolute(path1, *pwd); - remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); - for (i = 0; g.gl_pathv[i] && !interrupted; i++) { - printf(gettext("Removing %s\n"), g.gl_pathv[i]); - err = do_rm(conn, g.gl_pathv[i]); - if (err != 0 && err_abort) - break; - } - break; - case I_MKDIR: - path1 = make_absolute(path1, *pwd); - attrib_clear(&a); - a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; - a.perm = 0777; - err = do_mkdir(conn, path1, &a); - break; - case I_RMDIR: - path1 = make_absolute(path1, *pwd); - err = do_rmdir(conn, path1); - break; - case I_CHDIR: - path1 = make_absolute(path1, *pwd); - if ((tmp = do_realpath(conn, path1)) == NULL) { - err = 1; - break; - } - if ((aa = do_stat(conn, tmp, 0)) == NULL) { - xfree(tmp); - err = 1; - break; - } - if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) { - error("Can't change directory: Can't check target"); - xfree(tmp); - err = 1; - break; - } - if (!S_ISDIR(aa->perm)) { - error("Can't change directory: \"%s\" is not " - "a directory", tmp); - xfree(tmp); - err = 1; - break; - } - xfree(*pwd); - *pwd = tmp; - break; - case I_LS: - if (!path1) { - do_globbed_ls(conn, *pwd, *pwd, lflag); - break; - } - - /* Strip pwd off beginning of non-absolute paths */ - tmp = NULL; - if (*path1 != '/') - tmp = *pwd; - - path1 = make_absolute(path1, *pwd); - err = do_globbed_ls(conn, path1, tmp, lflag); - break; - case I_LCHDIR: - if (chdir(path1) == -1) { - error("Couldn't change local directory to " - "\"%s\": %s", path1, strerror(errno)); - err = 1; - } - break; - case I_LMKDIR: - if (mkdir(path1, 0777) == -1) { - error("Couldn't create local directory " - "\"%s\": %s", path1, strerror(errno)); - err = 1; - } - break; - case I_LLS: - local_do_ls(cmd); - break; - case I_SHELL: - local_do_shell(cmd); - break; - case I_LUMASK: - umask(n_arg); - printf(gettext("Local umask: %03lo\n"), n_arg); - break; - case I_CHMOD: - path1 = make_absolute(path1, *pwd); - attrib_clear(&a); - a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; - a.perm = n_arg; - remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); - for (i = 0; g.gl_pathv[i] && !interrupted; i++) { - printf(gettext("Changing mode on %s\n"), g.gl_pathv[i]); - err = do_setstat(conn, g.gl_pathv[i], &a); - if (err != 0 && err_abort) - break; - } - break; - case I_CHOWN: - case I_CHGRP: - path1 = make_absolute(path1, *pwd); - remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); - for (i = 0; g.gl_pathv[i] && !interrupted; i++) { - if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { - if (err != 0 && err_abort) - break; - else - continue; - } - if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { - error("Can't get current ownership of " - "remote file \"%s\"", g.gl_pathv[i]); - if (err != 0 && err_abort) - break; - else - continue; - } - aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; - if (cmdnum == I_CHOWN) { - printf(gettext("Changing owner on %s\n"), g.gl_pathv[i]); - aa->uid = n_arg; - } else { - printf(gettext("Changing group on %s\n"), g.gl_pathv[i]); - aa->gid = n_arg; - } - err = do_setstat(conn, g.gl_pathv[i], aa); - if (err != 0 && err_abort) - break; - } - break; - case I_PWD: - printf(gettext("Remote working directory: %s\n"), *pwd); - break; - case I_LPWD: - if (!getcwd(path_buf, sizeof(path_buf))) { - error("Couldn't get local cwd: %s", strerror(errno)); - err = -1; - break; - } - printf(gettext("Local working directory: %s\n"), path_buf); - break; - case I_QUIT: - /* Processed below */ - break; - case I_HELP: - help(); - break; - case I_VERSION: - printf(gettext("SFTP protocol version %u\n"), sftp_proto_version(conn)); - break; - case I_PROGRESS: - showprogress = !showprogress; - if (showprogress) - printf("Progress meter enabled\n"); - else - printf("Progress meter disabled\n"); - break; - default: - fatal("%d is not implemented", cmdnum); - } - - if (g.gl_pathc) - globfree(&g); - if (path1) - xfree(path1); - if (path2) - xfree(path2); - - /* If an unignored error occurs in batch mode we should abort. */ - if (err_abort && err != 0) - return (-1); - else if (cmdnum == I_QUIT) - return (1); - - return (0); -} - -#ifdef USE_LIBEDIT -static char * -prompt(EditLine *el) -{ - return ("sftp> "); -} -#else -#ifdef USE_LIBTECLA -/* - * Disable default TAB completion for filenames, because it displays local - * files for every commands, which is not desirable. - */ -static -CPL_MATCH_FN(nomatch) -{ - return (0); -} -#endif /* USE_LIBTECLA */ -#endif /* USE_LIBEDIT */ - -int -interactive_loop(int fd_in, int fd_out, char *file1, char *file2) -{ - char *pwd; - char *dir = NULL; - char cmd[2048]; - struct sftp_conn *conn; - int err, interactive; - void *il = NULL; - -#ifdef USE_LIBEDIT - EditLine *el = NULL; - History *hl = NULL; - HistEvent hev; - - if (!batchmode && isatty(STDIN_FILENO)) { - if ((il = el = el_init(__progname, stdin, stdout, stderr)) == NULL) - fatal("Couldn't initialise editline"); - if ((hl = history_init()) == NULL) - fatal("Couldn't initialise editline history"); - history(hl, &hev, H_SETSIZE, 100); - el_set(el, EL_HIST, history, hl); - - el_set(el, EL_PROMPT, prompt); - el_set(el, EL_EDITOR, "emacs"); - el_set(el, EL_TERMINAL, NULL); - el_set(el, EL_SIGNAL, 1); - el_source(el, NULL); - } -#else -#ifdef USE_LIBTECLA - GetLine *gl = NULL; - - if (!batchmode && isatty(STDIN_FILENO)) { - if ((il = gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL) - fatal("Couldn't initialize GetLine"); - if (gl_customize_completion(gl, NULL, nomatch) != 0) { - (void) del_GetLine(gl); - fatal("Couldn't register completion function"); - } - } -#endif /* USE_LIBTECLA */ -#endif /* USE_LIBEDIT */ - - conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests); - if (conn == NULL) - fatal("Couldn't initialise connection to server"); - - pwd = do_realpath(conn, "."); - if (pwd == NULL) - fatal("Need cwd"); - - if (file1 != NULL) { - dir = xstrdup(file1); - dir = make_absolute(dir, pwd); - - if (remote_is_dir(conn, dir) && file2 == NULL) { - printf(gettext("Changing to: %s\n"), dir); - snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); - if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) { - xfree(dir); - xfree(pwd); - xfree(conn); - return (-1); - } - } else { - if (file2 == NULL) - snprintf(cmd, sizeof cmd, "get %s", dir); - else - snprintf(cmd, sizeof cmd, "get %s %s", dir, - file2); - - err = parse_dispatch_command(conn, cmd, &pwd, 1); - xfree(dir); - xfree(pwd); - xfree(conn); - return (err); - } - xfree(dir); - } - -#if defined(HAVE_SETVBUF) && !defined(BROKEN_SETVBUF) - setvbuf(stdout, NULL, _IOLBF, 0); - setvbuf(infile, NULL, _IOLBF, 0); -#else - setlinebuf(stdout); - setlinebuf(infile); -#endif - - interactive = !batchmode && isatty(STDIN_FILENO); - err = 0; - for (;;) { - char *cp; - - signal(SIGINT, SIG_IGN); - - if (il == NULL) { - if (interactive) - printf("sftp> "); - if (fgets(cmd, sizeof(cmd), infile) == NULL) { - if (interactive) - printf("\n"); - break; - } - if (!interactive) { /* Echo command */ - printf("sftp> %s", cmd); - if (strlen(cmd) > 0 && - cmd[strlen(cmd) - 1] != '\n') - printf("\n"); - } - } -#ifdef USE_LIBEDIT - else { - const char *line; - int count = 0; - - if ((line = el_gets(el, &count)) == NULL || count <= 0) { - printf("\n"); - break; - } - history(hl, &hev, H_ENTER, line); - if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) { - fprintf(stderr, gettext("Error: input line too long\n")); - continue; - } - } -#else -#ifdef USE_LIBTECLA - else { - const char *line; - - line = gl_get_line(gl, "sftp> ", NULL, -1); - if (line != NULL) { - if (strlcpy(cmd, line, sizeof(cmd)) >= - sizeof(cmd)) { - fprintf(stderr, gettext( - "Error: input line too long\n")); - continue; - } - } else { - GlReturnStatus rtn; - - rtn = gl_return_status(gl); - if (rtn == GLR_SIGNAL) { - gl_abandon_line(gl); - continue; - } else if (rtn == GLR_ERROR) { - fprintf(stderr, gettext( - "Error reading terminal: %s/\n"), - gl_error_message(gl, NULL, 0)); - } - break; - } - } -#endif /* USE_LIBTECLA */ -#endif /* USE_LIBEDIT */ - - cp = strrchr(cmd, '\n'); - if (cp) - *cp = '\0'; - - /* Handle user interrupts gracefully during commands */ - interrupted = 0; - signal(SIGINT, cmd_interrupt); - - err = parse_dispatch_command(conn, cmd, &pwd, batchmode); - if (err != 0) - break; - } - xfree(pwd); - xfree(conn); - -#ifdef USE_LIBEDIT - if (el != NULL) - el_end(el); -#else -#ifdef USE_LIBTECLA - if (gl != NULL) - (void) del_GetLine(gl); -#endif /* USE_LIBTECLA */ -#endif /* USE_LIBEDIT */ - - /* err == 1 signifies normal "quit" exit */ - return (err >= 0 ? 0 : -1); -} - -static void -connect_to_server(char *path, char **args, int *in, int *out) -{ - int c_in, c_out; - - int inout[2]; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1) - fatal("socketpair: %s", strerror(errno)); - *in = *out = inout[0]; - c_in = c_out = inout[1]; - - if ((sshpid = fork()) == -1) - fatal("fork: %s", strerror(errno)); - else if (sshpid == 0) { - if ((dup2(c_in, STDIN_FILENO) == -1) || - (dup2(c_out, STDOUT_FILENO) == -1)) { - fprintf(stderr, "dup2: %s\n", strerror(errno)); - _exit(1); - } - close(*in); - close(*out); - close(c_in); - close(c_out); - - /* - * The underlying ssh is in the same process group, so we must - * ignore SIGINT if we want to gracefully abort commands, - * otherwise the signal will make it to the ssh process and - * kill it too - */ - signal(SIGINT, SIG_IGN); - execvp(path, args); - fprintf(stderr, "exec: %s: %s\n", path, strerror(errno)); - _exit(1); - } - - signal(SIGTERM, killchild); - signal(SIGINT, killchild); - signal(SIGHUP, killchild); - close(c_in); - close(c_out); -} - -static void -usage(void) -{ - fprintf(stderr, - gettext("Usage: %s [-1Cv] [-b batchfile] [-B buffer_size]\n" - " [-F ssh_config] [-o ssh_option] [-P sftp_server_path]\n" - " [-R num_requests] [-s subsystem | sftp_server]\n" - " [-S program] [user@]host[:dir[/] | :file [file]]\n"), - __progname, __progname, __progname, __progname); - exit(1); -} - -int -main(int argc, char **argv) -{ - int in, out, ch, err; - char *host, *userhost, *cp, *file2 = NULL; - int debug_level = 0, sshver = 2; - char *file1 = NULL, *sftp_server = NULL; - char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL; - LogLevel ll = SYSLOG_LEVEL_INFO; - arglist args; - extern int optind; - extern char *optarg; - - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - - __progname = get_progname(argv[0]); - - (void) g11n_setlocale(LC_ALL, ""); - - memset(&args, '\0', sizeof(args)); - args.list = NULL; - addargs(&args, "%s", ssh_program); - addargs(&args, "-oForwardX11 no"); - addargs(&args, "-oForwardAgent no"); - addargs(&args, "-oClearAllForwardings yes"); - - ll = SYSLOG_LEVEL_INFO; - infile = stdin; - - while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) { - switch (ch) { - case 'C': - addargs(&args, "-C"); - break; - case 'v': - if (debug_level < 3) { - addargs(&args, "-v"); - ll = SYSLOG_LEVEL_DEBUG1 + debug_level; - } - debug_level++; - break; - case 'F': - case 'o': - addargs(&args, "-%c%s", ch, optarg); - break; - case '1': - sshver = 1; - if (sftp_server == NULL) - sftp_server = _PATH_SFTP_SERVER; - break; - case 's': - sftp_server = optarg; - break; - case 'S': - ssh_program = optarg; - replacearg(&args, 0, "%s", ssh_program); - break; - case 'b': - if (batchmode) - fatal("Batch file already specified."); - - /* Allow "-" as stdin */ - if (strcmp(optarg, "-") != 0 && - (infile = fopen(optarg, "r")) == NULL) - fatal("%s (%s).", strerror(errno), optarg); - showprogress = 0; - batchmode = 1; - addargs(&args, "-obatchmode yes"); - break; - case 'P': - sftp_direct = optarg; - break; - case 'B': - copy_buffer_len = strtol(optarg, &cp, 10); - if (copy_buffer_len == 0 || *cp != '\0') - fatal("Invalid buffer size \"%s\"", optarg); - break; - case 'R': - num_requests = strtol(optarg, &cp, 10); - if (num_requests == 0 || *cp != '\0') - fatal("Invalid number of requests \"%s\"", - optarg); - break; - case 'h': - default: - usage(); - } - } - - if (!isatty(STDERR_FILENO)) - showprogress = 0; - - log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1); - - if (sftp_direct == NULL) { - if (optind == argc || argc > (optind + 2)) - usage(); - - userhost = xstrdup(argv[optind]); - file2 = argv[optind+1]; - - if ((host = strrchr(userhost, '@')) == NULL) - host = userhost; - else { - *host++ = '\0'; - if (!userhost[0]) { - fprintf(stderr, gettext("Missing username\n")); - usage(); - } - addargs(&args, "-l%s", userhost); - } - - if ((cp = colon(host)) != NULL) { - *cp++ = '\0'; - file1 = cp; - } - - host = cleanhostname(host); - if (!*host) { - fprintf(stderr, gettext("Missing hostname\n")); - usage(); - } - - addargs(&args, "-oProtocol %d", sshver); - - /* no subsystem if the server-spec contains a '/' */ - if (sftp_server == NULL || strchr(sftp_server, '/') == NULL) - addargs(&args, "-s"); - - addargs(&args, "%s", host); - addargs(&args, "%s", (sftp_server != NULL ? - sftp_server : "sftp")); - - if (!batchmode) - fprintf(stderr, gettext("Connecting to %s...\n"), host); - connect_to_server(ssh_program, args.list, &in, &out); - } else { - args.list = NULL; - addargs(&args, "sftp-server"); - - if (!batchmode) - fprintf(stderr, gettext("Attaching to %s...\n"), sftp_direct); - connect_to_server(sftp_direct, args.list, &in, &out); - } - freeargs(&args); - - err = interactive_loop(in, out, file1, file2); - - shutdown(in, SHUT_RDWR); - shutdown(out, SHUT_RDWR); - - close(in); - close(out); - if (batchmode) - fclose(infile); - - while (waitpid(sshpid, NULL, 0) == -1) - if (errno != EINTR) - fatal("Couldn't wait for ssh process: %s", - strerror(errno)); - - return (err == 0 ? 0 : 1); -} diff --git a/usr/src/cmd/ssh/ssh-add/Makefile b/usr/src/cmd/ssh/ssh-add/Makefile deleted file mode 100644 index 3235839e06..0000000000 --- a/usr/src/cmd/ssh/ssh-add/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/ssh-add/Makefile - -PROG= ssh-add - -OBJS = \ - ssh-add.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -install: all $(ROOTPROG) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/ssh-add/ssh-add.c b/usr/src/cmd/ssh/ssh-add/ssh-add.c deleted file mode 100644 index cfa1ce320e..0000000000 --- a/usr/src/cmd/ssh/ssh-add/ssh-add.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: ssh-add.c,v 1.63 2002/09/19 15:51:23 markus Exp $"); - -#include <openssl/evp.h> - -#include "ssh.h" -#include "rsa.h" -#include "log.h" -#include "xmalloc.h" -#include "key.h" -#include "authfd.h" -#include "authfile.h" -#include "pathnames.h" -#include "readpass.h" -#include "misc.h" - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - -/* argv0 */ -extern char *__progname; - -/* Default files to add */ -static char *default_files[] = { - _PATH_SSH_CLIENT_ID_RSA, - _PATH_SSH_CLIENT_ID_DSA, - _PATH_SSH_CLIENT_IDENTITY, - NULL -}; - -/* Default lifetime (0 == forever) */ -static int lifetime = 0; - -/* we keep a cache of one passphrases */ -static char *pass = NULL; -static void -clear_pass(void) -{ - if (pass) { - memset(pass, 0, strlen(pass)); - xfree(pass); - pass = NULL; - } -} - -static int -delete_file(AuthenticationConnection *ac, const char *filename) -{ - Key *public; - char *comment = NULL; - int ret = -1; - - public = key_load_public(filename, &comment); - if (public == NULL) { - printf(gettext("Bad key file %s\n"), filename); - return -1; - } - if (ssh_remove_identity(ac, public)) { - fprintf(stderr, gettext("Identity removed: %s (%s)\n"), - filename, comment); - ret = 0; - } else - fprintf(stderr, gettext("Could not remove identity: %s\n"), - filename); - - key_free(public); - xfree(comment); - - return ret; -} - -/* Send a request to remove all identities. */ -static int -delete_all(AuthenticationConnection *ac) -{ - int ret = -1; - - if (ssh_remove_all_identities(ac, 1)) - ret = 0; - /* ignore error-code for ssh2 */ - ssh_remove_all_identities(ac, 2); - - if (ret == 0) - fprintf(stderr, gettext("All identities removed.\n")); - else - fprintf(stderr, gettext("Failed to remove all identities.\n")); - - return ret; -} - -static int -add_file(AuthenticationConnection *ac, const char *filename) -{ - struct stat st; - Key *private; - char *comment = NULL; - char msg[1024]; - int ret = -1; - - if (stat(filename, &st) < 0) { - perror(filename); - return -1; - } - /* At first, try empty passphrase */ - private = key_load_private(filename, "", &comment); - if (comment == NULL) - comment = xstrdup(filename); - /* try last */ - if (private == NULL && pass != NULL) - private = key_load_private(filename, pass, NULL); - if (private == NULL) { - /* clear passphrase since it did not work */ - clear_pass(); - snprintf(msg, sizeof msg, - gettext("Enter passphrase for %.200s: "), comment); - for (;;) { - pass = read_passphrase(msg, RP_ALLOW_STDIN); - if (strcmp(pass, "") == 0) { - clear_pass(); - xfree(comment); - return -1; - } - private = key_load_private(filename, pass, &comment); - if (private != NULL) - break; - clear_pass(); - strlcpy(msg, gettext("Bad passphrase, try again: "), - sizeof msg); - } - } - - if (ssh_add_identity_constrained(ac, private, comment, lifetime)) { - fprintf(stderr, gettext("Identity added: %s (%s)\n"), - filename, comment); - ret = 0; - if (lifetime != 0) - fprintf(stderr, - gettext("Lifetime set to %d seconds\n"), lifetime); - } else if (ssh_add_identity(ac, private, comment)) { - fprintf(stderr, gettext("Identity added: %s (%s)\n"), - filename, comment); - ret = 0; - } else { - fprintf(stderr, gettext("Could not add identity: %s\n"), - filename); - } - - xfree(comment); - key_free(private); - - return ret; -} - -static int -list_identities(AuthenticationConnection *ac, int do_fp) -{ - Key *key; - char *comment, *fp; - int had_identities = 0; - int version; - - 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 (do_fp) { - fp = key_fingerprint(key, SSH_FP_MD5, - SSH_FP_HEX); - printf("%d %s %s (%s)\n", - key_size(key), fp, comment, key_type(key)); - xfree(fp); - } else { - if (!key_write(key, stdout)) - fprintf(stderr, - gettext("key_write failed")); - fprintf(stdout, " %s\n", comment); - } - key_free(key); - xfree(comment); - } - } - if (!had_identities) { - printf(gettext("The agent has no identities.\n")); - return -1; - } - return 0; -} - -static int -lock_agent(AuthenticationConnection *ac, int lock) -{ - char prompt[100], *p1, *p2; - int passok = 1, ret = -1; - - strlcpy(prompt, "Enter lock password: ", sizeof(prompt)); - p1 = read_passphrase(prompt, RP_ALLOW_STDIN); - if (lock) { - strlcpy(prompt, "Again: ", sizeof prompt); - p2 = read_passphrase(prompt, RP_ALLOW_STDIN); - if (strcmp(p1, p2) != 0) { - fprintf(stderr, gettext("Passwords do not match.\n")); - passok = 0; - } - memset(p2, 0, strlen(p2)); - xfree(p2); - } - if (passok && ssh_lock_agent(ac, lock, p1)) { - if (lock) - fprintf(stderr, gettext("Agent locked.\n")); - else - fprintf(stderr, gettext("Agent unlocked.\n")); - ret = 0; - } else { - if (lock) - fprintf(stderr, gettext("Failed to lock agent.\n")); - else - fprintf(stderr, gettext("Failed to unlock agent.\n")); - } - memset(p1, 0, strlen(p1)); - xfree(p1); - return (ret); -} - -static int -do_file(AuthenticationConnection *ac, int deleting, char *file) -{ - if (deleting) { - if (delete_file(ac, file) == -1) - return -1; - } else { - if (add_file(ac, file) == -1) - return -1; - } - return 0; -} - -static void -usage(void) -{ - fprintf(stderr, - gettext( "Usage: %s [options]\n" - "Options:\n" - " -l List fingerprints of all identities.\n" - " -L List public key parameters of all identities.\n" - " -d Delete identity.\n" - " -D Delete all identities.\n" - " -x Lock agent.\n" - " -X Unlock agent.\n" - " -t life Set lifetime (seconds) when adding identities.\n" - ), __progname); -} - -int -main(int argc, char **argv) -{ - extern char *optarg; - extern int optind; - AuthenticationConnection *ac = NULL; - int i, ch, deleting = 0, ret = 0; - - __progname = get_progname(argv[0]); - - (void) g11n_setlocale(LC_ALL, ""); - - init_rng(); - seed_rng(); - - SSLeay_add_all_algorithms(); - - /* At first, get a connection to the authentication agent. */ - ac = ssh_get_authentication_connection(); - if (ac == NULL) { - fprintf(stderr, gettext("Could not open a connection " - "to your authentication agent.\n")); - exit(2); - } - while ((ch = getopt(argc, argv, "lLdDxXe:s:t:")) != -1) { - switch (ch) { - case 'l': - case 'L': - if (list_identities(ac, ch == 'l' ? 1 : 0) == -1) - ret = 1; - goto done; - break; - case 'x': - case 'X': - if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1) - ret = 1; - goto done; - break; - case 'd': - deleting = 1; - break; - case 'D': - if (delete_all(ac) == -1) - ret = 1; - goto done; - break; - case 't': - if ((lifetime = convtime(optarg)) == -1) { - fprintf(stderr, gettext("Invalid lifetime\n")); - ret = 1; - goto done; - } - break; - default: - usage(); - ret = 1; - goto done; - } - } - argc -= optind; - argv += optind; - if (argc == 0) { - char buf[MAXPATHLEN]; - struct passwd *pw; - struct stat st; - int count = 0; - - if ((pw = getpwuid(getuid())) == NULL) { - fprintf(stderr, gettext("No user found with uid %u\n"), - (u_int)getuid()); - ret = 1; - goto done; - } - - for(i = 0; default_files[i]; i++) { - snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir, - default_files[i]); - if (stat(buf, &st) < 0) - continue; - if (do_file(ac, deleting, buf) == -1) - ret = 1; - else - count++; - } - if (count == 0) - ret = 1; - } else { - for(i = 0; i < argc; i++) { - if (do_file(ac, deleting, argv[i]) == -1) - ret = 1; - } - } - clear_pass(); - -done: - ssh_close_authentication_connection(ac); - return ret; -} diff --git a/usr/src/cmd/ssh/ssh-agent/Makefile b/usr/src/cmd/ssh/ssh-agent/Makefile deleted file mode 100644 index ab2e1eb49d..0000000000 --- a/usr/src/cmd/ssh/ssh-agent/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/ssh-agent/Makefile - -PROG= ssh-agent - -OBJS = \ - ssh-agent.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -install: all $(ROOTPROG) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/ssh-agent/ssh-agent.c b/usr/src/cmd/ssh/ssh-agent/ssh-agent.c deleted file mode 100644 index 1ac5f4030d..0000000000 --- a/usr/src/cmd/ssh/ssh-agent/ssh-agent.c +++ /dev/null @@ -1,1192 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - * - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -#include "sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.159 2008/06/28 14:05:15 djm Exp $"); - -#ifdef HAVE_SOLARIS_PRIVILEGE -#include <priv.h> -#endif /* HAVE_SOLARIS_PRIVILEGE */ - -#include <openssl/evp.h> -#include <openssl/md5.h> - -#include "ssh.h" -#include "rsa.h" -#include "buffer.h" -#include "bufaux.h" -#include "xmalloc.h" -#include "key.h" -#include "authfd.h" -#include "compat.h" -#include "log.h" -#include "readpass.h" -#include "misc.h" - -typedef enum { - AUTH_UNUSED, - AUTH_SOCKET, - AUTH_CONNECTION -} sock_type; - -typedef struct { - int fd; - sock_type type; - Buffer input; - Buffer output; - Buffer request; -} SocketEntry; - -u_int sockets_alloc = 0; -SocketEntry *sockets = NULL; - -typedef struct identity { - TAILQ_ENTRY(identity) next; - Key *key; - char *comment; - u_int death; - u_int confirm; -} Identity; - -typedef struct { - int nentries; - TAILQ_HEAD(idqueue, identity) idlist; -} Idtab; - -/* private key table, one per protocol version */ -Idtab idtable[3]; - -int max_fd = 0; - -/* pid of shell == parent of agent */ -pid_t parent_pid = -1; -u_int parent_alive_interval = 0; - -/* pathname and directory for AUTH_SOCKET */ -char socket_name[MAXPATHLEN]; -char socket_dir[MAXPATHLEN]; - -/* locking */ -int locked = 0; -char *lock_passwd = NULL; - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - -/* Default lifetime (0 == forever) */ -static int lifetime = 0; - -static void -close_socket(SocketEntry *e) -{ - close(e->fd); - e->fd = -1; - e->type = AUTH_UNUSED; - buffer_free(&e->input); - buffer_free(&e->output); - buffer_free(&e->request); -} - -static void -idtab_init(void) -{ - int i; - - for (i = 0; i <=2; i++) { - TAILQ_INIT(&idtable[i].idlist); - idtable[i].nentries = 0; - } -} - -/* return private key table for requested protocol version */ -static Idtab * -idtab_lookup(int version) -{ - if (version < 1 || version > 2) - fatal("internal error, bad protocol version %d", version); - return &idtable[version]; -} - -static void -free_identity(Identity *id) -{ - key_free(id->key); - xfree(id->comment); - xfree(id); -} - -/* return matching private key for given public key */ -static Identity * -lookup_identity(Key *key, int version) -{ - Identity *id; - - Idtab *tab = idtab_lookup(version); - TAILQ_FOREACH(id, &tab->idlist, next) { - if (key_equal(key, id->key)) - return (id); - } - return (NULL); -} - -/* Check confirmation of keysign request */ -static int -confirm_key(Identity *id) -{ - char *p; - int ret = -1; - - p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); - if (ask_permission( - gettext("Allow use of key %s?\nKey fingerprint %s."), - id->comment, p)) - ret = 0; - xfree(p); - - return (ret); -} - -/* send list of supported public keys to 'client' */ -static void -process_request_identities(SocketEntry *e, int version) -{ - Idtab *tab = idtab_lookup(version); - Identity *id; - Buffer msg; - - buffer_init(&msg); - buffer_put_char(&msg, (version == 1) ? - SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); - buffer_put_int(&msg, tab->nentries); - TAILQ_FOREACH(id, &tab->idlist, next) { - if (id->key->type == KEY_RSA1) { - 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 { - u_char *blob; - u_int blen; - key_to_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 */ -static void -process_authentication_challenge1(SocketEntry *e) -{ - u_char buf[32], mdbuf[16], session_id[16]; - u_int response_type; - BIGNUM *challenge; - Identity *id; - int i, len; - Buffer msg; - MD5_CTX md; - Key *key; - - buffer_init(&msg); - key = key_new(KEY_RSA1); - if ((challenge = BN_new()) == NULL) - fatal("process_authentication_challenge1: BN_new failed"); - - (void) buffer_get_int(&e->request); /* ignored */ - buffer_get_bignum(&e->request, key->rsa->e); - buffer_get_bignum(&e->request, key->rsa->n); - buffer_get_bignum(&e->request, challenge); - - /* Only protocol 1.1 is supported */ - if (buffer_len(&e->request) == 0) - goto failure; - buffer_get(&e->request, session_id, 16); - response_type = buffer_get_int(&e->request); - if (response_type != 1) - goto failure; - - id = lookup_identity(key, 1); - if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { - Key *private = id->key; - /* Decrypt the challenge using the private key. */ - if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) - goto failure; - - /* 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; - } - 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 */ -static void -process_sign_request2(SocketEntry *e) -{ - u_char *blob, *data, *signature = NULL; - u_int blen, dlen, slen = 0; - extern uint32_t datafellows; - int odatafellows; - int ok = -1, flags; - Buffer msg; - Key *key; - - datafellows = 0; - - blob = buffer_get_string(&e->request, &blen); - data = buffer_get_string(&e->request, &dlen); - - flags = buffer_get_int(&e->request); - odatafellows = datafellows; - if (flags & SSH_AGENT_OLD_SIGNATURE) - datafellows = SSH_BUG_SIGBLOB; - - key = key_from_blob(blob, blen); - if (key != NULL) { - Identity *id = lookup_identity(key, 2); - if (id != NULL && (!id->confirm || confirm_key(id) == 0)) - ok = key_sign(id->key, &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_free(&msg); - xfree(data); - xfree(blob); - if (signature != NULL) - xfree(signature); - datafellows = odatafellows; -} - -/* shared */ -static void -process_remove_identity(SocketEntry *e, int version) -{ - u_int blen, bits; - int success = 0; - Key *key = NULL; - u_char *blob; - - switch (version) { - case 1: - key = key_new(KEY_RSA1); - bits = buffer_get_int(&e->request); - buffer_get_bignum(&e->request, key->rsa->e); - buffer_get_bignum(&e->request, key->rsa->n); - - if (bits != key_size(key)) - log("Warning: identity keysize mismatch: actual %u, announced %u", - key_size(key), bits); - break; - case 2: - blob = buffer_get_string(&e->request, &blen); - key = key_from_blob(blob, blen); - xfree(blob); - break; - } - if (key != NULL) { - Identity *id = lookup_identity(key, version); - if (id != 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 move - * all the entries between the empty slot and the end - * of the array. - */ - Idtab *tab = idtab_lookup(version); - if (tab->nentries < 1) - fatal("process_remove_identity: " - "internal error: tab->nentries %d", - tab->nentries); - TAILQ_REMOVE(&tab->idlist, id, next); - free_identity(id); - tab->nentries--; - success = 1; - } - key_free(key); - } - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); -} - -static void -process_remove_all_identities(SocketEntry *e, int version) -{ - Idtab *tab = idtab_lookup(version); - Identity *id; - - /* Loop over all identities and clear the keys. */ - for (id = TAILQ_FIRST(&tab->idlist); id; - id = TAILQ_FIRST(&tab->idlist)) { - TAILQ_REMOVE(&tab->idlist, id, next); - free_identity(id); - } - - /* Mark that there are no identities. */ - tab->nentries = 0; - - /* Send success. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); -} - -/* removes expired keys and returns number of seconds until the next expiry */ -static u_int -reaper(void) -{ - u_int deadline = 0, now = time(NULL); - Identity *id, *nxt; - int version; - Idtab *tab; - - for (version = 1; version < 3; version++) { - tab = idtab_lookup(version); - for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { - nxt = TAILQ_NEXT(id, next); - if (id->death == 0) - continue; - if (now >= id->death) { - debug("expiring key '%s'", id->comment); - TAILQ_REMOVE(&tab->idlist, id, next); - free_identity(id); - tab->nentries--; - } else - deadline = (deadline == 0) ? id->death : - MIN(deadline, id->death); - } - } - if (deadline == 0 || deadline <= now) - return 0; - else - return (deadline - now); -} - -static void -process_add_identity(SocketEntry *e, int version) -{ - Idtab *tab = idtab_lookup(version); - Identity *id; - int type, success = 0, death = 0, confirm = 0; - char *type_name, *comment; - Key *k = NULL; - - switch (version) { - case 1: - k = key_new_private(KEY_RSA1); - (void) buffer_get_int(&e->request); /* ignored */ - buffer_get_bignum(&e->request, k->rsa->n); - buffer_get_bignum(&e->request, k->rsa->e); - buffer_get_bignum(&e->request, k->rsa->d); - buffer_get_bignum(&e->request, k->rsa->iqmp); - - /* SSH and SSL have p and q swapped */ - buffer_get_bignum(&e->request, k->rsa->q); /* p */ - buffer_get_bignum(&e->request, k->rsa->p); /* q */ - - /* Generate additional parameters */ - rsa_generate_additional_parameters(k->rsa); - break; - case 2: - type_name = buffer_get_string(&e->request, NULL); - type = key_type_from_name(type_name); - xfree(type_name); - switch (type) { - case KEY_DSA: - k = key_new_private(type); - buffer_get_bignum2(&e->request, k->dsa->p); - buffer_get_bignum2(&e->request, k->dsa->q); - buffer_get_bignum2(&e->request, k->dsa->g); - buffer_get_bignum2(&e->request, k->dsa->pub_key); - buffer_get_bignum2(&e->request, k->dsa->priv_key); - break; - case KEY_RSA: - k = key_new_private(type); - buffer_get_bignum2(&e->request, k->rsa->n); - buffer_get_bignum2(&e->request, k->rsa->e); - buffer_get_bignum2(&e->request, k->rsa->d); - buffer_get_bignum2(&e->request, k->rsa->iqmp); - buffer_get_bignum2(&e->request, k->rsa->p); - buffer_get_bignum2(&e->request, k->rsa->q); - - /* Generate additional parameters */ - rsa_generate_additional_parameters(k->rsa); - break; - default: - buffer_clear(&e->request); - goto send; - } - break; - } - /* enable blinding */ - switch (k->type) { - case KEY_RSA: - case KEY_RSA1: - if (RSA_blinding_on(k->rsa, NULL) != 1) { - error("process_add_identity: RSA_blinding_on failed"); - key_free(k); - goto send; - } - break; - } - comment = buffer_get_string(&e->request, NULL); - if (k == NULL) { - xfree(comment); - goto send; - } - while (buffer_len(&e->request)) { - switch ((type = buffer_get_char(&e->request))) { - case SSH_AGENT_CONSTRAIN_LIFETIME: - death = time(NULL) + buffer_get_int(&e->request); - break; - case SSH_AGENT_CONSTRAIN_CONFIRM: - confirm = 1; - break; - default: - error("process_add_identity: " - "Unknown constraint type %d", type); - xfree(comment); - key_free(k); - goto send; - } - } - success = 1; - if (lifetime && !death) - death = time(NULL) + lifetime; - if ((id = lookup_identity(k, version)) == NULL) { - id = xmalloc(sizeof(Identity)); - id->key = k; - TAILQ_INSERT_TAIL(&tab->idlist, id, next); - /* Increment the number of identities. */ - tab->nentries++; - } else { - key_free(k); - xfree(id->comment); - } - id->comment = comment; - id->death = death; - id->confirm = confirm; -send: - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); -} - -/* XXX todo: encrypt sensitive data with passphrase */ -static void -process_lock_agent(SocketEntry *e, int lock) -{ - int success = 0; - char *passwd; - - passwd = buffer_get_string(&e->request, NULL); - if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { - locked = 0; - memset(lock_passwd, 0, strlen(lock_passwd)); - xfree(lock_passwd); - lock_passwd = NULL; - success = 1; - } else if (!locked && lock) { - locked = 1; - lock_passwd = xstrdup(passwd); - success = 1; - } - memset(passwd, 0, strlen(passwd)); - xfree(passwd); - - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); -} - -static void -no_identities(SocketEntry *e, u_int type) -{ - Buffer msg; - - buffer_init(&msg); - buffer_put_char(&msg, - (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? - SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); - buffer_put_int(&msg, 0); - buffer_put_int(&e->output, buffer_len(&msg)); - buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); - buffer_free(&msg); -} - -/* dispatch incoming messages */ - -static void -process_message(SocketEntry *e) -{ - u_int msg_len, type; - u_char *cp; - - if (buffer_len(&e->input) < 5) - return; /* Incomplete message. */ - cp = buffer_ptr(&e->input); - msg_len = get_u32(cp); - if (msg_len > 256 * 1024) { - close_socket(e); - return; - } - if (buffer_len(&e->input) < msg_len + 4) - return; - - /* move the current input to e->request */ - buffer_consume(&e->input, 4); - buffer_clear(&e->request); - buffer_append(&e->request, buffer_ptr(&e->input), msg_len); - buffer_consume(&e->input, msg_len); - type = buffer_get_char(&e->request); - - /* check wheter agent is locked */ - if (locked && type != SSH_AGENTC_UNLOCK) { - buffer_clear(&e->request); - switch (type) { - case SSH_AGENTC_REQUEST_RSA_IDENTITIES: - case SSH2_AGENTC_REQUEST_IDENTITIES: - /* send empty lists */ - no_identities(e, type); - break; - default: - /* send a fail message for all other request types */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_FAILURE); - } - return; - } - - debug("type %d", type); - switch (type) { - case SSH_AGENTC_LOCK: - case SSH_AGENTC_UNLOCK: - process_lock_agent(e, type == SSH_AGENTC_LOCK); - break; - /* ssh1 */ - case SSH_AGENTC_RSA_CHALLENGE: - process_authentication_challenge1(e); - break; - case SSH_AGENTC_REQUEST_RSA_IDENTITIES: - process_request_identities(e, 1); - break; - case SSH_AGENTC_ADD_RSA_IDENTITY: - case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED: - process_add_identity(e, 1); - break; - case SSH_AGENTC_REMOVE_RSA_IDENTITY: - process_remove_identity(e, 1); - break; - case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: - 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: - case SSH2_AGENTC_ADD_ID_CONSTRAINED: - 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. */ - error("Unknown message %d", type); - buffer_clear(&e->request); - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_FAILURE); - break; - } -} - -static void -new_socket(sock_type type, int fd) -{ - u_int i, old_alloc, new_alloc; - - set_nonblock(fd); - - if (fd > max_fd) - max_fd = fd; - - for (i = 0; i < sockets_alloc; i++) - if (sockets[i].type == AUTH_UNUSED) { - sockets[i].fd = fd; - buffer_init(&sockets[i].input); - buffer_init(&sockets[i].output); - buffer_init(&sockets[i].request); - sockets[i].type = type; - return; - } - old_alloc = sockets_alloc; - new_alloc = sockets_alloc + 10; - sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0])); - for (i = old_alloc; i < new_alloc; i++) - sockets[i].type = AUTH_UNUSED; - sockets_alloc = new_alloc; - sockets[old_alloc].fd = fd; - buffer_init(&sockets[old_alloc].input); - buffer_init(&sockets[old_alloc].output); - buffer_init(&sockets[old_alloc].request); - sockets[old_alloc].type = type; -} - -static int -prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, - struct timeval **tvpp) -{ - u_int i, sz, deadline; - int n = 0; - static struct timeval tv; - - for (i = 0; i < sockets_alloc; i++) { - switch (sockets[i].type) { - case AUTH_SOCKET: - case AUTH_CONNECTION: - n = MAX(n, sockets[i].fd); - break; - case AUTH_UNUSED: - break; - default: - fatal("Unknown socket type %d", sockets[i].type); - break; - } - } - - sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); - if (*fdrp == NULL || sz > *nallocp) { - if (*fdrp) - xfree(*fdrp); - if (*fdwp) - xfree(*fdwp); - *fdrp = xmalloc(sz); - *fdwp = xmalloc(sz); - *nallocp = sz; - } - if (n < *fdl) - debug("XXX shrink: %d < %d", n, *fdl); - *fdl = n; - memset(*fdrp, 0, sz); - memset(*fdwp, 0, sz); - - for (i = 0; i < sockets_alloc; i++) { - switch (sockets[i].type) { - case AUTH_SOCKET: - case AUTH_CONNECTION: - FD_SET(sockets[i].fd, *fdrp); - if (buffer_len(&sockets[i].output) > 0) - FD_SET(sockets[i].fd, *fdwp); - break; - default: - break; - } - } - deadline = reaper(); - if (parent_alive_interval != 0) - deadline = (deadline == 0) ? parent_alive_interval : - MIN(deadline, parent_alive_interval); - if (deadline == 0) { - *tvpp = NULL; - } else { - tv.tv_sec = deadline; - tv.tv_usec = 0; - *tvpp = &tv; - } - return (1); -} - -static void -after_select(fd_set *readset, fd_set *writeset) -{ - struct sockaddr_un sunaddr; - socklen_t slen; - char buf[1024]; - int len, sock; - u_int i; - uid_t euid; - gid_t egid; - - for (i = 0; i < sockets_alloc; i++) - switch (sockets[i].type) { - case AUTH_UNUSED: - break; - case AUTH_SOCKET: - if (FD_ISSET(sockets[i].fd, readset)) { - slen = sizeof(sunaddr); - sock = accept(sockets[i].fd, - (struct sockaddr *)&sunaddr, &slen); - if (sock < 0) { - error("accept from AUTH_SOCKET: %s", - strerror(errno)); - break; - } - if (getpeereid(sock, &euid, &egid) < 0) { - error("getpeereid %d failed: %s", - sock, strerror(errno)); - close(sock); - break; - } - if ((euid != 0) && (getuid() != euid)) { - error("uid mismatch: " - "peer euid %u != uid %u", - (u_int) euid, (u_int) getuid()); - close(sock); - break; - } - new_socket(AUTH_CONNECTION, sock); - } - break; - case AUTH_CONNECTION: - if (buffer_len(&sockets[i].output) > 0 && - FD_ISSET(sockets[i].fd, writeset)) { - do { - len = write(sockets[i].fd, - buffer_ptr(&sockets[i].output), - buffer_len(&sockets[i].output)); - if (len == -1 && (errno == EAGAIN || - errno == EINTR || - errno == EWOULDBLOCK)) - continue; - break; - } while (1); - if (len <= 0) { - close_socket(&sockets[i]); - break; - } - buffer_consume(&sockets[i].output, len); - } - if (FD_ISSET(sockets[i].fd, readset)) { - do { - len = read(sockets[i].fd, buf, sizeof(buf)); - if (len == -1 && (errno == EAGAIN || - errno == EINTR || - errno == EWOULDBLOCK)) - continue; - break; - } while (1); - if (len <= 0) { - close_socket(&sockets[i]); - break; - } - buffer_append(&sockets[i].input, buf, len); - process_message(&sockets[i]); - } - break; - default: - fatal("Unknown type %d", sockets[i].type); - } -} - -static void -cleanup_socket(void) -{ - if (socket_name[0]) - unlink(socket_name); - if (socket_dir[0]) - rmdir(socket_dir); -} - -void -cleanup_exit(int i) -{ - cleanup_socket(); - _exit(i); -} - -/*ARGSUSED*/ -static void -cleanup_handler(int sig) -{ - cleanup_socket(); - _exit(2); -} - -static void -check_parent_exists(void) -{ -#ifdef HAVE_SOLARIS_PRIVILEGE - /* - * We can not simply use "kill(ppid, 0) < 0" to detect if the parent - * has exited when the child process no longer has the - * PRIV_PROC_SESSION privilege. - */ - if (parent_pid != -1 && getppid() != parent_pid) { -#else - if (parent_pid != -1 && kill(parent_pid, 0) < 0) { - -#endif - /* printf("Parent has died - Authentication agent exiting.\n"); */ - cleanup_socket(); - _exit(2); - } -} - -static void -usage(void) -{ - fprintf(stderr, - gettext("Usage: %s [options] [command [args ...]]\n" - "Options:\n" - " -c Generate C-shell commands on stdout.\n" - " -s Generate Bourne shell commands on stdout.\n" - " -k Kill the current agent.\n" - " -d Debug mode.\n" - " -a socket Bind agent socket to given name.\n" - " -t life Default identity lifetime (seconds).\n"), - __progname); - exit(1); -} - -int -main(int ac, char **av) -{ - int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; - int sock, fd, ch, result, saved_errno; - u_int nalloc; - char *shell, *pidstr, *agentsocket = NULL; - const char *format; - fd_set *readsetp = NULL, *writesetp = NULL; - struct sockaddr_un sunaddr; -#ifdef HAVE_SETRLIMIT - struct rlimit rlim; -#endif - int prev_mask; - extern int optind; - extern char *optarg; - pid_t pid; - char pidstrbuf[1 + 3 * sizeof pid]; - struct timeval *tvp = NULL; -#ifdef HAVE_SOLARIS_PRIVILEGE - priv_set_t *myprivs; -#endif /* HAVE_SOLARIS_PRIVILEGE */ - - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - - /* drop */ - setegid(getgid()); - setgid(getgid()); - - SSLeay_add_all_algorithms(); - - __progname = get_progname(av[0]); - init_rng(); - seed_rng(); - - while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { - switch (ch) { - case 'c': - if (s_flag) - usage(); - c_flag++; - break; - case 'k': - k_flag++; - break; - case 's': - if (c_flag) - usage(); - s_flag++; - break; - case 'd': - if (d_flag) - usage(); - d_flag++; - break; - case 'a': - agentsocket = optarg; - break; - case 't': - if ((lifetime = convtime(optarg)) == -1) { - fprintf(stderr, gettext("Invalid lifetime\n")); - usage(); - } - break; - default: - usage(); - } - } - ac -= optind; - av += optind; - - if (ac > 0 && (c_flag || k_flag || s_flag || d_flag)) - usage(); - - if (ac == 0 && !c_flag && !s_flag) { - shell = getenv("SHELL"); - if (shell != NULL && - strncmp(shell + strlen(shell) - 3, "csh", 3) == 0) - c_flag = 1; - } - if (k_flag) { - pidstr = getenv(SSH_AGENTPID_ENV_NAME); - if (pidstr == NULL) { - fprintf(stderr, - gettext("%s not set, cannot kill agent\n"), - SSH_AGENTPID_ENV_NAME); - exit(1); - } - pid = atoi(pidstr); - if (pid < 1) { - fprintf(stderr, - gettext("%s not set, cannot kill agent\n"), - SSH_AGENTPID_ENV_NAME); - exit(1); - } - if (kill(pid, SIGTERM) == -1) { - perror("kill"); - exit(1); - } - format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; - printf(format, SSH_AUTHSOCKET_ENV_NAME); - printf(format, SSH_AGENTPID_ENV_NAME); - printf("echo "); - printf(gettext("Agent pid %ld killed;\n"), (long)pid); - exit(0); - } - parent_pid = getpid(); - - if (agentsocket == NULL) { - /* Create private directory for agent socket */ - strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir); - if (mkdtemp(socket_dir) == NULL) { - perror("mkdtemp: private socket dir"); - exit(1); - } - snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, - (long)parent_pid); - } else { - /* Try to use specified agent socket */ - socket_dir[0] = '\0'; - strlcpy(socket_name, agentsocket, sizeof socket_name); - } - - /* - * Create socket early so it will exist before command gets run from - * the parent. - */ - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - perror("socket"); - *socket_name = '\0'; /* Don't unlink any existing file */ - cleanup_exit(1); - } - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); - prev_mask = umask(0177); - if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) { - perror("bind"); - *socket_name = '\0'; /* Don't unlink any existing file */ - umask(prev_mask); - cleanup_exit(1); - } - umask(prev_mask); - if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { - perror("listen"); - cleanup_exit(1); - } - - /* - * Fork, and have the parent execute the command, if any, or present - * the socket data. The child continues as the authentication agent. - */ - if (d_flag) { - log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1); - format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; - printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, - SSH_AUTHSOCKET_ENV_NAME); - printf("echo "); - printf(gettext("Agent pid %ld;\n"), (long)parent_pid); - goto skip; - } - pid = fork(); - if (pid == -1) { - perror("fork"); - cleanup_exit(1); - } - if (pid != 0) { /* Parent - execute the given command. */ - close(sock); - snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); - if (ac == 0) { - format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; - printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, - SSH_AUTHSOCKET_ENV_NAME); - printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, - SSH_AGENTPID_ENV_NAME); - printf("echo "); - printf(gettext("Agent pid %ld;\n"), (long)pid); - exit(0); - } - if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || - setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { - perror("setenv"); - exit(1); - } - execvp(av[0], av); - perror(av[0]); - exit(1); - } - /* child */ - log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0); - -#ifdef HAVE_SOLARIS_PRIVILEGE - /* - * Drop unneeded privs, including basic ones like fork/exec. - * - * Idiom: remove from 'basic' privs we know we don't want, - * invert the result and remove the resulting set from P. - * - * None of the priv_delset() calls below, nor the setppriv call - * below can fail, so their return values are not checked. - */ - if ((myprivs = priv_str_to_set("basic", ",", NULL)) == NULL) - fatal("priv_str_to_set failed: %m"); - (void) priv_delset(myprivs, PRIV_PROC_EXEC); - (void) priv_delset(myprivs, PRIV_PROC_FORK); - (void) priv_delset(myprivs, PRIV_FILE_LINK_ANY); - (void) priv_delset(myprivs, PRIV_PROC_INFO); - (void) priv_delset(myprivs, PRIV_PROC_SESSION); - priv_inverse(myprivs); - (void) setppriv(PRIV_OFF, PRIV_PERMITTED, myprivs); - (void) priv_freeset(myprivs); -#endif /* HAVE_SOLARIS_PRIVILEGE */ - - if (setsid() == -1) { - error("setsid: %s", strerror(errno)); - cleanup_exit(1); - } - - (void)chdir("/"); - if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { - /* XXX might close listen socket */ - (void)dup2(fd, STDIN_FILENO); - (void)dup2(fd, STDOUT_FILENO); - (void)dup2(fd, STDERR_FILENO); - if (fd > 2) - close(fd); - } - -#ifdef HAVE_SETRLIMIT - /* deny core dumps, since memory contains unencrypted private keys */ - rlim.rlim_cur = rlim.rlim_max = 0; - if (setrlimit(RLIMIT_CORE, &rlim) < 0) { - error("setrlimit RLIMIT_CORE: %s", strerror(errno)); - cleanup_exit(1); - } -#endif - -skip: - new_socket(AUTH_SOCKET, sock); - if (ac > 0) - parent_alive_interval = 10; - idtab_init(); - if (!d_flag) - signal(SIGINT, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, cleanup_handler); - signal(SIGTERM, cleanup_handler); - nalloc = 0; - - while (1) { - prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); - result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); - saved_errno = errno; - if (parent_alive_interval != 0) - check_parent_exists(); - (void) reaper(); /* remove expired keys */ - if (result < 0) { - if (saved_errno == EINTR) - continue; - fatal("select: %s", strerror(saved_errno)); - } else if (result > 0) - after_select(readsetp, writesetp); - } - /* NOTREACHED */ - return (0); /* keep lint happy */ -} diff --git a/usr/src/cmd/ssh/ssh-http-proxy-connect/Makefile b/usr/src/cmd/ssh/ssh-http-proxy-connect/Makefile deleted file mode 100644 index 0c717f2155..0000000000 --- a/usr/src/cmd/ssh/ssh-http-proxy-connect/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -PROG= ssh-http-proxy-connect - -DIRS= $(ROOTLIBSSH) - -OBJS= ssh-http-proxy-connect.o - -SRCS= $(OBJS:.o=.c) - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket - -install: all $(DIRS) $(ROOTLIBSSHPROG) $(ROOTLIBSSH) - -$(ROOTLIBSSHPROG)/%: % - $(INS.file) - -$(DIRS): - $(INS.dir) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../../Makefile.targ -include ../Makefile.msg.targ diff --git a/usr/src/cmd/ssh/ssh-http-proxy-connect/ssh-http-proxy-connect.c b/usr/src/cmd/ssh/ssh-http-proxy-connect/ssh-http-proxy-connect.c deleted file mode 100644 index 33182730ae..0000000000 --- a/usr/src/cmd/ssh/ssh-http-proxy-connect/ssh-http-proxy-connect.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * An http client that let's users 'ssh' to the - * outside of the firewall by opening up a connection - * through the http proxy. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <strings.h> -#include <unistd.h> -#include <inttypes.h> -#include <errno.h> -#include <poll.h> -#include <signal.h> -#include <locale.h> -#include <libintl.h> -#include <netinet/in.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <sys/time.h> -#include <sys/stropts.h> -#include <sys/stat.h> -#include <sys/varargs.h> -#include "proxy-io.h" - -#define DEFAULT_HTTPPROXYPORT "80" -#define CONNECT_STRLEN 256 - -static int debug_flag = 0; - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("Usage: ssh-http-proxy-connect " - "[-h http_proxy_host] [-p http_proxy_port]\n" - "remote_host remote_port\n")); - exit(1); -} - -/* PRINTFLIKE1 */ -static void -debug(const char *format, ...) -{ - char fmtbuf[BUFFER_SIZ]; - va_list args; - - if (debug_flag == 0) { - return; - } - va_start(args, format); - (void) snprintf(fmtbuf, sizeof (fmtbuf), - "ssh-http-proxy: %s\n", format); - (void) vfprintf(stderr, fmtbuf, args); - va_end(args); -} - -static void -signal_handler(int sig) -{ - exit(0); -} - -int -main(int argc, char **argv) -{ - extern char *optarg; - extern int optind; - int retval, err_code, sock, ssh_port; - int version, ret_code; - char *httpproxy = NULL; - char *temp, *httpproxyport = NULL; - char *ssh_host; - char connect_str[CONNECT_STRLEN], connect_reply[BUFFER_SIZ]; - char *ret_string; - struct addrinfo hints, *ai; - struct pollfd fds[2]; - - /* Initialization for variables, set locale and textdomain */ - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ -#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ -#endif - (void) textdomain(TEXT_DOMAIN); - - /* Set up the signal handler */ - (void) signal(SIGINT, signal_handler); - (void) signal(SIGPIPE, signal_handler); - (void) signal(SIGPOLL, signal_handler); - - while ((retval = getopt(argc, argv, "dp:h:")) != -1) { - switch (retval) { - case 'h': - httpproxy = optarg; - break; - case 'p': - httpproxyport = optarg; - break; - case 'd': - debug_flag = 1; - break; - default: - break; - } - } - - if (optind != argc - 2) { - usage(); - } - - ssh_host = argv[optind++]; - ssh_port = atoi(argv[optind]); - - /* - * If the name of the http proxy were not - * passed on the command line, try the - * user's environment. First try HTTPPROXY. - * If it's not set, try http_proxy. - * Check the url specified for http_proxy - * for errors. - */ - if (httpproxy == NULL) { - if ((httpproxy = getenv("HTTPPROXY")) == NULL) { - /* Try the other environment variable http_proxy */ - if ((temp = getenv("http_proxy")) != NULL) { - temp += strlen("http://"); - if (strpbrk(temp, ":") == NULL) { - /* Malformed url */ - (void) fprintf(stderr, gettext("ssh-http-proxy: " - "Incorrect url specified for http_proxy " - "environment variable\n")); - exit(1); - } - httpproxy = strtok(temp, ":"); - httpproxyport = strtok(NULL, "/"); - } else { - (void) fprintf(stderr, - gettext("ssh-http-proxy: http proxy not specified\n")); - exit(1); - } - } - } - - /* - * Extract the proxy port number from the user's environment. - * Ignored if HTTPPROXY is not set. - */ - if ((httpproxy != NULL) && (httpproxyport == NULL)) { - if ((httpproxyport = getenv("HTTPPROXYPORT")) == NULL) { - httpproxyport = DEFAULT_HTTPPROXYPORT; - } - } - - debug("HTTPPROXY = %s", httpproxy); - debug("HTTPPROXYPORT = %s", httpproxyport); - - bzero(&hints, sizeof (struct addrinfo)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - if ((err_code = getaddrinfo(httpproxy, httpproxyport, &hints, &ai)) - != 0) { - (void) fprintf(stderr, "ssh-http-proxy: Unable to " - "perform name lookup\n"); - (void) fprintf(stderr, "%s: %s\n", httpproxy, - gai_strerror(err_code)); - exit(1); - } - - if ((sock = socket(ai->ai_family, SOCK_STREAM, 0)) < 0) { - perror("socket"); - exit(1); - } - - /* Connect to the http proxy */ - if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { - (void) fprintf(stderr, gettext("ssh-http-proxy: Unable to connect" - " to %s: %s\n"), httpproxy, strerror(errno)); - (void) close(sock); - exit(1); - } else { - /* Successful connection. */ - (void) snprintf(connect_str, sizeof (connect_str), - "CONNECT %s:%d HTTP/1.1\r\n\r\n", ssh_host, ssh_port); - if (write(sock, &connect_str, strlen(connect_str)) < 0) { - perror("write"); - (void) close(sock); - exit(1); - } - - if (read(sock, connect_reply, sizeof (connect_reply)) == -1) { - perror("read"); - (void) close(sock); - exit(1); - } - - if (sscanf(connect_reply, "HTTP/1.%d %d", - &version, &ret_code) != 2) { - (void) fprintf(stderr, - gettext("ssh-http-proxy: HTTP reply not understood\n")); - (void) close(sock); - exit(1); - } - - ret_string = strtok(connect_reply, "\n"); - - /* If the return error code is not 200, print an error and quit. */ - if (ret_code != 200) { - (void) fprintf(stderr, "%s\n", ret_string); - (void) close(sock); - exit(1); - } else { - debug("%s", ret_string); - } - } - - fds[0].fd = STDIN_FILENO; /* Poll stdin for data. */ - fds[1].fd = sock; /* Poll the socket for data. */ - fds[0].events = fds[1].events = POLLIN; - - for (;;) { - if (poll(fds, 2, INFTIM) == -1) { - perror("poll"); - (void) close(sock); - exit(1); - } - - /* Data arrived on stdin, write it to the socket */ - if (fds[0].revents & POLLIN) { - if (proxy_read_write_loop(STDIN_FILENO, sock) == 0) { - (void) close(sock); - exit(1); - } - } else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { - (void) close(sock); - exit(1); - } - - /* Data arrived on the socket, write it to stdout */ - if (fds[1].revents & POLLIN) { - if (proxy_read_write_loop(sock, STDOUT_FILENO) == 0) { - (void) close(sock); - exit(1); - } - } else if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) { - (void) close(sock); - exit(1); - } - } - - /* NOTREACHED */ - return (0); -} diff --git a/usr/src/cmd/ssh/ssh-keygen/Makefile b/usr/src/cmd/ssh/ssh-keygen/Makefile deleted file mode 100644 index 0c90716768..0000000000 --- a/usr/src/cmd/ssh/ssh-keygen/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/ssh-keygen/Makefile - -PROG= ssh-keygen - -OBJS = \ - ssh-keygen.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsunw_crypto -lsocket - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -install: all $(ROOTPROG) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c b/usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c deleted file mode 100644 index c79e76ae36..0000000000 --- a/usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c +++ /dev/null @@ -1,1377 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ - -/* $OpenBSD: ssh-keygen.c,v 1.205 2011/01/11 06:13:10 djm Exp $ */ - -#include "includes.h" -#include <openssl/evp.h> -#include <openssl/pem.h> - -#include "xmalloc.h" -#include "key.h" -#include "rsa.h" -#include "authfile.h" -#include "uuencode.h" -#include "buffer.h" -#include "bufaux.h" -#include "pathnames.h" -#include "log.h" -#include "readpass.h" -#include "misc.h" -#include <langinfo.h> -#include "match.h" -#include "hostfile.h" -#include "tildexpand.h" - -/* Number of bits in the RSA/DSA key. This value can be set on the command line. */ -#define DEFAULT_BITS_RSA 2048 -#define DEFAULT_BITS_DSA 1024 -u_int32_t bits = 0; - -/* - * Flag indicating that we just want to change the passphrase. This can be - * set on the command line. - */ -int change_passphrase = 0; - -/* - * Flag indicating that we just want to change the comment. This can be set - * on the command line. - */ -int change_comment = 0; - -int quiet = 0; - -/* Flag indicating that we want to hash a known_hosts file */ -int hash_hosts = 0; -/* Flag indicating that we want to lookup a host in known_hosts file */ -int find_host = 0; -/* Flag indicating that we want to delete a host from a known_hosts file */ -int delete_host = 0; - -/* Flag indicating that we just want to see the key fingerprint */ -int print_fingerprint = 0; -int print_bubblebabble = 0; - -/* The identity file name, given on the command line or entered by the user. */ -char identity_file[1024]; -int have_identity = 0; - -/* This is set to the passphrase if given on the command line. */ -char *identity_passphrase = NULL; - -/* This is set to the new passphrase if given on the command line. */ -char *identity_new_passphrase = NULL; - -/* This is set to the new comment if given on the command line. */ -char *identity_comment = NULL; - -/* Conversion to/from various formats */ -int convert_to = 0; -int convert_from = 0; -enum { - FMT_RFC4716, - FMT_PKCS8, - FMT_PEM -} convert_format = FMT_RFC4716; -int print_public = 0; - -char *key_type_name = NULL; - -/* argv0 */ -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - -char hostname[MAXHOSTNAMELEN]; - -static void -ask_filename(struct passwd *pw, const char *prompt) -{ - char buf[1024]; - char *name = NULL; - - if (key_type_name == NULL) - name = _PATH_SSH_CLIENT_ID_RSA; - else { - switch (key_type_from_name(key_type_name)) { - case KEY_RSA1: - name = _PATH_SSH_CLIENT_IDENTITY; - break; - case KEY_DSA: - name = _PATH_SSH_CLIENT_ID_DSA; - break; - case KEY_RSA: - name = _PATH_SSH_CLIENT_ID_RSA; - break; - default: - fprintf(stderr, gettext("bad key type")); - exit(1); - break; - } - } - snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); - fprintf(stderr, "%s (%s): ", gettext(prompt), identity_file); - if (fgets(buf, sizeof(buf), stdin) == NULL) - exit(1); - if (strchr(buf, '\n')) - *strchr(buf, '\n') = 0; - if (strcmp(buf, "") != 0) - strlcpy(identity_file, buf, sizeof(identity_file)); - have_identity = 1; -} - -static Key * -load_identity(char *filename) -{ - char *pass; - Key *prv; - - prv = key_load_private(filename, "", NULL); - if (prv == NULL) { - if (identity_passphrase) - pass = xstrdup(identity_passphrase); - else - pass = read_passphrase(gettext("Enter passphrase: "), - RP_ALLOW_STDIN); - prv = key_load_private(filename, pass, NULL); - memset(pass, 0, strlen(pass)); - xfree(pass); - } - return prv; -} - -#define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" -#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----" -#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" -#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb - -static void -do_convert_to_ssh2(struct passwd *pw, Key *k) -{ - u_int len; - u_char *blob; - char comment[61]; - - if (key_to_blob(k, &blob, &len) <= 0) { - fprintf(stderr, "key_to_blob failed\n"); - exit(1); - } - /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ - snprintf(comment, sizeof(comment), - "%u-bit %s, converted by %s@%s from OpenSSH", - key_size(k), key_type(k), - pw->pw_name, hostname); - - fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); - fprintf(stdout, "Comment: \"%s\"\n", comment); - dump_base64(stdout, blob, len); - fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); - key_free(k); - xfree(blob); - exit(0); -} - -static void -do_convert_to_pkcs8(Key *k) -{ - switch (key_type_plain(k->type)) { - case KEY_RSA: - if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) - fatal("PEM_write_RSA_PUBKEY failed"); - break; - case KEY_DSA: - if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) - fatal("PEM_write_DSA_PUBKEY failed"); - break; - default: - fatal("%s: unsupported key type %s", __func__, key_type(k)); - } - exit(0); -} - -static void -do_convert_to_pem(Key *k) -{ - switch (key_type_plain(k->type)) { - case KEY_RSA: - if (!PEM_write_RSAPublicKey(stdout, k->rsa)) - fatal("PEM_write_RSAPublicKey failed"); - break; - case KEY_DSA: - if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) - fatal("PEM_write_DSAPublicKey failed"); - break; - default: - fatal("%s: unsupported key type %s", __func__, key_type(k)); - } - exit(0); -} - -static void -do_convert_to(struct passwd *pw) -{ - Key *k; - struct stat st; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) - fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - if ((k = key_load_public(identity_file, NULL)) == NULL) { - if ((k = load_identity(identity_file)) == NULL) { - fprintf(stderr, "load failed\n"); - exit(1); - } - } - if (k->type == KEY_RSA1) { - fprintf(stderr, "version 1 keys are not supported\n"); - exit(1); - } - - switch (convert_format) { - case FMT_RFC4716: - do_convert_to_ssh2(pw, k); - break; - case FMT_PKCS8: - do_convert_to_pkcs8(k); - break; - case FMT_PEM: - do_convert_to_pem(k); - break; - default: - fatal("%s: unknown key format %d", __func__, convert_format); - } - exit(0); -} - - -static void -buffer_get_bignum_bits(Buffer *b, BIGNUM *value) -{ - u_int bignum_bits = buffer_get_int(b); - u_int bytes = (bignum_bits + 7) / 8; - - if (buffer_len(b) < bytes) - fatal("buffer_get_bignum_bits: input buffer too small: " - "need %d have %d", bytes, buffer_len(b)); - if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL) - fatal("buffer_get_bignum_bits: BN_bin2bn failed"); - buffer_consume(b, bytes); -} - -static Key * -do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) -{ - Buffer b; - Key *key = NULL; - char *type, *cipher; - u_char *sig, data[] = "abcde12345"; - int magic, rlen, ktype, i1, i2, i3, i4; - u_int slen; - u_long e; - - buffer_init(&b); - buffer_append(&b, blob, blen); - - magic = buffer_get_int(&b); - if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { - error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); - buffer_free(&b); - return NULL; - } - i1 = buffer_get_int(&b); - type = buffer_get_string(&b, NULL); - cipher = buffer_get_string(&b, NULL); - i2 = buffer_get_int(&b); - i3 = buffer_get_int(&b); - i4 = buffer_get_int(&b); - debug("ignore (%d %d %d %d)", i1, i2, i3, i4); - if (strcmp(cipher, "none") != 0) { - error("unsupported cipher %s", cipher); - xfree(cipher); - buffer_free(&b); - xfree(type); - return NULL; - } - xfree(cipher); - - if (strstr(type, "dsa")) { - ktype = KEY_DSA; - } else if (strstr(type, "rsa")) { - ktype = KEY_RSA; - } else { - buffer_free(&b); - xfree(type); - return NULL; - } - key = key_new_private(ktype); - xfree(type); - - switch (key->type) { - case KEY_DSA: - buffer_get_bignum_bits(&b, key->dsa->p); - buffer_get_bignum_bits(&b, key->dsa->g); - buffer_get_bignum_bits(&b, key->dsa->q); - buffer_get_bignum_bits(&b, key->dsa->pub_key); - buffer_get_bignum_bits(&b, key->dsa->priv_key); - break; - case KEY_RSA: - e = buffer_get_char(&b); - debug("e %lx", e); - if (e < 30) { - e <<= 8; - e += buffer_get_char(&b); - debug("e %lx", e); - e <<= 8; - e += buffer_get_char(&b); - debug("e %lx", e); - } - if (!BN_set_word(key->rsa->e, e)) { - buffer_free(&b); - key_free(key); - return NULL; - } - buffer_get_bignum_bits(&b, key->rsa->d); - buffer_get_bignum_bits(&b, key->rsa->n); - buffer_get_bignum_bits(&b, key->rsa->iqmp); - buffer_get_bignum_bits(&b, key->rsa->q); - buffer_get_bignum_bits(&b, key->rsa->p); - rsa_generate_additional_parameters(key->rsa); - break; - } - rlen = buffer_len(&b); - if (rlen != 0) - error("do_convert_private_ssh2_from_blob: " - "remaining bytes in key blob %d", rlen); - buffer_free(&b); - - /* try the key */ - key_sign(key, &sig, &slen, data, sizeof(data)); - key_verify(key, sig, slen, data, sizeof(data)); - xfree(sig); - return key; -} - -static int -get_line(FILE *fp, char *line, size_t len) -{ - int c; - size_t pos = 0; - - line[0] = '\0'; - while ((c = fgetc(fp)) != EOF) { - if (pos >= len - 1) { - fprintf(stderr, "input line too long.\n"); - exit(1); - } - switch (c) { - case '\r': - c = fgetc(fp); - if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) { - fprintf(stderr, "unget: %s\n", strerror(errno)); - exit(1); - } - return pos; - case '\n': - return pos; - } - line[pos++] = c; - line[pos] = '\0'; - } - /* We reached EOF */ - return -1; -} - -static void -do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) -{ - int blen; - u_int len; - char line[1024]; - u_char blob[8096]; - char encoded[8096]; - int escaped = 0; - FILE *fp; - - fp = fopen(identity_file, "r"); - if (fp == NULL) { - perror(identity_file); - exit(1); - } - encoded[0] = '\0'; - while ((blen = get_line(fp, line, sizeof(line))) != -1) { - if (line[blen - 1] == '\\') - escaped++; - if (strncmp(line, "----", 4) == 0 || - strstr(line, ": ") != NULL) { - if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) - *private = 1; - if (strstr(line, " END ") != NULL) { - break; - } - /* fprintf(stderr, "ignore: %s", line); */ - continue; - } - if (escaped) { - escaped--; - /* fprintf(stderr, "escaped: %s", line); */ - continue; - } - strlcat(encoded, line, sizeof(encoded)); - } - len = strlen(encoded); - if (((len % 4) == 3) && - (encoded[len-1] == '=') && - (encoded[len-2] == '=') && - (encoded[len-3] == '=')) - encoded[len-3] = '\0'; - blen = uudecode(encoded, blob, sizeof(blob)); - if (blen < 0) { - fprintf(stderr, gettext("uudecode failed.\n")); - exit(1); - } - *k = *private ? - do_convert_private_ssh2_from_blob(blob, blen) : - key_from_blob(blob, blen); - if (*k == NULL) { - fprintf(stderr, gettext("decode blob failed.\n")); - exit(1); - } - fclose(fp); -} - -static void -do_convert_from_pkcs8(Key **k, int *private) -{ - EVP_PKEY *pubkey; - FILE *fp; - - if ((fp = fopen(identity_file, "r")) == NULL) - fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { - fatal("%s: %s is not a recognised public key format", __func__, - identity_file); - } - fclose(fp); - switch (EVP_PKEY_type(pubkey->type)) { - case EVP_PKEY_RSA: - *k = key_new(KEY_UNSPEC); - (*k)->type = KEY_RSA; - (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); - break; - case EVP_PKEY_DSA: - *k = key_new(KEY_UNSPEC); - (*k)->type = KEY_DSA; - (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); - break; - default: - fatal("%s: unsupported pubkey type %d", __func__, - EVP_PKEY_type(pubkey->type)); - } - EVP_PKEY_free(pubkey); - return; -} - -static void -do_convert_from_pem(Key **k, int *private) -{ - FILE *fp; - RSA *rsa; - - if ((fp = fopen(identity_file, "r")) == NULL) - fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { - *k = key_new(KEY_UNSPEC); - (*k)->type = KEY_RSA; - (*k)->rsa = rsa; - fclose(fp); - return; - } - fatal("%s: unrecognised raw private key format", __func__); -} - -static void -do_convert_from(struct passwd *pw) -{ - Key *k = NULL; - int private = 0, ok = 0; - struct stat st; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) - fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - - switch (convert_format) { - case FMT_RFC4716: - do_convert_from_ssh2(pw, &k, &private); - break; - case FMT_PKCS8: - do_convert_from_pkcs8(&k, &private); - break; - case FMT_PEM: - do_convert_from_pem(&k, &private); - break; - default: - fatal("%s: unknown key format %d", __func__, convert_format); - } - - if (!private) - ok = key_write(k, stdout); - if (ok) - fprintf(stdout, "\n"); - else { - switch (k->type) { - case KEY_DSA: - ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, - NULL, 0, NULL, NULL); - break; - case KEY_RSA: - ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, - NULL, 0, NULL, NULL); - break; - default: - fatal("%s: unsupported key type %s", __func__, - key_type(k)); - } - } - - if (!ok) { - fprintf(stderr, "key write failed\n"); - exit(1); - } - key_free(k); - exit(0); -} - -static void -do_print_public(struct passwd *pw) -{ - Key *prv; - struct stat st; - - if (!have_identity) - ask_filename(pw, gettext("Enter file in which the key is")); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - prv = load_identity(identity_file); - if (prv == NULL) { - fprintf(stderr, gettext("load failed\n")); - exit(1); - } - if (!key_write(prv, stdout)) - fprintf(stderr, gettext("key_write failed")); - key_free(prv); - fprintf(stdout, "\n"); - exit(0); -} - -static void -do_fingerprint(struct passwd *pw) -{ - FILE *f; - Key *public; - char *comment = NULL, *cp, *ep, line[16*1024], *fp; - int i, skip = 0, num = 1, invalid = 1; - enum fp_rep rep; - enum fp_type fptype; - struct stat st; - - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - - if (!have_identity) - ask_filename(pw, gettext("Enter file in which the key is")); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - public = key_load_public(identity_file, &comment); - if (public != NULL) { - fp = key_fingerprint(public, fptype, rep); - printf("%u %s %s\n", key_size(public), fp, comment); - key_free(public); - xfree(comment); - xfree(fp); - exit(0); - } - if (comment) { - xfree(comment); - comment = NULL; - } - - f = fopen(identity_file, "r"); - if (f != NULL) { - while (fgets(line, sizeof(line), f)) { - i = strlen(line) - 1; - if (line[i] != '\n') { - error("line %d too long: %.40s...", num, line); - skip = 1; - continue; - } - num++; - if (skip) { - skip = 0; - continue; - } - line[i] = '\0'; - - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '\n' || *cp == '#') - continue; - i = strtol(cp, &ep, 10); - if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { - int quoted = 0; - comment = cp; - for (; *cp && (quoted || (*cp != ' ' && - *cp != '\t')); cp++) { - if (*cp == '\\' && cp[1] == '"') - cp++; /* Skip both */ - else if (*cp == '"') - quoted = !quoted; - } - if (!*cp) - continue; - *cp++ = '\0'; - } - ep = cp; - public = key_new(KEY_RSA1); - if (key_read(public, &cp) != 1) { - cp = ep; - key_free(public); - public = key_new(KEY_UNSPEC); - if (key_read(public, &cp) != 1) { - key_free(public); - continue; - } - } - comment = *cp ? cp : comment; - fp = key_fingerprint(public, fptype, rep); - printf("%u %s %s\n", key_size(public), fp, - comment ? comment : gettext("no comment")); - xfree(fp); - key_free(public); - invalid = 0; - } - fclose(f); - } - if (invalid) { - printf(gettext("%s is not a public key file.\n"), - identity_file); - exit(1); - } - exit(0); -} - -static void -print_host(FILE *f, const char *name, Key *public, int hash) -{ - if (hash && (name = host_hash(name, NULL, 0)) == NULL) - fatal("hash_host failed"); - fprintf(f, "%s ", name); - if (!key_write(public, f)) - fatal("key_write failed"); - fprintf(f, "\n"); -} - -static void -do_known_hosts(struct passwd *pw, const char *name) -{ - FILE *in, *out = stdout; - Key *public; - char *cp, *cp2, *kp, *kp2; - char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; - int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; - - if (!have_identity) { - cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); - if (strlcpy(identity_file, cp, sizeof(identity_file)) >= - sizeof(identity_file)) - fatal("Specified known hosts path too long"); - xfree(cp); - have_identity = 1; - } - if ((in = fopen(identity_file, "r")) == NULL) - fatal("fopen: %s", strerror(errno)); - - /* - * Find hosts goes to stdout, hash and deletions happen in-place - * A corner case is ssh-keygen -HF foo, which should go to stdout - */ - if (!find_host && (hash_hosts || delete_host)) { - if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) || - strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) || - strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) || - strlcat(old, ".old", sizeof(old)) >= sizeof(old)) - fatal("known_hosts path too long"); - umask(077); - if ((c = mkstemp(tmp)) == -1) - fatal("mkstemp: %s", strerror(errno)); - if ((out = fdopen(c, "w")) == NULL) { - c = errno; - unlink(tmp); - fatal("fdopen: %s", strerror(c)); - } - inplace = 1; - } - - while (fgets(line, sizeof(line), in)) { - num++; - i = strlen(line) - 1; - if (line[i] != '\n') { - error("line %d too long: %.40s...", num, line); - skip = 1; - invalid = 1; - continue; - } - if (skip) { - skip = 0; - continue; - } - line[i] = '\0'; - - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '\n' || *cp == '#') { - if (inplace) - fprintf(out, "%s\n", cp); - continue; - } - /* Find the end of the host name portion. */ - for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) - ; - if (*kp == '\0' || *(kp + 1) == '\0') { - error("line %d missing key: %.40s...", - num, line); - invalid = 1; - continue; - } - *kp++ = '\0'; - kp2 = kp; - - public = key_new(KEY_RSA1); - if (key_read(public, &kp) != 1) { - kp = kp2; - key_free(public); - public = key_new(KEY_UNSPEC); - if (key_read(public, &kp) != 1) { - error("line %d invalid key: %.40s...", - num, line); - key_free(public); - invalid = 1; - continue; - } - } - - if (*cp == HASH_DELIM) { - if (find_host || delete_host) { - cp2 = host_hash(name, cp, strlen(cp)); - if (cp2 == NULL) { - error("line %d: invalid hashed " - "name: %.64s...", num, line); - invalid = 1; - continue; - } - c = (strcmp(cp2, cp) == 0); - if (find_host && c) { - printf(gettext("# Host %s found: " - "line %d type %s\n"), name, - num, key_type(public)); - print_host(out, cp, public, 0); - } - if (delete_host && !c) - print_host(out, cp, public, 0); - } else if (hash_hosts) - print_host(out, cp, public, 0); - } else { - if (find_host || delete_host) { - c = (match_hostname(name, cp, - strlen(cp)) == 1); - if (find_host && c) { - printf(gettext("# Host %s found: " - "line %d type %s\n"), name, - num, key_type(public)); - print_host(out, name, public, hash_hosts); - } - if (delete_host && !c) - print_host(out, cp, public, 0); - } else if (hash_hosts) { - for (cp2 = strsep(&cp, ","); - cp2 != NULL && *cp2 != '\0'; - cp2 = strsep(&cp, ",")) { - if (strcspn(cp2, "*?!") != strlen(cp2)) - fprintf(stderr, gettext("Warning: " - "ignoring host name with " - "metacharacters: %.64s\n"), - cp2); - else - print_host(out, cp2, public, 1); - } - has_unhashed = 1; - } - } - key_free(public); - } - fclose(in); - - if (invalid) { - fprintf(stderr, gettext("%s is not a valid known_host file.\n"), - identity_file); - if (inplace) { - fprintf(stderr, gettext("Not replacing existing known_hosts " - "file because of errors\n")); - fclose(out); - unlink(tmp); - } - exit(1); - } - - if (inplace) { - fclose(out); - - /* Backup existing file */ - if (unlink(old) == -1 && errno != ENOENT) - fatal("unlink %.100s: %s", old, strerror(errno)); - if (link(identity_file, old) == -1) - fatal("link %.100s to %.100s: %s", identity_file, old, - strerror(errno)); - /* Move new one into place */ - if (rename(tmp, identity_file) == -1) { - error("rename\"%s\" to \"%s\": %s", tmp, identity_file, - strerror(errno)); - unlink(tmp); - unlink(old); - exit(1); - } - - fprintf(stderr, gettext("%s updated.\n"), identity_file); - fprintf(stderr, gettext("Original contents retained as %s\n"), old); - if (has_unhashed) { - fprintf(stderr, gettext("WARNING: %s contains unhashed " - "entries\n"), old); - fprintf(stderr, gettext("Delete this file to ensure privacy " - "of hostnames\n")); - } - } - - exit(0); -} - -/* - * Perform changing a passphrase. The argument is the passwd structure - * for the current user. - */ -static void -do_change_passphrase(struct passwd *pw) -{ - char *comment; - char *old_passphrase, *passphrase1, *passphrase2; - struct stat st; - Key *private; - - if (!have_identity) - ask_filename(pw, gettext("Enter file in which the key is")); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - /* Try to load the file with empty passphrase. */ - private = key_load_private(identity_file, "", &comment); - if (private == NULL) { - if (identity_passphrase) - old_passphrase = xstrdup(identity_passphrase); - else - old_passphrase = - read_passphrase(gettext("Enter old passphrase: "), - RP_ALLOW_STDIN); - private = key_load_private(identity_file, old_passphrase, - &comment); - memset(old_passphrase, 0, strlen(old_passphrase)); - xfree(old_passphrase); - if (private == NULL) { - printf(gettext("Bad passphrase.\n")); - exit(1); - } - } - printf(gettext("Key has comment '%s'\n"), comment); - - /* Ask the new passphrase (twice). */ - if (identity_new_passphrase) { - passphrase1 = xstrdup(identity_new_passphrase); - passphrase2 = NULL; - } else { - passphrase1 = - read_passphrase(gettext("Enter new passphrase (empty" - " for no passphrase): "), RP_ALLOW_STDIN); - passphrase2 = read_passphrase(gettext("Enter same " - "passphrase again: "), RP_ALLOW_STDIN); - - /* Verify that they are the same. */ - if (strcmp(passphrase1, passphrase2) != 0) { - memset(passphrase1, 0, strlen(passphrase1)); - memset(passphrase2, 0, strlen(passphrase2)); - xfree(passphrase1); - xfree(passphrase2); - printf(gettext("Pass phrases do not match. Try " - "again.\n")); - exit(1); - } - /* Destroy the other copy. */ - memset(passphrase2, 0, strlen(passphrase2)); - xfree(passphrase2); - } - - /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase1, comment)) { - printf(gettext("Saving the key failed: %s.\n"), identity_file); - memset(passphrase1, 0, strlen(passphrase1)); - xfree(passphrase1); - key_free(private); - xfree(comment); - exit(1); - } - /* Destroy the passphrase and the copy of the key in memory. */ - memset(passphrase1, 0, strlen(passphrase1)); - xfree(passphrase1); - key_free(private); /* Destroys contents */ - xfree(comment); - - printf(gettext("Your identification has been saved with the new " - "passphrase.\n")); - exit(0); -} - -/* - * Change the comment of a private key file. - */ -static void -do_change_comment(struct passwd *pw) -{ - char new_comment[1024], *comment, *passphrase; - Key *private; - Key *public; - struct stat st; - FILE *f; - int fd; - - if (!have_identity) - ask_filename(pw, gettext("Enter file in which the key is")); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - private = key_load_private(identity_file, "", &comment); - if (private == NULL) { - if (identity_passphrase) - passphrase = xstrdup(identity_passphrase); - else if (identity_new_passphrase) - passphrase = xstrdup(identity_new_passphrase); - else - passphrase = - read_passphrase(gettext("Enter passphrase: "), - RP_ALLOW_STDIN); - /* Try to load using the passphrase. */ - private = key_load_private(identity_file, passphrase, &comment); - if (private == NULL) { - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - printf(gettext("Bad passphrase.\n")); - exit(1); - } - } else { - passphrase = xstrdup(""); - } - if (private->type != KEY_RSA1) { - fprintf(stderr, gettext("Comments are only supported for " - "RSA1 keys.\n")); - key_free(private); - exit(1); - } - printf(gettext("Key now has comment '%s'\n"), comment); - - if (identity_comment) { - strlcpy(new_comment, identity_comment, sizeof(new_comment)); - } else { - printf(gettext("Enter new comment: ")); - fflush(stdout); - if (!fgets(new_comment, sizeof(new_comment), stdin)) { - memset(passphrase, 0, strlen(passphrase)); - key_free(private); - exit(1); - } - if (strchr(new_comment, '\n')) - *strchr(new_comment, '\n') = 0; - } - - /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase, new_comment)) { - printf(gettext("Saving the key failed: %s.\n"), identity_file); - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - key_free(private); - xfree(comment); - exit(1); - } - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - public = key_from_private(private); - key_free(private); - - strlcat(identity_file, ".pub", sizeof(identity_file)); - fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - printf(gettext("Could not save your public key in %s\n"), - identity_file); - exit(1); - } - f = fdopen(fd, "w"); - if (f == NULL) { - printf(gettext("fdopen %s failed"), identity_file); - exit(1); - } - if (!key_write(public, f)) - fprintf(stderr, gettext("write key failed")); - key_free(public); - fprintf(f, " %s\n", new_comment); - fclose(f); - - xfree(comment); - - printf(gettext("The comment in your key file has been changed.\n")); - exit(0); -} - -static void -usage(void) -{ - fprintf(stderr, gettext( - "Usage: %s [options]\n" - "Options:\n" - " -b bits Number of bits in the key to create.\n" - " -B Show bubblebabble digest of key file.\n" - " -c Change comment in private and public key files.\n" - " -C comment Provide new comment.\n" - " -e Convert OpenSSH to foreign format key file.\n" - " -f filename Filename of the key file.\n" - " -F hostname Find hostname in known hosts file.\n" - " -H Hash names in known_hosts file.\n" - " -i Convert foreign format to OpenSSH key file.\n" - " -l Show fingerprint of key file.\n" - " -m key_fmt Conversion format for -e/-i (PEM|PKCS8|RFC4716).\n" - " -N phrase Provide new passphrase.\n" - " -p Change passphrase of private key file.\n" - " -P phrase Provide old passphrase.\n" - " -q Quiet.\n" - " -R hostname Remove host from known_hosts file.\n" - " -t type Specify type of key to create.\n" - " -y Read private key file and print public key.\n" - ), __progname); - - exit(1); -} - -/* - * Main program for key management. - */ -int -main(int argc, char **argv) -{ - char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; - char *rr_hostname = NULL; - Key *private, *public; - struct passwd *pw; - struct stat st; - int opt, type, fd; - FILE *f; - - extern int optind; - extern char *optarg; - - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - - __progname = get_progname(argv[0]); - - g11n_setlocale(LC_ALL, ""); - - SSLeay_add_all_algorithms(); - init_rng(); - seed_rng(); - - /* we need this for the home * directory. */ - pw = getpwuid(getuid()); - if (!pw) { - printf(gettext("You don't exist, go away!\n")); - exit(1); - } - if (gethostname(hostname, sizeof(hostname)) < 0) { - perror("gethostname"); - exit(1); - } - -#define GETOPT_ARGS "BcdeHilpqxXyb:C:f:F:m:N:P:R:t:" - - while ((opt = getopt(argc, argv, GETOPT_ARGS)) != -1) { - switch (opt) { - case 'b': - bits = atoi(optarg); - if (bits < 512 || bits > 32768) { - printf(gettext("Bits has bad value.\n")); - exit(1); - } - break; - case 'F': - find_host = 1; - rr_hostname = optarg; - break; - case 'H': - hash_hosts = 1; - break; - case 'R': - delete_host = 1; - rr_hostname = optarg; - break; - case 'l': - print_fingerprint = 1; - break; - case 'B': - print_bubblebabble = 1; - break; - case 'm': - if (strcasecmp(optarg, "RFC4716") == 0 || - strcasecmp(optarg, "ssh2") == 0) { - convert_format = FMT_RFC4716; - break; - } - if (strcasecmp(optarg, "PKCS8") == 0) { - convert_format = FMT_PKCS8; - break; - } - if (strcasecmp(optarg, "PEM") == 0) { - convert_format = FMT_PEM; - break; - } - fatal("Unsupported conversion format \"%s\"", optarg); - /*NOTREACHED*/ - case 'p': - change_passphrase = 1; - break; - case 'c': - change_comment = 1; - break; - case 'f': - strlcpy(identity_file, optarg, sizeof(identity_file)); - have_identity = 1; - break; - case 'P': - identity_passphrase = optarg; - break; - case 'N': - identity_new_passphrase = optarg; - break; - case 'C': - identity_comment = optarg; - break; - case 'q': - quiet = 1; - break; - case 'e': - case 'x': - /* export key */ - convert_to = 1; - break; - case 'i': - case 'X': - /* import key */ - convert_from = 1; - break; - case 'y': - print_public = 1; - break; - case 'd': - key_type_name = "dsa"; - break; - case 't': - key_type_name = optarg; - break; - case '?': - default: - usage(); - } - } - if (optind < argc) { - printf(gettext("Too many arguments.\n")); - usage(); - } - if (change_passphrase && change_comment) { - printf(gettext("Can only have one of -p and -c.\n")); - usage(); - } - if (delete_host || hash_hosts || find_host) - do_known_hosts(pw, rr_hostname); - if (print_fingerprint || print_bubblebabble) - do_fingerprint(pw); - if (change_passphrase) - do_change_passphrase(pw); - if (change_comment) - do_change_comment(pw); - if (convert_to) - do_convert_to(pw); - if (convert_from) - do_convert_from(pw); - if (print_public) - do_print_public(pw); - - arc4random_stir(); - - if (key_type_name == NULL) { - printf(gettext("You must specify a key type (-t).\n")); - usage(); - } - type = key_type_from_name(key_type_name); - if (type == KEY_UNSPEC) { - fprintf(stderr, gettext("unknown key type %s\n"), - key_type_name); - exit(1); - } - if (bits == 0) - bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS_RSA; - - if (!quiet) - printf(gettext("Generating public/private %s key pair.\n"), - key_type_name); - private = key_generate(type, bits); - if (private == NULL) { - fprintf(stderr, gettext("key_generate failed")); - exit(1); - } - public = key_from_private(private); - - if (!have_identity) - ask_filename(pw, gettext("Enter file in which to save the key")); - - /* Create ~/.ssh directory if it doesn't already exist. */ - snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR); - if (strstr(identity_file, dotsshdir) != NULL && - stat(dotsshdir, &st) < 0) { - if (mkdir(dotsshdir, 0700) < 0) - error("Could not create directory '%s'.", dotsshdir); - else if (!quiet) - printf(gettext("Created directory '%s'.\n"), dotsshdir); - } - /* If the file already exists, ask the user to confirm. */ - if (stat(identity_file, &st) >= 0) { - char yesno[128]; - printf(gettext("%s already exists.\n"), identity_file); - printf(gettext("Overwrite (%s/%s)? "), - nl_langinfo(YESSTR), nl_langinfo(NOSTR)); - fflush(stdout); - if (fgets(yesno, sizeof(yesno), stdin) == NULL) - exit(1); - if (strcasecmp(chop(yesno), nl_langinfo(YESSTR)) != 0) - exit(1); - } - /* Ask for a passphrase (twice). */ - if (identity_passphrase) - passphrase1 = xstrdup(identity_passphrase); - else if (identity_new_passphrase) - passphrase1 = xstrdup(identity_new_passphrase); - else { -passphrase_again: - passphrase1 = - read_passphrase(gettext("Enter passphrase (empty " - "for no passphrase): "), RP_ALLOW_STDIN); - passphrase2 = read_passphrase(gettext("Enter same " - "passphrase again: "), RP_ALLOW_STDIN); - if (strcmp(passphrase1, passphrase2) != 0) { - /* - * The passphrases do not match. Clear them and - * retry. - */ - memset(passphrase1, 0, strlen(passphrase1)); - memset(passphrase2, 0, strlen(passphrase2)); - xfree(passphrase1); - xfree(passphrase2); - printf(gettext("Passphrases do not match. Try " - "again.\n")); - goto passphrase_again; - } - /* Clear the other copy of the passphrase. */ - memset(passphrase2, 0, strlen(passphrase2)); - xfree(passphrase2); - } - - if (identity_comment) { - strlcpy(comment, identity_comment, sizeof(comment)); - } else { - /* Create default commend field for the passphrase. */ - snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); - } - - /* Save the key with the given passphrase and comment. */ - if (!key_save_private(private, identity_file, passphrase1, comment)) { - printf(gettext("Saving the key failed: %s.\n"), identity_file); - memset(passphrase1, 0, strlen(passphrase1)); - xfree(passphrase1); - exit(1); - } - /* Clear the passphrase. */ - memset(passphrase1, 0, strlen(passphrase1)); - xfree(passphrase1); - - /* Clear the private key and the random number generator. */ - key_free(private); - arc4random_stir(); - - if (!quiet) - printf(gettext("Your identification has been saved in %s.\n"), - identity_file); - - strlcat(identity_file, ".pub", sizeof(identity_file)); - fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - printf(gettext("Could not save your public key in %s\n"), - identity_file); - exit(1); - } - f = fdopen(fd, "w"); - if (f == NULL) { - printf(gettext("fdopen %s failed"), identity_file); - exit(1); - } - if (!key_write(public, f)) - fprintf(stderr, gettext("write key failed")); - fprintf(f, " %s\n", comment); - fclose(f); - - if (!quiet) { - char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); - printf(gettext("Your public key has been saved in %s.\n"), - identity_file); - printf(gettext("The key fingerprint is:\n")); - printf("%s %s\n", fp, comment); - xfree(fp); - } - - key_free(public); - return(0); - /* NOTREACHED */ -} diff --git a/usr/src/cmd/ssh/ssh-keyscan/Makefile b/usr/src/cmd/ssh/ssh-keyscan/Makefile deleted file mode 100644 index 90428880a3..0000000000 --- a/usr/src/cmd/ssh/ssh-keyscan/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/ssh-keyscan/Makefile - -PROG= ssh-keyscan - -OBJS = \ - ssh-keyscan.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lnsl -lz -lsunw_crypto - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ - -install: all $(ROOTPROG) diff --git a/usr/src/cmd/ssh/ssh-keyscan/ssh-keyscan.c b/usr/src/cmd/ssh/ssh-keyscan/ssh-keyscan.c deleted file mode 100644 index 8879289088..0000000000 --- a/usr/src/cmd/ssh/ssh-keyscan/ssh-keyscan.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. - * - * Modification and redistribution in source and binary forms is - * permitted provided that due credit is given to the author and the - * OpenBSD project by leaving this copyright notice intact. - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.40 2002/07/06 17:47:58 stevesk Exp $"); - -#include "sys-queue.h" - -#include <openssl/bn.h> - -#include <setjmp.h> -#include "xmalloc.h" -#include "ssh.h" -#include "ssh1.h" -#include "key.h" -#include "kex.h" -#include "compat.h" -#include "myproposal.h" -#include "packet.h" -#include "dispatch.h" -#include "buffer.h" -#include "bufaux.h" -#include "log.h" -#include "atomicio.h" -#include "misc.h" - -/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. - Default value is AF_UNSPEC means both IPv4 and IPv6. */ -#ifdef IPV4_DEFAULT -int IPv4or6 = AF_INET; -#else -int IPv4or6 = AF_UNSPEC; -#endif - -int ssh_port = SSH_DEFAULT_PORT; - -#define KT_RSA1 1 -#define KT_DSA 2 -#define KT_RSA 4 - -int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */ - -#define MAXMAXFD 256 - -/* The number of seconds after which to give up on a TCP connection */ -int timeout = 5; - -int maxfd; -#define MAXCON (maxfd - 10) - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif -fd_set *read_wait; -size_t read_wait_size; -int ncon; -int nonfatal_fatal = 0; -jmp_buf kexjmp; -Key *kexjmp_key; - -/* - * Keep a connection structure for each file descriptor. The state - * associated with file descriptor n is held in fdcon[n]. - */ -typedef struct Connection { - u_char c_status; /* State of connection on this file desc. */ -#define CS_UNUSED 0 /* File descriptor unused */ -#define CS_CON 1 /* Waiting to connect/read greeting */ -#define CS_SIZE 2 /* Waiting to read initial packet size */ -#define CS_KEYS 3 /* Waiting to read public key packet */ - int c_fd; /* Quick lookup: c->c_fd == c - fdcon */ - int c_plen; /* Packet length field for ssh packet */ - int c_len; /* Total bytes which must be read. */ - int c_off; /* Length of data read so far. */ - int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */ - char *c_namebase; /* Address to free for c_name and c_namelist */ - char *c_name; /* Hostname of connection for errors */ - char *c_namelist; /* Pointer to other possible addresses */ - char *c_output_name; /* Hostname of connection for output */ - char *c_data; /* Data read from this fd */ - Kex *c_kex; /* The key-exchange struct for ssh2 */ - struct timeval c_tv; /* Time at which connection gets aborted */ - TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */ -} con; - -TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */ -con *fdcon; - -/* - * This is just a wrapper around fgets() to make it usable. - */ - -/* Stress-test. Increase this later. */ -#define LINEBUF_SIZE 16 - -typedef struct { - char *buf; - u_int size; - int lineno; - const char *filename; - FILE *stream; - void (*errfun) (const char *,...); -} Linebuf; - -static Linebuf * -Linebuf_alloc(const char *filename, void (*errfun) (const char *,...)) -{ - Linebuf *lb; - - if (!(lb = malloc(sizeof(*lb)))) { - if (errfun) - (*errfun) ("linebuf (%s): malloc failed\n", - filename ? filename : "(stdin)"); - return (NULL); - } - if (filename) { - lb->filename = filename; - if (!(lb->stream = fopen(filename, "r"))) { - xfree(lb); - if (errfun) - (*errfun) ("%s: %s\n", filename, strerror(errno)); - return (NULL); - } - } else { - lb->filename = "(stdin)"; - lb->stream = stdin; - } - - if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) { - if (errfun) - (*errfun) ("linebuf (%s): malloc failed\n", lb->filename); - xfree(lb); - return (NULL); - } - lb->errfun = errfun; - lb->lineno = 0; - return (lb); -} - -static void -Linebuf_free(Linebuf * lb) -{ - fclose(lb->stream); - xfree(lb->buf); - xfree(lb); -} - -#if 0 -static void -Linebuf_restart(Linebuf * lb) -{ - clearerr(lb->stream); - rewind(lb->stream); - lb->lineno = 0; -} - -static int -Linebuf_lineno(Linebuf * lb) -{ - return (lb->lineno); -} -#endif - -static char * -Linebuf_getline(Linebuf * lb) -{ - int n = 0; - void *p; - - lb->lineno++; - for (;;) { - /* Read a line */ - if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) { - if (ferror(lb->stream) && lb->errfun) - (*lb->errfun)("%s: %s\n", lb->filename, - strerror(errno)); - return (NULL); - } - n = strlen(lb->buf); - - /* Return it or an error if it fits */ - if (n > 0 && lb->buf[n - 1] == '\n') { - lb->buf[n - 1] = '\0'; - return (lb->buf); - } - if (n != lb->size - 1) { - if (lb->errfun) - (*lb->errfun)("%s: skipping incomplete last line\n", - lb->filename); - return (NULL); - } - /* Double the buffer if we need more space */ - lb->size *= 2; - if ((p = realloc(lb->buf, lb->size)) == NULL) { - lb->size /= 2; - if (lb->errfun) - (*lb->errfun)("linebuf (%s): realloc failed\n", - lb->filename); - return (NULL); - } - lb->buf = p; - } -} - -static int -fdlim_get(int hard) -{ -#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) - struct rlimit rlfd; - - if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) - return (-1); - if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY) - return 10000; - else - return hard ? rlfd.rlim_max : rlfd.rlim_cur; -#elif defined (HAVE_SYSCONF) - return sysconf (_SC_OPEN_MAX); -#else - return 10000; -#endif -} - -static int -fdlim_set(int lim) -{ -#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) - struct rlimit rlfd; -#endif - - if (lim <= 0) - return (-1); -#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) - if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) - return (-1); - rlfd.rlim_cur = lim; - if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0) - return (-1); -#elif defined (HAVE_SETDTABLESIZE) - setdtablesize(lim); -#endif - return (0); -} - -/* - * This is an strsep function that returns a null field for adjacent - * separators. This is the same as the 4.4BSD strsep, but different from the - * one in the GNU libc. - */ -static char * -xstrsep(char **str, const char *delim) -{ - char *s, *e; - - if (!**str) - return (NULL); - - s = *str; - e = s + strcspn(s, delim); - - if (*e != '\0') - *e++ = '\0'; - *str = e; - - return (s); -} - -/* - * Get the next non-null token (like GNU strsep). Strsep() will return a - * null token for two adjacent separators, so we may have to loop. - */ -static char * -strnnsep(char **stringp, char *delim) -{ - char *tok; - - do { - tok = xstrsep(stringp, delim); - } while (tok && *tok == '\0'); - return (tok); -} - -static Key * -keygrab_ssh1(con *c) -{ - static Key *rsa; - static Buffer msg; - - if (rsa == NULL) { - buffer_init(&msg); - rsa = key_new(KEY_RSA1); - } - buffer_append(&msg, c->c_data, c->c_plen); - buffer_consume(&msg, 8 - (c->c_plen & 7)); /* padding */ - if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) { - error("%s: invalid packet type", c->c_name); - buffer_clear(&msg); - return NULL; - } - buffer_consume(&msg, 8); /* cookie */ - - /* server key */ - (void) buffer_get_int(&msg); - buffer_get_bignum(&msg, rsa->rsa->e); - buffer_get_bignum(&msg, rsa->rsa->n); - - /* host key */ - (void) buffer_get_int(&msg); - buffer_get_bignum(&msg, rsa->rsa->e); - buffer_get_bignum(&msg, rsa->rsa->n); - - buffer_clear(&msg); - - return (rsa); -} - -static int -hostjump(Key *hostkey) -{ - kexjmp_key = hostkey; - longjmp(kexjmp, 1); - /* NOTREACHED */ - return (0); -} - -static int -ssh2_capable(int remote_major, int remote_minor) -{ - switch (remote_major) { - case 1: - if (remote_minor == 99) - return 1; - break; - case 2: - return 1; - default: - break; - } - return 0; -} - -static Key * -keygrab_ssh2(con *c) -{ - int j; - - packet_set_connection(c->c_fd, c->c_fd); - enable_compat20(); - my_clnt_proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - c->c_keytype == KT_DSA? "ssh-dss": "ssh-rsa"; - c->c_kex = kex_setup(c->c_name, my_clnt_proposal, NULL); - kex_start(c->c_kex); - c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; - c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; - c->c_kex->verify_host_key = hostjump; - - if (!(j = setjmp(kexjmp))) { - nonfatal_fatal = 1; - dispatch_run(DISPATCH_BLOCK, &c->c_kex->done, c->c_kex); - fprintf(stderr, "Impossible! dispatch_run() returned!\n"); - exit(1); - } - nonfatal_fatal = 0; - xfree(c->c_kex); - c->c_kex = NULL; - packet_close(); - - return j < 0? NULL : kexjmp_key; -} - -static void -keyprint(con *c, Key *key) -{ - if (!key) - return; - - fprintf(stdout, "%s ", c->c_output_name ? c->c_output_name : c->c_name); - key_write(key, stdout); - fputs("\n", stdout); -} - -static int -tcpconnect(char *host) -{ - struct addrinfo hints, *ai, *aitop; - char strport[NI_MAXSERV]; - int gaierr, s = -1; - - snprintf(strport, sizeof strport, "%d", ssh_port); - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_socktype = SOCK_STREAM; - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr)); - for (ai = aitop; ai; ai = ai->ai_next) { - s = socket(ai->ai_family, SOCK_STREAM, 0); - if (s < 0) { - error("socket: %s", strerror(errno)); - continue; - } - if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) - fatal("F_SETFL: %s", strerror(errno)); - if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 && - errno != EINPROGRESS) - error("connect (`%s'): %s", host, strerror(errno)); - else - break; - close(s); - s = -1; - } - freeaddrinfo(aitop); - return s; -} - -static int -conalloc(char *iname, char *oname, int keytype) -{ - char *namebase, *name, *namelist; - int s; - - namebase = namelist = xstrdup(iname); - - do { - name = xstrsep(&namelist, ","); - if (!name) { - xfree(namebase); - return (-1); - } - } while ((s = tcpconnect(name)) < 0); - - if (s >= maxfd) - fatal("conalloc: fdno %d too high", s); - if (fdcon[s].c_status) - fatal("conalloc: attempt to reuse fdno %d", s); - - fdcon[s].c_fd = s; - fdcon[s].c_status = CS_CON; - fdcon[s].c_namebase = namebase; - fdcon[s].c_name = name; - fdcon[s].c_namelist = namelist; - fdcon[s].c_output_name = xstrdup(oname); - fdcon[s].c_data = (char *) &fdcon[s].c_plen; - fdcon[s].c_len = 4; - fdcon[s].c_off = 0; - fdcon[s].c_keytype = keytype; - gettimeofday(&fdcon[s].c_tv, NULL); - fdcon[s].c_tv.tv_sec += timeout; - TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); - FD_SET(s, read_wait); - ncon++; - return (s); -} - -static void -confree(int s) -{ - if (s >= maxfd || fdcon[s].c_status == CS_UNUSED) - fatal("confree: attempt to free bad fdno %d", s); - close(s); - xfree(fdcon[s].c_namebase); - xfree(fdcon[s].c_output_name); - if (fdcon[s].c_status == CS_KEYS) - xfree(fdcon[s].c_data); - fdcon[s].c_status = CS_UNUSED; - fdcon[s].c_keytype = 0; - TAILQ_REMOVE(&tq, &fdcon[s], c_link); - FD_CLR(s, read_wait); - ncon--; -} - -static void -contouch(int s) -{ - TAILQ_REMOVE(&tq, &fdcon[s], c_link); - gettimeofday(&fdcon[s].c_tv, NULL); - fdcon[s].c_tv.tv_sec += timeout; - TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); -} - -static int -conrecycle(int s) -{ - con *c = &fdcon[s]; - int ret; - - ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype); - confree(s); - return (ret); -} - -static void -congreet(int s) -{ - int remote_major, remote_minor, n = 0; - char buf[256], *cp; - char remote_version[sizeof buf]; - size_t bufsiz; - con *c = &fdcon[s]; - - bufsiz = sizeof(buf); - cp = buf; - while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n') { - if (*cp == '\r') - *cp = '\n'; - cp++; - } - if (n < 0) { - if (errno != ECONNREFUSED) - error("read (%s): %s", c->c_name, strerror(errno)); - conrecycle(s); - return; - } - if (n == 0) { - error("%s: Connection closed by remote host", c->c_name); - conrecycle(s); - return; - } - if (*cp != '\n' && *cp != '\r') { - error("%s: bad greeting", c->c_name); - confree(s); - return; - } - *cp = '\0'; - if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", - &remote_major, &remote_minor, remote_version) == 3) - compat_datafellows(remote_version); - else - datafellows = 0; - if (c->c_keytype != KT_RSA1) { - if (!ssh2_capable(remote_major, remote_minor)) { - debug("%s doesn't support ssh2", c->c_name); - confree(s); - return; - } - } else if (remote_major != 1) { - debug("%s doesn't support ssh1", c->c_name); - confree(s); - return; - } - fprintf(stderr, "# %s %s\n", c->c_name, chop(buf)); - n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", - c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, - c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); - if (atomicio(write, s, buf, n) != n) { - error("write (%s): %s", c->c_name, strerror(errno)); - confree(s); - return; - } - if (c->c_keytype != KT_RSA1) { - keyprint(c, keygrab_ssh2(c)); - confree(s); - return; - } - c->c_status = CS_SIZE; - contouch(s); -} - -static void -conread(int s) -{ - con *c = &fdcon[s]; - int n; - - if (c->c_status == CS_CON) { - congreet(s); - return; - } - n = read(s, c->c_data + c->c_off, c->c_len - c->c_off); - if (n < 0) { - error("read (%s): %s", c->c_name, strerror(errno)); - confree(s); - return; - } - c->c_off += n; - - if (c->c_off == c->c_len) - switch (c->c_status) { - case CS_SIZE: - c->c_plen = htonl(c->c_plen); - c->c_len = c->c_plen + 8 - (c->c_plen & 7); - c->c_off = 0; - c->c_data = xmalloc(c->c_len); - c->c_status = CS_KEYS; - break; - case CS_KEYS: - keyprint(c, keygrab_ssh1(c)); - confree(s); - return; - break; - default: - fatal("conread: invalid status %d", c->c_status); - break; - } - - contouch(s); -} - -static void -conloop(void) -{ - struct timeval seltime, now; - fd_set *r, *e; - con *c; - int i; - - gettimeofday(&now, NULL); - c = TAILQ_FIRST(&tq); - - if (c && (c->c_tv.tv_sec > now.tv_sec || - (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) { - seltime = c->c_tv; - seltime.tv_sec -= now.tv_sec; - seltime.tv_usec -= now.tv_usec; - if (seltime.tv_usec < 0) { - seltime.tv_usec += 1000000; - seltime.tv_sec--; - } - } else - seltime.tv_sec = seltime.tv_usec = 0; - - r = xmalloc(read_wait_size); - memcpy(r, read_wait, read_wait_size); - e = xmalloc(read_wait_size); - memcpy(e, read_wait, read_wait_size); - - while (select(maxfd, r, NULL, e, &seltime) == -1 && - (errno == EAGAIN || errno == EINTR)) - ; - - for (i = 0; i < maxfd; i++) { - if (FD_ISSET(i, e)) { - error("%s: exception!", fdcon[i].c_name); - confree(i); - } else if (FD_ISSET(i, r)) - conread(i); - } - xfree(r); - xfree(e); - - c = TAILQ_FIRST(&tq); - while (c && (c->c_tv.tv_sec < now.tv_sec || - (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) { - int s = c->c_fd; - - c = TAILQ_NEXT(c, c_link); - conrecycle(s); - } -} - -static void -do_host(char *host) -{ - char *name = strnnsep(&host, " \t\n"); - int j; - - if (name == NULL) - return; - for (j = KT_RSA1; j <= KT_RSA; j *= 2) { - if (get_keytypes & j) { - while (ncon >= MAXCON) - conloop(); - conalloc(name, *host ? host : name, j); - } - } -} - -void -fatal(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_FATAL, fmt, args); - va_end(args); - if (nonfatal_fatal) - longjmp(kexjmp, -1); - else - fatal_cleanup(); -} - -static void -usage(void) -{ - fprintf(stderr, - gettext("Usage: %s [-v46] [-p port] [-T timeout] [-f file]\n" - "\t\t [host | addrlist namelist] [...]\n"), - __progname); - exit(1); -} - -int -main(int argc, char **argv) -{ - int debug_flag = 0, log_level = SYSLOG_LEVEL_INFO; - int opt, fopt_count = 0; - char *tname; - - extern int optind; - extern char *optarg; - - __progname = get_progname(argv[0]); - - (void) g11n_setlocale(LC_ALL, ""); - - init_rng(); - seed_rng(); - TAILQ_INIT(&tq); - - if (argc <= 1) - usage(); - - while ((opt = getopt(argc, argv, "v46p:T:t:f:")) != -1) { - switch (opt) { - case 'p': - ssh_port = a2port(optarg); - if (ssh_port == 0) { - fprintf(stderr, gettext("Bad port '%s'\n"), - optarg); - exit(1); - } - break; - case 'T': - timeout = convtime(optarg); - if (timeout == -1 || timeout == 0) { - fprintf(stderr, gettext("Bad timeout '%s'\n"), - optarg); - usage(); - } - break; - case 'v': - if (!debug_flag) { - debug_flag = 1; - log_level = SYSLOG_LEVEL_DEBUG1; - } - else if (log_level < SYSLOG_LEVEL_DEBUG3) - log_level++; - else - fatal("Too high debugging level."); - break; - case 'f': - if (strcmp(optarg, "-") == 0) - optarg = NULL; - argv[fopt_count++] = optarg; - break; - case 't': - get_keytypes = 0; - tname = strtok(optarg, ","); - while (tname) { - int type = key_type_from_name(tname); - switch (type) { - case KEY_RSA1: - get_keytypes |= KT_RSA1; - break; - case KEY_DSA: - get_keytypes |= KT_DSA; - break; - case KEY_RSA: - get_keytypes |= KT_RSA; - break; - case KEY_UNSPEC: - fatal("unknown key type %s", tname); - } - tname = strtok(NULL, ","); - } - break; - case '4': - IPv4or6 = AF_INET; - break; - case '6': - IPv4or6 = AF_INET6; - break; - case '?': - default: - usage(); - } - } - if (optind == argc && !fopt_count) - usage(); - - log_init("ssh-keyscan", log_level, SYSLOG_FACILITY_USER, 1); - - maxfd = fdlim_get(1); - if (maxfd < 0) - fatal("%s: fdlim_get: bad value", __progname); - if (maxfd > MAXMAXFD) - maxfd = MAXMAXFD; - if (MAXCON <= 0) - fatal("%s: not enough file descriptors", __progname); - if (maxfd > fdlim_get(0)) - fdlim_set(maxfd); - fdcon = xmalloc(maxfd * sizeof(con)); - memset(fdcon, 0, maxfd * sizeof(con)); - - read_wait_size = howmany(maxfd, NFDBITS) * sizeof(fd_mask); - read_wait = xmalloc(read_wait_size); - memset(read_wait, 0, read_wait_size); - - if (fopt_count) { - Linebuf *lb; - char *line; - int j; - - for (j = 0; j < fopt_count; j++) { - lb = Linebuf_alloc(argv[j], error); - if (!lb) - continue; - while ((line = Linebuf_getline(lb)) != NULL) - do_host(line); - Linebuf_free(lb); - } - } - - while (optind < argc) - do_host(argv[optind++]); - - while (ncon > 0) - conloop(); - - return (0); -} diff --git a/usr/src/cmd/ssh/ssh-keysign/Makefile b/usr/src/cmd/ssh/ssh-keysign/Makefile deleted file mode 100644 index 649935a050..0000000000 --- a/usr/src/cmd/ssh/ssh-keysign/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/ssh-keysign/Makefile - -PROG= ssh-keysign - -DIRS= $(ROOTLIBSSH) - - -OBJS = ssh-keysign.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -FILEMODE= 04555 - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lnsl -lz -lsunw_crypto - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ - -install: all $(DIRS) $(ROOTLIBSSHPROG) $(ROOTLIBSSH) - - -$(ROOTLIBSSHPROG)/%: % - $(INS.file) - -$(DIRS): - $(INS.dir) diff --git a/usr/src/cmd/ssh/ssh-keysign/ssh-keysign.c b/usr/src/cmd/ssh/ssh-keysign/ssh-keysign.c deleted file mode 100644 index 66f6fde586..0000000000 --- a/usr/src/cmd/ssh/ssh-keysign/ssh-keysign.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Copyright (c) 2002 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-keysign.c,v 1.7 2002/07/03 14:21:05 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <unistd.h> - -#include <openssl/evp.h> -#include <openssl/rand.h> -#include <openssl/rsa.h> - -#include "log.h" -#include "key.h" -#include "ssh.h" -#include "ssh2.h" -#include "misc.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "authfile.h" -#include "msg.h" -#include "canohost.h" -#include "pathnames.h" -#include "readconf.h" - -uid_t original_real_uid; /* XXX readconf.c needs this */ - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -#ifndef lint -char *__progname; -#endif /* lint */ -#endif - -static int -valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, - u_int datalen) -{ - Buffer b; - Key *key; - u_char *pkblob; - u_int blen, len; - char *pkalg, *p; - int pktype, fail; - - fail = 0; - - buffer_init(&b); - buffer_append(&b, data, datalen); - - /* session id, currently limited to SHA1 (20 bytes) */ - p = buffer_get_string(&b, &len); - if (len != 20) - fail++; - xfree(p); - - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) - fail++; - - /* server user */ - buffer_skip_string(&b); - - /* service */ - p = buffer_get_string(&b, NULL); - if (strcmp("ssh-connection", p) != 0) - fail++; - xfree(p); - - /* method */ - p = buffer_get_string(&b, NULL); - if (strcmp("hostbased", p) != 0) - fail++; - xfree(p); - - /* pubkey */ - pkalg = buffer_get_string(&b, NULL); - pkblob = buffer_get_string(&b, &blen); - - pktype = key_type_from_name(pkalg); - if (pktype == KEY_UNSPEC) - fail++; - else if ((key = key_from_blob(pkblob, blen)) == NULL) - fail++; - else if (key->type != pktype) - fail++; - xfree(pkalg); - xfree(pkblob); - - /* client host name, handle trailing dot */ - p = buffer_get_string(&b, &len); - debug2("valid_request: check expect chost %s got %s", host, p); - if (strlen(host) != len - 1) - fail++; - else if (p[len - 1] != '.') - fail++; - else if (strncasecmp(host, p, len - 1) != 0) - fail++; - xfree(p); - - /* local user */ - p = buffer_get_string(&b, NULL); - - if (strcmp(pw->pw_name, p) != 0) - fail++; - xfree(p); - - /* end of message */ - if (buffer_len(&b) != 0) - fail++; - - debug3("valid_request: fail %d", fail); - - if (fail && key != NULL) - key_free(key); - else - *ret = key; - - return (fail ? -1 : 0); -} - -int -main(int argc, char **argv) -{ - Buffer b; - Options options; - Key *keys[2], *key; - struct passwd *pw; - int key_fd[2], i, found, version = 2, fd; - u_char *signature, *data; - char *host; - u_int slen, dlen; - u_int32_t rnd[256]; - - /* - * Since these two open()s are all that's done here before - * dropping privileges with setreuid(), and since having been - * privileged protects ssh-keysign from core dumps and tracing, - * there's no need to use Least Privilege interfaces like - * setppriv(2). - */ - key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); - key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); - - (void) setreuid(getuid(), getuid()); - - (void) g11n_setlocale(LC_ALL, ""); - - init_rng(); - seed_rng(); - arc4random_stir(); - -#ifdef DEBUG_SSH_KEYSIGN - log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); -#endif - - /* verify that ssh-keysign is enabled by the admin */ - original_real_uid = getuid(); /* XXX readconf.c needs this */ - initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options); - fill_default_options(&options); - if (options.hostbased_authentication != 1) - fatal("Hostbased authentication not enabled in %s", - _PATH_HOST_CONFIG_FILE); - - if (key_fd[0] == -1 && key_fd[1] == -1) - fatal("could not open any host key"); - - if ((pw = getpwuid(getuid())) == NULL) - fatal("getpwuid failed"); - pw = pwcopy(pw); - - SSLeay_add_all_algorithms(); - for (i = 0; i < 256; i++) - rnd[i] = arc4random(); - RAND_seed(rnd, sizeof(rnd)); - - found = 0; - for (i = 0; i < 2; i++) { - keys[i] = NULL; - if (key_fd[i] == -1) - continue; - keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC, - NULL, NULL); - (void) close(key_fd[i]); - if (keys[i] != NULL && keys[i]->type == KEY_RSA) { - if (RSA_blinding_on(keys[i]->rsa, NULL) != 1) { - error("RSA_blinding_on failed"); - key_free(keys[i]); - keys[i] = NULL; - } - } - if (keys[i] != NULL) - found = 1; - } - if (!found) - fatal("no hostkey found"); - - buffer_init(&b); - if (ssh_msg_recv(STDIN_FILENO, &b) < 0) - fatal("ssh_msg_recv failed"); - if (buffer_get_char(&b) != version) - fatal("bad version"); - fd = buffer_get_int(&b); - if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO)) - fatal("bad fd"); - if ((host = get_local_name(fd)) == NULL) - fatal("cannot get sockname for fd"); - - data = buffer_get_string(&b, &dlen); - if (valid_request(pw, host, &key, data, dlen) < 0) - fatal("not a valid request"); - xfree(host); - - found = 0; - for (i = 0; i < 2; i++) { - if (keys[i] != NULL && - key_equal(key, keys[i])) { - found = 1; - break; - } - } - if (!found) - fatal("no matching hostkey found"); - - if (key_sign(keys[i], &signature, &slen, data, dlen) != 0) - fatal("key_sign failed"); - xfree(data); - - /* send reply */ - buffer_clear(&b); - buffer_put_string(&b, signature, slen); - ssh_msg_send(STDOUT_FILENO, version, &b); - - return (0); -} diff --git a/usr/src/cmd/ssh/ssh-socks5-proxy-connect/Makefile b/usr/src/cmd/ssh/ssh-socks5-proxy-connect/Makefile deleted file mode 100644 index 765aca9af0..0000000000 --- a/usr/src/cmd/ssh/ssh-socks5-proxy-connect/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -PROG= ssh-socks5-proxy-connect - -DIRS= $(ROOTLIBSSH) - -OBJS= ssh-socks5-proxy-connect.o - -SRCS= $(OBJS:.o=.c) - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket - -install: all $(DIRS) $(ROOTLIBSSHPROG) $(ROOTLIBSSH) - -$(ROOTLIBSSHPROG)/%: % - $(INS.file) - -$(DIRS): - $(INS.dir) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../../Makefile.targ -include ../Makefile.msg.targ diff --git a/usr/src/cmd/ssh/ssh-socks5-proxy-connect/ssh-socks5-proxy-connect.c b/usr/src/cmd/ssh/ssh-socks5-proxy-connect/ssh-socks5-proxy-connect.c deleted file mode 100644 index 131eb73fcc..0000000000 --- a/usr/src/cmd/ssh/ssh-socks5-proxy-connect/ssh-socks5-proxy-connect.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * A SOCKS client that let's users 'ssh' to the - * outside of the firewall by opening up a connection - * through the SOCKS server. Supports only SOCKS v5. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <strings.h> -#include <unistd.h> -#include <inttypes.h> -#include <errno.h> -#include <poll.h> -#include <signal.h> -#include <locale.h> -#include <libintl.h> -#include <netinet/in.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <sys/time.h> -#include <sys/stropts.h> -#include <sys/stat.h> -#include <sys/varargs.h> -#include "proxy-io.h" - -#define DEFAULT_SOCKS5_PORT "1080" - -static int debug_flag = 0; - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("Usage: ssh-socks5-proxy-connect " - "[-h socks5_proxy_host] [-p socks5_proxy_port] \n" - "remote_host remote_port\n")); - exit(1); -} - -/* PRINTFLIKE1 */ -static void -debug(const char *format, ...) -{ - char fmtbuf[BUFFER_SIZ]; - va_list args; - - if (debug_flag == 0) { - return; - } - va_start(args, format); - (void) snprintf(fmtbuf, sizeof (fmtbuf), - "ssh-socks5-proxy: %s\n", format); - (void) vfprintf(stderr, fmtbuf, args); - va_end(args); -} - -static void -signal_handler(int sig) -{ - exit(0); -} - -static int -do_version_exchange(int sockfd) -{ - char buffer[3], recv_buf[2]; - - buffer[0] = 0x05; /* VER */ - buffer[1] = 0x01; /* NMETHODS */ - buffer[2] = 0x00; /* METHODS */ - - if (write(sockfd, &buffer, sizeof (buffer)) < 0) { - perror("write"); - return (0); - } - - if (read(sockfd, &recv_buf, sizeof (recv_buf)) == -1) { - perror("read"); - return (0); - } - - /* - * No need to check the server's version as per - * the protocol spec. Check the method supported - * by the server. Currently if the server does not - * support NO AUTH, we disconnect. - */ - if (recv_buf[1] != 0x00) { - debug("Unsupported Authentication Method"); - return (0); - } - - /* Return success. */ - return (1); -} - -static void -send_request( - int sockfd, - const char *ssh_host, - uchar_t ssh_host_len, - uint16_t *ssh_port) -{ - int failure = 1; - char *buffer, *temp, recv_buf[BUFFER_SIZ]; - uchar_t version = 0x05, cmd = 0x01, rsv = 0x00, atyp = 0x03; - - buffer = malloc(strlen(ssh_host) + 7); - - temp = buffer; - - /* Assemble the request packet */ - (void) memcpy(temp, &version, sizeof (version)); - temp += sizeof (version); - (void) memcpy(temp, &cmd, sizeof (cmd)); - temp += sizeof (cmd); - (void) memcpy(temp, &rsv, sizeof (rsv)); - temp += sizeof (rsv); - (void) memcpy(temp, &atyp, sizeof (atyp)); - temp += sizeof (atyp); - (void) memcpy(temp, &ssh_host_len, sizeof (ssh_host_len)); - temp += sizeof (ssh_host_len); - (void) memcpy(temp, ssh_host, strlen(ssh_host)); - temp += strlen(ssh_host); - (void) memcpy(temp, ssh_port, sizeof (*ssh_port)); - temp += sizeof (*ssh_port); - - if (write(sockfd, buffer, temp - buffer) == -1) { - perror("write"); - exit(1); - } - - /* - * The maximum size of the protocol message we are waiting for is 10 - * bytes -- VER[1], REP[1], RSV[1], ATYP[1], BND.ADDR[4] and - * BND.PORT[2]; see RFC 1928, section "6. Replies" for more details. - * Everything else is already a part of the data we are supposed to - * deliver to the requester. We know that BND.ADDR is exactly 4 bytes - * since as you can see below, we accept only ATYP == 1 which specifies - * that the IPv4 address is in a binary format. - */ - if (read(sockfd, &recv_buf, 10) == -1) { - perror("read"); - exit(1); - } - - /* temp now points to the recieve buffer. */ - temp = recv_buf; - - /* Check the server's version. */ - if (*temp++ != 0x05) { - (void) fprintf(stderr, gettext("Unsupported SOCKS version: %x\n"), - recv_buf[0]); - exit(1); - } - - /* Check server's reply */ - switch (*temp++) { - case 0x00: - failure = 0; - debug("CONNECT command Succeeded."); - break; - case 0x01: - debug("General SOCKS server failure."); - break; - case 0x02: - debug("Connection not allowed by ruleset."); - break; - case 0x03: - debug("Network Unreachable."); - break; - case 0x04: - debug("Host unreachable."); - break; - case 0x05: - debug("Connection refused."); - break; - case 0x06: - debug("TTL expired."); - break; - case 0x07: - debug("Command not supported"); - break; - case 0x08: - debug("Address type not supported."); - break; - default: - (void) fprintf(stderr, gettext("ssh-socks5-proxy: " - "SOCKS Server reply not understood\n")); - } - - if (failure == 1) { - exit(1); - } - - /* Parse the rest of the packet */ - - /* Ignore RSV */ - temp++; - - /* Check ATYP */ - if (*temp != 0x01) { - (void) fprintf(stderr, gettext("ssh-socks5-proxy: " - "Address type not supported: %u\n"), *temp); - exit(1); - } - - free(buffer); -} - -int -main(int argc, char **argv) -{ - extern char *optarg; - extern int optind; - int retval, err_code, sock; - uint16_t ssh_port; - uchar_t ssh_host_len; - char *socks_server = NULL, *socks_port = NULL; - char *ssh_host; - struct addrinfo hints, *ai; - struct pollfd fds[2]; - - /* Initialization for variables, set locale and textdomain */ - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ -#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ -#endif - (void) textdomain(TEXT_DOMAIN); - - /* Set up the signal handler */ - (void) signal(SIGINT, signal_handler); - (void) signal(SIGPIPE, signal_handler); - (void) signal(SIGPOLL, signal_handler); - - while ((retval = getopt(argc, argv, "dp:h:")) != -1) { - switch (retval) { - case 'h': - socks_server = optarg; - break; - case 'p': - socks_port = optarg; - break; - case 'd': - debug_flag = 1; - break; - default: - break; - } - } - - if (optind != argc - 2) { - usage(); - } - - ssh_host = argv[optind++]; - ssh_host_len = (uchar_t)strlen(ssh_host); - ssh_port = htons(atoi(argv[optind])); - - /* - * If the name and/or port number of the - * socks server were not passed on the - * command line, try the user's environment. - */ - if (socks_server == NULL) { - if ((socks_server = getenv("SOCKS5_SERVER")) == NULL) { - (void) fprintf(stderr, gettext("ssh-socks5-proxy: " - "SOCKS5 SERVER not specified\n")); - exit(1); - } - } - if (socks_port == NULL) { - if ((socks_port = getenv("SOCKS5_PORT")) == NULL) { - socks_port = DEFAULT_SOCKS5_PORT; - } - } - - debug("SOCKS5_SERVER = %s", socks_server); - debug("SOCKS5_PORT = %s", socks_port); - - bzero(&hints, sizeof (struct addrinfo)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - if ((err_code = getaddrinfo(socks_server, socks_port, &hints, &ai)) - != 0) { - (void) fprintf(stderr, "%s: %s\n", socks_server, - gai_strerror(err_code)); - exit(1); - } - - if ((sock = socket(ai->ai_family, SOCK_STREAM, 0)) < 0) { - perror("socket"); - exit(1); - } - - /* Connect to the SOCKS server */ - if (connect(sock, ai->ai_addr, ai->ai_addrlen) == 0) { - debug("Connected to the SOCKS server"); - /* Do the SOCKS v5 communication with the server. */ - if (do_version_exchange(sock) > 0) { - debug("Done version exchange"); - send_request(sock, ssh_host, ssh_host_len, &ssh_port); - } else { - (void) fprintf(stderr, gettext("ssh-socks5-proxy: Client and " - "Server versions differ.\n")); - (void) close(sock); - exit(1); - } - } else { - perror("connect"); - (void) close(sock); - exit(1); - } - - fds[0].fd = STDIN_FILENO; /* Poll stdin for data. */ - fds[1].fd = sock; /* Poll the socket for data. */ - fds[0].events = fds[1].events = POLLIN; - - for (;;) { - if (poll(fds, 2, INFTIM) == -1) { - perror("poll"); - (void) close(sock); - exit(1); - } - - /* Data arrived on stdin, write it to the socket */ - if (fds[0].revents & POLLIN) { - if (proxy_read_write_loop(STDIN_FILENO, sock) == 0) { - (void) close(sock); - exit(1); - } - } else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { - (void) close(sock); - exit(1); - } - - /* Data arrived on the socket, write it to stdout */ - if (fds[1].revents & POLLIN) { - if (proxy_read_write_loop(sock, STDOUT_FILENO) == 0) { - (void) close(sock); - exit(1); - } - } else if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) { - (void) close(sock); - exit(1); - } - } - - /* NOTREACHED */ - return (0); -} diff --git a/usr/src/cmd/ssh/ssh/Makefile b/usr/src/cmd/ssh/ssh/Makefile deleted file mode 100644 index 2d77334497..0000000000 --- a/usr/src/cmd/ssh/ssh/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/ssh/Makefile - -PROG= ssh - -OBJS = ssh.o \ - sshconnect.o \ - sshconnect1.o \ - sshconnect2.o \ - sshtty.o \ - clientloop.o \ - gss-clnt.o -SRCS = $(OBJS:.o=.c) - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket \ - -lnsl \ - -lz \ - -lsunw_crypto \ - -lgss - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) ../libssh/$(MACH)/libssh.a ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -install: all $(ROOTPROG) - -clean: - $(RM) -f $(OBJS) $(PROG) - -lint: lint_SRCS - -include ../Makefile.msg.targ - -XGETFLAGS += --keyword=log -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/ssh/clientloop.c b/usr/src/cmd/ssh/ssh/clientloop.c deleted file mode 100644 index 8a9985c632..0000000000 --- a/usr/src/cmd/ssh/ssh/clientloop.c +++ /dev/null @@ -1,1626 +0,0 @@ -/* - * 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". - * - * - * 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, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.104 2002/08/22 19:38:42 stevesk Exp $"); - -#include "ssh.h" -#include "ssh1.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "packet.h" -#include "buffer.h" -#include "compat.h" -#include "channels.h" -#include "dispatch.h" -#include "buffer.h" -#include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "readconf.h" -#include "clientloop.h" -#include "authfd.h" -#include "atomicio.h" -#include "sshtty.h" -#include "misc.h" -#include "readpass.h" - -/* import options */ -extern Options options; - -/* Flag indicating that stdin should be redirected from /dev/null. */ -extern int stdin_null_flag; - -/* - * Name of the host we are connecting to. This is the name given on the - * command line, or the HostName specified for the user-supplied name in a - * configuration file. - */ -extern char *host; - -/* - * Flag to indicate that we have received a window change signal which has - * not yet been processed. This will cause a message indicating the new - * window size to be sent to the server a little later. This is volatile - * because this is updated in a signal handler. - */ -static volatile sig_atomic_t received_window_change_signal = 0; -static volatile sig_atomic_t received_signal = 0; - -/* Flag indicating whether the user's terminal is in non-blocking mode. */ -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. */ -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 u_long stdin_bytes, stdout_bytes, stderr_bytes; -static u_int buffer_high; /* Soft max buffer size. */ -static int connection_in; /* Connection to server (input). */ -static int connection_out; /* Connection to server (output). */ -static int need_rekeying; /* Set to non-zero if rekeying is requested. */ -static int session_closed = 0; /* In SSH2: login session closed. */ -static int server_alive_timeouts = 0; /* Number of outstanding alive packets. */ - -static void client_init_dispatch(void); -int session_ident = -1; - -/*XXX*/ -extern Kex *xxx_kex; - -extern int will_daemonize; - -/* Restores stdin to blocking mode. */ - -static void -leave_non_blocking(void) -{ - if (in_non_blocking_mode) { - (void) fcntl(fileno(stdin), F_SETFL, 0); - in_non_blocking_mode = 0; - fatal_remove_cleanup((void (*) (void *)) leave_non_blocking, NULL); - } -} - -/* Puts stdin terminal in non-blocking mode. */ - -static void -enter_non_blocking(void) -{ - in_non_blocking_mode = 1; - (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); - fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL); -} - -/* - * Signal handler for the window change signal (SIGWINCH). This just sets a - * flag indicating that the window has changed. - */ - -static void -window_change_handler(int sig) -{ - received_window_change_signal = 1; - signal(SIGWINCH, window_change_handler); -} - -/* - * Signal handler for signals that cause the program to terminate. These - * signals must be trapped to restore terminal modes. - */ - -static void -signal_handler(int sig) -{ - received_signal = sig; - quit_pending = 1; -} - -/* - * Returns current time in seconds from Jan 1, 1970 with the maximum - * available resolution. - */ - -static double -get_current_time(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; -} - -#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" -void -client_x11_get_proto(const char *display, const char *xauth_path, - u_int trusted, char **_proto, char **_data) -{ - char cmd[1024]; - char line[512]; - char xdisplay[512]; - static char proto[512], data[512]; - FILE *f; - int got_data = 0, generated = 0, do_unlink = 0, i; - char *xauthdir, *xauthfile; - struct stat st; - - xauthdir = xauthfile = NULL; - *_proto = proto; - *_data = data; - proto[0] = data[0] = '\0'; - - if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { - debug("No xauth program."); - } else { - if (display == NULL) { - debug("x11_get_proto: DISPLAY not set"); - return; - } - /* - * Handle FamilyLocal case where $DISPLAY does - * not match an authorization entry. For this we - * just try "xauth list unix:displaynum.screennum". - * XXX: "localhost" match to determine FamilyLocal - * is not perfect. - */ - if (strncmp(display, "localhost:", 10) == 0) { - snprintf(xdisplay, sizeof(xdisplay), "unix:%s", - display + 10); - display = xdisplay; - } - if (trusted == 0) { - xauthdir = xmalloc(MAXPATHLEN); - xauthfile = xmalloc(MAXPATHLEN); - strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); - if (mkdtemp(xauthdir) != NULL) { - do_unlink = 1; - snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", - xauthdir); - snprintf(cmd, sizeof(cmd), - "%s -f %s generate %s " SSH_X11_PROTO - " untrusted timeout 1200 2>" _PATH_DEVNULL, - xauth_path, xauthfile, display); - debug2("x11_get_proto: %s", cmd); - if (system(cmd) == 0) - generated = 1; - } - } - - /* - * When in untrusted mode, we read the cookie only if it was - * successfully generated as an untrusted one in the step - * above. - */ - if (trusted || generated) { - snprintf(cmd, sizeof(cmd), - "%s %s%s list %s 2>" _PATH_DEVNULL, - xauth_path, - generated ? "-f " : "" , - generated ? xauthfile : "", - display); - debug2("x11_get_proto: %s", cmd); - f = popen(cmd, "r"); - if (f && fgets(line, sizeof(line), f) && - sscanf(line, "%*s %511s %511s", proto, data) == 2) - got_data = 1; - if (f) - pclose(f); - } - else - error("Warning: untrusted X11 forwarding setup failed: " - "xauth key data not generated"); - } - - if (do_unlink) { - unlink(xauthfile); - rmdir(xauthdir); - } - if (xauthdir) - xfree(xauthdir); - if (xauthfile) - xfree(xauthfile); - - /* - * If we didn't get authentication data, just make up some - * data. The forwarding code will check the validity of the - * response anyway, and substitute this data. The X11 - * server, however, will ignore this fake data and use - * whatever authentication mechanisms it was using otherwise - * for the local connection. - */ - if (!got_data) { - u_int32_t rnd = 0; - - log("Warning: No xauth data; " - "using fake authentication data for X11 forwarding."); - strlcpy(proto, SSH_X11_PROTO, sizeof proto); - for (i = 0; i < 16; i++) { - if (i % 4 == 0) - rnd = arc4random(); - snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", - rnd & 0xff); - rnd >>= 8; - } - } -} - -/* - * This is called when the interactive is entered. This checks if there is - * an EOF coming on stdin. We must check this explicitly, as select() does - * not appear to wake up when redirecting from /dev/null. - */ - -static void -client_check_initial_eof_on_stdin(void) -{ - int len; - char buf[1]; - - /* - * If standard input is to be "redirected from /dev/null", we simply - * mark that we have seen an EOF and send an EOF message to the - * server. Otherwise, we try to read a single character; it appears - * that for some files, such /dev/null, select() never wakes up for - * read for this descriptor, which means that we never get EOF. This - * way we will get the EOF if stdin comes from /dev/null or similar. - */ - if (stdin_null_flag) { - /* Fake EOF on stdin. */ - debug("Sending eof."); - stdin_eof = 1; - packet_start(SSH_CMSG_EOF); - packet_send(); - } else { - enter_non_blocking(); - - /* Check for immediate EOF on stdin. */ - len = read(fileno(stdin), buf, 1); - if (len == 0) { - /* EOF. Record that we have seen it and send EOF to server. */ - debug("Sending eof."); - stdin_eof = 1; - packet_start(SSH_CMSG_EOF); - packet_send(); - } else if (len > 0) { - /* - * Got data. We must store the data in the buffer, - * and also process it as an escape character if - * appropriate. - */ - if ((u_char) buf[0] == escape_char) - escape_pending = 1; - else - buffer_append(&stdin_buffer, buf, 1); - } - leave_non_blocking(); - } -} - - -/* - * Make packets from buffered stdin data, and buffer them for sending to the - * connection. - */ - -static void -client_make_packets_from_stdin_data(void) -{ - u_int len; - - /* Send buffered stdin data to the server. */ - while (buffer_len(&stdin_buffer) > 0 && - packet_not_very_much_data_to_write()) { - len = buffer_len(&stdin_buffer); - /* Keep the packets at reasonable size. */ - if (len > packet_get_maxsize()) - len = packet_get_maxsize(); - packet_start(SSH_CMSG_STDIN_DATA); - packet_put_string(buffer_ptr(&stdin_buffer), len); - packet_send(); - buffer_consume(&stdin_buffer, len); - stdin_bytes += len; - /* If we have a pending EOF, send it now. */ - if (stdin_eof && buffer_len(&stdin_buffer) == 0) { - packet_start(SSH_CMSG_EOF); - packet_send(); - } - } -} - -/* - * Checks if the client window has changed, and sends a packet about it to - * the server if so. The actual change is detected elsewhere (by a software - * interrupt on Unix); this just checks the flag and sends a message if - * appropriate. - */ - -static void -client_check_window_change(void) -{ - struct winsize ws; - Channel *c; - - if (! received_window_change_signal) - return; - - /* - * We want to send a window-change request only when a session is - * already established and alive. - * - * Note: During session handshake we cannot send window-change request, - * because we do not know the remote channel ID yet. We have to store - * the information about signals which have arrived and send the - * window-change request when the channel and the session are fully - * established. - */ - if (compat20) { - if (session_ident == -1 || session_closed) - return; - c = channel_lookup(session_ident); - if (c == NULL || c->type != SSH_CHANNEL_OPEN || - c->remote_id == -1) - return; - } - - received_window_change_signal = 0; - - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - return; - - debug2("client_check_window_change: changed"); - - if (compat20) { - channel_request_start(session_ident, "window-change", 0); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - packet_send(); - } else { - packet_start(SSH_CMSG_WINDOW_SIZE); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - packet_send(); - } -} - -static void -client_global_request_reply(int type, u_int32_t seq, void *ctxt) -{ - server_alive_timeouts = 0; - client_global_request_reply_fwd(type, seq, ctxt); -} - -static void -server_alive_check(void) -{ - if (++server_alive_timeouts > options.server_alive_count_max) { - log("Timeout, server not responding."); - fatal_cleanup(); - } - packet_start(SSH2_MSG_GLOBAL_REQUEST); - packet_put_cstring("keepalive@openssh.com"); - packet_put_char(1); /* boolean: want reply */ - packet_send(); -} - -/* - * Waits until the client can do something (some data becomes available on - * one of the file descriptors). - */ - -static void -client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, - int *maxfdp, int *nallocp, int rekeying) -{ - struct timeval tv, *tvp; - int ret; - - /* Add any selections by the channel mechanism. */ - channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); - - if (!compat20) { - /* Read from the connection, unless our buffers are full. */ - if (buffer_len(&stdout_buffer) < buffer_high && - buffer_len(&stderr_buffer) < buffer_high && - channel_not_very_much_buffered_data()) - FD_SET(connection_in, *readsetp); - /* - * Read from stdin, unless we have seen EOF or have very much - * buffered data to send to the server. - */ - if (!stdin_eof && packet_not_very_much_data_to_write()) - FD_SET(fileno(stdin), *readsetp); - - /* Select stdout/stderr if have data in buffer. */ - if (buffer_len(&stdout_buffer) > 0) - FD_SET(fileno(stdout), *writesetp); - if (buffer_len(&stderr_buffer) > 0) - FD_SET(fileno(stderr), *writesetp); - } else { - /* channel_prepare_select could have closed the last channel */ - if (session_closed && !channel_still_open() && - !packet_have_data_to_write()) { - /* clear mask since we did not call select() */ - memset(*readsetp, 0, *nallocp); - memset(*writesetp, 0, *nallocp); - return; - } else { - FD_SET(connection_in, *readsetp); - } - } - - /* Select server connection if have data to write to the server. */ - if (packet_have_data_to_write()) - FD_SET(connection_out, *writesetp); - - /* - * Wait for something to happen. This will suspend the process until - * some selected descriptor can be read, written, or has some other - * event pending. - */ - - if (options.server_alive_interval == 0 || !compat20) - tvp = NULL; - else { - tv.tv_sec = options.server_alive_interval; - tv.tv_usec = 0; - tvp = &tv; - } - ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); - if (ret < 0) { - char buf[100]; - - /* - * We have to clear the select masks, because we return. - * We have to return, because the mainloop checks for the flags - * set by the signal handlers. - */ - memset(*readsetp, 0, *nallocp); - memset(*writesetp, 0, *nallocp); - - if (errno == EINTR) - return; - /* Note: we might still have data in the buffers. */ - snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); - buffer_append(&stderr_buffer, buf, strlen(buf)); - quit_pending = 1; - } else if (ret == 0) - server_alive_check(); -} - -static void -client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) -{ - struct winsize oldws, newws; - - /* Flush stdout and stderr buffers. */ - 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(); - - /* - * Free (and clear) the buffer to reduce the amount of data that gets - * written to swap. - */ - buffer_free(bin); - buffer_free(bout); - buffer_free(berr); - - /* Save old window size. */ - ioctl(fileno(stdin), TIOCGWINSZ, &oldws); - - /* Send the suspend signal to the program itself. */ - kill(getpid(), SIGTSTP); - - /* Check if the window size has changed. */ - if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 && - (oldws.ws_row != newws.ws_row || - oldws.ws_col != newws.ws_col || - oldws.ws_xpixel != newws.ws_xpixel || - oldws.ws_ypixel != newws.ws_ypixel)) - received_window_change_signal = 1; - - /* OK, we have been continued by the user. Reinitialize buffers. */ - buffer_init(bin); - buffer_init(bout); - buffer_init(berr); - - enter_raw_mode(); -} - -static void -client_process_net_input(fd_set * readset) -{ - int len; - char buf[8192]; - - /* - * Read input from the server, and add any such data to the buffer of - * the packet subsystem. - */ - if (FD_ISSET(connection_in, readset)) { - /* Read as much as possible. */ - len = read(connection_in, buf, sizeof(buf)); - if (len == 0) { - /* Received EOF. The remote host has closed the connection. */ - snprintf(buf, sizeof buf, - gettext("Connection to %.300s closed " - "by remote host.\n"), - host); - buffer_append(&stderr_buffer, buf, strlen(buf)); - quit_pending = 1; - return; - } - /* - * There is a kernel bug on Solaris that causes select to - * sometimes wake up even though there is no data available. - */ - if (len < 0 && (errno == EAGAIN || errno == EINTR)) - len = 0; - - if (len < 0) { - /* An error has encountered. Perhaps there is a network problem. */ - snprintf(buf, sizeof buf, - gettext("Read from remote host " - "%.300s: %.100s\n"), - host, strerror(errno)); - buffer_append(&stderr_buffer, buf, strlen(buf)); - quit_pending = 1; - return; - } - packet_process_incoming(buf, len); - } -} - -static void -process_cmdline(void) -{ - void (*handler)(int); - char *s, *cmd; - int delete = 0; - int local = 0; - Forward fwd; - - memset(&fwd, 0, sizeof(fwd)); - - leave_raw_mode(); - handler = signal(SIGINT, SIG_IGN); - cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); - if (s == NULL) - goto out; - while (isspace(*s)) - s++; - if (*s == '-') - s++; /* Skip cmdline '-', if any */ - if (*s == '\0') - goto out; - - if (*s == 'h' || *s == 'H' || *s == '?') { - log("Commands:"); - log(" -L[bind_address:]port:host:hostport " - "Request local forward"); - log(" -R[bind_address:]port:host:hostport " - "Request remote forward"); - log(" -KR[bind_address:]port " - "Cancel remote forward"); - goto out; - } - - if (*s == 'K') { - delete = 1; - s++; - } - if (*s != 'L' && *s != 'R') { - log("Invalid command."); - goto out; - } - if (*s == 'L') - local = 1; - if (local && delete) { - log("Not supported."); - goto out; - } - if ((!local || delete) && !compat20) { - log("Not supported for SSH protocol version 1."); - goto out; - } - - while (isspace(*++s)) - ; - - if (delete) { - if (parse_forward(0, &fwd, s) == 0) { - log("Bad forwarding close port"); - goto out; - } - channel_request_rforward_cancel(fwd.listen_host, fwd.listen_port); - } else { - if (parse_forward(1, &fwd, s) == 0) { - log("Bad forwarding specification."); - goto out; - } - if (local) { - if (channel_setup_local_fwd_listener(fwd.listen_host, - fwd.listen_port, fwd.connect_host, - fwd.connect_port, options.gateway_ports) < 0) { - log("Port forwarding failed."); - goto out; - } - } else { - if (channel_request_remote_forwarding(fwd.listen_host, - fwd.listen_port, fwd.connect_host, - fwd.connect_port) < 0) { - log("Port forwarding failed."); - goto out; - } - } - - log("Forwarding port."); - } - -out: - signal(SIGINT, handler); - enter_raw_mode(); - if (cmd != NULL) - xfree(cmd); - if (fwd.listen_host != NULL) - xfree(fwd.listen_host); - if (fwd.connect_host != NULL) - xfree(fwd.connect_host); -} - -/* - * If we are using the engine we must not fork until we do key reexchange. See - * PKCS#11 spec for more information on fork safety and packet.c for information - * about forking with the engine. - */ -void -client_daemonize(void) -{ - if (compat20 == 1 && options.use_openssl_engine == 1) { - will_daemonize = 1; - debug("must rekey before daemonizing"); - kex_send_kexinit(xxx_kex); - need_rekeying = 0; - } - else { - if (daemon(1, 1) < 0) { - fatal("daemon() failed: %.200s", - strerror(errno)); - } - } -} - -/* process the characters one by one */ -static int -process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) -{ - char string[1536]; - int bytes = 0; - u_int i; - u_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)); - - quit_pending = 1; - return -1; - - case 'Z' - 64: - /* Suspend the program. */ - /* Print a message to that effect to the user. */ - snprintf(string, sizeof string, - gettext("%c^Z [suspend ssh]\n"), - escape_char); - buffer_append(berr, string, strlen(string)); - - /* Restore terminal modes and suspend. */ - client_suspend_self(bin, bout, berr); - - /* We have been continued. */ - continue; - - case 'B': - if (compat20) { - snprintf(string, sizeof string, - gettext("%cB [sent break]\n"), - escape_char); - buffer_append(berr, string, - strlen(string)); - channel_request_start(session_ident, - "break", 0); - packet_put_int(1000); - packet_send(); - } - continue; - - case 'R': - if (compat20) { - if (datafellows & SSH_BUG_NOREKEY) - log("Server does not support re-keying"); - else - need_rekeying = 1; - } - continue; - - case '&': - /* - * Detach the program (continue to serve connections, - * but put in background and no more new connections). - */ - /* Restore tty modes. */ - leave_raw_mode(); - - /* Stop listening for new connections. */ - channel_stop_listening(); - - snprintf(string, sizeof string, - gettext("%c& [backgrounded]\n"), - escape_char); - buffer_append(berr, string, strlen(string)); - - client_daemonize(); - - /* The child continues serving connections. */ - if (compat20) { - buffer_append(bin, "\004", 1); - /* fake EOF on stdin */ - return -1; - } else 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(); - } - } - continue; - - case '?': - snprintf(string, sizeof string, gettext( -"%c?\n\ -Supported escape sequences:\n\ -%c. - terminate connection\n\ -%cB - send break (SSH protocol 2 only)\n\ -%cC - open a command line\n\ -%cR - Request rekey (SSH protocol 2 only)\n\ -%c^Z - suspend ssh\n\ -%c# - list forwarded connections\n\ -%c& - background ssh (when waiting for connections to terminate)\n\ -%c? - this message\n\ -%c%c - send the escape character by typing it twice\n\ -(Note that escapes are only recognized immediately after newline.)\n"), - escape_char, escape_char, escape_char, escape_char, - escape_char, escape_char, escape_char, escape_char, - escape_char, 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; - - case 'C': - process_cmdline(); - 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; -} - -static void -client_process_input(fd_set * readset) -{ - int len; - char buf[8192]; - - /* Read input from stdin. */ - if (FD_ISSET(fileno(stdin), readset)) { - /* Read as much as possible. */ - len = read(fileno(stdin), buf, sizeof(buf)); - if (len < 0 && (errno == EAGAIN || errno == EINTR)) - return; /* we'll try again later */ - if (len <= 0) { - /* - * Received EOF or error. They are treated - * similarly, except that an error message is printed - * if it was an error condition. - */ - if (len < 0) { - snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); - buffer_append(&stderr_buffer, buf, strlen(buf)); - } - /* Mark that we have seen EOF. */ - stdin_eof = 1; - /* - * Send an EOF message to the server unless there is - * data in the buffer. If there is data in the - * buffer, no message will be sent now. Code - * elsewhere will send the EOF when the buffer - * becomes empty if stdin_eof is set. - */ - if (buffer_len(&stdin_buffer) == 0) { - packet_start(SSH_CMSG_EOF); - packet_send(); - } - } else if (escape_char == SSH_ESCAPECHAR_NONE) { - /* - * Normal successful read, and no escape character. - * Just append the data to buffer. - */ - buffer_append(&stdin_buffer, buf, len); - } else { - /* - * Normal, successful read. But we have an escape character - * and have to process the characters one by one. - */ - if (process_escapes(&stdin_buffer, &stdout_buffer, - &stderr_buffer, buf, len) == -1) - return; - } - } -} - -static void -client_process_output(fd_set * writeset) -{ - int len; - char buf[100]; - - /* Write buffered output to stdout. */ - if (FD_ISSET(fileno(stdout), writeset)) { - /* Write as much data as possible. */ - len = write(fileno(stdout), buffer_ptr(&stdout_buffer), - buffer_len(&stdout_buffer)); - if (len <= 0) { - if (errno == EINTR || errno == EAGAIN) - len = 0; - else { - /* - * An error or EOF was encountered. Put an - * error message to stderr buffer. - */ - snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); - buffer_append(&stderr_buffer, buf, strlen(buf)); - quit_pending = 1; - return; - } - } - /* Consume printed data from the buffer. */ - buffer_consume(&stdout_buffer, len); - stdout_bytes += len; - } - /* Write buffered output to stderr. */ - if (FD_ISSET(fileno(stderr), writeset)) { - /* Write as much data as possible. */ - len = write(fileno(stderr), buffer_ptr(&stderr_buffer), - buffer_len(&stderr_buffer)); - if (len <= 0) { - if (errno == EINTR || errno == EAGAIN) - len = 0; - else { - /* EOF or error, but can't even print error message. */ - quit_pending = 1; - return; - } - } - /* Consume printed characters from the buffer. */ - buffer_consume(&stderr_buffer, len); - stderr_bytes += len; - } -} - -/* - * Get packets from the connection input buffer, and process them as long as - * there are packets available. - * - * Any unknown packets received during the actual - * session cause the session to terminate. This is - * intended to make debugging easier since no - * confirmations are sent. Any compatible protocol - * extensions must be negotiated during the - * preparatory phase. - */ - -static void -client_process_buffered_input_packets(void) -{ - dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL); -} - -/* scan buf[] for '~' before sending data to the peer */ - -static 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); -} - -static void -client_channel_closed(int id, void *arg) -{ - if (id != session_ident) - error("client_channel_closed: id %d != session_ident %d", - id, session_ident); - channel_cancel_cleanup(id); - session_closed = 1; - if (in_raw_mode()) - leave_raw_mode(); -} - -/* - * Implements the interactive session with the server. This is called after - * the user has been authenticated, and a command has been started on the - * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character - * used as an escape character for terminating or suspending the session. - */ - -int -client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) -{ - fd_set *readset = NULL, *writeset = NULL; - double start_time, total_time; - int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; - char buf[100]; - - debug("Entering interactive session."); - - start_time = get_current_time(); - - /* Initialize variables. */ - escape_pending = 0; - last_was_cr = 1; - exit_status = -1; - stdin_eof = 0; - buffer_high = 64 * 1024; - connection_in = packet_get_connection_in(); - connection_out = packet_get_connection_out(); - max_fd = MAX(connection_in, connection_out); - - if (!compat20) { - /* enable nonblocking unless tty */ - if (!isatty(fileno(stdin))) - set_nonblock(fileno(stdin)); - if (!isatty(fileno(stdout))) - set_nonblock(fileno(stdout)); - if (!isatty(fileno(stderr))) - set_nonblock(fileno(stderr)); - max_fd = MAX(max_fd, fileno(stdin)); - max_fd = MAX(max_fd, fileno(stdout)); - max_fd = MAX(max_fd, fileno(stderr)); - } - stdin_bytes = 0; - stdout_bytes = 0; - stderr_bytes = 0; - quit_pending = 0; - escape_char = escape_char_arg; - - /* Initialize buffers. */ - buffer_init(&stdin_buffer); - buffer_init(&stdout_buffer); - buffer_init(&stderr_buffer); - - client_init_dispatch(); - - /* - * Set signal handlers to restore non-blocking mode, but - * don't overwrite SIG_IGN - matches behavious from rsh(1). - */ - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, signal_handler); - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, signal_handler); - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, signal_handler); - if (have_pty) - signal(SIGWINCH, window_change_handler); - - if (have_pty) - enter_raw_mode(); - - if (compat20) { - session_ident = ssh2_chan_id; - if (escape_char != SSH_ESCAPECHAR_NONE) - channel_register_filter(session_ident, - simple_escape_filter); - if (session_ident != -1) - channel_register_cleanup(session_ident, - client_channel_closed); - } else { - /* Check if we should immediately send eof on stdin. */ - client_check_initial_eof_on_stdin(); - } - - /* Main loop of the client for the interactive session mode. */ - while (!quit_pending) { - - /* Process buffered packets sent by the server. */ - client_process_buffered_input_packets(); - - if (compat20 && session_closed && !channel_still_open()) - break; - - rekeying = (xxx_kex != NULL && !xxx_kex->done); - - if (rekeying) { - debug("rekeying in progress"); - } else { - /* - * Make packets of buffered stdin data, and buffer - * them for sending to the server. - */ - if (!compat20) - client_make_packets_from_stdin_data(); - - /* - * Make packets from buffered channel data, and - * enqueue them for sending to the server. - */ - if (packet_not_very_much_data_to_write()) - channel_output_poll(); - - /* - * Check if the window size has changed, and buffer a - * message about it to the server if so. - */ - client_check_window_change(); - - if (quit_pending) - break; - } - /* - * Wait until we have something to do (something becomes - * available on one of the descriptors). - */ - max_fd2 = max_fd; - client_wait_until_can_do_something(&readset, &writeset, - &max_fd2, &nalloc, rekeying); - - if (quit_pending) - break; - - /* Do channel operations unless rekeying in progress. */ - if (!rekeying) { - channel_after_select(readset, writeset); - if (need_rekeying || packet_need_rekeying()) { - debug("rekey limit reached, need rekeying"); - kex_send_kexinit(xxx_kex); - need_rekeying = 0; - } - } - - /* Buffer input from the connection. */ - client_process_net_input(readset); - - if (quit_pending) - break; - - if (!compat20) { - /* Buffer data from stdin */ - client_process_input(readset); - /* - * Process output to stdout and stderr. Output to - * the connection is processed elsewhere (above). - */ - client_process_output(writeset); - } - - /* Send as much buffered packet data as possible to the sender. */ - if (FD_ISSET(connection_out, writeset)) - packet_write_poll(); - } - if (readset) - xfree(readset); - if (writeset) - xfree(writeset); - - /* Terminate the session. */ - - /* Stop watching for window change. */ - if (have_pty) - signal(SIGWINCH, SIG_DFL); - - channel_free_all(); - - if (have_pty) - leave_raw_mode(); - - /* restore blocking io */ - if (!isatty(fileno(stdin))) - unset_nonblock(fileno(stdin)); - if (!isatty(fileno(stdout))) - unset_nonblock(fileno(stdout)); - if (!isatty(fileno(stderr))) - unset_nonblock(fileno(stderr)); - - if (received_signal) { - if (in_non_blocking_mode) /* XXX */ - leave_non_blocking(); - fatal("Killed by signal %d.", (int) received_signal); - } - - /* - * In interactive mode (with pseudo tty) display a message indicating - * that the connection has been closed. - */ - if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { - snprintf(buf, sizeof buf, - gettext("Connection to %.64s closed.\n"), - host); - buffer_append(&stderr_buffer, buf, strlen(buf)); - } - - /* Output any buffered data for stdout. */ - while (buffer_len(&stdout_buffer) > 0) { - len = write(fileno(stdout), buffer_ptr(&stdout_buffer), - buffer_len(&stdout_buffer)); - if (len <= 0) { - error("Write failed flushing stdout buffer."); - break; - } - buffer_consume(&stdout_buffer, len); - stdout_bytes += len; - } - - /* Output any buffered data for stderr. */ - while (buffer_len(&stderr_buffer) > 0) { - len = write(fileno(stderr), buffer_ptr(&stderr_buffer), - buffer_len(&stderr_buffer)); - if (len <= 0) { - error("Write failed flushing stderr buffer."); - break; - } - buffer_consume(&stderr_buffer, len); - stderr_bytes += len; - } - - /* Clear and free any buffers. */ - memset(buf, 0, sizeof(buf)); - buffer_free(&stdin_buffer); - buffer_free(&stdout_buffer); - buffer_free(&stderr_buffer); - - /* Report bytes transferred, and transfer rates. */ - total_time = get_current_time() - start_time; - debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", - stdin_bytes, stdout_bytes, stderr_bytes, total_time); - if (total_time > 0) - debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", - stdin_bytes / total_time, stdout_bytes / total_time, - stderr_bytes / total_time); - - /* Return the exit status of the program. */ - debug("Exit status %d", exit_status); - return exit_status; -} - -/*********/ - -static void -client_input_stdout_data(int type, u_int32_t seq, void *ctxt) -{ - u_int data_len; - char *data = packet_get_string(&data_len); - packet_check_eom(); - buffer_append(&stdout_buffer, data, data_len); - memset(data, 0, data_len); - xfree(data); -} -static void -client_input_stderr_data(int type, u_int32_t seq, void *ctxt) -{ - u_int data_len; - char *data = packet_get_string(&data_len); - packet_check_eom(); - buffer_append(&stderr_buffer, data, data_len); - memset(data, 0, data_len); - xfree(data); -} -static void -client_input_exit_status(int type, u_int32_t seq, void *ctxt) -{ - exit_status = packet_get_int(); - packet_check_eom(); - /* Acknowledge the exit. */ - packet_start(SSH_CMSG_EXIT_CONFIRMATION); - packet_send(); - /* - * Must wait for packet to be sent since we are - * exiting the loop. - */ - packet_write_wait(); - /* Flag that we want to exit. */ - quit_pending = 1; -} - -static Channel * -client_request_forwarded_tcpip(const char *request_type, int rchan) -{ - Channel *c = NULL; - char *listen_address, *originator_address; - int listen_port, originator_port; - int sock; - - /* Get rest of the packet */ - listen_address = packet_get_string(NULL); - listen_port = packet_get_int(); - originator_address = packet_get_string(NULL); - originator_port = packet_get_int(); - packet_check_eom(); - - debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d", - listen_address, listen_port, originator_address, originator_port); - - sock = channel_connect_by_listen_address(listen_port); - if (sock < 0) { - xfree(originator_address); - xfree(listen_address); - return NULL; - } - c = channel_new("forwarded-tcpip", - SSH_CHANNEL_CONNECTING, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - xstrdup(originator_address), 1); - xfree(originator_address); - xfree(listen_address); - return c; -} - -static Channel * -client_request_x11(const char *request_type, int rchan) -{ - Channel *c = NULL; - char *originator; - int originator_port; - int sock; - - if (!options.forward_x11) { - error("Warning: ssh server tried X11 forwarding."); - error("Warning: this is probably a break in attempt by a malicious server."); - return NULL; - } - originator = packet_get_string(NULL); - if (datafellows & SSH_BUG_X11FWD) { - debug2("buggy server: x11 request w/o originator_port"); - originator_port = 0; - } else { - originator_port = packet_get_int(); - } - packet_check_eom(); - /* XXX check permission */ - debug("client_request_x11: request from %s %d", originator, - originator_port); - xfree(originator); - sock = x11_connect_display(); - if (sock < 0) - return NULL; - c = channel_new("x11", - SSH_CHANNEL_X11_OPEN, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, - xstrdup("x11"), 1); - c->force_drain = 1; - return c; -} - -static Channel * -client_request_agent(const char *request_type, int rchan) -{ - Channel *c = NULL; - int sock; - - if (!options.forward_agent) { - error("Warning: ssh server tried agent forwarding."); - error("Warning: this is probably a break in attempt by a malicious server."); - return NULL; - } - sock = ssh_get_authentication_socket(); - if (sock < 0) - return NULL; - c = channel_new("authentication agent connection", - SSH_CHANNEL_OPEN, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - xstrdup("authentication agent connection"), 1); - c->force_drain = 1; - return c; -} - -/* XXXX move to generic input handler */ -static void -client_input_channel_open(int type, u_int32_t seq, void *ctxt) -{ - Channel *c = NULL; - char *ctype; - int rchan; - u_int rmaxpack, rwindow, len; - - ctype = packet_get_string(&len); - rchan = packet_get_int(); - rwindow = packet_get_int(); - rmaxpack = packet_get_int(); - - debug("client_input_channel_open: ctype %s rchan %d win %d max %d", - ctype, rchan, rwindow, rmaxpack); - - if (strcmp(ctype, "forwarded-tcpip") == 0) { - c = client_request_forwarded_tcpip(ctype, rchan); - } else if (strcmp(ctype, "x11") == 0) { - c = client_request_x11(ctype, rchan); - } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { - c = client_request_agent(ctype, rchan); - } -/* XXX duplicate : */ - if (c != NULL) { - debug("confirm %s", ctype); - c->remote_id = rchan; - c->remote_window = rwindow; - c->remote_maxpacket = rmaxpack; - if (c->type != SSH_CHANNEL_CONNECTING) { - packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(c->remote_id); - packet_put_int(c->self); - packet_put_int(c->local_window); - packet_put_int(c->local_maxpacket); - packet_send(); - } - } else { - debug("failure %s", ctype); - packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(rchan); - packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); - if (!(datafellows & SSH_BUG_OPENFAILURE)) { - packet_put_utf8_cstring("open failed"); - packet_put_cstring(""); - } - packet_send(); - } - xfree(ctype); -} - -static void -client_input_channel_req(int type, u_int32_t seq, void *ctxt) -{ - Channel *c = NULL; - int id, reply, success = 0; - char *rtype; - - id = packet_get_int(); - rtype = packet_get_string(NULL); - reply = packet_get_char(); - - debug("client_input_channel_req: channel %d rtype %s reply %d", - id, rtype, reply); - - if (session_ident == -1) { - error("client_input_channel_req: no channel %d", session_ident); - } else if (id != session_ident) { - error("client_input_channel_req: channel %d: wrong channel: %d", - session_ident, id); - } - c = channel_lookup(id); - if (c == NULL) { - error("client_input_channel_req: channel %d: unknown channel", id); - } else if (strcmp(rtype, "eow@openssh.com") == 0) { - packet_check_eom(); - chan_rcvd_eow(c); - } else if (strcmp(rtype, "exit-status") == 0) { - success = 1; - exit_status = packet_get_int(); - packet_check_eom(); - } - if (reply) { - packet_start(success ? - SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); - packet_put_int(c->remote_id); - packet_send(); - } - xfree(rtype); -} - -static void -client_input_global_request(int type, u_int32_t seq, void *ctxt) -{ - char *rtype; - int want_reply; - int success = 0; - - rtype = packet_get_string(NULL); - want_reply = packet_get_char(); - debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply); - if (want_reply) { - packet_start(success ? - SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); - packet_send(); - packet_write_wait(); - } - xfree(rtype); -} - -static void -client_init_dispatch_20(void) -{ - dispatch_init(&dispatch_protocol_error); - - dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); - dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); - dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); - dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); - dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); - dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); - dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); - dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); - dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); - dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); - - /* rekeying */ - dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); - - /* global request reply messages */ - dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); - dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); -} - -static void -client_init_dispatch_13(void) -{ - dispatch_init(NULL); - dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); - dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); - dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); - dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); - dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); - dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); - dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); - dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); - dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); - - dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? - &auth_input_open_request : &deny_input_open); - dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? - &x11_input_open : &deny_input_open); -} - -static void -client_init_dispatch_15(void) -{ - client_init_dispatch_13(); - dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); - dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); -} - -static void -client_init_dispatch(void) -{ - if (compat20) - client_init_dispatch_20(); - else if (compat13) - client_init_dispatch_13(); - else - client_init_dispatch_15(); -} diff --git a/usr/src/cmd/ssh/ssh/gss-clnt.c b/usr/src/cmd/ssh/ssh/gss-clnt.c deleted file mode 100644 index 05cd358217..0000000000 --- a/usr/src/cmd/ssh/ssh/gss-clnt.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" - -#ifdef GSSAPI - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "ssh.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "packet.h" -#include "compat.h" -#include <openssl/evp.h> -#include "cipher.h" -#include "kex.h" -#include "log.h" -#include "compat.h" - -#include <netdb.h> - -#include "ssh-gss.h" - -void -ssh_gssapi_client_kex_hook(Kex *kex, char **proposal) -{ - gss_OID_set mechs = GSS_C_NULL_OID_SET; - - if (kex == NULL || kex->serverhost == NULL) - fatal("INTERNAL ERROR (%s)", __func__); - - ssh_gssapi_client_mechs(kex->serverhost, &mechs); - ssh_gssapi_modify_kex(kex, mechs, proposal); -} - -void -ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs) -{ - gss_OID_set indicated = GSS_C_NULL_OID_SET; - gss_OID_set acquired, supported; - gss_OID mech; - gss_cred_id_t creds; - Gssctxt *ctxt = NULL; - gss_buffer_desc tok; - OM_uint32 maj, min; - int i; - char *errmsg; - - if (!mechs) - return; - *mechs = GSS_C_NULL_OID_SET; - - maj = gss_indicate_mechs(&min, &indicated); - if (GSS_ERROR(maj)) { - debug("No GSS-API mechanisms are installed"); - return; - } - - maj = gss_create_empty_oid_set(&min, &supported); - if (GSS_ERROR(maj)) { - errmsg = ssh_gssapi_last_error(NULL, &maj, &min); - debug("Failed to allocate resources (%s) for GSS-API", errmsg); - xfree(errmsg); - (void) gss_release_oid_set(&min, &indicated); - return; - } - maj = gss_acquire_cred(&min, GSS_C_NO_NAME, 0, indicated, - GSS_C_INITIATE, &creds, &acquired, NULL); - - if (GSS_ERROR(maj)) { - errmsg = ssh_gssapi_last_error(NULL, &maj, &min); - debug("Failed to acquire GSS-API credentials for any " - "mechanisms (%s)", errmsg); - xfree(errmsg); - (void) gss_release_oid_set(&min, &indicated); - (void) gss_release_oid_set(&min, &supported); - return; - } - (void) gss_release_cred(&min, &creds); - - for (i = 0; i < acquired->count; i++) { - mech = &acquired->elements[i]; - - if (ssh_gssapi_is_spnego(mech)) - continue; - - ssh_gssapi_build_ctx(&ctxt, 1, mech); - if (!ctxt) - continue; - - /* - * This is useful for mechs like Kerberos, which can - * detect unknown target princs here, but not for - * mechs like SPKM, which cannot detect unknown princs - * until context tokens are actually exchanged. - * - * 'Twould be useful to have a test that could save us - * the bother of trying this for SPKM and the such... - */ - maj = ssh_gssapi_init_ctx(ctxt, server_host, 0, NULL, &tok); - if (GSS_ERROR(maj)) { - errmsg = ssh_gssapi_last_error(ctxt, NULL, NULL); - debug("Skipping GSS-API mechanism %s (%s)", - ssh_gssapi_oid_to_name(mech), errmsg); - xfree(errmsg); - continue; - } - - (void) gss_release_buffer(&min, &tok); - - maj = gss_add_oid_set_member(&min, mech, &supported); - if (GSS_ERROR(maj)) { - errmsg = ssh_gssapi_last_error(NULL, &maj, &min); - debug("Failed to allocate resources (%s) for GSS-API", - errmsg); - xfree(errmsg); - } - } - - *mechs = supported; -} - - -/* - * Wrapper to init_sec_context. Requires that the context contains: - * - * oid - * server name (from ssh_gssapi_import_name) - */ -OM_uint32 -ssh_gssapi_init_ctx(Gssctxt *ctx, const char *server_host, int deleg_creds, - gss_buffer_t recv_tok, gss_buffer_t send_tok) -{ - int flags = GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG; - - debug("%s(%p, %s, %d, %p, %p)", __func__, ctx, server_host, - deleg_creds, recv_tok, send_tok); - - if (deleg_creds) { - flags |= GSS_C_DELEG_FLAG; - debug("Delegating GSS-API credentials"); - } - - /* Build target principal */ - if (ctx->desired_name == GSS_C_NO_NAME && - !ssh_gssapi_import_name(ctx, server_host)) { - return (ctx->major); - } - - ctx->major = gss_init_sec_context(&ctx->minor, GSS_C_NO_CREDENTIAL, - &ctx->context, ctx->desired_name, ctx->desired_mech, flags, - 0, /* default lifetime */ - NULL, /* no channel bindings */ - recv_tok, - NULL, /* actual mech type */ - send_tok, &ctx->flags, - NULL); /* actual lifetime */ - - if (GSS_ERROR(ctx->major)) - ssh_gssapi_error(ctx, "calling GSS_Init_sec_context()"); - - return (ctx->major); -} -#endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/ssh/ssh.c b/usr/src/cmd/ssh/ssh/ssh.c deleted file mode 100644 index d122875470..0000000000 --- a/usr/src/cmd/ssh/ssh/ssh.c +++ /dev/null @@ -1,1245 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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. - * - * 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) 2000, 2001, 2002 Markus Friedl. 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.186 2002/09/19 01:58:18 djm Exp $"); - -#include <openssl/err.h> - -#include "ssh.h" -#include "ssh1.h" -#include "ssh2.h" -#include "compat.h" -#include "cipher.h" -#include "xmalloc.h" -#include "packet.h" -#include "buffer.h" -#include "channels.h" -#include "key.h" -#include "authfd.h" -#include "authfile.h" -#include "pathnames.h" -#include "clientloop.h" -#include "log.h" -#include "readconf.h" -#include "sshconnect.h" -#include "tildexpand.h" -#include "dispatch.h" -#include "misc.h" -#include "kex.h" -#include "mac.h" -#include "sshtty.h" - -#include "g11n.h" - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - -/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. - Default value is AF_UNSPEC means both IPv4 and IPv6. */ -#ifdef IPV4_DEFAULT -int IPv4or6 = AF_INET; -#else -int IPv4or6 = AF_UNSPEC; -#endif - -/* Flag indicating whether debug mode is on. This can be set on the command line. */ -int debug_flag = 0; - -/* Flag indicating whether a tty should be allocated */ -int tty_flag = 0; -int no_tty_flag = 0; -int force_tty_flag = 0; - -/* don't exec a shell */ -int no_shell_flag = 0; - -/* - * Flag indicating that nothing should be read from stdin. This can be set - * on the command line. - */ -int stdin_null_flag = 0; - -/* - * Flag indicating that ssh should fork after authentication. This is useful - * so that the passphrase can be entered manually, and then ssh goes to the - * background. - */ -int fork_after_authentication_flag = 0; - -/* - * General data structure for command line options and options configurable - * in configuration files. See readconf.h. - */ -Options options; - -/* optional user configfile */ -char *config = NULL; - -/* - * Name of the host we are connecting to. This is the name given on the - * command line, or the HostName specified for the user-supplied name in a - * configuration file. - */ -char *host; - -/* socket address the host resolves to */ -struct sockaddr_storage hostaddr; - -/* Private host keys. */ -Sensitive sensitive_data; - -/* Original real UID. */ -uid_t original_real_uid; -uid_t original_effective_uid; - -/* command to be executed */ -Buffer command; - -/* Should we execute a command or invoke a subsystem? */ -int subsystem_flag = 0; - -/* # of replies received for global requests */ -static int client_global_request_id = 0; - -/* pid of proxycommand child process */ -pid_t proxy_command_pid = 0; - -/* Prints a help message to the user. This function never returns. */ - -static void -usage(void) -{ - fprintf(stderr, - gettext("Usage: %s [options] host [command]\n" - "Options:\n" - " -l user Log in using this user name.\n" - " -n Redirect input from /dev/null.\n" - " -F config Config file (default: ~/%s).\n" - " -A Enable authentication agent forwarding.\n" - " -a Disable authentication agent forwarding " - "(default).\n" -#ifdef AFS - " -k Disable Kerberos ticket and AFS token " - "forwarding.\n" -#endif /* AFS */ - " -X Enable X11 connection forwarding.\n" - " -x Disable X11 connection forwarding (default).\n" - " -i file Identity for public key authentication " - "(default: ~/.ssh/identity)\n" - " -t Tty; allocate a tty even if command is given.\n" - " -T Do not allocate a tty.\n" - " -v Verbose; display verbose debugging messages.\n" - " Multiple -v increases verbosity.\n" - " -V Display version number only.\n" - " -q Quiet; don't display any warning messages.\n" - " -f Fork into background after authentication.\n" - " -e char Set escape character; ``none'' = disable " - "(default: ~).\n" - " -c cipher Select encryption algorithm\n" - " -m macs Specify MAC algorithms for protocol version 2.\n" - " -p port Connect to this port. Server must be " - "on the same port.\n" - " -L listen-port:host:port Forward local port to " - "remote address\n" - " -R listen-port:host:port Forward remote port to " - "local address\n" - " These cause %s to listen for connections " - "on a port, and\n" - " forward them to the other side by " - "connecting to host:port.\n" - " -D port Enable dynamic application-level " - "port forwarding.\n" - " -C Enable compression.\n" - " -N Do not execute a shell or command.\n" - " -g Allow remote hosts to connect to forwarded " - "ports.\n" - " -1 Force protocol version 1.\n" - " -2 Force protocol version 2.\n" - " -4 Use IPv4 only.\n" - " -6 Use IPv6 only.\n" - " -o 'option' Process the option as if it was read " - "from a configuration file.\n" - " -s Invoke command (mandatory) as SSH2 subsystem.\n" - " -b addr Local IP address.\n"), - __progname, _PATH_SSH_USER_CONFFILE, __progname); - exit(1); -} - -static int ssh_session(void); -static int ssh_session2(void); -static void load_public_identity_files(void); -static void rsh_connect(char *host, char *user, Buffer * command); - -/* - * Main program for the ssh client. - */ -int -main(int ac, char **av) -{ - int i, opt, exit_status; - char *p, *cp, buf[256], *pw_name, *pw_dir; - struct stat st; - struct passwd *pw; - int dummy; - extern int optind, optreset; - extern char *optarg; - Forward fwd; - - __progname = get_progname(av[0]); - - (void) g11n_setlocale(LC_ALL, ""); - - init_rng(); - - /* - * Save the original real uid. It will be needed later (uid-swapping - * may clobber the real uid). - */ - original_real_uid = getuid(); - original_effective_uid = geteuid(); - - /* - * Use uid-swapping to give up root privileges for the duration of - * option processing. We will re-instantiate the rights when we are - * ready to create the privileged port, and will permanently drop - * them when the port has been created (actually, when the connection - * has been made, as we may need to create the port several times). - */ - PRIV_END; - -#ifdef HAVE_SETRLIMIT - /* If we are installed setuid root be careful to not drop core. */ - if (original_real_uid != original_effective_uid) { - struct rlimit rlim; - rlim.rlim_cur = rlim.rlim_max = 0; - if (setrlimit(RLIMIT_CORE, &rlim) < 0) - fatal("setrlimit failed: %.100s", strerror(errno)); - } -#endif - /* - * Get user data. It may happen that NIS or LDAP connection breaks down - * during the user's session. We should try to do our best and use the - * HOME and LOGNAME variables. Remember that the SSH client might be the - * only tool available to fix the problem with the naming services. - */ - pw = getpwuid(original_real_uid); - if (pw == NULL) { - if ((pw_dir = getenv("HOME")) == NULL) { - log("User account's password entry not found and HOME " - "not set. Set it manually and try again. " - "Exiting."); - exit(1); - } - log("User account's password entry not found, using " - "the HOME variable."); - - if ((pw_name = getenv("LOGNAME")) == NULL) { - log("Need a local user name but LOGNAME is not set. " - "Set it manually and try again. Exiting."); - exit(1); - } - log("Local user name '%s' set from the LOGNAME variable.", - pw_name); - - pw_dir = xstrdup(pw_dir); - pw_name = xstrdup(pw_name); - } else { - pw_name = xstrdup(pw->pw_name); - pw_dir = xstrdup(pw->pw_dir); - } - - /* - * Set our umask to something reasonable, as some files are created - * with the default umask. This will make them world-readable but - * writable only by the owner, which is ok for all files for which we - * don't set the modes explicitly. - */ - umask(022); - - /* Initialize option structure to indicate that no values have been set. */ - initialize_options(&options); - - /* Parse command-line arguments. */ - host = NULL; - -again: - while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) { - switch (opt) { - case '1': - options.protocol = SSH_PROTO_1; - break; - case '2': - options.protocol = SSH_PROTO_2; - break; - case '4': - IPv4or6 = AF_INET; - break; - case '6': - IPv4or6 = AF_INET6; - break; - case 'n': - stdin_null_flag = 1; - break; - case 'f': - fork_after_authentication_flag = 1; - stdin_null_flag = 1; - break; - case 'x': - options.forward_x11 = 0; - break; - case 'X': - options.forward_x11 = 1; - break; - case 'g': - options.gateway_ports = 1; - break; - case 'P': /* deprecated */ - fprintf(stderr, gettext("Warning: Option -P has " - "been deprecated\n")); - options.use_privileged_port = 0; - break; - case 'a': - options.forward_agent = 0; - break; - case 'A': - options.forward_agent = 1; - break; -#ifdef AFS - case 'k': - options.kerberos_tgt_passing = 0; - options.afs_token_passing = 0; - break; -#endif - case 'i': - if (stat(optarg, &st) < 0) { - fprintf(stderr, - gettext("Warning: Identity file %s " - "does not exist.\n"), optarg); - break; - } - if (options.num_identity_files >= - SSH_MAX_IDENTITY_FILES) - fatal("Too many identity files specified " - "(max %d)", SSH_MAX_IDENTITY_FILES); - options.identity_files[options.num_identity_files++] = - xstrdup(optarg); - break; - case 'I': - fprintf(stderr, "no support for smartcards.\n"); - break; - case 't': - if (tty_flag) - force_tty_flag = 1; - tty_flag = 1; - break; - case 'v': - if (0 == debug_flag) { - debug_flag = 1; - options.log_level = SYSLOG_LEVEL_DEBUG1; - } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { - options.log_level++; - break; - } else - fatal("Too high debugging level."); - /* FALLTHROUGH */ - case 'V': - fprintf(stderr, - gettext("%s, SSH protocols %d.%d/%d.%d, " - "OpenSSL 0x%8.8lx\n"), - SSH_VERSION, - PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, - SSLeay()); - if (opt == 'V') - exit(0); - break; - case 'q': - options.log_level = SYSLOG_LEVEL_QUIET; - break; - case 'e': - if (optarg[0] == '^' && optarg[2] == 0 && - (u_char) optarg[1] >= 64 && - (u_char) optarg[1] < 128) - options.escape_char = (u_char) optarg[1] & 31; - else if (strlen(optarg) == 1) - options.escape_char = (u_char) optarg[0]; - else if (strcmp(optarg, "none") == 0) - options.escape_char = SSH_ESCAPECHAR_NONE; - else { - fprintf(stderr, - gettext("Bad escape character '%s'.\n"), - optarg); - exit(1); - } - break; - case 'c': - if (ciphers_valid(optarg)) { - /* SSH2 only */ - options.ciphers = xstrdup(optarg); - options.cipher = SSH_CIPHER_ILLEGAL; - } else { - /* SSH1 only */ - options.cipher = cipher_number(optarg); - if (options.cipher == -1) { - fprintf(stderr, - gettext("Unknown cipher " - "type '%s'\n"), - optarg); - exit(1); - } - if (options.cipher == SSH_CIPHER_3DES) - options.ciphers = "3des-cbc"; - else if (options.cipher == SSH_CIPHER_BLOWFISH) - options.ciphers = "blowfish-cbc"; - else - options.ciphers = (char *)-1; - } - break; - case 'm': - if (mac_valid(optarg)) - options.macs = xstrdup(optarg); - else { - fprintf(stderr, - gettext("Unknown mac type '%s'\n"), - optarg); - exit(1); - } - break; - case 'p': - options.port = a2port(optarg); - if (options.port == 0) { - fprintf(stderr, gettext("Bad port '%s'\n"), - optarg); - exit(1); - } - break; - case 'l': - options.user = optarg; - break; - - case 'L': - if (parse_forward(1, &fwd, optarg)) - add_local_forward(&options, &fwd); - else - fatal("Bad local forwarding specification " - "'%s'\n", optarg); - break; - - case 'R': - if (parse_forward(1, &fwd, optarg)) - add_remote_forward(&options, &fwd); - else - fatal("Bad remote forwarding specification " - "'%s'\n", optarg); - break; - - case 'D': - if (parse_forward(0, &fwd, optarg) == 0) - fatal("Bad dynamic forwarding specification " - "'%s'\n", optarg); - fwd.connect_host = "socks"; - add_local_forward(&options, &fwd); - break; - - case 'C': - options.compression = 1; - break; - case 'N': - no_shell_flag = 1; - no_tty_flag = 1; - break; - case 'T': - no_tty_flag = 1; - break; - case 'o': - dummy = 1; - if (process_config_line(&options, host ? host : "", - optarg, "command-line", 0, &dummy) != 0) - exit(1); - break; - case 's': - subsystem_flag = 1; - break; - case 'b': - options.bind_address = optarg; - break; - case 'F': - config = optarg; - break; - default: - usage(); - } - } - - ac -= optind; - av += optind; - - if (ac > 0 && !host && **av != '-') { - if (strchr(*av, '@')) { - p = xstrdup(*av); - cp = strchr(p, '@'); - if (cp == NULL || cp == p) - usage(); - options.user = p; - *cp = '\0'; - host = ++cp; - } else - host = *av; - ac--, av++; - if (ac > 0) { - optind = 0; - optreset = 1; - goto again; - } - } - - /* Check that we got a host name. */ - if (!host) - usage(); - - SSLeay_add_all_algorithms(); - ERR_load_crypto_strings(); - channel_set_af(IPv4or6); - - /* Initialize the command to execute on remote host. */ - buffer_init(&command); - - /* - * Save the command to execute on the remote host in a buffer. There - * is no limit on the length of the command, except by the maximum - * packet size. Also sets the tty flag if there is no command. - */ - if (!ac) { - /* No command specified - execute shell on a tty. */ - tty_flag = 1; - if (subsystem_flag) { - fprintf(stderr, - gettext("You must specify a subsystem " - "to invoke.\n")); - usage(); - } - } else { - /* A command has been specified. Store it into the buffer. */ - for (i = 0; i < ac; i++) { - if (i) - buffer_append(&command, " ", 1); - buffer_append(&command, av[i], strlen(av[i])); - } - } - - /* Cannot fork to background if no command. */ - 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. */ - if (buffer_len(&command) == 0) - tty_flag = 1; - - /* Force no tty */ - if (no_tty_flag) - tty_flag = 0; - /* Do not allocate a tty if stdin is not a tty. */ - if (!isatty(fileno(stdin)) && !force_tty_flag) { - if (tty_flag) - log("Pseudo-terminal will not be allocated because stdin is not a terminal."); - tty_flag = 0; - } - - /* - * Initialize "log" output. Since we are the client all output - * actually goes to stderr. - */ - log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, - SYSLOG_FACILITY_USER, 1); - - /* - * Read per-user configuration file. Ignore the system wide config - * file if the user specifies a config file on the command line. - */ - if (config != NULL) { - if (!read_config_file(config, host, &options)) - fatal("Can't open user config file %.100s: " - "%.100s", config, strerror(errno)); - } else { - snprintf(buf, sizeof buf, "%.100s/%.100s", pw_dir, - _PATH_SSH_USER_CONFFILE); - (void)read_config_file(buf, host, &options); - - /* Read systemwide configuration file after use config. */ - (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, &options); - } - - process_unknown_options(&options); - - /* Fill configuration defaults. */ - fill_default_options(&options); - - /* reinit */ - log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); - - seed_rng(); - - if (options.user == NULL) - options.user = xstrdup(pw_name); - - if (options.hostname != NULL) - host = options.hostname; - - /* Disable rhosts authentication if not running as root. */ -#ifdef HAVE_CYGWIN - /* Ignore uid if running under Windows */ - if (!options.use_privileged_port) { -#else - if (original_effective_uid != 0 || !options.use_privileged_port) { -#endif - debug("Rhosts Authentication disabled, " - "originating port will not be trusted."); - options.rhosts_authentication = 0; - } - /* Open a connection to the remote host. */ - - /* XXX OpenSSH has deprecated UseRsh */ - if (options.use_rsh) { - seteuid(original_real_uid); - setuid(original_real_uid); - rsh_connect(host, options.user, &command); - fatal("rsh_connect returned"); - } - - if (ssh_connect(host, &hostaddr, options.port, IPv4or6, - options.connection_attempts, -#ifdef HAVE_CYGWIN - options.use_privileged_port, -#else - original_effective_uid == 0 && options.use_privileged_port, -#endif - options.proxy_command) != 0) { - /* XXX OpenSSH has deprecated FallbackToRsh */ - if (options.fallback_to_rsh) { - seteuid(original_real_uid); - setuid(original_real_uid); - rsh_connect(host, options.user, &command); - fatal("rsh_connect returned"); - } - exit(1); - } - - /* - * If we successfully made the connection, load the host private key - * in case we will need it later for combined rsa-rhosts - * authentication. This must be done before releasing extra - * privileges, because the file is only readable by root. - * If we cannot access the private keys, load the public keys - * instead and try to execute the ssh-keysign helper instead. - */ - sensitive_data.nkeys = 0; - sensitive_data.keys = NULL; - sensitive_data.external_keysign = 0; - if (options.rhosts_rsa_authentication || - options.hostbased_authentication) { - sensitive_data.nkeys = 3; - sensitive_data.keys = xmalloc(sensitive_data.nkeys * - sizeof(Key)); - - PRIV_START; - sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, - _PATH_HOST_KEY_FILE, "", NULL); - sensitive_data.keys[1] = key_load_private_type(KEY_DSA, - _PATH_HOST_DSA_KEY_FILE, "", NULL); - sensitive_data.keys[2] = key_load_private_type(KEY_RSA, - _PATH_HOST_RSA_KEY_FILE, "", NULL); - PRIV_END; - - if (options.hostbased_authentication == 1 && - sensitive_data.keys[0] == NULL && - sensitive_data.keys[1] == NULL && - sensitive_data.keys[2] == NULL) { - sensitive_data.keys[1] = key_load_public( - _PATH_HOST_DSA_KEY_FILE, NULL); - sensitive_data.keys[2] = key_load_public( - _PATH_HOST_RSA_KEY_FILE, NULL); - sensitive_data.external_keysign = 1; - } - } - /* - * Get rid of any extra privileges that we may have. We will no - * longer need them. Also, extra privileges could make it very hard - * to read identity files and other non-world-readable files from the - * user's home directory if it happens to be on a NFS volume where - * root is mapped to nobody. - */ - seteuid(original_real_uid); - setuid(original_real_uid); - - /* - * Now that we are back to our own permissions, create ~/.ssh - * directory if it doesn\'t already exist. - */ - snprintf(buf, sizeof buf, "%.100s%s%.100s", pw_dir, - strcmp(pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); - xfree(pw_dir); - if (stat(buf, &st) < 0) - if (mkdir(buf, 0700) < 0) - error("Could not create directory '%.200s'.", buf); - - /* load options.identity_files */ - load_public_identity_files(); - - /* Expand ~ in known host file names. */ - /* XXX mem-leaks: */ - options.system_hostfile = - tilde_expand_filename(options.system_hostfile, original_real_uid); - options.user_hostfile = - tilde_expand_filename(options.user_hostfile, original_real_uid); - options.system_hostfile2 = - tilde_expand_filename(options.system_hostfile2, original_real_uid); - options.user_hostfile2 = - tilde_expand_filename(options.user_hostfile2, original_real_uid); - - signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ - - /* Log into the remote system. This never returns if the login fails. */ - ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw_name); - xfree(pw_name); - - /* We no longer need the private host keys. Clear them now. */ - if (sensitive_data.nkeys != 0) { - for (i = 0; i < sensitive_data.nkeys; i++) { - if (sensitive_data.keys[i] != NULL) { - /* Destroys contents safely */ - debug3("clear hostkey %d", i); - key_free(sensitive_data.keys[i]); - sensitive_data.keys[i] = NULL; - } - } - xfree(sensitive_data.keys); - } - for (i = 0; i < options.num_identity_files; i++) { - if (options.identity_files[i]) { - xfree(options.identity_files[i]); - options.identity_files[i] = NULL; - } - if (options.identity_keys[i]) { - key_free(options.identity_keys[i]); - options.identity_keys[i] = NULL; - } - } - - exit_status = compat20 ? ssh_session2() : ssh_session(); - packet_close(); - - /* - * Send SIGHUP to proxy command if used. We don't wait() in - * case it hangs and instead rely on init to reap the child - */ - if (proxy_command_pid > 1) - kill(proxy_command_pid, SIGHUP); - - return exit_status; -} - -static void -ssh_init_forwarding(void) -{ - int success = 0; - int i; - - /* Initiate local TCP/IP port forwardings. */ - for (i = 0; i < options.num_local_forwards; i++) { - debug("Local connections to %.200s:%d forwarded to remote " - "address %.200s:%d", - (options.local_forwards[i].listen_host == NULL) ? - (options.gateway_ports ? "*" : "LOCALHOST") : - options.local_forwards[i].listen_host, - options.local_forwards[i].listen_port, - options.local_forwards[i].connect_host, - options.local_forwards[i].connect_port); - success += channel_setup_local_fwd_listener( - options.local_forwards[i].listen_host, - options.local_forwards[i].listen_port, - options.local_forwards[i].connect_host, - options.local_forwards[i].connect_port, - options.gateway_ports); - } - if (i > 0 && success == 0) - error("Could not request local forwarding."); - - /* Initiate remote TCP/IP port forwardings. */ - for (i = 0; i < options.num_remote_forwards; i++) { - debug("Remote connections from %.200s:%d forwarded to " - "local address %.200s:%d", - (options.remote_forwards[i].listen_host == NULL) ? - "LOCALHOST" : options.remote_forwards[i].listen_host, - options.remote_forwards[i].listen_port, - options.remote_forwards[i].connect_host, - options.remote_forwards[i].connect_port); - if (channel_request_remote_forwarding( - options.remote_forwards[i].listen_host, - options.remote_forwards[i].listen_port, - options.remote_forwards[i].connect_host, - options.remote_forwards[i].connect_port) < 0) { - log("Warning: Could not request remote forwarding."); - } - } -} - -static void -check_agent_present(void) -{ - if (options.forward_agent) { - /* Clear agent forwarding if we don't have an agent. */ - if (!ssh_agent_present()) - options.forward_agent = 0; - } -} - -static int -ssh_session(void) -{ - int type; - int interactive = 0; - int have_tty = 0; - struct winsize ws; - char *cp; - const char *display; - - /* Enable compression if requested. */ - if (options.compression) { - debug("Requesting compression at level %d.", options.compression_level); - - if (options.compression_level < 1 || options.compression_level > 9) - fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); - - /* Send the request. */ - packet_start(SSH_CMSG_REQUEST_COMPRESSION); - packet_put_int(options.compression_level); - packet_send(); - packet_write_wait(); - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - packet_start_compression(options.compression_level); - else if (type == SSH_SMSG_FAILURE) - log("Warning: Remote host refused compression."); - else - packet_disconnect("Protocol error waiting for compression response."); - } - /* Allocate a pseudo tty if appropriate. */ - if (tty_flag) { - debug("Requesting pty."); - - /* Start the packet. */ - packet_start(SSH_CMSG_REQUEST_PTY); - - /* Store TERM in the packet. There is no limit on the - length of the string. */ - cp = getenv("TERM"); - if (!cp) - cp = ""; - packet_put_cstring(cp); - - /* Store window size in the packet. */ - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - memset(&ws, 0, sizeof(ws)); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - - /* Store tty modes in the packet. */ - tty_make_modes(fileno(stdin), NULL); - - /* Send the packet, and wait for it to leave. */ - packet_send(); - packet_write_wait(); - - /* Read response from the server. */ - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) { - interactive = 1; - have_tty = 1; - } else if (type == SSH_SMSG_FAILURE) - log("Warning: Remote host failed or refused to allocate a pseudo tty."); - else - packet_disconnect("Protocol error waiting for pty request response."); - } - /* Request X11 forwarding if enabled and DISPLAY is set. */ - display = getenv("DISPLAY"); - if (options.forward_x11 && display != NULL) { - char *proto, *data; - /* Get reasonable local authentication information. */ - client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, &proto, &data); - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(0, display, proto, data); - - /* Read response from the server. */ - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) { - interactive = 1; - } else if (type == SSH_SMSG_FAILURE) { - log("Warning: Remote host denied X11 forwarding."); - } else { - packet_disconnect("Protocol error waiting for X11 forwarding"); - } - } - /* Tell the packet module whether this is an interactive session. */ - packet_set_interactive(interactive); - - /* Request authentication agent forwarding if appropriate. */ - check_agent_present(); - - if (options.forward_agent) { - debug("Requesting authentication agent forwarding."); - auth_request_forwarding(); - - /* Read response from the server. */ - type = packet_read(); - packet_check_eom(); - if (type != SSH_SMSG_SUCCESS) - log("Warning: Remote host denied authentication agent forwarding."); - } - - /* Initiate port forwardings. */ - ssh_init_forwarding(); - - /* If requested, let ssh continue in the background. */ - if (fork_after_authentication_flag) - if (daemon(1, 1) < 0) - fatal("daemon() failed: %.200s", strerror(errno)); - - /* - * If a command was specified on the command line, execute the - * command now. Otherwise request the server to start a shell. - */ - if (buffer_len(&command) > 0) { - int len = buffer_len(&command); - if (len > 900) - len = 900; - debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); - packet_start(SSH_CMSG_EXEC_CMD); - packet_put_string(buffer_ptr(&command), buffer_len(&command)); - packet_send(); - packet_write_wait(); - } else { - debug("Requesting shell."); - packet_start(SSH_CMSG_EXEC_SHELL); - packet_send(); - packet_write_wait(); - } - - /* Enter the interactive session. */ - return client_loop(have_tty, tty_flag ? - options.escape_char : SSH_ESCAPECHAR_NONE, 0); -} - -static void -client_subsystem_reply(int type, u_int32_t seq, void *ctxt) -{ - int id, len; - - id = packet_get_int(); - len = buffer_len(&command); - if (len > 900) - len = 900; - packet_check_eom(); - if (type == SSH2_MSG_CHANNEL_FAILURE) - fatal("Request for subsystem '%.*s' failed on channel %d", - len, (u_char *)buffer_ptr(&command), id); -} - -void -client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) -{ - int i; - - i = client_global_request_id++; - if (i >= options.num_remote_forwards) - return; - debug("remote forward %s for: listen %d, connect %s:%d", - type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", - options.remote_forwards[i].listen_port, - options.remote_forwards[i].connect_host, - options.remote_forwards[i].connect_port); - if (type == SSH2_MSG_REQUEST_FAILURE) - log("Warning: remote port forwarding failed for listen port %d", - options.remote_forwards[i].listen_port); -} - -static -void -ssh_session2_setlocale(int id) -{ - char *loc; - -#define remote_setlocale(envvar) \ - if ((loc = getenv(envvar)) != NULL) {\ - channel_request_start(id, "env", 0);\ - debug2("Sent request for environment variable %s=%s", envvar, \ - loc); \ - packet_put_cstring(envvar);\ - packet_put_cstring(loc);\ - packet_send();\ - } - - remote_setlocale("LANG") - - remote_setlocale("LC_CTYPE") - remote_setlocale("LC_COLLATE") - remote_setlocale("LC_TIME") - remote_setlocale("LC_NUMERIC") - remote_setlocale("LC_MONETARY") - remote_setlocale("LC_MESSAGES") - - remote_setlocale("LC_ALL") -} - -/* request pty/x11/agent/tcpfwd/shell for channel */ -static void -ssh_session2_setup(int id, void *arg) -{ - int len; - const char *display; - int interactive = 0; - struct termios tio; - - debug("ssh_session2_setup: id %d", id); - - ssh_session2_setlocale(id); - - if (tty_flag) { - struct winsize ws; - char *cp; - cp = getenv("TERM"); - if (!cp) - cp = ""; - /* Store window size in the packet. */ - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - memset(&ws, 0, sizeof(ws)); - - channel_request_start(id, "pty-req", 0); - packet_put_cstring(cp); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - tio = get_saved_tio(); - tty_make_modes(/*ignored*/ 0, &tio); - packet_send(); - interactive = 1; - /* XXX wait for reply */ - } - - display = getenv("DISPLAY"); - if (options.forward_x11 && display != NULL) { - char *proto, *data; - /* Get reasonable local authentication information. */ - client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, &proto, &data); - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(id, display, proto, data); - interactive = 1; - /* XXX wait for reply */ - } - - check_agent_present(); - if (options.forward_agent) { - debug("Requesting authentication agent forwarding."); - channel_request_start(id, "auth-agent-req@openssh.com", 0); - packet_send(); - } - - len = buffer_len(&command); - if (len > 0) { - if (len > 900) - len = 900; - if (subsystem_flag) { - debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command)); - channel_request_start(id, "subsystem", /*want reply*/ 1); - /* register callback for reply */ - /* XXX we assume that client_loop has already been called */ - dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply); - dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply); - } else { - debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); - channel_request_start(id, "exec", 0); - } - packet_put_string(buffer_ptr(&command), buffer_len(&command)); - packet_send(); - } else { - channel_request_start(id, "shell", 0); - packet_send(); - } - - packet_set_interactive(interactive); -} - -/* open new channel for a session */ -static int -ssh_session2_open(void) -{ - Channel *c; - int window, packetmax, in, out, err; - - if (stdin_null_flag) { - in = open(_PATH_DEVNULL, O_RDONLY); - } else { - in = dup(STDIN_FILENO); - } - out = dup(STDOUT_FILENO); - err = dup(STDERR_FILENO); - - if (in < 0 || out < 0 || err < 0) - fatal("dup() in/out/err failed"); - - /* enable nonblocking unless tty */ - if (!isatty(in)) - set_nonblock(in); - if (!isatty(out)) - set_nonblock(out); - if (!isatty(err)) - set_nonblock(err); - - window = CHAN_SES_WINDOW_DEFAULT; - packetmax = CHAN_SES_PACKET_DEFAULT; - if (tty_flag) { - window >>= 1; - packetmax >>= 1; - } - c = channel_new( - "session", SSH_CHANNEL_OPENING, in, out, err, - window, packetmax, CHAN_EXTENDED_WRITE, - xstrdup("client-session"), /*nonblock*/0); - - debug3("ssh_session2_open: channel_new: %d", c->self); - - channel_send_open(c->self); - if (!no_shell_flag) - channel_register_confirm(c->self, ssh_session2_setup); - - return c->self; -} - -static int -ssh_session2(void) -{ - int id = -1; - - /* XXX should be pre-session */ - ssh_init_forwarding(); - - if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) - id = ssh_session2_open(); - - /* If requested, let ssh continue in the background. */ - if (fork_after_authentication_flag) - client_daemonize(); - - return (client_loop(tty_flag, tty_flag ? - options.escape_char : SSH_ESCAPECHAR_NONE, id)); -} - -static void -load_public_identity_files(void) -{ - char *filename; - int i = 0; - Key *public; - - for (; i < options.num_identity_files; i++) { - filename = tilde_expand_filename(options.identity_files[i], - original_real_uid); - public = key_load_public(filename, NULL); - debug("identity file %s type %d", filename, - public ? public->type : -1); - xfree(options.identity_files[i]); - options.identity_files[i] = filename; - options.identity_keys[i] = public; - } -} - -/* - * Connects to the given host using rsh(or prints an error message and exits - * if rsh is not available). This function never returns. - */ -static void -rsh_connect(char *host, char *user, Buffer * command) -{ - char *args[10]; - int i; - - log("Using rsh. WARNING: Connection will not be encrypted."); - /* Build argument list for rsh. */ - i = 0; - args[i++] = _PATH_RSH; - /* host may have to come after user on some systems */ - args[i++] = host; - if (user) { - args[i++] = "-l"; - args[i++] = user; - } - if (buffer_len(command) > 0) { - buffer_append(command, "\0", 1); - args[i++] = buffer_ptr(command); - } - args[i++] = NULL; - if (debug_flag) { - for (i = 0; args[i]; i++) { - if (i != 0) - (void) fprintf(stderr, " "); - (void) fprintf(stderr, "%s", args[i]); - } - (void) fprintf(stderr, "\n"); - } - (void) execv(_PATH_RSH, args); - perror(_PATH_RSH); - exit(1); -} diff --git a/usr/src/cmd/ssh/ssh/sshconnect.c b/usr/src/cmd/ssh/ssh/sshconnect.c deleted file mode 100644 index 74c3b6fa26..0000000000 --- a/usr/src/cmd/ssh/ssh/sshconnect.c +++ /dev/null @@ -1,1117 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.135 2002/09/19 01:58:18 djm Exp $"); - -#include <openssl/bn.h> - -#include "ssh.h" -#include "xmalloc.h" -#include "rsa.h" -#include "buffer.h" -#include "packet.h" -#include "uidswap.h" -#include "compat.h" -#include "key.h" -#include "sshconnect.h" -#include "hostfile.h" -#include "log.h" -#include "readconf.h" -#include "atomicio.h" -#include "misc.h" -#include "readpass.h" -#include <langinfo.h> -#include <regex.h> -#include <err.h> -#include "engine.h" - -char *client_version_string = NULL; -char *server_version_string = NULL; - -/* import */ -extern Options options; -extern char *__progname; -extern uid_t original_real_uid; -extern uid_t original_effective_uid; -extern pid_t proxy_command_pid; -extern ENGINE *e; - -#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ -#define INET6_ADDRSTRLEN 46 -#endif - -static int show_other_keys(const char *, Key *); - -/* - * Connect to the given ssh server using a proxy command. - */ -static int -ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) -{ - Buffer command; - const char *cp; - char *command_string; - int pin[2], pout[2]; - pid_t pid; - char strport[NI_MAXSERV]; - - /* Convert the port number into a string. */ - snprintf(strport, sizeof strport, "%hu", port); - - /* - * Build the final command string in the buffer by making the - * appropriate substitutions to the given proxy command. - * - * Use "exec" to avoid "sh -c" processes on some platforms - * (e.g. Solaris) - */ - buffer_init(&command); - -#define EXECLEN (sizeof ("exec") - 1) - for (cp = proxy_command; *cp && isspace(*cp) ; cp++) - ; - if (strncmp(cp, "exec", EXECLEN) != 0 || - (strlen(cp) >= EXECLEN && !isspace(*(cp + EXECLEN)))) - buffer_append(&command, "exec ", EXECLEN + 1); -#undef EXECLEN - - for (cp = proxy_command; *cp; cp++) { - if (cp[0] == '%' && cp[1] == '%') { - buffer_append(&command, "%", 1); - cp++; - continue; - } - if (cp[0] == '%' && cp[1] == 'h') { - buffer_append(&command, host, strlen(host)); - cp++; - continue; - } - if (cp[0] == '%' && cp[1] == 'p') { - buffer_append(&command, strport, strlen(strport)); - cp++; - continue; - } - buffer_append(&command, cp, 1); - } - buffer_append(&command, "\0", 1); - - /* Get the final command string. */ - command_string = buffer_ptr(&command); - - /* Create pipes for communicating with the proxy. */ - if (pipe(pin) < 0 || pipe(pout) < 0) - fatal("Could not create pipes to communicate with the proxy: %.100s", - strerror(errno)); - - debug("Executing proxy command: %.500s", command_string); - - /* Fork and execute the proxy command. */ - if ((pid = fork()) == 0) { - char *argv[10]; - - /* Child. Permanently give up superuser privileges. */ - seteuid(original_real_uid); - setuid(original_real_uid); - - /* Redirect stdin and stdout. */ - close(pin[1]); - if (pin[0] != 0) { - if (dup2(pin[0], 0) < 0) - perror("dup2 stdin"); - close(pin[0]); - } - close(pout[0]); - if (dup2(pout[1], 1) < 0) - perror("dup2 stdout"); - /* Cannot be 1 because pin allocated two descriptors. */ - close(pout[1]); - - /* Stderr is left as it is so that error messages get - printed on the user's terminal. */ - argv[0] = _PATH_BSHELL; - argv[1] = "-c"; - argv[2] = command_string; - argv[3] = NULL; - - /* Execute the proxy command. Note that we gave up any - extra privileges above. */ - execv(argv[0], argv); - perror(argv[0]); - exit(1); - } - /* Parent. */ - if (pid < 0) - fatal("fork failed: %.100s", strerror(errno)); - else - proxy_command_pid = pid; /* save pid to clean up later */ - - /* Close child side of the descriptors. */ - close(pin[0]); - close(pout[1]); - - /* Free the command name. */ - buffer_free(&command); - - /* Set the connection file descriptors. */ - packet_set_connection(pout[0], pin[1]); - - /* Indicate OK return */ - return 0; -} - -/* - * Creates a (possibly privileged) socket for use as the ssh connection. - */ -static int -ssh_create_socket(int privileged, int family) -{ - int sock, gaierr; - struct addrinfo hints, *res; - - /* - * If we are running as root and want to connect to a privileged - * port, bind our own socket to a privileged port. - */ - if (privileged) { - int p = IPPORT_RESERVED - 1; - PRIV_START; - sock = rresvport_af(&p, family); - PRIV_END; - if (sock < 0) - error("rresvport: af=%d %.100s", family, strerror(errno)); - else - debug("Allocated local port %d.", p); - return sock; - } - sock = socket(family, SOCK_STREAM, 0); - if (sock < 0) - error("socket: %.100s", strerror(errno)); - - /* Bind the socket to an alternative local IP address */ - if (options.bind_address == NULL) - return sock; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - gaierr = getaddrinfo(options.bind_address, "0", &hints, &res); - if (gaierr) { - error("getaddrinfo: %s: %s", options.bind_address, - gai_strerror(gaierr)); - close(sock); - return -1; - } - if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { - error("bind: %s: %s", options.bind_address, strerror(errno)); - close(sock); - freeaddrinfo(res); - return -1; - } - freeaddrinfo(res); - return sock; -} - -/* - * Connect with timeout. Implements ConnectTimeout option. - */ -static int -timeout_connect(int sockfd, const struct sockaddr *serv_addr, - socklen_t addrlen, int timeout) -{ - fd_set *fdset; - struct timeval tv; - socklen_t optlen; - int optval, rc, result = -1; - - if (timeout <= 0) - return (connect(sockfd, serv_addr, addrlen)); - - set_nonblock(sockfd); - rc = connect(sockfd, serv_addr, addrlen); - if (rc == 0) { - unset_nonblock(sockfd); - return (0); - } - if (errno != EINPROGRESS) - return (-1); - - fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS), - sizeof(fd_mask)); - FD_SET(sockfd, fdset); - tv.tv_sec = timeout; - tv.tv_usec = 0; - - for (;;) { - rc = select(sockfd + 1, NULL, fdset, NULL, &tv); - if (rc != -1 || errno != EINTR) - break; - } - - switch (rc) { - case 0: - /* Timed out */ - errno = ETIMEDOUT; - break; - case -1: - /* Select error */ - debug("select: %s", strerror(errno)); - break; - case 1: - /* Completed or failed */ - optval = 0; - optlen = sizeof(optval); - if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, - &optlen) == -1) { - debug("getsockopt: %s", strerror(errno)); - break; - } - if (optval != 0) { - errno = optval; - break; - } - result = 0; - unset_nonblock(sockfd); - break; - default: - /* Should not occur */ - fatal("Bogus return (%d) from select()", rc); - } - - xfree(fdset); - return (result); -} - -/* - * Opens a TCP/IP connection to the remote server on the given host. - * The address of the remote host will be returned in hostaddr. - * If port is 0, the default port will be used. If needpriv is true, - * a privileged port will be allocated to make the connection. - * This requires super-user privileges if needpriv is true. - * Connection_attempts specifies the maximum number of tries (one per - * second). If proxy_command is non-NULL, it specifies the command (with %h - * and %p substituted for host and port, respectively) to use to contact - * the daemon. - * Return values: - * 0 for OK - * ECONNREFUSED if we got a "Connection Refused" by the peer on any address - * ECONNABORTED if we failed without a "Connection refused" - * Suitable error messages for the connection failure will already have been - * printed. - */ -int -ssh_connect(const char *host, struct sockaddr_storage * hostaddr, - ushort_t port, int family, int connection_attempts, - int needpriv, const char *proxy_command) -{ - int gaierr; - int on = 1; - int sock = -1, attempt; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - struct addrinfo hints, *ai, *aitop; - struct servent *sp; - /* - * Did we get only other errors than "Connection refused" (which - * should block fallback to rsh and similar), or did we get at least - * one "Connection refused"? - */ - int full_failure = 1; - - debug("ssh_connect: needpriv %d", needpriv); - - /* Get default port if port has not been set. */ - if (port == 0) { - sp = getservbyname(SSH_SERVICE_NAME, "tcp"); - if (sp) - port = ntohs(sp->s_port); - else - port = SSH_DEFAULT_PORT; - } - /* If a proxy command is given, connect using it. */ - if (proxy_command != NULL) - return ssh_proxy_connect(host, port, proxy_command); - - /* No proxy command. */ - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%u", port); - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("%s: %.100s: %s", __progname, host, - gai_strerror(gaierr)); - - /* - * Try to connect several times. On some machines, the first time - * will sometimes fail. In general socket code appears to behave - * quite magically on many machines. - */ - for (attempt = 0; ;) { - if (attempt > 0) - debug("Trying again..."); - - /* Loop through addresses for this host, and try each one in - sequence until the connection succeeds. */ - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) - continue; - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, - ntop, sizeof(ntop), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("ssh_connect: getnameinfo failed"); - continue; - } - debug("Connecting to %.200s [%.100s] port %s.", - host, ntop, strport); - - /* Create a socket for connecting. */ - sock = ssh_create_socket(needpriv, ai->ai_family); - if (sock < 0) - /* Any error is already output */ - continue; - - if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, - options.connection_timeout) >= 0) { - /* Successful connection. */ - memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); - break; - } else { - if (errno == ECONNREFUSED) - full_failure = 0; - debug("connect to address %s port %s: %s", - ntop, strport, strerror(errno)); - /* - * Close the failed socket; there appear to - * be some problems when reusing a socket for - * which connect() has already returned an - * error. - */ - close(sock); - } - } - if (ai) - break; /* Successful connection. */ - - attempt++; - if (attempt >= connection_attempts) - break; - /* Sleep a moment before retrying. */ - sleep(1); - } - - freeaddrinfo(aitop); - - /* Return failure if we didn't get a successful connection. */ - if (attempt >= connection_attempts) { - log("ssh: connect to host %s port %s: %s", - host, strport, strerror(errno)); - return full_failure ? ECONNABORTED : ECONNREFUSED; - } - - debug("Connection established."); - - /* Set keepalives if requested. */ - if (options.keepalives && - setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, - sizeof(on)) < 0) - debug2("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); - - /* Set the connection. */ - packet_set_connection(sock, sock); - - return 0; -} - -/* - * Waits for the server identification string, and sends our own - * identification string. - */ -static void -ssh_exchange_identification(void) -{ - char buf[256], remote_version[256]; /* must be same size! */ - int remote_major, remote_minor, i, mismatch; - int connection_in = packet_get_connection_in(); - int connection_out = packet_get_connection_out(); - int minor1 = PROTOCOL_MINOR_1; - - /* Read other side\'s version identification. */ - 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; - } - } - buf[sizeof(buf) - 1] = 0; - if (strncmp(buf, "SSH-", 4) == 0) - break; - debug("ssh_exchange_identification: %s", buf); - } - server_version_string = xstrdup(buf); - - /* - * Check that the versions match. In future this might accept - * several versions and set appropriate flags to handle them. - */ - if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", - &remote_major, &remote_minor, remote_version) != 3) - fatal("Bad remote protocol version identification: '%.100s'", buf); - debug("Remote protocol version %d.%d, remote software version %.100s", - remote_major, remote_minor, remote_version); - - compat_datafellows(remote_version); - mismatch = 0; - - switch (remote_major) { - case 1: - if (remote_minor == 99 && - (options.protocol & SSH_PROTO_2) && - !(options.protocol & SSH_PROTO_1_PREFERRED)) { - enable_compat20(); - break; - } - if (!(options.protocol & SSH_PROTO_1)) { - mismatch = 1; - break; - } - if (remote_minor < 3) { - fatal("Remote machine has too old SSH software version."); - } else if (remote_minor == 3 || remote_minor == 4) { - /* We speak 1.3, too. */ - enable_compat13(); - minor1 = 3; - if (options.forward_agent) { - log("Agent forwarding disabled for protocol 1.3"); - options.forward_agent = 0; - } - } - break; - case 2: - if (options.protocol & SSH_PROTO_2) { - enable_compat20(); - break; - } - /* FALLTHROUGH */ - default: - mismatch = 1; - break; - } - if (mismatch) - fatal("Protocol major versions differ: %d vs. %d", - (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, - remote_major); - /* Send our own protocol version identification. */ - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", - compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, - compat20 ? PROTOCOL_MINOR_2 : minor1, - SSH_VERSION); - if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) - fatal("write: %.100s", strerror(errno)); - client_version_string = xstrdup(buf); - chop(client_version_string); - chop(server_version_string); - debug("Local version string %.100s", client_version_string); -} - -/* defaults to 'no' */ -static int -confirm(const char *prompt) -{ - const char *msg; - char *p, *again = NULL; - int n, ret = -1; - regex_t yesre, nore; - char *errstr; - int rerr, errlen; - - if (options.batch_mode) - return 0; - n = snprintf(NULL, 0, gettext("Please type '%s' or '%s': "), - nl_langinfo(YESSTR), nl_langinfo(NOSTR)); - again = xmalloc(n + 1); - (void) snprintf(again, n + 1, gettext("Please type '%s' or '%s': "), - nl_langinfo(YESSTR), nl_langinfo(NOSTR)); - - if ((rerr = regcomp(&yesre, nl_langinfo(YESEXPR), REG_EXTENDED)) != 0) { - errlen = regerror(rerr, &yesre, NULL, 0); - if ((errstr = malloc(errlen)) == NULL) - err(1, "malloc"); - regerror(rerr, &yesre, errstr, errlen); - errx(1, "YESEXPR: %s: %s", nl_langinfo(YESEXPR), errstr); - } - - if ((rerr = regcomp(&nore, nl_langinfo(NOEXPR), REG_EXTENDED)) != 0) { - errlen = regerror(rerr, &nore, NULL, 0); - if ((errstr = malloc(errlen)) == NULL) - err(1, "malloc"); - regerror(rerr, &nore, errstr, errlen); - errx(1, "NOEXPR: %s: %s", nl_langinfo(NOEXPR), errstr); - } - - for (msg = prompt;;msg = again) { - p = read_passphrase(msg, RP_ECHO); - if (p == NULL || (p[0] == '\0') || (p[0] == '\n') || - regexec(&nore, p, 0, NULL, 0) == 0) - ret = 0; - if (p && regexec(&yesre, p, 0, NULL, 0) == 0) - ret = 1; - if (p) - xfree(p); - if (ret != -1) { - regfree(&yesre); - regfree(&nore); - return ret; - } - } -} - -/* - * check whether the supplied host key is valid, return -1 if the key - * is not valid. the user_hostfile will not be updated if 'readonly' is true. - */ -static int -check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, int - validated, int readonly, const char *user_hostfile, const char - *system_hostfile) -{ - Key *file_key; - char *type = key_type(host_key); - char *ip = NULL; - char hostline[1000], *hostp, *fp; - HostStatus host_status; - HostStatus ip_status; - int r, local = 0, host_ip_differ = 0; - int salen; - char ntop[NI_MAXHOST]; - char msg[1024]; - int len, host_line, ip_line, has_keys; - const char *host_file = NULL, *ip_file = NULL; - - /* - * Force accepting of the host key for loopback/localhost. The - * problem is that if the home directory is NFS-mounted to multiple - * machines, localhost will refer to a different machine in each of - * them, and the user will get bogus HOST_CHANGED warnings. This - * essentially disables host authentication for localhost; however, - * this is probably not a real problem. - */ - /** hostaddr == 0! */ - switch (hostaddr->sa_family) { - case AF_INET: - /* LINTED */ - local = (ntohl(((struct sockaddr_in *)hostaddr)-> - sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; - salen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - /* LINTED */ - local = IN6_IS_ADDR_LOOPBACK( - &(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); - salen = sizeof(struct sockaddr_in6); - break; - default: - local = 0; - salen = sizeof(struct sockaddr_storage); - break; - } - if (options.no_host_authentication_for_localhost == 1 && local && - options.host_key_alias == NULL) { - debug("Forcing accepting of host key for " - "loopback/localhost."); - return 0; - } - - /* - * We don't have the remote ip-address for connections - * using a proxy command - */ - if (options.proxy_command == NULL) { - if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop), - NULL, 0, NI_NUMERICHOST) != 0) - fatal("check_host_key: getnameinfo failed"); - ip = xstrdup(ntop); - } else { - ip = xstrdup("<no hostip for proxy command>"); - } - /* - * Turn off check_host_ip if the connection is to localhost, via proxy - * command or if we don't have a hostname to compare with - */ - if (options.check_host_ip && - (local || strcmp(host, ip) == 0 || options.proxy_command != NULL)) - options.check_host_ip = 0; - - /* - * Allow the user to record the key under a different name. This is - * useful for ssh tunneling over forwarded connections or if you run - * multiple sshd's on different ports on the same machine. - */ - if (options.host_key_alias != NULL) { - host = options.host_key_alias; - debug("using hostkeyalias: %s", host); - } - - /* - * Store the host key from the known host file in here so that we can - * compare it with the key for the IP address. - */ - file_key = key_new(host_key->type); - - /* - * Check if the host key is present in the user's list of known - * hosts or in the systemwide list. - */ - host_file = user_hostfile; - host_status = check_host_in_hostfile(host_file, host, host_key, - file_key, &host_line); - if (host_status == HOST_NEW) { - host_file = system_hostfile; - host_status = check_host_in_hostfile(host_file, host, host_key, - file_key, &host_line); - } - /* - * Also perform check for the ip address, skip the check if we are - * localhost or the hostname was an ip address to begin with - */ - if (options.check_host_ip) { - Key *ip_key = key_new(host_key->type); - - ip_file = user_hostfile; - ip_status = check_host_in_hostfile(ip_file, ip, host_key, - ip_key, &ip_line); - if (ip_status == HOST_NEW) { - ip_file = system_hostfile; - ip_status = check_host_in_hostfile(ip_file, ip, - host_key, ip_key, &ip_line); - } - if (host_status == HOST_CHANGED && - (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) - host_ip_differ = 1; - - key_free(ip_key); - } else - ip_status = host_status; - - key_free(file_key); - - switch (host_status) { - case HOST_OK: - /* The host is known and the key matches. */ - if (validated) - debug("Host '%.200s' is known and matches the %s host key.", - host, type); - else - debug("Host '%.200s' is known and matches the %s host " - "key.", host, type); - debug("Found key in %s:%d", host_file, host_line); - if (options.check_host_ip && ip_status == HOST_NEW) { - if (readonly) - log("%s host key for IP address " - "'%.128s' not in list of known hosts.", - type, ip); - else if (!add_host_to_hostfile(user_hostfile, ip, - host_key, options.hash_known_hosts)) - log("Failed to add the %s host key for IP " - "address '%.128s' to the list of known " - "hosts (%.30s).", type, ip, user_hostfile); - else - log("Warning: Permanently added the %s host " - "key for IP address '%.128s' to the list " - "of known hosts.", type, ip); - } - break; - case HOST_NEW: - if (readonly) - goto fail; - /* The host is new. */ - if (!validated && options.strict_host_key_checking == 1) { - /* - * User has requested strict host key checking. We - * will not add the host key automatically. The only - * alternative left is to abort. - */ - error("No %s host key is known for %.200s and you " - "have requested strict checking.", type, host); - goto fail; - } else if (!validated && - options.strict_host_key_checking == 2) { - has_keys = show_other_keys(host, host_key); - /* The default */ - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - snprintf(msg, sizeof(msg), - gettext("The authenticity of host '%.200s (%s)' " - "can't be established%s\n%s key fingerprint " - "is %s.\n" - "Are you sure you want to continue connecting " - "(%s/%s)? "), - host, ip, - has_keys ? gettext(",\nbut keys of different type " - "are already known for this host.") : ".", - type, fp, nl_langinfo(YESSTR), nl_langinfo(NOSTR)); - xfree(fp); - if (!confirm(msg)) - goto fail; - } - /* - * If not in strict mode, add the key automatically to the - * local known_hosts file. - */ - if (options.check_host_ip && ip_status == HOST_NEW) { - snprintf(hostline, sizeof(hostline), "%s,%s", - host, ip); - hostp = hostline; - if (options.hash_known_hosts) { - /* Add hash of host and IP separately */ - r = add_host_to_hostfile(user_hostfile, host, - host_key, options.hash_known_hosts) && - add_host_to_hostfile(user_hostfile, ip, - host_key, options.hash_known_hosts); - } else { - /* Add unhashed "host,ip" */ - r = add_host_to_hostfile(user_hostfile, - hostline, host_key, - options.hash_known_hosts); - } - } else { - r = add_host_to_hostfile(user_hostfile, host, host_key, - options.hash_known_hosts); - hostp = host; - } - - if (!r) - log("Failed to add the host to the list of known " - "hosts (%.500s).", user_hostfile); - else - log("Warning: Permanently added '%.200s' (%s) to the " - "list of known hosts.", hostp, type); - break; - case HOST_CHANGED: - if (validated) { - log("Warning: The host key for host %s has changed; " - "please update your known hosts file(s) " - "(%s:%d)", host, host_file, host_line); - if (options.check_host_ip && host_ip_differ) { - log("Warning: The host key for host %s has " - "changed; please update your known " - "hosts file(s) (%s:%d)", ip, host_file, - host_line); - - } - break; - } - if (options.check_host_ip && host_ip_differ) { - char *msg; - if (ip_status == HOST_NEW) - msg = "is unknown"; - else if (ip_status == HOST_OK) - msg = "is unchanged"; - else - msg = "has a different value"; - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" - "@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @\n" - "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" - "The %s host key for %s has changed,\n" - "and the key for the according IP address %s\n" - "%s. This could either mean that\n" - "DNS SPOOFING is happening or the IP address for the host\n" - "and its host key have changed at the same time.\n", - type, host, ip, msg); - if (ip_status != HOST_NEW) - error("Offending key for IP in %s:%d", ip_file, ip_line); - } - /* The host key has changed. */ - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" - "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n" - "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" - "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n" - "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n" - "It is also possible that the %s host key has just been changed.\n" - "The fingerprint for the %s key sent by the remote host is\n%s.\n" - "Please contact your system administrator.\n" - "Add correct host key in %.100s to get rid of this message.\n" - "Offending key in %s:%d\n", - type, type, fp, user_hostfile, host_file, host_line); - xfree(fp); - - /* - * If strict host key checking is in use, the user will have - * to edit the key manually and we can only abort. - */ - if (options.strict_host_key_checking) { - error("%s host key for %.200s has changed and you have " - "requested strict checking.", type, host); - goto fail; - } - - /* - * If strict host key checking has not been requested, allow - * the connection but without password authentication or - * agent forwarding. - */ - if (options.password_authentication) { - error("Password authentication is disabled to avoid " - "man-in-the-middle attacks."); - options.password_authentication = 0; - } - if (options.forward_agent) { - error("Agent forwarding is disabled to avoid " - "man-in-the-middle attacks."); - options.forward_agent = 0; - } - if (options.forward_x11) { - error("X11 forwarding is disabled to avoid " - "man-in-the-middle attacks."); - options.forward_x11 = 0; - } - if (options.num_local_forwards > 0 || - options.num_remote_forwards > 0) { - error("Port forwarding is disabled to avoid " - "man-in-the-middle attacks."); - options.num_local_forwards = - options.num_remote_forwards = 0; - } - /* - * XXX Should permit the user to change to use the new id. - * This could be done by converting the host key to an - * identifying sentence, tell that the host identifies itself - * by that sentence, and ask the user if he/she whishes to - * accept the authentication. - */ - break; - case HOST_FOUND: - fatal("internal error"); - break; - } - - if (options.check_host_ip && host_status != HOST_CHANGED && - ip_status == HOST_CHANGED) { - snprintf(msg, sizeof(msg), - gettext("Warning: the %s host key for '%.200s' " - "differs from the key for the IP address '%.128s'" - "\nOffending key for IP in %s:%d"), - type, host, ip, ip_file, ip_line); - if (host_status == HOST_OK) { - len = strlen(msg); - snprintf(msg + len, sizeof(msg) - len, - "\nMatching host key in %s:%d", - host_file, host_line); - } - if (!validated && options.strict_host_key_checking == 1) { - log(msg); - error("Exiting, you have requested strict checking."); - goto fail; - } else if (!validated && - options.strict_host_key_checking == 2) { - snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg), - gettext("\nAre you sure you want to continue " - "connecting (%s/%s)"), - nl_langinfo(YESSTR), nl_langinfo(NOSTR)); - if (!confirm(msg)) - goto fail; - } else { - log(msg); - } - } - - xfree(ip); - return 0; - -fail: - xfree(ip); - return -1; -} - -int -verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) -{ - struct stat st; - - /* return ok if the key can be found in an old keyfile */ - if (stat(options.system_hostfile2, &st) == 0 || - stat(options.user_hostfile2, &st) == 0) { - if (check_host_key(host, hostaddr, host_key, 0, /*readonly*/ 1, - options.user_hostfile2, options.system_hostfile2) == 0) - return 0; - } - return check_host_key(host, hostaddr, host_key, 0, /*readonly*/ 0, - options.user_hostfile, options.system_hostfile); -} - -int -accept_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) -{ - struct stat st; - - /* return ok if the key can be found in an old keyfile */ - if (stat(options.system_hostfile2, &st) == 0 || - stat(options.user_hostfile2, &st) == 0) { - if (check_host_key(host, hostaddr, host_key, 1, /*readonly*/ 1, - options.user_hostfile2, options.system_hostfile2) == 0) - return 0; - } - return check_host_key(host, hostaddr, host_key, 1, /*readonly*/ 0, - options.user_hostfile, options.system_hostfile); -} -/* - * Starts a dialog with the server, and authenticates the current user on the - * server. This does not need any extra privileges. The basic connection - * to the server must already have been established before this is called. - * If login fails, this function prints an error and never returns. - * This function does not require super-user privileges. - */ -void -ssh_login(Sensitive *sensitive, const char *orighost, - struct sockaddr *hostaddr, char *pw_name) -{ - char *host, *cp; - char *server_user, *local_user; - - local_user = xstrdup(pw_name); - server_user = options.user ? options.user : local_user; - - /* Convert the user-supplied hostname into all lowercase. */ - host = xstrdup(orighost); - for (cp = host; *cp; cp++) - if (isupper(*cp)) - *cp = tolower(*cp); - - /* Exchange protocol version identification strings with the server. */ - ssh_exchange_identification(); - - /* - * See comment at definition of will_daemonize for information why we - * don't support the PKCS#11 engine with protocol 1. - */ - if (compat20 == 1 && options.use_openssl_engine == 1) { - /* - * If this fails then 'e' will be NULL which means we do not use - * the engine, as if UseOpenSSLEngine was set to "no". This is - * important in case we go to the background after the - * authentication. - */ - e = pkcs11_engine_load(options.use_openssl_engine); - } - - /* Put the connection into non-blocking mode. */ - packet_set_nonblocking(); - - /* key exchange */ - /* authenticate user */ - if (compat20) { - /* - * Note that the host pointer is saved in ssh_kex2() for later - * use during the key re-exchanges so we must not xfree() it. - */ - ssh_kex2(host, hostaddr); - ssh_userauth2(local_user, server_user, host, sensitive); - } else { - ssh_kex(host, hostaddr); - ssh_userauth1(local_user, server_user, host, sensitive); - } - - xfree(local_user); -} - -void -ssh_put_password(char *password) -{ - int size; - char *padded; - - if (datafellows & SSH_BUG_PASSWORDPAD) { - packet_put_cstring(password); - return; - } - size = roundup(strlen(password) + 1, 32); - padded = xmalloc(size); - memset(padded, 0, size); - strlcpy(padded, password, size); - packet_put_string(padded, size); - memset(padded, 0, size); - xfree(padded); -} - -static int -show_key_from_file(const char *file, const char *host, int keytype) -{ - Key *found; - char *fp; - int line, ret; - - found = key_new(keytype); - if ((ret = lookup_key_in_hostfile_by_type(file, host, - keytype, found, &line))) { - fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); - log("WARNING: %s key found for host %s\n" - "in %s:%d\n" - "%s key fingerprint %s.", - key_type(found), host, file, line, - key_type(found), fp); - xfree(fp); - } - key_free(found); - return (ret); -} - -/* print all known host keys for a given host, but skip keys of given type */ -static int -show_other_keys(const char *host, Key *key) -{ - int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, -1}; - int i, found = 0; - - for (i = 0; type[i] != -1; i++) { - if (type[i] == key->type) - continue; - if (type[i] != KEY_RSA1 && - show_key_from_file(options.user_hostfile2, host, type[i])) { - found = 1; - continue; - } - if (type[i] != KEY_RSA1 && - show_key_from_file(options.system_hostfile2, host, type[i])) { - found = 1; - continue; - } - if (show_key_from_file(options.user_hostfile, host, type[i])) { - found = 1; - continue; - } - if (show_key_from_file(options.system_hostfile, host, type[i])) { - found = 1; - continue; - } - debug2("no key of type %d for host %s", type[i], host); - } - return (found); -} diff --git a/usr/src/cmd/ssh/ssh/sshconnect1.c b/usr/src/cmd/ssh/ssh/sshconnect1.c deleted file mode 100644 index 19cdd84cb6..0000000000 --- a/usr/src/cmd/ssh/ssh/sshconnect1.c +++ /dev/null @@ -1,1312 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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". - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $"); - -#include <openssl/bn.h> -#include <openssl/md5.h> - -#ifdef KRB4 -#include <krb.h> -#endif -#ifdef KRB5 -#include <krb5.h> -#ifndef HEIMDAL -#define krb5_get_err_text(context,code) error_message(code) -#endif /* !HEIMDAL */ -#endif -#ifdef AFS -#include <kafs.h> -#include "radix.h" -#endif - -#include "ssh.h" -#include "ssh1.h" -#include "xmalloc.h" -#include "rsa.h" -#include "buffer.h" -#include "packet.h" -#include "mpaux.h" -#include "uidswap.h" -#include "log.h" -#include "readconf.h" -#include "key.h" -#include "authfd.h" -#include "sshconnect.h" -#include "authfile.h" -#include "readpass.h" -#include "cipher.h" -#include "canohost.h" -#include "auth.h" - -/* Session id for the current session. */ -u_char session_id[16]; -u_int supported_authentications = 0; - -extern Options options; -extern char *__progname; - -/* - * Checks if the user has an authentication agent, and if so, tries to - * authenticate using the agent. - */ -static int -try_agent_authentication(void) -{ - int type; - char *comment; - AuthenticationConnection *auth; - u_char response[16]; - u_int i; - Key *key; - BIGNUM *challenge; - - /* Get connection to the agent. */ - auth = ssh_get_authentication_connection(); - if (!auth) - return 0; - - if ((challenge = BN_new()) == NULL) - fatal("try_agent_authentication: BN_new failed"); - /* Loop through identities served by the agent. */ - 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); - xfree(comment); - - /* Tell the server that we are willing to authenticate using this key. */ - packet_start(SSH_CMSG_AUTH_RSA); - packet_put_bignum(key->rsa->n); - packet_send(); - packet_write_wait(); - - /* Wait for server's response. */ - type = packet_read(); - - /* The server sends failure if it doesn\'t like our key or - 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. */ - if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) - packet_disconnect("Protocol error during RSA authentication: %d", - type); - - packet_get_bignum(challenge); - packet_check_eom(); - - debug("Received RSA challenge from server."); - - /* Ask the agent to decrypt the challenge. */ - 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. */ - packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); - for (i = 0; i < 16; i++) - packet_put_char(response[i]); - packet_send(); - packet_write_wait(); - - /* Wait for response from the server. */ - type = packet_read(); - - /* The server returns success if it accepted the authentication. */ - if (type == SSH_SMSG_SUCCESS) { - ssh_close_authentication_connection(auth); - BN_clear_free(challenge); - debug("RSA authentication accepted by server."); - return 1; - } - /* Otherwise it should return failure. */ - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error waiting RSA auth response: %d", - type); - } - ssh_close_authentication_connection(auth); - BN_clear_free(challenge); - debug("RSA authentication using agent refused."); - return 0; -} - -/* - * Computes the proper response to a RSA challenge, and sends the response to - * the server. - */ -static void -respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) -{ - u_char buf[32], response[16]; - MD5_CTX md; - int i, len; - - /* Decrypt the challenge using the private key. */ - /* XXX think about Bleichenbacher, too */ - if (rsa_private_decrypt(challenge, challenge, prv) <= 0) - packet_disconnect( - "respond_to_rsa_challenge: rsa_private_decrypt failed"); - - /* Compute the response. */ - /* The response is MD5 of decrypted challenge plus session id. */ - len = BN_num_bytes(challenge); - if (len <= 0 || len > sizeof(buf)) - packet_disconnect( - "respond_to_rsa_challenge: bad challenge length %d", len); - - memset(buf, 0, sizeof(buf)); - BN_bn2bin(challenge, buf + sizeof(buf) - len); - MD5_Init(&md); - MD5_Update(&md, buf, 32); - MD5_Update(&md, session_id, 16); - MD5_Final(response, &md); - - debug("Sending response to host key RSA challenge."); - - /* Send the response back to the server. */ - packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); - for (i = 0; i < 16; i++) - packet_put_char(response[i]); - packet_send(); - packet_write_wait(); - - memset(buf, 0, sizeof(buf)); - memset(response, 0, sizeof(response)); - memset(&md, 0, sizeof(md)); -} - -/* - * Checks if the user has authentication file, and if so, tries to authenticate - * the user using it. - */ -static int -try_rsa_authentication(int idx) -{ - BIGNUM *challenge; - Key *public, *private; - char buf[300], *passphrase, *comment, *authfile; - int i, type, quit; - - public = options.identity_keys[idx]; - authfile = options.identity_files[idx]; - comment = xstrdup(authfile); - - debug("Trying RSA authentication with key '%.100s'", comment); - - /* Tell the server that we are willing to authenticate using this key. */ - packet_start(SSH_CMSG_AUTH_RSA); - packet_put_bignum(public->rsa->n); - packet_send(); - packet_write_wait(); - - /* Wait for server's response. */ - type = packet_read(); - - /* - * The server responds with failure if it doesn\'t like our key or - * doesn\'t support RSA authentication. - */ - if (type == SSH_SMSG_FAILURE) { - debug("Server refused our key."); - xfree(comment); - return 0; - } - /* Otherwise, the server should respond with a challenge. */ - if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) - packet_disconnect("Protocol error during RSA authentication: %d", type); - - /* Get the challenge from the packet. */ - if ((challenge = BN_new()) == NULL) - fatal("try_rsa_authentication: BN_new failed"); - packet_get_bignum(challenge); - packet_check_eom(); - - debug("Received RSA challenge from server."); - - /* - * If the key is not stored in external hardware, we have to - * load the private key. Try first with empty passphrase; if it - * fails, ask for a passphrase. - */ - if (public->flags & KEY_FLAG_EXT) - private = public; - else - private = key_load_private_type(KEY_RSA1, authfile, "", NULL); - if (private == NULL && !options.batch_mode) { - snprintf(buf, sizeof(buf), - gettext("Enter passphrase for RSA key '%.100s': "), - comment); - for (i = 0; i < options.number_of_password_prompts; i++) { - passphrase = read_passphrase(buf, 0); - if (strcmp(passphrase, "") != 0) { - private = key_load_private_type(KEY_RSA1, - authfile, passphrase, NULL); - quit = 0; - } else { - debug2("no passphrase given, try next key"); - quit = 1; - } - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - if (private != NULL || quit) - break; - debug2("bad passphrase given, try again..."); - } - } - /* We no longer need the comment. */ - xfree(comment); - - if (private == NULL) { - if (!options.batch_mode) - error("Bad passphrase."); - - /* Send a dummy response packet to avoid protocol error. */ - packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); - for (i = 0; i < 16; i++) - packet_put_char(0); - packet_send(); - packet_write_wait(); - - /* Expect the server to reject it... */ - packet_read_expect(SSH_SMSG_FAILURE); - BN_clear_free(challenge); - return 0; - } - - /* Compute and send a response to the challenge. */ - respond_to_rsa_challenge(challenge, private->rsa); - - /* Destroy the private key unless it in external hardware. */ - if (!(private->flags & KEY_FLAG_EXT)) - key_free(private); - - /* We no longer need the challenge. */ - BN_clear_free(challenge); - - /* Wait for response from the server. */ - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) { - debug("RSA authentication accepted by server."); - return 1; - } - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error waiting RSA auth response: %d", type); - debug("RSA authentication refused."); - return 0; -} - -/* - * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv - * authentication and RSA host authentication. - */ -static int -try_rhosts_rsa_authentication(const char *local_user, Key * host_key) -{ - int type; - BIGNUM *challenge; - - debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); - - /* Tell the server that we are willing to authenticate using this key. */ - packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); - packet_put_cstring(local_user); - packet_put_int(BN_num_bits(host_key->rsa->n)); - packet_put_bignum(host_key->rsa->e); - packet_put_bignum(host_key->rsa->n); - packet_send(); - packet_write_wait(); - - /* Wait for server's response. */ - type = packet_read(); - - /* The server responds with failure if it doesn't admit our - .rhosts authentication or doesn't know our host key. */ - if (type == SSH_SMSG_FAILURE) { - debug("Server refused our rhosts authentication or host key."); - return 0; - } - /* Otherwise, the server should respond with a challenge. */ - if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) - packet_disconnect("Protocol error during RSA authentication: %d", type); - - /* Get the challenge from the packet. */ - if ((challenge = BN_new()) == NULL) - fatal("try_rhosts_rsa_authentication: BN_new failed"); - packet_get_bignum(challenge); - packet_check_eom(); - - debug("Received RSA challenge for host key from server."); - - /* Compute a response to the challenge. */ - respond_to_rsa_challenge(challenge, host_key->rsa); - - /* We no longer need the challenge. */ - BN_clear_free(challenge); - - /* Wait for response from the server. */ - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) { - debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); - return 1; - } - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error waiting RSA auth response: %d", type); - debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); - return 0; -} - -#ifdef KRB4 -static int -try_krb4_authentication(void) -{ - KTEXT_ST auth; /* Kerberos data */ - char *reply; - char inst[INST_SZ]; - char *realm; - CREDENTIALS cred; - int r, type; - socklen_t slen; - Key_schedule schedule; - u_long checksum, cksum; - MSG_DAT msg_data; - struct sockaddr_in local, foreign; - struct stat st; - - /* Don't do anything if we don't have any tickets. */ - if (stat(tkt_string(), &st) < 0) - return 0; - - strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)), - INST_SZ); - - realm = (char *)krb_realmofhost(get_canonical_hostname(1)); - if (!realm) { - debug("Kerberos v4: no realm for %s", get_canonical_hostname(1)); - return 0; - } - /* This can really be anything. */ - checksum = (u_long)getpid(); - - r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); - if (r != KSUCCESS) { - debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]); - return 0; - } - /* Get session key to decrypt the server's reply with. */ - r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); - if (r != KSUCCESS) { - debug("get_cred failed: %s", krb_err_txt[r]); - return 0; - } - des_key_sched((des_cblock *) cred.session, schedule); - - /* Send authentication info to server. */ - packet_start(SSH_CMSG_AUTH_KERBEROS); - packet_put_string((char *) auth.dat, auth.length); - packet_send(); - packet_write_wait(); - - /* Zero the buffer. */ - (void) memset(auth.dat, 0, MAX_KTXT_LEN); - - slen = sizeof(local); - memset(&local, 0, sizeof(local)); - if (getsockname(packet_get_connection_in(), - (struct sockaddr *)&local, &slen) < 0) - debug("getsockname failed: %s", strerror(errno)); - - slen = sizeof(foreign); - memset(&foreign, 0, sizeof(foreign)); - if (getpeername(packet_get_connection_in(), - (struct sockaddr *)&foreign, &slen) < 0) { - debug("getpeername failed: %s", strerror(errno)); - fatal_cleanup(); - } - /* Get server reply. */ - type = packet_read(); - switch (type) { - case SSH_SMSG_FAILURE: - /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ - debug("Kerberos v4 authentication failed."); - return 0; - break; - - case SSH_SMSG_AUTH_KERBEROS_RESPONSE: - /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ - debug("Kerberos v4 authentication accepted."); - - /* Get server's response. */ - reply = packet_get_string((u_int *) &auth.length); - if (auth.length >= MAX_KTXT_LEN) - fatal("Kerberos v4: Malformed response from server"); - memcpy(auth.dat, reply, auth.length); - xfree(reply); - - packet_check_eom(); - - /* - * If his response isn't properly encrypted with the session - * key, and the decrypted checksum fails to match, he's - * bogus. Bail out. - */ - r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, - &foreign, &local, &msg_data); - if (r != KSUCCESS) { - debug("Kerberos v4 krb_rd_priv failed: %s", - krb_err_txt[r]); - packet_disconnect("Kerberos v4 challenge failed!"); - } - /* Fetch the (incremented) checksum that we supplied in the request. */ - memcpy((char *)&cksum, (char *)msg_data.app_data, - sizeof(cksum)); - cksum = ntohl(cksum); - - /* If it matches, we're golden. */ - if (cksum == checksum + 1) { - debug("Kerberos v4 challenge successful."); - return 1; - } else - packet_disconnect("Kerberos v4 challenge failed!"); - break; - - default: - packet_disconnect("Protocol error on Kerberos v4 response: %d", type); - } - return 0; -} - -#endif /* KRB4 */ - -#ifdef KRB5 -static int -try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) -{ - krb5_error_code problem; - const char *tkfile; - struct stat buf; - krb5_ccache ccache = NULL; - const char *remotehost; - krb5_data ap; - int type; - krb5_ap_rep_enc_part *reply = NULL; - int ret; - - memset(&ap, 0, sizeof(ap)); - - problem = krb5_init_context(context); - if (problem) { - debug("Kerberos v5: krb5_init_context failed"); - ret = 0; - goto out; - } - - problem = krb5_auth_con_init(*context, auth_context); - if (problem) { - debug("Kerberos v5: krb5_auth_con_init failed"); - ret = 0; - goto out; - } - -#ifndef HEIMDAL - problem = krb5_auth_con_setflags(*context, *auth_context, - KRB5_AUTH_CONTEXT_RET_TIME); - if (problem) { - debug("Keberos v5: krb5_auth_con_setflags failed"); - ret = 0; - goto out; - } -#endif - - tkfile = krb5_cc_default_name(*context); - if (strncmp(tkfile, "FILE:", 5) == 0) - tkfile += 5; - - if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) { - debug("Kerberos v5: could not get default ccache (permission denied)."); - ret = 0; - goto out; - } - - problem = krb5_cc_default(*context, &ccache); - if (problem) { - debug("Kerberos v5: krb5_cc_default failed: %s", - krb5_get_err_text(*context, problem)); - ret = 0; - goto out; - } - - remotehost = get_canonical_hostname(1); - - problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED, - "host", remotehost, NULL, ccache, &ap); - if (problem) { - debug("Kerberos v5: krb5_mk_req failed: %s", - krb5_get_err_text(*context, problem)); - ret = 0; - goto out; - } - - packet_start(SSH_CMSG_AUTH_KERBEROS); - packet_put_string((char *) ap.data, ap.length); - packet_send(); - packet_write_wait(); - - xfree(ap.data); - ap.length = 0; - - type = packet_read(); - switch (type) { - case SSH_SMSG_FAILURE: - /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ - debug("Kerberos v5 authentication failed."); - ret = 0; - break; - - case SSH_SMSG_AUTH_KERBEROS_RESPONSE: - /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ - debug("Kerberos v5 authentication accepted."); - - /* Get server's response. */ - ap.data = packet_get_string((unsigned int *) &ap.length); - packet_check_eom(); - /* XXX je to dobre? */ - - problem = krb5_rd_rep(*context, *auth_context, &ap, &reply); - if (problem) { - ret = 0; - } - ret = 1; - break; - - default: - packet_disconnect("Protocol error on Kerberos v5 response: %d", - type); - ret = 0; - break; - - } - - out: - if (ccache != NULL) - krb5_cc_close(*context, ccache); - if (reply != NULL) - krb5_free_ap_rep_enc_part(*context, reply); - if (ap.length > 0) -#ifdef HEIMDAL - krb5_data_free(&ap); -#else - krb5_free_data_contents(*context, &ap); -#endif - - return (ret); -} - -static void -send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) -{ - int fd, type; - krb5_error_code problem; - krb5_data outbuf; - krb5_ccache ccache = NULL; - krb5_creds creds; -#ifdef HEIMDAL - krb5_kdc_flags flags; -#else - int forwardable; -#endif - const char *remotehost; - - memset(&creds, 0, sizeof(creds)); - memset(&outbuf, 0, sizeof(outbuf)); - - fd = packet_get_connection_in(); - -#ifdef HEIMDAL - problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd); -#else - problem = krb5_auth_con_genaddrs(context, auth_context, fd, - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); -#endif - if (problem) - goto out; - - problem = krb5_cc_default(context, &ccache); - if (problem) - goto out; - - problem = krb5_cc_get_principal(context, ccache, &creds.client); - if (problem) - goto out; - - remotehost = get_canonical_hostname(1); - -#ifdef HEIMDAL - problem = krb5_build_principal(context, &creds.server, - strlen(creds.client->realm), creds.client->realm, - "krbtgt", creds.client->realm, NULL); -#else - problem = krb5_build_principal(context, &creds.server, - creds.client->realm.length, creds.client->realm.data, - "host", remotehost, NULL); -#endif - if (problem) - goto out; - - creds.times.endtime = 0; - -#ifdef HEIMDAL - flags.i = 0; - flags.b.forwarded = 1; - flags.b.forwardable = krb5_config_get_bool(context, NULL, - "libdefaults", "forwardable", NULL); - problem = krb5_get_forwarded_creds(context, auth_context, - ccache, flags.i, remotehost, &creds, &outbuf); -#else - forwardable = 1; - problem = krb5_fwd_tgt_creds(context, auth_context, remotehost, - creds.client, creds.server, ccache, forwardable, &outbuf); -#endif - - if (problem) - goto out; - - packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); - packet_put_string((char *)outbuf.data, outbuf.length); - packet_send(); - packet_write_wait(); - - type = packet_read(); - - if (type == SSH_SMSG_SUCCESS) { - char *pname; - - krb5_unparse_name(context, creds.client, &pname); - debug("Kerberos v5 TGT forwarded (%s).", pname); - xfree(pname); - } else - debug("Kerberos v5 TGT forwarding failed."); - - return; - - out: - if (problem) - debug("Kerberos v5 TGT forwarding failed: %s", - krb5_get_err_text(context, problem)); - if (creds.client) - krb5_free_principal(context, creds.client); - if (creds.server) - krb5_free_principal(context, creds.server); - if (ccache) - krb5_cc_close(context, ccache); - if (outbuf.data) - xfree(outbuf.data); -} -#endif /* KRB5 */ - -#ifdef AFS -static void -send_krb4_tgt(void) -{ - CREDENTIALS *creds; - struct stat st; - char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; - int problem, type; - - /* Don't do anything if we don't have any tickets. */ - if (stat(tkt_string(), &st) < 0) - return; - - creds = xmalloc(sizeof(*creds)); - - problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm); - if (problem) - goto out; - - problem = krb_get_cred("krbtgt", prealm, prealm, creds); - if (problem) - goto out; - - if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { - problem = RD_AP_EXP; - goto out; - } - creds_to_radix(creds, (u_char *)buffer, sizeof(buffer)); - - packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); - packet_put_cstring(buffer); - packet_send(); - packet_write_wait(); - - type = packet_read(); - - if (type == SSH_SMSG_SUCCESS) - debug("Kerberos v4 TGT forwarded (%s%s%s@%s).", - creds->pname, creds->pinst[0] ? "." : "", - creds->pinst, creds->realm); - else - debug("Kerberos v4 TGT rejected."); - - xfree(creds); - return; - - out: - debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]); - xfree(creds); -} - -static void -send_afs_tokens(void) -{ - CREDENTIALS creds; - struct ViceIoctl parms; - struct ClearToken ct; - int i, type, len; - char buf[2048], *p, *server_cell; - char buffer[8192]; - - /* Move over ktc_GetToken, here's something leaner. */ - for (i = 0; i < 100; i++) { /* just in case */ - parms.in = (char *) &i; - parms.in_size = sizeof(i); - parms.out = buf; - parms.out_size = sizeof(buf); - if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) - break; - p = buf; - - /* Get secret token. */ - memcpy(&creds.ticket_st.length, p, sizeof(u_int)); - if (creds.ticket_st.length > MAX_KTXT_LEN) - break; - p += sizeof(u_int); - memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); - p += creds.ticket_st.length; - - /* Get clear token. */ - memcpy(&len, p, sizeof(len)); - if (len != sizeof(struct ClearToken)) - break; - p += sizeof(len); - memcpy(&ct, p, len); - p += len; - p += sizeof(len); /* primary flag */ - server_cell = p; - - /* Flesh out our credentials. */ - strlcpy(creds.service, "afs", sizeof(creds.service)); - creds.instance[0] = '\0'; - strlcpy(creds.realm, server_cell, REALM_SZ); - memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); - creds.issue_date = ct.BeginTimestamp; - creds.lifetime = krb_time_to_life(creds.issue_date, - ct.EndTimestamp); - creds.kvno = ct.AuthHandle; - snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); - creds.pinst[0] = '\0'; - - /* Encode token, ship it off. */ - if (creds_to_radix(&creds, (u_char *)buffer, - sizeof(buffer)) <= 0) - break; - packet_start(SSH_CMSG_HAVE_AFS_TOKEN); - packet_put_cstring(buffer); - packet_send(); - packet_write_wait(); - - /* Roger, Roger. Clearance, Clarence. What's your vector, - Victor? */ - type = packet_read(); - - if (type == SSH_SMSG_FAILURE) - debug("AFS token for cell %s rejected.", server_cell); - else if (type != SSH_SMSG_SUCCESS) - packet_disconnect("Protocol error on AFS token response: %d", type); - } -} - -#endif /* AFS */ - -/* - * Tries to authenticate with any string-based challenge/response system. - * Note that the client code is not tied to s/key or TIS. - */ -static int -try_challenge_response_authentication(void) -{ - int type, i; - u_int clen; - char prompt[1024]; - char *challenge, *response; - - debug("Doing challenge response authentication."); - - for (i = 0; i < options.number_of_password_prompts; i++) { - /* request a challenge */ - packet_start(SSH_CMSG_AUTH_TIS); - packet_send(); - packet_write_wait(); - - type = packet_read(); - if (type != SSH_SMSG_FAILURE && - type != SSH_SMSG_AUTH_TIS_CHALLENGE) { - packet_disconnect("Protocol error: got %d in response " - "to SSH_CMSG_AUTH_TIS", type); - } - if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { - debug("No challenge."); - return 0; - } - challenge = packet_get_string(&clen); - packet_check_eom(); - snprintf(prompt, sizeof prompt, "%s%s", challenge, - strchr(challenge, '\n') ? "" : gettext("\nResponse: ")); - xfree(challenge); - if (i != 0) - error("Permission denied, please try again."); - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! " - "Response will be transmitted in clear text."); - response = read_passphrase(prompt, 0); - if (strcmp(response, "") == 0) { - xfree(response); - break; - } - packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); - ssh_put_password(response); - memset(response, 0, strlen(response)); - xfree(response); - packet_send(); - packet_write_wait(); - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - return 1; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response " - "to SSH_CMSG_AUTH_TIS_RESPONSE", type); - } - /* failure */ - return 0; -} - -/* - * Tries to authenticate with plain passwd authentication. - */ -static int -try_password_authentication(char *prompt) -{ - int type, i; - char *password; - - debug("Doing password authentication."); - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Password will be transmitted in clear text."); - for (i = 0; i < options.number_of_password_prompts; i++) { - if (i != 0) - error("Permission denied, please try again."); - password = read_passphrase(prompt, 0); - packet_start(SSH_CMSG_AUTH_PASSWORD); - ssh_put_password(password); - memset(password, 0, strlen(password)); - xfree(password); - packet_send(); - packet_write_wait(); - - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - return 1; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to passwd auth", type); - } - /* failure */ - return 0; -} - -/* - * SSH1 key exchange - */ -void -ssh_kex(char *host, struct sockaddr *hostaddr) -{ - int i; - BIGNUM *key; - Key *host_key, *server_key; - int bits, rbits; - int ssh_cipher_default = SSH_CIPHER_3DES; - u_char session_key[SSH_SESSION_KEY_LENGTH]; - u_char cookie[8]; - u_int supported_ciphers; - u_int server_flags, client_flags; - u_int32_t rand = 0; - - debug("Waiting for server public key."); - - /* Wait for a public key packet from the server. */ - packet_read_expect(SSH_SMSG_PUBLIC_KEY); - - /* Get cookie from the packet. */ - for (i = 0; i < 8; i++) - cookie[i] = packet_get_char(); - - /* Get the public key. */ - server_key = key_new(KEY_RSA1); - bits = packet_get_int(); - packet_get_bignum(server_key->rsa->e); - packet_get_bignum(server_key->rsa->n); - - rbits = BN_num_bits(server_key->rsa->n); - if (bits != rbits) { - log("Warning: Server lies about size of server public key: " - "actual size is %d bits vs. announced %d.", rbits, bits); - log("Warning: This may be due to an old implementation of ssh."); - } - /* Get the host key. */ - host_key = key_new(KEY_RSA1); - bits = packet_get_int(); - packet_get_bignum(host_key->rsa->e); - packet_get_bignum(host_key->rsa->n); - - rbits = BN_num_bits(host_key->rsa->n); - if (bits != rbits) { - log("Warning: Server lies about size of server host key: " - "actual size is %d bits vs. announced %d.", rbits, bits); - log("Warning: This may be due to an old implementation of ssh."); - } - - /* Get protocol flags. */ - server_flags = packet_get_int(); - packet_set_protocol_flags(server_flags); - - supported_ciphers = packet_get_int(); - supported_authentications = packet_get_int(); - packet_check_eom(); - - debug("Received server public key (%d bits) and host key (%d bits).", - BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); - - if (verify_host_key(host, hostaddr, host_key) == -1) - fatal("Host key verification failed."); - - client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; - - compute_session_id(session_id, cookie, host_key->rsa->n, server_key->rsa->n); - - /* Generate a session key. */ - arc4random_stir(); - - /* - * Generate an encryption key for the session. The key is a 256 bit - * random number, interpreted as a 32-byte key, with the least - * significant 8 bits being the first byte of the key. - */ - for (i = 0; i < 32; i++) { - if (i % 4 == 0) - rand = arc4random(); - session_key[i] = rand & 0xff; - rand >>= 8; - } - - /* - * According to the protocol spec, the first byte of the session key - * is the highest byte of the integer. The session key is xored with - * the first 16 bytes of the session id. - */ - if ((key = BN_new()) == NULL) - fatal("respond_to_rsa_challenge: BN_new failed"); - BN_set_word(key, 0); - for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { - BN_lshift(key, key, 8); - if (i < 16) - BN_add_word(key, session_key[i] ^ session_id[i]); - else - BN_add_word(key, session_key[i]); - } - - /* - * Encrypt the integer using the public key and host key of the - * server (key with smaller modulus first). - */ - if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { - /* Public key has smaller modulus. */ - if (BN_num_bits(host_key->rsa->n) < - BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " - "SSH_KEY_BITS_RESERVED %d", - BN_num_bits(host_key->rsa->n), - BN_num_bits(server_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - rsa_public_encrypt(key, key, server_key->rsa); - rsa_public_encrypt(key, key, host_key->rsa); - } else { - /* Host key has smaller modulus (or they are equal). */ - if (BN_num_bits(server_key->rsa->n) < - BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " - "SSH_KEY_BITS_RESERVED %d", - BN_num_bits(server_key->rsa->n), - BN_num_bits(host_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - rsa_public_encrypt(key, key, host_key->rsa); - rsa_public_encrypt(key, key, server_key->rsa); - } - - /* Destroy the public keys since we no longer need them. */ - key_free(server_key); - key_free(host_key); - - if (options.cipher == SSH_CIPHER_NOT_SET) { - if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) - options.cipher = ssh_cipher_default; - } else if (options.cipher == SSH_CIPHER_ILLEGAL || - !(cipher_mask_ssh1(1) & (1 << options.cipher))) { - log("No valid SSH1 cipher, using %.100s instead.", - cipher_name(ssh_cipher_default)); - options.cipher = ssh_cipher_default; - } - /* Check that the selected cipher is supported. */ - if (!(supported_ciphers & (1 << options.cipher))) - fatal("Selected cipher type %.100s not supported by server.", - cipher_name(options.cipher)); - - debug("Encryption type: %.100s", cipher_name(options.cipher)); - - /* Send the encrypted session key to the server. */ - packet_start(SSH_CMSG_SESSION_KEY); - packet_put_char(options.cipher); - - /* Send the cookie back to the server. */ - for (i = 0; i < 8; i++) - packet_put_char(cookie[i]); - - /* Send and destroy the encrypted encryption key integer. */ - packet_put_bignum(key); - BN_clear_free(key); - - /* Send protocol flags. */ - packet_put_int(client_flags); - - /* Send the packet now. */ - packet_send(); - packet_write_wait(); - - debug("Sent encrypted session key."); - - /* Set the encryption key. */ - packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); - - /* We will no longer need the session key here. Destroy any extra copies. */ - memset(session_key, 0, sizeof(session_key)); - - /* - * Expect a success message from the server. Note that this message - * will be received in encrypted form. - */ - packet_read_expect(SSH_SMSG_SUCCESS); - - debug("Received encrypted confirmation."); -} - -/* - * Authenticate user - */ -void -ssh_userauth1(const char *local_user, const char *server_user, char *host, - Sensitive *sensitive) -{ -#ifdef KRB5 - krb5_context context = NULL; - krb5_auth_context auth_context = NULL; -#endif - int i, type; - - if (supported_authentications == 0) - fatal("ssh_userauth1: server supports no auth methods"); - - /* Send the name of the user to log in as on the server. */ - packet_start(SSH_CMSG_USER); - packet_put_cstring(server_user); - packet_send(); - packet_write_wait(); - - /* - * The server should respond with success if no authentication is - * needed (the user has no password). Otherwise the server responds - * with failure. - */ - type = packet_read(); - - /* check whether the connection was accepted without authentication. */ - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type); - -#ifdef KRB5 - if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && - options.kerberos_authentication) { - debug("Trying Kerberos v5 authentication."); - - if (try_krb5_authentication(&context, &auth_context)) { - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type); - } - } -#endif /* KRB5 */ - -#ifdef KRB4 - if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && - options.kerberos_authentication) { - debug("Trying Kerberos v4 authentication."); - - if (try_krb4_authentication()) { - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type); - } - } -#endif /* KRB4 */ - - /* - * Use rhosts authentication if running in privileged socket and we - * do not wish to remain anonymous. - */ - if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && - options.rhosts_authentication) { - debug("Trying rhosts authentication."); - packet_start(SSH_CMSG_AUTH_RHOSTS); - packet_put_cstring(local_user); - packet_send(); - packet_write_wait(); - - /* The server should respond with success or failure. */ - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to rhosts auth", - type); - } - /* - * Try .rhosts or /etc/hosts.equiv authentication with RSA host - * authentication. - */ - if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && - options.rhosts_rsa_authentication) { - for (i = 0; i < sensitive->nkeys; i++) { - if (sensitive->keys[i] != NULL && - sensitive->keys[i]->type == KEY_RSA1 && - try_rhosts_rsa_authentication(local_user, - sensitive->keys[i])) - goto success; - } - } - /* Try RSA authentication if the server supports it. */ - if ((supported_authentications & (1 << SSH_AUTH_RSA)) && - options.rsa_authentication) { - /* - * Try RSA authentication using the authentication agent. The - * agent is tried first because no passphrase is needed for - * it, whereas identity files may require passphrases. - */ - if (try_agent_authentication()) - goto success; - - /* Try RSA authentication for each identity. */ - for (i = 0; i < options.num_identity_files; i++) - if (options.identity_keys[i] != NULL && - options.identity_keys[i]->type == KEY_RSA1 && - try_rsa_authentication(i)) - goto success; - } - /* Try challenge response authentication if the server supports it. */ - if ((supported_authentications & (1 << SSH_AUTH_TIS)) && - options.challenge_response_authentication && !options.batch_mode) { - if (try_challenge_response_authentication()) - goto success; - } - /* Try password authentication if the server supports it. */ - if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && - options.password_authentication && !options.batch_mode) { - char prompt[80]; - - snprintf(prompt, sizeof(prompt), - gettext("%.30s@%.128s's password: "), - server_user, host); - if (try_password_authentication(prompt)) - goto success; - } - /* All authentication methods have failed. Exit with an error message. */ - fatal("Permission denied (all authentication methods have failed)."); - /* NOTREACHED */ - - success: -#ifdef KRB5 - /* Try Kerberos v5 TGT passing. */ - if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && - options.kerberos_tgt_passing && context && auth_context) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - send_krb5_tgt(context, auth_context); - } - if (auth_context) - krb5_auth_con_free(context, auth_context); - if (context) - krb5_free_context(context); -#endif - -#ifdef AFS - /* Try Kerberos v4 TGT passing if the server supports it. */ - if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && - options.kerberos_tgt_passing) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - send_krb4_tgt(); - } - /* Try AFS token passing if the server supports it. */ - if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && - options.afs_token_passing && k_hasafs()) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); - send_afs_tokens(); - } -#endif /* AFS */ - - return; /* need statement after label */ -} diff --git a/usr/src/cmd/ssh/ssh/sshconnect2.c b/usr/src/cmd/ssh/ssh/sshconnect2.c deleted file mode 100644 index e485355b6a..0000000000 --- a/usr/src/cmd/ssh/ssh/sshconnect2.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.107 2002/07/01 19:48:46 markus Exp $"); - -#include "ssh.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "buffer.h" -#include "packet.h" -#include "compat.h" -#include "bufaux.h" -#include "cipher.h" -#include "kex.h" -#include "myproposal.h" -#include "sshconnect.h" -#include "authfile.h" -#include "dh.h" -#include "authfd.h" -#include "log.h" -#include "readconf.h" -#include "readpass.h" -#include "match.h" -#include "dispatch.h" -#include "canohost.h" -#include "msg.h" -#include "pathnames.h" -#include "g11n.h" - -#ifdef GSSAPI -#include "ssh-gss.h" -extern Gssctxt *xxx_gssctxt; -#endif /* GSSAPI */ - -/* import */ -extern char *client_version_string; -extern char *server_version_string; -extern Options options; -extern Buffer command; - -/* - * SSH2 key exchange - */ - -u_char *session_id2 = NULL; -int session_id2_len = 0; - -char *xxx_host; -struct sockaddr *xxx_hostaddr; - -Kex *xxx_kex = NULL; - -static int -verify_host_key_callback(Key *hostkey) -{ - if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) - fatal("Host key verification failed."); - return 0; -} - -static int -accept_host_key_callback(Key *hostkey) -{ - if (accept_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) - log("GSS-API authenticated host key addition to " - "known_hosts file failed"); - return 0; -} - -void -ssh_kex2(char *host, struct sockaddr *hostaddr) -{ - Kex *kex; - Kex_hook_func kex_hook = NULL; - static char **myproposal; - - myproposal = my_clnt_proposal; - - xxx_host = host; - xxx_hostaddr = hostaddr; - -#ifdef GSSAPI - /* Add the GSSAPI mechanisms currently supported on this client to - * the key exchange algorithm proposal */ - if (options.gss_keyex) - kex_hook = ssh_gssapi_client_kex_hook; -#endif /* GSSAPI */ - if (options.ciphers == (char *)-1) { - log("No valid ciphers for protocol version 2 given, using defaults."); - options.ciphers = NULL; - } - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); - myproposal[PROPOSAL_ENC_ALGS_STOC] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); - if (options.compression) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none"; - } else { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib"; - } - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - } - if (options.hostkeyalgorithms != NULL) - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - options.hostkeyalgorithms; - - if (options.rekey_limit) - packet_set_rekey_limit((u_int32_t)options.rekey_limit); - - if (datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS) { - char *locale = setlocale(LC_ALL, ""); - - /* Solaris 9 SSHD expects a locale, not a langtag list */ - myproposal[PROPOSAL_LANG_CTOS] = ""; - if (locale != NULL && *locale != '\0' && - strcmp(locale, "C") != 0) - myproposal[PROPOSAL_LANG_CTOS] = locale; - } else { - myproposal[PROPOSAL_LANG_CTOS] = g11n_getlangs(); - } - - /* Same languages proposal for both directions */ - if (myproposal[PROPOSAL_LANG_CTOS] == NULL) { - myproposal[PROPOSAL_LANG_CTOS] = ""; - myproposal[PROPOSAL_LANG_STOC] = ""; - } else { - myproposal[PROPOSAL_LANG_STOC] = - myproposal[PROPOSAL_LANG_CTOS]; - } - - /* start key exchange */ - kex = kex_setup(host, myproposal, kex_hook); - kex_start(kex); - kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; -#ifdef GSSAPI - kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; - kex->options.gss_deleg_creds = options.gss_deleg_creds; -#endif /* GSSAPI */ - kex->client_version_string=client_version_string; - kex->server_version_string=server_version_string; - kex->verify_host_key=&verify_host_key_callback; - kex->accept_host_key=&accept_host_key_callback; - - xxx_kex = kex; - - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); - - session_id2 = kex->session_id; - session_id2_len = kex->session_id_len; - -#ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - packet_start(SSH2_MSG_IGNORE); - packet_put_cstring("markus"); - packet_send(); - packet_write_wait(); -#endif - debug("done: ssh_kex2."); -} - -/* - * Authenticate user - */ - -typedef struct Authctxt Authctxt; -typedef struct Authmethod Authmethod; - -typedef int sign_cb_fn( - Authctxt *authctxt, Key *key, - u_char **sigp, u_int *lenp, u_char *data, u_int datalen); - -struct Authctxt { - const char *server_user; - const char *local_user; - const char *host; - const char *service; - Authmethod *method; - int success; - char *authlist; - /* pubkey */ - Key *last_key; - sign_cb_fn *last_key_sign; - int last_key_hint; - AuthenticationConnection *agent; - /* hostbased */ - Sensitive *sensitive; - /* kbd-interactive */ - int info_req_seen; - /* generic */ - void *methoddata; -}; -struct Authmethod { - char *name; /* string to compare against server's list */ - int (*userauth)(Authctxt *authctxt); - void (*cleanup)(Authctxt *authctxt); - int *enabled; /* flag in option struct that enables method */ - int *batch_flag; /* flag in option struct that disables method */ -}; - -void input_userauth_success(int, u_int32_t, void *); -void input_userauth_failure(int, u_int32_t, void *); -void input_userauth_banner(int, u_int32_t, void *); -void input_userauth_error(int, u_int32_t, void *); -void input_userauth_info_req(int, u_int32_t, void *); -void input_userauth_pk_ok(int, u_int32_t, void *); -void input_userauth_passwd_changereq(int, u_int32_t, void *); - -int userauth_none(Authctxt *); -int userauth_pubkey(Authctxt *); -int userauth_passwd(Authctxt *); -int userauth_kbdint(Authctxt *); -int userauth_hostbased(Authctxt *); - -#ifdef GSSAPI -static int userauth_gssapi_keyex(Authctxt *authctxt); -static int userauth_gssapi(Authctxt *authctxt); -static void userauth_gssapi_cleanup(Authctxt *authctxt); -static void input_gssapi_response(int type, u_int32_t, void *); -static void input_gssapi_token(int type, u_int32_t, void *); -static void input_gssapi_hash(int type, u_int32_t, void *); -static void input_gssapi_error(int, u_int32_t, void *); -static void input_gssapi_errtok(int, u_int32_t, void *); -#endif /* GSSAPI */ - -void userauth(Authctxt *, char *); - -static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *); -static void clear_auth_state(Authctxt *); - -static Authmethod *authmethod_get(char *authlist); -static Authmethod *authmethod_lookup(const char *name); -static char *authmethods_get(void); - -Authmethod authmethods[] = { -#ifdef GSSAPI - {"gssapi-keyex", - userauth_gssapi_keyex, - userauth_gssapi_cleanup, - &options.gss_keyex, - NULL}, - {"gssapi-with-mic", - userauth_gssapi, - userauth_gssapi_cleanup, - &options.gss_authentication, - NULL}, -#endif /* GSSAPI */ - {"hostbased", - userauth_hostbased, - NULL, - &options.hostbased_authentication, - NULL}, - {"publickey", - userauth_pubkey, - NULL, - &options.pubkey_authentication, - NULL}, - {"keyboard-interactive", - userauth_kbdint, - NULL, - &options.kbd_interactive_authentication, - &options.batch_mode}, - {"password", - userauth_passwd, - NULL, - &options.password_authentication, - &options.batch_mode}, - {"none", - userauth_none, - NULL, - NULL, - NULL}, - {NULL, NULL, NULL, NULL, NULL} -}; - -void -ssh_userauth2(const char *local_user, const char *server_user, char *host, - Sensitive *sensitive) -{ - Authctxt authctxt; - int type; - - if (options.challenge_response_authentication) - options.kbd_interactive_authentication = 1; - - packet_start(SSH2_MSG_SERVICE_REQUEST); - packet_put_cstring("ssh-userauth"); - packet_send(); - debug("send SSH2_MSG_SERVICE_REQUEST"); - packet_write_wait(); - type = packet_read(); - if (type != SSH2_MSG_SERVICE_ACCEPT) - fatal("Server denied authentication request: %d", type); - if (packet_remaining() > 0) { - char *reply = packet_get_string(NULL); - debug2("service_accept: %s", reply); - xfree(reply); - } else { - debug2("buggy server: service_accept w/o service"); - } - packet_check_eom(); - debug("got SSH2_MSG_SERVICE_ACCEPT"); - - if (options.preferred_authentications == NULL) - options.preferred_authentications = authmethods_get(); - - /* setup authentication context */ - memset(&authctxt, 0, sizeof(authctxt)); - authctxt.agent = ssh_get_authentication_connection(); - authctxt.server_user = server_user; - authctxt.local_user = local_user; - authctxt.host = host; - authctxt.service = "ssh-connection"; /* service name */ - authctxt.success = 0; - authctxt.method = authmethod_lookup("none"); - authctxt.authlist = NULL; - authctxt.methoddata = NULL; - authctxt.sensitive = sensitive; - authctxt.info_req_seen = 0; - if (authctxt.method == NULL) - fatal("ssh_userauth2: internal error: cannot send userauth none request"); - - /* initial userauth request */ - userauth_none(&authctxt); - - dispatch_init(&input_userauth_error); - dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); - dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); - dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); - dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ - - if (authctxt.agent != NULL) - ssh_close_authentication_connection(authctxt.agent); - - debug("Authentication succeeded (%s)", authctxt.method->name); -} -void -userauth(Authctxt *authctxt, char *authlist) -{ - if (authctxt->method != NULL && - authctxt->method->cleanup != NULL) - authctxt->method->cleanup(authctxt); - - if (authlist == NULL) { - authlist = authctxt->authlist; - } else { - if (authctxt->authlist) - xfree(authctxt->authlist); - authctxt->authlist = authlist; - } - for (;;) { - Authmethod *method = authmethod_get(authlist); - if (method == NULL) - fatal("Permission denied (%s).", authlist); - authctxt->method = method; - if (method->userauth(authctxt) != 0) { - debug2("we sent a %s packet, wait for reply", method->name); - break; - } else { - debug2("we did not send a packet, disable method"); - method->enabled = NULL; - } - } -} - -void -input_userauth_error(int type, u_int32_t seq, void *ctxt) -{ - fatal("input_userauth_error: bad message during authentication: " - "type %d", type); -} - -void -input_userauth_banner(int type, u_int32_t seq, void *ctxt) -{ - char *msg, *lang; - - debug3("input_userauth_banner"); - msg = packet_get_utf8_string(NULL); - lang = packet_get_string(NULL); - /* - * Banner is a warning message according to RFC 4252. So, never print - * a banner in error log level or lower. If the log level is higher, - * use DisableBanner option to decide whether to display it or not. - */ - if (options.log_level > SYSLOG_LEVEL_ERROR) { - if (options.disable_banner == 0 || - (options.disable_banner == SSH_NO_BANNER_IN_EXEC_MODE && - buffer_len(&command) == 0)) { - msg = g11n_filter_string(msg); - (void) fprintf(stderr, "%s", msg); - } - } - xfree(msg); - xfree(lang); -} - -void -input_userauth_success(int type, u_int32_t seq, void *ctxt) -{ - Authctxt *authctxt = ctxt; - if (authctxt == NULL) - fatal("input_userauth_success: no authentication context"); - if (authctxt->authlist) - xfree(authctxt->authlist); - if (authctxt->method != NULL && - authctxt->method->cleanup != NULL) - authctxt->method->cleanup(authctxt); - clear_auth_state(authctxt); - authctxt->success = 1; /* break out */ -} - -void -input_userauth_failure(int type, u_int32_t seq, void *ctxt) -{ - Authctxt *authctxt = ctxt; - char *authlist = NULL; - int partial; - - if (authctxt == NULL) - fatal("input_userauth_failure: no authentication context"); - - authlist = packet_get_string(NULL); - partial = packet_get_char(); - packet_check_eom(); - - if (partial != 0) - log("Authenticated with partial success."); - debug("Authentications that can continue: %s", authlist); - - clear_auth_state(authctxt); - userauth(authctxt, authlist); -} -void -input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Key *key = NULL; - Buffer b; - int pktype, sent = 0; - u_int alen, blen; - char *pkalg, *fp; - u_char *pkblob; - - if (authctxt == NULL) - fatal("input_userauth_pk_ok: no authentication context"); - if (datafellows & SSH_BUG_PKOK) { - /* this is similar to SSH_BUG_PKAUTH */ - debug2("input_userauth_pk_ok: SSH_BUG_PKOK"); - pkblob = packet_get_string(&blen); - buffer_init(&b); - buffer_append(&b, pkblob, blen); - pkalg = buffer_get_string(&b, &alen); - buffer_free(&b); - } else { - pkalg = packet_get_string(&alen); - pkblob = packet_get_string(&blen); - } - packet_check_eom(); - - debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d", - pkalg, blen, authctxt->last_key, authctxt->last_key_hint); - - do { - if (authctxt->last_key == NULL || - authctxt->last_key_sign == NULL) { - debug("no last key or no sign cb"); - break; - } - if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { - debug("unknown pkalg %s", pkalg); - break; - } - if ((key = key_from_blob(pkblob, blen)) == NULL) { - debug("no key from blob. pkalg %s", pkalg); - break; - } - if (key->type != pktype) { - error("input_userauth_pk_ok: type mismatch " - "for decoded key (received %d, expected %d)", - key->type, pktype); - break; - } - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); - debug2("input_userauth_pk_ok: fp %s", fp); - xfree(fp); - if (!key_equal(key, authctxt->last_key)) { - debug("key != last_key"); - break; - } - sent = sign_and_send_pubkey(authctxt, key, - authctxt->last_key_sign); - } while (0); - - if (key != NULL) - key_free(key); - xfree(pkalg); - xfree(pkblob); - - /* unregister */ - clear_auth_state(authctxt); - dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL); - - /* try another method if we did not send a packet */ - if (sent == 0) - userauth(authctxt, NULL); - -} - -#ifdef GSSAPI -int -userauth_gssapi(Authctxt *authctxt) -{ - Gssctxt *gssctxt = NULL; - static int initialized = 0; - static int mech_idx = 0; - static gss_OID_set supported = GSS_C_NULL_OID_SET; - gss_OID mech = GSS_C_NULL_OID; - - /* Things work better if we send one mechanism at a time, rather - * than them all at once. This means that if we fail at some point - * in the middle of a negotiation, we can come back and try something - * different. */ - - if (datafellows & SSH_OLD_GSSAPI) return 0; - - /* Before we offer a mechanism, check that we can support it. Don't - * bother trying to get credentials - as the standard fallback will - * deal with that kind of failure. - */ - - if (!initialized) { - initialized = 1; - ssh_gssapi_client_mechs(authctxt->host, &supported); - if (supported == GSS_C_NULL_OID_SET || supported->count == 0) - return (0); - } else if (supported != GSS_C_NULL_OID_SET) { - /* Try next mech, if any */ - mech_idx++; - - if (mech_idx >= supported->count) - return (0); - } else { - return (0); - } - - mech = &supported->elements[mech_idx]; - - ssh_gssapi_build_ctx(&gssctxt, 1, mech); - authctxt->methoddata=(void *)gssctxt; - - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - - packet_put_int(1); - - /* The newest gsskeyex draft stipulates that OIDs should - * be DER encoded, so we need to add the object type and - * length information back on */ - if (datafellows & SSH_BUG_GSSAPI_BER) { - packet_put_string(mech->elements, mech->length); - } else { - packet_put_int((mech->length)+2); - packet_put_char(0x06); - packet_put_char(mech->length); - packet_put_raw(mech->elements, mech->length); - } - - packet_send(); - packet_write_wait(); - - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,&input_gssapi_response); - - return 1; -} - -void -input_gssapi_response(int type, u_int32_t plen, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - OM_uint32 status,ms; - u_int oidlen; - char *oidv; - gss_buffer_desc send_tok; - - if (authctxt == NULL) - fatal("input_gssapi_response: no authentication context"); - gssctxt = authctxt->methoddata; - - /* Setup our OID */ - oidv=packet_get_string(&oidlen); - - if (datafellows & SSH_BUG_GSSAPI_BER) { - if (!ssh_gssapi_check_mech_oid(gssctxt,oidv,oidlen)) { - gss_OID oid; - - oid = ssh_gssapi_make_oid(oidlen, oidv); - debug("Server returned different OID (%s) than expected (%s)", - ssh_gssapi_oid_to_str(oid), - ssh_gssapi_oid_to_str(gssctxt->desired_mech)); - ssh_gssapi_release_oid(&oid); - clear_auth_state(authctxt); - userauth(authctxt,NULL); - return; - } - } else { - if(oidv[0]!=0x06 || oidv[1]!=oidlen-2) { - debug("Badly encoded mechanism OID received"); - clear_auth_state(authctxt); - userauth(authctxt,NULL); - return; - } - if (!ssh_gssapi_check_mech_oid(gssctxt,oidv+2,oidlen-2)) { - gss_OID oid; - - oid = ssh_gssapi_make_oid(oidlen-2, oidv+2); - debug("Server returned different OID (%s) than expected (%s)", - ssh_gssapi_oid_to_str(oid), - ssh_gssapi_oid_to_str(gssctxt->desired_mech)); - clear_auth_state(authctxt); - userauth(authctxt,NULL); - return; - } - } - - packet_check_eom(); - - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,&input_gssapi_error); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,&input_gssapi_errtok); - - status = ssh_gssapi_init_ctx(gssctxt, authctxt->host, - options.gss_deleg_creds, - GSS_C_NO_BUFFER, &send_tok); - if (GSS_ERROR(status)) { - if (send_tok.length>0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); - packet_put_string(send_tok.value,send_tok.length); - packet_send(); - packet_write_wait(); - } - /* Start again with next method on list */ - debug("Trying to start again"); - clear_auth_state(authctxt); - userauth(authctxt,NULL); - return; - } - - /* We must have data to send */ - packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); - packet_put_string(send_tok.value,send_tok.length); - packet_send(); - packet_write_wait(); - gss_release_buffer(&ms, &send_tok); -} - -void -input_gssapi_token(int type, u_int32_t plen, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - gss_buffer_desc send_tok, recv_tok, g_mic_data; - Buffer mic_data; - OM_uint32 status; - u_int slen; - - if (authctxt == NULL || authctxt->method == NULL) - fatal("input_gssapi_response: no authentication context"); - gssctxt = authctxt->methoddata; - - recv_tok.value=packet_get_string(&slen); - recv_tok.length=slen; /* safe typecast */ - - status=ssh_gssapi_init_ctx(gssctxt, authctxt->host, - options.gss_deleg_creds, - &recv_tok, &send_tok); - - packet_check_eom(); - - if (GSS_ERROR(status)) { - if (send_tok.length>0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); - packet_put_string(send_tok.value,send_tok.length); - packet_send(); - packet_write_wait(); - } - /* Start again with the next method in the list */ - clear_auth_state(authctxt); - userauth(authctxt,NULL); - return; - } - - if (send_tok.length>0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); - packet_put_string(send_tok.value,send_tok.length); - packet_send(); - packet_write_wait(); - } - - if (status != GSS_S_COMPLETE) - return; - - /* Make data buffer to MIC */ - buffer_init(&mic_data); - buffer_put_string(&mic_data, session_id2, session_id2_len); - buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&mic_data, authctxt->server_user); - buffer_put_cstring(&mic_data, authctxt->service); - buffer_put_cstring(&mic_data, authctxt->method->name); - - /* Make MIC */ - g_mic_data.value = buffer_ptr(&mic_data); - g_mic_data.length = buffer_len(&mic_data); - - status = ssh_gssapi_get_mic(gssctxt, &g_mic_data, &send_tok); - buffer_clear(&mic_data); - - if (GSS_ERROR(status) || send_tok.length == 0) { - /* - * Oops, now what? There's no error token... - * Next userauth - */ - debug("GSS_GetMIC() failed! - " - "Abandoning GSSAPI userauth"); - clear_auth_state(authctxt); - userauth(authctxt,NULL); - return; - } - packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); - packet_put_string(send_tok.value,send_tok.length); - packet_send(); - packet_write_wait(); -} - -void -input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) -{ - OM_uint32 min_status; - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - gss_buffer_desc send_tok, recv_tok; - - if (authctxt == NULL) - fatal("input_gssapi_response: no authentication context"); - gssctxt = authctxt->methoddata; - - recv_tok.value=packet_get_string(&recv_tok.length); - - /* Stick it into GSSAPI and see what it says */ - (void) ssh_gssapi_init_ctx(gssctxt, authctxt->host, - options.gss_deleg_creds, - &recv_tok, &send_tok); - - xfree(recv_tok.value); - (void) gss_release_buffer(&min_status, &send_tok); - - debug("Server sent a GSS-API error token during GSS userauth -- %s", - ssh_gssapi_last_error(gssctxt, NULL, NULL)); - - packet_check_eom(); - - /* We can't send a packet to the server */ - - /* The draft says that we should wait for the server to fail - * before starting the next authentication. So, we clear the - * state, but don't do anything else - */ - clear_auth_state(authctxt); - return; -} - -void -input_gssapi_error(int type, u_int32_t plen, void *ctxt) -{ - OM_uint32 maj,min; - char *msg; - char *lang; - - maj = packet_get_int(); - min = packet_get_int(); - msg = packet_get_string(NULL); - lang = packet_get_string(NULL); - - packet_check_eom(); - - fprintf(stderr, "Server GSSAPI Error:\n%s (%d, %d)\n", msg, maj, min); - xfree(msg); - xfree(lang); -} - -int -userauth_gssapi_keyex(Authctxt *authctxt) -{ - Gssctxt *gssctxt; - gss_buffer_desc send_tok; - OM_uint32 status; - static int attempt = 0; - - if (authctxt == NULL || authctxt->method == NULL) - fatal("input_gssapi_response: no authentication context"); - - if (xxx_gssctxt == NULL || xxx_gssctxt->context == GSS_C_NO_CONTEXT) - return 0; - - if (strcmp(authctxt->method->name, "gssapi-keyex") == 0) - authctxt->methoddata = gssctxt = xxx_gssctxt; - - if (attempt++ >= 1) - return 0; - - if (strcmp(authctxt->method->name, "gssapi-keyex") == 0) { - gss_buffer_desc g_mic_data; - Buffer mic_data; - - debug2("Authenticating with GSS-API context from key exchange (w/ MIC)"); - - /* Make data buffer to MIC */ - buffer_init(&mic_data); - buffer_put_string(&mic_data, session_id2, session_id2_len); - buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&mic_data, authctxt->server_user); - buffer_put_cstring(&mic_data, authctxt->service); - buffer_put_cstring(&mic_data, authctxt->method->name); - - /* Make MIC */ - g_mic_data.value = buffer_ptr(&mic_data); - g_mic_data.length = buffer_len(&mic_data); - status = ssh_gssapi_get_mic(gssctxt, &g_mic_data, &send_tok); - buffer_clear(&mic_data); - - if (GSS_ERROR(status) || send_tok.length == 0) { - /* - * Oops, now what? There's no error token... - * Next userauth - */ - debug("GSS_GetMIC() failed! - " - "Abandoning GSSAPI userauth"); - clear_auth_state(authctxt); - userauth(authctxt,NULL); - return 0; - } - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_string(send_tok.value,send_tok.length); /* MIC */ - packet_send(); - packet_write_wait(); - (void) gss_release_buffer(&status, &send_tok); - } else if (strcmp(authctxt->method->name, "external-keyx") == 0) { - debug2("Authentication with deprecated \"external-keyx\"" - " method not supported"); - return 0; - } - return 1; -} - -static -void -userauth_gssapi_cleanup(Authctxt *authctxt) -{ - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,NULL); - - if (authctxt == NULL || - authctxt->method == NULL || - authctxt->methoddata == NULL) - return; - - if (strncmp(authctxt->method->name, "gssapi", strlen("gssapi")) == 0) { - ssh_gssapi_delete_ctx((Gssctxt **)&authctxt->methoddata); - } -} -#endif /* GSSAPI */ - -int -userauth_none(Authctxt *authctxt) -{ - /* initial userauth request */ - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_send(); - return 1; - -} - -int -userauth_passwd(Authctxt *authctxt) -{ - static int attempt = 0; - char prompt[150]; - char *password; - - if (attempt++ >= options.number_of_password_prompts) - return 0; - - if (attempt != 1) - error("Permission denied, please try again."); - - snprintf(prompt, sizeof(prompt), gettext("%.30s@%.128s's password: "), - authctxt->server_user, authctxt->host); - password = read_passphrase(prompt, 0); - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_char(0); - packet_put_cstring(password); - memset(password, 0, strlen(password)); - xfree(password); - packet_add_padding(64); - packet_send(); - - dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, - &input_userauth_passwd_changereq); - - return 1; -} -/* - * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST - */ -void -input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) -{ - Authctxt *authctxt = ctxt; - char *info, *lang, *password = NULL, *retype = NULL; - char prompt[150]; - - debug2("input_userauth_passwd_changereq"); - - if (authctxt == NULL) - fatal("input_userauth_passwd_changereq: " - "no authentication context"); - - info = packet_get_utf8_string(NULL); - if (strlen(info) != 0) { - info = g11n_filter_string(info); - log("%s", info); - } - xfree(info); - lang = packet_get_string(NULL); - xfree(lang); - - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_char(1); /* additional info */ - snprintf(prompt, sizeof(prompt), - gettext("Enter %.30s@%.128s's old password: "), - authctxt->server_user, authctxt->host); - password = read_passphrase(prompt, 0); - packet_put_cstring(password); - memset(password, 0, strlen(password)); - xfree(password); - password = NULL; - while (password == NULL) { - snprintf(prompt, sizeof(prompt), - gettext("Enter %.30s@%.128s's new password: "), - authctxt->server_user, authctxt->host); - password = read_passphrase(prompt, RP_ALLOW_EOF); - if (password == NULL) { - /* bail out */ - return; - } - snprintf(prompt, sizeof(prompt), - gettext("Retype %.30s@%.128s's new password: "), - authctxt->server_user, authctxt->host); - retype = read_passphrase(prompt, 0); - if (strcmp(password, retype) != 0) { - memset(password, 0, strlen(password)); - xfree(password); - log("Mismatch; try again, EOF to quit."); - password = NULL; - } - memset(retype, 0, strlen(retype)); - xfree(retype); - } - packet_put_cstring(password); - memset(password, 0, strlen(password)); - xfree(password); - packet_add_padding(64); - packet_send(); - - dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, - &input_userauth_passwd_changereq); -} - -static void -clear_auth_state(Authctxt *authctxt) -{ - /* XXX clear authentication state */ - dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL); -#ifdef GSSAPI - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,NULL); -#endif /* GSSAPI */ - - if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) { - debug3("clear_auth_state: key_free %p", authctxt->last_key); - key_free(authctxt->last_key); - } - authctxt->last_key = NULL; - authctxt->last_key_hint = -2; - authctxt->last_key_sign = NULL; -} - -static int -sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) -{ - Buffer b; - u_char *blob, *signature; - u_int bloblen, slen; - int skip = 0; - int ret = -1; - int have_sig = 1; - - debug3("sign_and_send_pubkey"); - - if (key_to_blob(k, &blob, &bloblen) == 0) { - /* we cannot handle this key */ - debug3("sign_and_send_pubkey: cannot handle key"); - return 0; - } - /* data to be signed */ - buffer_init(&b); - if (datafellows & SSH_OLD_SESSIONID) { - buffer_append(&b, session_id2, session_id2_len); - skip = session_id2_len; - } else { - buffer_put_string(&b, session_id2, session_id2_len); - skip = buffer_len(&b); - } - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, authctxt->server_user); - buffer_put_cstring(&b, - datafellows & SSH_BUG_PKSERVICE ? - "ssh-userauth" : - authctxt->service); - if (datafellows & SSH_BUG_PKAUTH) { - buffer_put_char(&b, have_sig); - } else { - buffer_put_cstring(&b, authctxt->method->name); - buffer_put_char(&b, have_sig); - buffer_put_cstring(&b, key_ssh_name(k)); - } - buffer_put_string(&b, blob, bloblen); - - /* generate signature */ - ret = (*sign_callback)(authctxt, k, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - if (ret == -1) { - xfree(blob); - buffer_free(&b); - return 0; - } -#ifdef DEBUG_PK - buffer_dump(&b); -#endif - if (datafellows & SSH_BUG_PKSERVICE) { - buffer_clear(&b); - buffer_append(&b, session_id2, session_id2_len); - skip = session_id2_len; - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, authctxt->server_user); - buffer_put_cstring(&b, authctxt->service); - buffer_put_cstring(&b, authctxt->method->name); - buffer_put_char(&b, have_sig); - if (!(datafellows & SSH_BUG_PKAUTH)) - buffer_put_cstring(&b, key_ssh_name(k)); - buffer_put_string(&b, blob, bloblen); - } - xfree(blob); - - /* append signature */ - buffer_put_string(&b, signature, slen); - xfree(signature); - - /* skip session id and packet type */ - if (buffer_len(&b) < skip + 1) - fatal("userauth_pubkey: internal error"); - buffer_consume(&b, skip + 1); - - /* put remaining data from buffer into packet */ - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_raw(buffer_ptr(&b), buffer_len(&b)); - buffer_free(&b); - packet_send(); - - return 1; -} - -static int -send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback, - int hint) -{ - u_char *blob; - u_int bloblen, have_sig = 0; - - debug3("send_pubkey_test"); - - if (key_to_blob(k, &blob, &bloblen) == 0) { - /* we cannot handle this key */ - debug3("send_pubkey_test: cannot handle key"); - return 0; - } - /* register callback for USERAUTH_PK_OK message */ - authctxt->last_key_sign = sign_callback; - authctxt->last_key_hint = hint; - authctxt->last_key = k; - dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); - - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_char(have_sig); - if (!(datafellows & SSH_BUG_PKAUTH)) - packet_put_cstring(key_ssh_name(k)); - packet_put_string(blob, bloblen); - xfree(blob); - packet_send(); - return 1; -} - -static Key * -load_identity_file(char *filename) -{ - Key *private; - char prompt[300], *passphrase; - int quit, i; - struct stat st; - - if (stat(filename, &st) < 0) { - debug3("no such identity: %s", filename); - return NULL; - } - private = key_load_private_type(KEY_UNSPEC, filename, "", NULL); - if (private == NULL) { - if (options.batch_mode) - return NULL; - snprintf(prompt, sizeof prompt, - gettext("Enter passphrase for key '%.100s': "), filename); - for (i = 0; i < options.number_of_password_prompts; i++) { - passphrase = read_passphrase(prompt, 0); - if (strcmp(passphrase, "") != 0) { - private = key_load_private_type(KEY_UNSPEC, filename, - passphrase, NULL); - quit = 0; - } else { - debug2("no passphrase given, try next key"); - quit = 1; - } - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - if (private != NULL || quit) - break; - debug2("bad passphrase given, try again..."); - } - } - return private; -} - -static int -identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - Key *private; - int idx, ret; - - idx = authctxt->last_key_hint; - if (idx < 0) - return -1; - - /* private key is stored in external hardware */ - if (options.identity_keys[idx]->flags & KEY_FLAG_EXT) - return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen); - - private = load_identity_file(options.identity_files[idx]); - if (private == NULL) - return -1; - ret = key_sign(private, sigp, lenp, data, datalen); - key_free(private); - return ret; -} - -static int -agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen); -} - -static int -key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - return key_sign(key, sigp, lenp, data, datalen); -} - -static int -userauth_pubkey_agent(Authctxt *authctxt) -{ - static int called = 0; - int ret = 0; - char *comment; - Key *k; - - if (called == 0) { - if (ssh_get_num_identities(authctxt->agent, 2) == 0) - debug2("userauth_pubkey_agent: no keys at all"); - called = 1; - } - k = ssh_get_next_identity(authctxt->agent, &comment, 2); - if (k == NULL) { - debug2("userauth_pubkey_agent: no more keys"); - } else { - debug("Offering agent key: %s", comment); - xfree(comment); - ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1); - if (ret == 0) - key_free(k); - } - if (ret == 0) - debug2("userauth_pubkey_agent: no message sent"); - return ret; -} - -int -userauth_pubkey(Authctxt *authctxt) -{ - static int idx = 0; - int sent = 0; - Key *key; - char *filename; - - if (authctxt->agent != NULL) { - do { - sent = userauth_pubkey_agent(authctxt); - } while (!sent && authctxt->agent->howmany > 0); - } - while (!sent && idx < options.num_identity_files) { - key = options.identity_keys[idx]; - filename = options.identity_files[idx]; - if (key == NULL) { - debug("Trying private key: %s", filename); - key = load_identity_file(filename); - if (key != NULL) { - sent = sign_and_send_pubkey(authctxt, key, - key_sign_cb); - key_free(key); - } - } else if (key->type != KEY_RSA1) { - debug("Trying public key: %s", filename); - sent = send_pubkey_test(authctxt, key, - identity_sign_cb, idx); - } - idx++; - } - return sent; -} - -/* - * Send userauth request message specifying keyboard-interactive method. - */ -int -userauth_kbdint(Authctxt *authctxt) -{ - static int attempt = 0; - - if (attempt++ >= options.number_of_password_prompts) - return 0; - /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ - if (attempt > 1 && !authctxt->info_req_seen) { - debug3("userauth_kbdint: disable: no info_req_seen"); - dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); - return 0; - } - - debug2("userauth_kbdint"); - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_cstring(""); /* lang */ - packet_put_cstring(options.kbd_interactive_devices ? - options.kbd_interactive_devices : ""); - packet_send(); - - dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); - return 1; -} - -/* - * parse INFO_REQUEST, prompt user and send INFO_RESPONSE - */ -void -input_userauth_info_req(int type, u_int32_t seq, void *ctxt) -{ - Authctxt *authctxt = ctxt; - char *name, *inst, *lang, *prompt, *response; - u_int num_prompts, i; - int echo = 0; - - debug2("input_userauth_info_req"); - - if (authctxt == NULL) - fatal("input_userauth_info_req: no authentication context"); - - authctxt->info_req_seen = 1; - - /* - * We assume that ASCII is used for user name although it is defined - * by the protocol to use UTF-8 encoding. Therefore, we don't perform - * code conversion from UTF-8 to native codeset for the user name - * string. - */ - name = packet_get_string(NULL); - inst = packet_get_utf8_string(NULL); - lang = packet_get_string(NULL); - if (strlen(name) != 0) { - name = g11n_filter_string(name); - log("%s", name); - } - if (strlen(inst) != 0) { - inst = g11n_filter_string(inst); - log("%s", inst); - } - xfree(name); - xfree(inst); - xfree(lang); - - num_prompts = packet_get_int(); - /* - * Begin to build info response packet based on prompts requested. - * We commit to providing the correct number of responses, so if - * further on we run into a problem that prevents this, we have to - * be sure and clean this up and send a correct error response. - */ - packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); - packet_put_int(num_prompts); - - debug2("input_userauth_info_req: num_prompts %d", num_prompts); - for (i = 0; i < num_prompts; i++) { - prompt = packet_get_utf8_string(NULL); - echo = packet_get_char(); - - prompt = g11n_filter_string(prompt); - response = read_passphrase(prompt, echo ? RP_ECHO : 0); - - /* - * We assume that ASCII is used for password as well. We - * don't perform code conversion from native codeset to - * UTF-8 for the password string. - */ - packet_put_cstring(response); - memset(response, 0, strlen(response)); - xfree(response); - xfree(prompt); - } - packet_check_eom(); /* done with parsing incoming message. */ - - packet_add_padding(64); - packet_send(); -} - -static int -ssh_keysign(Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - Buffer b; - struct stat st; - pid_t pid; - int to[2], from[2], status, version = 2; - - debug2("ssh_keysign called"); - - if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { - error("ssh_keysign: no installed: %s", strerror(errno)); - return -1; - } - if (fflush(stdout) != 0) - error("ssh_keysign: fflush: %s", strerror(errno)); - if (pipe(to) < 0) { - error("ssh_keysign: pipe: %s", strerror(errno)); - return -1; - } - if (pipe(from) < 0) { - error("ssh_keysign: pipe: %s", strerror(errno)); - return -1; - } - if ((pid = fork()) < 0) { - error("ssh_keysign: fork: %s", strerror(errno)); - return -1; - } - if (pid == 0) { - seteuid(getuid()); - setuid(getuid()); - close(from[0]); - if (dup2(from[1], STDOUT_FILENO) < 0) - fatal("ssh_keysign: dup2: %s", strerror(errno)); - close(to[1]); - if (dup2(to[0], STDIN_FILENO) < 0) - fatal("ssh_keysign: dup2: %s", strerror(errno)); - close(from[1]); - close(to[0]); - execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); - fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, - strerror(errno)); - } - close(from[1]); - close(to[0]); - - buffer_init(&b); - buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */ - buffer_put_string(&b, data, datalen); - ssh_msg_send(to[1], version, &b); - - if (ssh_msg_recv(from[0], &b) < 0) { - error("ssh_keysign: no reply"); - buffer_clear(&b); - return -1; - } - close(from[0]); - close(to[1]); - - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - break; - - if (buffer_get_char(&b) != version) { - error("ssh_keysign: bad version"); - buffer_clear(&b); - return -1; - } - *sigp = buffer_get_string(&b, lenp); - buffer_clear(&b); - - return 0; -} - -int -userauth_hostbased(Authctxt *authctxt) -{ - Key *private = NULL; - Sensitive *sensitive = authctxt->sensitive; - Buffer b; - u_char *signature, *blob; - char *chost, *pkalg, *p; - const char *service; - u_int blen, slen; - int ok, i, len, found = 0; - static int last_hostkey = -1; - - /* check for a useful key */ - for (i = 0; i < sensitive->nkeys; i++) { - private = sensitive->keys[i]; - if (private && private->type != KEY_RSA1 && i > last_hostkey) { - found = 1; - last_hostkey = i; - /* we take and free the key */ - sensitive->keys[i] = NULL; - break; - } - } - if (!found) { - debug("No more client hostkeys for hostbased authentication"); - return 0; - } - if (key_to_blob(private, &blob, &blen) == 0) { - key_free(private); - return 0; - } - /* figure out a name for the client host */ - p = get_local_name(packet_get_connection_in()); - if (p == NULL) { - error("userauth_hostbased: cannot get local ipaddr/name"); - key_free(private); - return 0; - } - - service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : - authctxt->service; - pkalg = xstrdup(key_ssh_name(private)); - - len = strlen(p) + 2; - chost = xmalloc(len); - strlcpy(chost, p, len); - strlcat(chost, ".", len); - xfree(p); - debug2("userauth_hostbased: chost %s, pkalg %s", chost, pkalg); - - buffer_init(&b); - /* construct data */ - buffer_put_string(&b, session_id2, session_id2_len); - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, authctxt->server_user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, authctxt->method->name); - buffer_put_cstring(&b, pkalg); - buffer_put_string(&b, blob, blen); - buffer_put_cstring(&b, chost); - buffer_put_cstring(&b, authctxt->local_user); -#ifdef DEBUG_PK - buffer_dump(&b); -#endif - if (sensitive->external_keysign) - ok = ssh_keysign(private, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - else - ok = key_sign(private, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - key_free(private); - buffer_free(&b); - if (ok != 0) { - error("key_sign failed"); - xfree(chost); - xfree(pkalg); - return 0; - } - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_cstring(pkalg); - packet_put_string(blob, blen); - packet_put_cstring(chost); - packet_put_cstring(authctxt->local_user); - packet_put_string(signature, slen); - memset(signature, 's', slen); - xfree(signature); - xfree(chost); - xfree(pkalg); - - packet_send(); - return 1; -} - -/* find auth method */ - -/* - * given auth method name, if configurable options permit this method fill - * in auth_ident field and return true, otherwise return false. - */ -static int -authmethod_is_enabled(Authmethod *method) -{ - if (method == NULL) - return 0; - /* return false if options indicate this method is disabled */ - if (method->enabled == NULL || *method->enabled == 0) - return 0; - /* return false if batch mode is enabled but method needs interactive mode */ - if (method->batch_flag != NULL && *method->batch_flag != 0) - return 0; - return 1; -} - -static Authmethod * -authmethod_lookup(const char *name) -{ - Authmethod *method = NULL; - if (name != NULL) { - for (method = authmethods; method->name != NULL; method++) { - if (strcmp(name, method->name) == 0) - return method; - } - } - debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); - return NULL; -} - -/* XXX internal state */ -static Authmethod *current = NULL; -static char *supported = NULL; -static char *preferred = NULL; - -/* - * Given the authentication method list sent by the server, return the - * next method we should try. If the server initially sends a nil list, - * use a built-in default list. - */ -static Authmethod * -authmethod_get(char *authlist) -{ - char *name = NULL; - u_int next; - - /* Use a suitable default if we're passed a nil list. */ - if (authlist == NULL || strlen(authlist) == 0) - authlist = options.preferred_authentications; - - if (supported == NULL || strcmp(authlist, supported) != 0) { - debug3("start over, passed a different list %s", authlist); - if (supported != NULL) - xfree(supported); - supported = xstrdup(authlist); - preferred = options.preferred_authentications; - debug3("preferred %s", preferred); - current = NULL; - } else if (current != NULL && authmethod_is_enabled(current)) - return current; - - for (;;) { - if ((name = match_list(preferred, supported, &next)) == NULL) { - debug("No more authentication methods to try."); - current = NULL; - return NULL; - } - preferred += next; - debug3("authmethod_lookup %s", name); - debug3("remaining preferred: %s", preferred); - if ((current = authmethod_lookup(name)) != NULL && - authmethod_is_enabled(current)) { - debug3("authmethod_is_enabled %s", name); - debug("Next authentication method: %s", name); - xfree(name); - return current; - } - xfree(name); - } -} - -static char * -authmethods_get(void) -{ - Authmethod *method = NULL; - Buffer b; - char *list; - - buffer_init(&b); - for (method = authmethods; method->name != NULL; method++) { - if (authmethod_is_enabled(method)) { - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - buffer_append(&b, method->name, strlen(method->name)); - } - } - buffer_append(&b, "\0", 1); - list = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - return list; -} diff --git a/usr/src/cmd/ssh/ssh/sshtty.c b/usr/src/cmd/ssh/ssh/sshtty.c deleted file mode 100644 index b90ff1d1ad..0000000000 --- a/usr/src/cmd/ssh/ssh/sshtty.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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) 2001 Markus Friedl. All rights reserved. - * Copyright (c) 2001 Kevin Steves. 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: sshtty.c,v 1.3 2002/03/04 17:27:39 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "sshtty.h" -#include "log.h" - -static struct termios _saved_tio; -static int _in_raw_mode = 0; - -int -in_raw_mode(void) -{ - return _in_raw_mode; -} - -struct termios -get_saved_tio(void) -{ - return _saved_tio; -} - -void -leave_raw_mode(void) -{ - if (!_in_raw_mode) - return; - if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) - perror("tcsetattr"); - else - _in_raw_mode = 0; - - fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL); -} - -void -enter_raw_mode(void) -{ - struct termios tio; - - if (tcgetattr(fileno(stdin), &tio) == -1) { - perror("tcgetattr"); - return; - } - _saved_tio = tio; - tio.c_iflag |= IGNPAR; - tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); - tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); -#ifdef IEXTEN - tio.c_lflag &= ~IEXTEN; -#endif - tio.c_oflag &= ~OPOST; - tio.c_cc[VMIN] = 1; - tio.c_cc[VTIME] = 0; - if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) - perror("tcsetattr"); - else - _in_raw_mode = 1; - - fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL); -} diff --git a/usr/src/cmd/ssh/sshd/Makefile b/usr/src/cmd/ssh/sshd/Makefile deleted file mode 100644 index 4c82633347..0000000000 --- a/usr/src/cmd/ssh/sshd/Makefile +++ /dev/null @@ -1,116 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ssh/sshd/Makefile - -PROG= sshd - -DIRS= $(ROOTLIBSSH) - -OBJS = sshd.o \ - altprivsep.o \ - auth.o \ - auth1.o \ - auth2.o \ - auth-options.o \ - auth2-chall.o \ - auth2-gss.o \ - auth2-hostbased.o \ - auth2-kbdint.o \ - auth2-none.o \ - auth2-passwd.o \ - auth2-pam.o \ - auth2-pubkey.o \ - auth-bsdauth.o \ - auth-chall.o \ - auth-rhosts.o \ - auth-krb4.o \ - auth-krb5.o \ - auth-pam.o \ - auth-passwd.o \ - auth-rsa.o \ - auth-rh-rsa.o \ - auth-sia.o \ - auth-skey.o \ - bsmaudit.o \ - groupaccess.o \ - gss-serv.o \ - loginrec.o \ - servconf.o \ - serverloop.o \ - session.o \ - sshlogin.o \ - sshpty.o - -EXTOBJS = sftp-server.o - -SRCS = $(OBJS:.o=.c) ../sftp-server/sftp-server.c - -include ../../Makefile.cmd -include ../Makefile.ssh-common - -LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket \ - -lnsl \ - -lz \ - -lpam \ - -lbsm \ - -lwrap \ - -lsunw_crypto \ - -lgss \ - -lcontract -MAPFILES = $(MAPFILE.INT) $(MAPFILE.NGB) -LDFLAGS += $(MAPFILES:%=-M%) - -POFILE_DIR= .. - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) $(EXTOBJS) $(MAPFILES) ../libssh/$(MACH)/libssh.a \ - ../libopenbsd-compat/$(MACH)/libopenbsd-compat.a - $(LINK.c) $(OBJS) $(EXTOBJS) -o $@ $(LDLIBS) $(DYNFLAGS) - $(POST_PROCESS) - -%.o : ../sftp-server/%.c - $(COMPILE.c) -o $@ $< - $(POST_PROCESS_O) - -install: all $(DIRS) $(ROOTLIBSSHPROG) $(ROOTLIBSSH) - - -$(ROOTLIBSSHPROG)/%: % - $(INS.file) - -$(DIRS): - $(INS.dir) - -clean: - $(RM) $(OBJS) $(EXTOBJS) - -lint: lint_SRCS - -include ../Makefile.msg.targ -include ../../Makefile.targ diff --git a/usr/src/cmd/ssh/sshd/altprivsep.c b/usr/src/cmd/ssh/sshd/altprivsep.c deleted file mode 100644 index 6f954feab5..0000000000 --- a/usr/src/cmd/ssh/sshd/altprivsep.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <fcntl.h> -#include <sys/types.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> - -#include <pwd.h> - -#include "includes.h" -#include "atomicio.h" -#include "auth.h" -#include "bufaux.h" -#include "buffer.h" -#include "cipher.h" -#include "compat.h" -#include "dispatch.h" -#include "getput.h" -#include "kex.h" -#include "log.h" -#include "mac.h" -#include "packet.h" -#include "uidswap.h" -#include "ssh2.h" -#include "sshlogin.h" -#include "xmalloc.h" -#include "altprivsep.h" -#include "canohost.h" -#include "engine.h" -#include "servconf.h" - -#ifdef HAVE_BSM -#include "bsmaudit.h" -adt_session_data_t *ah = NULL; -#endif /* HAVE_BSM */ - -#ifdef GSSAPI -#include "ssh-gss.h" -extern Gssctxt *xxx_gssctxt; -#endif /* GSSAPI */ - -extern Kex *xxx_kex; -extern u_char *session_id2; -extern int session_id2_len; - -static Buffer to_monitor; -static Buffer from_monitor; - -/* - * Sun's Alternative Privilege Separation basics: - * - * Abstract - * -------- - * - * sshd(1M) fork()s and drops privs in the child while retaining privs - * in the parent (a.k.a., the monitor). The unprivileged sshd and the - * monitor talk over a pipe using a simple protocol. - * - * The monitor protocol is all about having the monitor carry out the - * only operations that require privileges OR access to privileged - * resources. These are: utmpx/wtmpx record keeping, auditing, and - * SSHv2 re-keying. - * - * Re-Keying - * --------- - * - * Re-keying is the only protocol version specific aspect of sshd in - * which the monitor gets involved. - * - * The monitor processes all SSHv2 re-key protocol packets, but the - * unprivileged sshd process does the transport layer crypto for those - * packets. - * - * The monitor and its unprivileged sshd child process treat - * SSH_MSG_NEWKEYS SSH2 messages specially: a) the monitor does not call - * set_newkeys(), but b) the child asks the monitor for the set of - * negotiated algorithms, key, IV and what not for the relevant - * transport direction and then calls set_newkeys(). - * - * Monitor Protocol - * ---------------- - * - * Monitor IPC message formats are similar to SSHv2 messages, minus - * compression, encryption, padding and MACs: - * - * - 4 octet message length - * - message data - * - 1 octet message type - * - message data - * - * In broad strokes: - * - * - IPC: pipe, exit(2)/wait4(2) - * - * - threads: the monitor and child are single-threaded - * - * - monitor main loop: a variant of server_loop2(), for re-keying only - * - unpriv child main loop: server_loop2(), as usual - * - * - protocol: - * - key exchange packets are always forwarded as is to the monitor - * - newkeys, record_login(), record_logout() are special packets - * using the packet type range reserved for local extensions - * - * - the child drops privs and runs like a normal sshd, except that it - * sets dispatch handlers for key exchange packets that forward the - * packets to the monitor - * - * Event loops: - * - * - all monitor protocols are synchronous: because the SSHv2 rekey - * protocols are synchronous and because the other monitor operations - * are synchronous (or have no replies), - * - * - server_loop2() is modified to check the monitor pipe for rekey - * packets to forward to the client - * - * - and dispatch handlers are set, upon receipt of KEXINIT (and reset - * when NEWKEYS is sent out) to forward incoming rekey packets to the - * monitor. - * - * - the monitor runs an event loop not unlike server_loop2() and runs - * key exchanges almost exactly as a pre-altprivsep sshd would - * - * - unpriv sshd exit -> monitor cleanup (including audit logout) and exit - * - * - fatal() in monitor -> forcibly shutdown() socket and kill/wait for - * child (so that the audit event for the logout better reflects - * reality -- i.e., logged out means logged out, but for bg jobs) - * - * Message formats: - * - * - key exchange packets/replies forwarded "as is" - * - * - all other monitor requests are sent as SSH2_PRIV_MSG_ALTPRIVSEP and have a - * sub-type identifier (one octet) - * - private request sub-types include: - * - get new shared secret from last re-key - * - record login (utmpx/wtmpx), request data contains three arguments: - * pid, ttyname, program name - * - record logout (utmpx/wtmpx), request data contains one argument: pid - * - * Reply sub-types include: - * - * - NOP (for record_login/logout) - * - new shared secret from last re-key - */ - -static int aps_started = 0; -static int is_monitor = 0; - -static pid_t monitor_pid, child_pid; -static int pipe_fds[2]; -static int pipe_fd = -1; -static Buffer input_pipe, output_pipe; /* for pipe I/O */ - -static Authctxt *xxx_authctxt; - -/* Monitor functions */ -extern void aps_monitor_loop(Authctxt *authctxt, pid_t child_pid); -static void aps_record_login(void); -static void aps_record_logout(void); -static void aps_start_rekex(void); -Authctxt *aps_read_auth_context(void); - -/* main functions for handling the monitor */ -static pid_t altprivsep_start_monitor(Authctxt **authctxt); -static void altprivsep_do_monitor(Authctxt *authctxt, pid_t child_pid); -static int altprivsep_started(void); -static int altprivsep_is_monitor(void); - -/* calls _to_ monitor from unprivileged process */ -static void altprivsep_get_newkeys(enum kex_modes mode); - -/* monitor-side fatal_cleanup callbacks */ -static void altprivsep_shutdown_sock(void *arg); - -/* Altprivsep packet utilities for communication with the monitor */ -static void altprivsep_packet_start(u_char); -static int altprivsep_packet_send(void); -static int altprivsep_fwd_packet(u_char type); - -static int altprivsep_packet_read(void); -static void altprivsep_packet_read_expect(int type); - -static void altprivsep_packet_put_char(int ch); -static void altprivsep_packet_put_int(u_int value); -static void altprivsep_packet_put_cstring(const char *str); -static void altprivsep_packet_put_raw(const void *buf, u_int len); - -static u_int altprivsep_packet_get_char(void); -static void *altprivsep_packet_get_raw(u_int *length_ptr); -static void *altprivsep_packet_get_string(u_int *length_ptr); - -Kex *prepare_for_ssh2_kex(void); - -/* - * Start monitor from privileged sshd process. - * - * Return values are like fork(2); the parent is the monitor. The caller should - * fatal() on error. - * - * Note that the monitor waits until the still privileged child finishes the - * authentication. The child drops its privileges after the authentication. - */ -static pid_t -altprivsep_start_monitor(Authctxt **authctxt) -{ - pid_t pid; - int junk; - - if (aps_started) - fatal("Monitor startup failed: missing state"); - - buffer_init(&output_pipe); - buffer_init(&input_pipe); - - if (pipe(pipe_fds) != 0) { - error("Monitor startup failure: could not create pipes: %s", - strerror(errno)); - return (-1); - } - - (void) fcntl(pipe_fds[0], F_SETFD, FD_CLOEXEC); - (void) fcntl(pipe_fds[1], F_SETFD, FD_CLOEXEC); - - monitor_pid = getpid(); - - if ((pid = fork()) > 0) { - /* - * From now on, all debug messages from monitor will have prefix - * "monitor " - */ - set_log_txt_prefix("monitor "); - (void) prepare_for_ssh2_kex(); - packet_set_server(); - /* parent */ - child_pid = pid; - - debug2("Monitor pid %ld, unprivileged child pid %ld", - monitor_pid, child_pid); - - (void) close(pipe_fds[1]); - pipe_fd = pipe_fds[0]; - - /* - * Signal readiness of the monitor and then read the - * authentication context from the child. - */ - (void) write(pipe_fd, &pid, sizeof (pid)); - packet_set_monitor(pipe_fd); - xxx_authctxt = *authctxt = aps_read_auth_context(); - - if (fcntl(pipe_fd, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %.100s", strerror(errno)); - - aps_started = 1; - is_monitor = 1; - - debug2("Monitor started"); - - return (pid); - } - - if (pid < 0) { - debug2("Monitor startup failure: could not fork unprivileged" - " process: %s", strerror(errno)); - return (pid); - } - - /* this is the child that will later drop privileges */ - - /* note that Solaris has bi-directional pipes so one pipe is enough */ - (void) close(pipe_fds[0]); - pipe_fd = pipe_fds[1]; - - /* wait for monitor to be ready */ - debug2("Waiting for monitor"); - (void) read(pipe_fd, &junk, sizeof (junk)); - debug2("Monitor signalled readiness"); - - buffer_init(&to_monitor); - buffer_init(&from_monitor); - - /* AltPrivSep interfaces are set up */ - aps_started = 1; - return (pid); -} - -int -altprivsep_get_pipe_fd(void) -{ - return (pipe_fd); -} - -/* - * This function is used in the unprivileged child for all packets in the range - * between SSH2_MSG_KEXINIT and SSH2_MSG_TRANSPORT_MAX. - */ -void -altprivsep_rekey(int type, u_int32_t seq, void *ctxt) -{ - Kex *kex = (Kex *)ctxt; - - if (kex == NULL) - fatal("Missing key exchange context in unprivileged process"); - - if (type != SSH2_MSG_NEWKEYS) { - debug2("Forwarding re-key packet (%d) to monitor", type); - if (!altprivsep_fwd_packet(type)) - fatal("altprivsep_rekey: Monitor not responding"); - } - - /* tell server_loop2() that we're re-keying */ - kex->done = 0; - - /* NEWKEYS is special: get the new keys for client->server direction */ - if (type == SSH2_MSG_NEWKEYS) { - debug2("received SSH2_MSG_NEWKEYS packet - " - "getting new inbound keys from the monitor"); - altprivsep_get_newkeys(MODE_IN); - kex->done = 1; - } -} - -void -altprivsep_process_input(fd_set *rset) -{ - void *data; - int type; - u_int dlen; - - if (pipe_fd == -1) - return; - - if (!FD_ISSET(pipe_fd, rset)) - return; - - debug2("reading from pipe to monitor (%d)", pipe_fd); - if ((type = altprivsep_packet_read()) == -1) - fatal("altprivsep_process_input: Monitor not responding"); - - if (!compat20) - return; /* shouldn't happen! but be safe */ - - if (type == 0) - return; /* EOF -- nothing to do here */ - - if (type >= SSH2_MSG_MAX) - fatal("Received garbage from monitor"); - - debug2("Read packet type %d from pipe to monitor", (u_int)type); - - if (type == SSH2_PRIV_MSG_ALTPRIVSEP) - return; /* shouldn't happen! */ - - /* NEWKEYS is special: get the new keys for server->client direction */ - if (type == SSH2_MSG_NEWKEYS) { - debug2("forwarding SSH2_MSG_NEWKEYS packet we got from monitor to " - "the client"); - packet_start(SSH2_MSG_NEWKEYS); - packet_send(); - debug2("getting new outbound keys from the monitor"); - altprivsep_get_newkeys(MODE_OUT); - return; - } - - data = altprivsep_packet_get_raw(&dlen); - - packet_start((u_char)type); - - if (data != NULL && dlen > 0) - packet_put_raw(data, dlen); - - packet_send(); -} - -static void -altprivsep_do_monitor(Authctxt *authctxt, pid_t child_pid) -{ - aps_monitor_loop(authctxt, child_pid); -} - -static int -altprivsep_started(void) -{ - return (aps_started); -} - -static int -altprivsep_is_monitor(void) -{ - return (is_monitor); -} - -/* - * A fatal cleanup function to forcibly shutdown the connection socket - */ -static void -altprivsep_shutdown_sock(void *arg) -{ - int sock; - - if (arg == NULL) - return; - - sock = *(int *)arg; - - (void) shutdown(sock, SHUT_RDWR); -} - -/* Calls _to_ monitor from unprivileged process */ -static int -altprivsep_fwd_packet(u_char type) -{ - u_int len; - void *data; - - altprivsep_packet_start(type); - data = packet_get_raw(&len); - altprivsep_packet_put_raw(data, len); - - /* packet_send()s any replies from the monitor to the client */ - return (altprivsep_packet_send()); -} - -extern Newkeys *current_keys[MODE_MAX]; - -/* To be called from packet.c:set_newkeys() before referencing current_keys */ -static void -altprivsep_get_newkeys(enum kex_modes mode) -{ - Newkeys *newkeys; - Comp *comp; - Enc *enc; - Mac *mac; - u_int len; - - if (!altprivsep_started()) - return; - - if (altprivsep_is_monitor()) - return; /* shouldn't happen */ - - /* request new keys */ - altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - altprivsep_packet_put_char(APS_MSG_NEWKEYS_REQ); - altprivsep_packet_put_int((u_int)mode); - altprivsep_packet_send(); - altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); - if (altprivsep_packet_get_char() != APS_MSG_NEWKEYS_REP) - fatal("Received garbage from monitor during re-keying"); - - newkeys = xmalloc(sizeof (*newkeys)); - memset(newkeys, 0, sizeof (*newkeys)); - - enc = &newkeys->enc; - mac = &newkeys->mac; - comp = &newkeys->comp; - - /* Cipher name, key, IV */ - enc->name = altprivsep_packet_get_string(NULL); - if ((enc->cipher = cipher_by_name(enc->name)) == NULL) - fatal("Monitor negotiated an unknown cipher during re-key"); - - enc->key = altprivsep_packet_get_string(&enc->key_len); - enc->iv = altprivsep_packet_get_string(&enc->block_size); - - /* MAC name */ - mac->name = altprivsep_packet_get_string(NULL); - if (mac_setup(mac, mac->name) < 0) - fatal("Monitor negotiated an unknown MAC algorithm " - "during re-key"); - - mac->key = altprivsep_packet_get_string(&len); - if (len > mac->key_len) - fatal("%s: bad mac key length: %d > %d", __func__, len, - mac->key_len); - - /* Compression algorithm name */ - comp->name = altprivsep_packet_get_string(NULL); - if (strcmp(comp->name, "zlib") != 0 && strcmp(comp->name, "none") != 0) - fatal("Monitor negotiated an unknown compression " - "algorithm during re-key"); - - comp->type = 0; - comp->enabled = 0; /* forces compression re-init, as per-spec */ - if (strcmp(comp->name, "zlib") == 0) - comp->type = 1; - - /* - * Now install new keys - * - * For now abuse kex.c/packet.c non-interfaces. Someday, when - * the many internal interfaces are parametrized, made reentrant - * and thread-safe, made more consistent, and when necessary-but- - * currently-missing interfaces are added then this bit of - * ugliness can be revisited. - * - * The ugliness is in the set_newkeys(), its name and the lack - * of a (Newkeys *) parameter, which forces us to pass the - * newkeys through current_keys[mode]. But this saves us some - * lines of code for now, though not comments. - * - * Also, we've abused, in the code above, knowledge of what - * set_newkeys() expects the current_keys[mode] to contain. - */ - current_keys[mode] = newkeys; - set_newkeys(mode); - -} - -void -altprivsep_record_login(pid_t pid, const char *ttyname) -{ - altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - altprivsep_packet_put_char(APS_MSG_RECORD_LOGIN); - altprivsep_packet_put_int(pid); - altprivsep_packet_put_cstring(ttyname); - altprivsep_packet_send(); - altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); -} - -void -altprivsep_record_logout(pid_t pid) -{ - altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - altprivsep_packet_put_char(APS_MSG_RECORD_LOGOUT); - altprivsep_packet_put_int(pid); - altprivsep_packet_send(); - altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); -} - -void -altprivsep_start_rekex(void) -{ - altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - altprivsep_packet_put_char(APS_MSG_START_REKEX); - altprivsep_packet_send(); - altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); -} - -/* - * The monitor needs some information that its child learns during the - * authentication process. Since the child was forked before the key exchange - * and authentication started it must send some context to the monitor after the - * authentication is finished. Less obvious part - monitor needs the session ID - * since it is used in the key generation process after the key (re-)exchange is - * finished. - */ -void -altprivsep_send_auth_context(Authctxt *authctxt) -{ - debug("sending auth context to the monitor"); - altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - altprivsep_packet_put_char(APS_MSG_AUTH_CONTEXT); - altprivsep_packet_put_int(authctxt->pw->pw_uid); - altprivsep_packet_put_int(authctxt->pw->pw_gid); - altprivsep_packet_put_cstring(authctxt->pw->pw_name); - altprivsep_packet_put_raw(session_id2, session_id2_len); - debug("will send %d bytes of auth context to the monitor", - buffer_len(&to_monitor)); - altprivsep_packet_send(); - altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); -} - -static void aps_send_newkeys(void); - -/* Monitor side dispatch handler for SSH2_PRIV_MSG_ALTPRIVSEP */ -/* ARGSUSED */ -void -aps_input_altpriv_msg(int type, u_int32_t seq, void *ctxt) -{ - u_char req_type; - - req_type = packet_get_char(); - - switch (req_type) { - case APS_MSG_NEWKEYS_REQ: - aps_send_newkeys(); - break; - case APS_MSG_RECORD_LOGIN: - aps_record_login(); - break; - case APS_MSG_RECORD_LOGOUT: - aps_record_logout(); - break; - case APS_MSG_START_REKEX: - aps_start_rekex(); - break; - default: - break; - } -} - -/* Monitor-side handlers for APS_MSG_* */ -static -void -aps_send_newkeys(void) -{ - Newkeys *newkeys; - Enc *enc; - Mac *mac; - Comp *comp; - enum kex_modes mode; - - /* get direction for which newkeys are wanted */ - mode = (enum kex_modes) packet_get_int(); - packet_check_eom(); - - /* get those newkeys */ - newkeys = kex_get_newkeys(mode); - enc = &newkeys->enc; - mac = &newkeys->mac; - comp = &newkeys->comp; - - /* - * Negotiated algorithms, client->server and server->client, for - * cipher, mac and compression. - */ - packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - packet_put_char(APS_MSG_NEWKEYS_REP); - packet_put_cstring(enc->name); - packet_put_string(enc->key, enc->key_len); - packet_put_string(enc->iv, enc->block_size); - packet_put_cstring(mac->name); - packet_put_string(mac->key, mac->key_len); - packet_put_cstring(comp->name); - - packet_send(); - free_keys(newkeys); -} - -struct _aps_login_rec { - pid_t lr_pid; - char *lr_tty; - struct _aps_login_rec *next; -}; - -typedef struct _aps_login_rec aps_login_rec; - -static aps_login_rec *aps_login_list = NULL; - -static -void -aps_record_login(void) -{ - aps_login_rec *new_rec; - struct stat sbuf; - size_t proc_path_len; - char *proc_path; - - new_rec = xmalloc(sizeof (aps_login_rec)); - memset(new_rec, 0, sizeof (aps_login_rec)); - - new_rec->lr_pid = packet_get_int(); - new_rec->lr_tty = packet_get_string(NULL); - - proc_path_len = snprintf(NULL, 0, "/proc/%d", new_rec->lr_pid); - proc_path = xmalloc(proc_path_len + 1); - (void) snprintf(proc_path, proc_path_len + 1, "/proc/%d", - new_rec->lr_pid); - - if (stat(proc_path, &sbuf) || - sbuf.st_uid != xxx_authctxt->pw->pw_uid || - stat(new_rec->lr_tty, &sbuf) < 0 || - sbuf.st_uid != xxx_authctxt->pw->pw_uid) { - debug2("Spurious record_login request from unprivileged sshd"); - xfree(proc_path); - xfree(new_rec->lr_tty); - xfree(new_rec); - return; - } - - /* Insert new record on list */ - new_rec->next = aps_login_list; - aps_login_list = new_rec; - - record_login(new_rec->lr_pid, new_rec->lr_tty, NULL, - xxx_authctxt->user); - - packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - packet_send(); - - xfree(proc_path); -} - -static -void -aps_record_logout(void) -{ - aps_login_rec **p, *q; - pid_t pid; - - pid = packet_get_int(); - packet_check_eom(); - - for (p = &aps_login_list; *p != NULL; p = &q->next) { - q = *p; - if (q->lr_pid == pid) { - record_logout(q->lr_pid, q->lr_tty, NULL, - xxx_authctxt->user); - - /* dequeue */ - *p = q->next; - xfree(q->lr_tty); - xfree(q); - break; - } - } - - packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - packet_send(); -} - -static -void -aps_start_rekex(void) -{ - /* - * Send confirmation. We could implement it without that but it doesn't - * bring any harm to do that and we are consistent with other subtypes - * of our private SSH2_PRIV_MSG_ALTPRIVSEP message type. - */ - packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - packet_send(); - - /* - * KEX_INIT message could be the one that reached the limit. In that - * case, it was already forwarded to us from the unnprivileged child, - * and maybe even acted upon. Obviously we must not send another - * KEX_INIT message. - */ - if (!(xxx_kex->flags & KEX_INIT_SENT)) - kex_send_kexinit(xxx_kex); - else - debug2("rekeying already in progress"); -} - -/* - * This is the monitor side of altprivsep_send_auth_context(). - */ -Authctxt * -aps_read_auth_context(void) -{ - unsigned char *tmp; - Authctxt *authctxt; - - /* - * After the successful authentication we get the context. Getting - * end-of-file means that authentication failed and we can exit as well. - */ - debug("reading the context from the child"); - packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); - debug3("got SSH2_PRIV_MSG_ALTPRIVSEP"); - if (packet_get_char() != APS_MSG_AUTH_CONTEXT) { - fatal("APS_MSG_AUTH_CONTEXT message subtype expected."); - } - - authctxt = xcalloc(1, sizeof(Authctxt)); - authctxt->pw = xcalloc(1, sizeof(struct passwd)); - - /* uid_t and gid_t are integers (UNIX spec) */ - authctxt->pw->pw_uid = packet_get_int(); - authctxt->pw->pw_gid = packet_get_int(); - authctxt->pw->pw_name = packet_get_string(NULL); - authctxt->user = xstrdup(authctxt->pw->pw_name); - debug3("uid/gid/username %d/%d/%s", authctxt->pw->pw_uid, - authctxt->pw->pw_gid, authctxt->user); - session_id2 = (unsigned char *)packet_get_raw((unsigned int*)&session_id2_len); - - /* we don't have this for SSH1. In that case, session_id2_len is 0. */ - if (session_id2_len > 0) { - tmp = (unsigned char *)xmalloc(session_id2_len); - memcpy(tmp, session_id2, session_id2_len); - session_id2 = tmp; - debug3("read session ID (%d B)", session_id2_len); - xxx_kex->session_id = tmp; - xxx_kex->session_id_len = session_id2_len; - } - debug("finished reading the context"); - - /* send confirmation */ - packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); - packet_send(); - - return (authctxt); -} - - -/* Utilities for communication with the monitor */ -static void -altprivsep_packet_start(u_char type) -{ - buffer_clear(&to_monitor); - buffer_put_char(&to_monitor, type); -} - -static void -altprivsep_packet_put_char(int ch) -{ - buffer_put_char(&to_monitor, ch); -} - -static void -altprivsep_packet_put_int(u_int value) -{ - buffer_put_int(&to_monitor, value); -} - -static void -altprivsep_packet_put_cstring(const char *str) -{ - buffer_put_cstring(&to_monitor, str); -} - -static void -altprivsep_packet_put_raw(const void *buf, u_int len) -{ - buffer_append(&to_monitor, buf, len); -} - -/* - * Send a monitor packet to the monitor. This function is blocking. - * - * Returns -1 if the monitor pipe has been closed earlier, fatal()s if - * there's any other problems. - */ -static int -altprivsep_packet_send(void) -{ - ssize_t len; - u_int32_t plen; /* packet length */ - u_char plen_buf[sizeof (plen)]; - u_char padlen; /* padding length */ - fd_set *setp; - int err; - - if (pipe_fd == -1) - return (-1); - - if ((plen = buffer_len(&to_monitor)) == 0) - return (0); - - /* - * We talk the SSHv2 binary packet protocol to the monitor, - * using the none cipher, mac and compression algorithms. - * - * But, interestingly, the none cipher has a block size of 8 - * bytes, thus we must pad the packet. - * - * Also, encryption includes the packet length, so the padding - * must account for that field. I.e., (sizeof (packet length) + - * sizeof (padding length) + packet length + padding length) % - * block_size must == 0. - * - * Also, there must be at least four (4) bytes of padding. - */ - padlen = (8 - ((plen + sizeof (plen) + sizeof (padlen)) % 8)) % 8; - if (padlen < 4) - padlen += 8; - - /* packet length counts padding and padding length field */ - plen += padlen + sizeof (padlen); - - PUT_32BIT(plen_buf, plen); - - setp = xmalloc(howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); - memset(setp, 0, howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); - FD_SET(pipe_fd, setp); - - while (select(pipe_fd + 1, NULL, setp, NULL, NULL) == -1) { - if (errno == EAGAIN || errno == EINTR) - continue; - else - goto pipe_gone; - } - - xfree(setp); - - /* packet length field */ - len = atomicio(write, pipe_fd, plen_buf, sizeof (plen)); - - if (len != sizeof (plen)) - goto pipe_gone; - - /* padding length field */ - len = atomicio(write, pipe_fd, &padlen, sizeof (padlen)); - - if (len != sizeof (padlen)) - goto pipe_gone; - - len = atomicio(write, pipe_fd, buffer_ptr(&to_monitor), plen - 1); - - if (len != (plen - 1)) - goto pipe_gone; - - buffer_clear(&to_monitor); - - return (1); - -pipe_gone: - - err = errno; - - (void) close(pipe_fd); - - pipe_fd = -1; - - fatal("altprvsep_packet_send: Monitor not responding: %.100s", - strerror(err)); - - /* NOTREACHED */ - return (0); -} - -/* - * Read a monitor packet from the monitor. This function is blocking. - */ -static int -altprivsep_packet_read(void) -{ - ssize_t len = -1; - u_int32_t plen; - u_char plen_buf[sizeof (plen)]; - u_char padlen; - fd_set *setp; - int err; - - if (pipe_fd == -1) - return (-1); - - setp = xmalloc(howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); - memset(setp, 0, howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); - FD_SET(pipe_fd, setp); - - while (select(pipe_fd + 1, setp, NULL, NULL, NULL) == -1) { - if (errno == EAGAIN || errno == EINTR) - continue; - else - goto pipe_gone; - } - - xfree(setp); - - /* packet length field */ - len = atomicio(read, pipe_fd, plen_buf, sizeof (plen)); - - plen = GET_32BIT(plen_buf); - - if (len != sizeof (plen)) - goto pipe_gone; - - /* padding length field */ - len = atomicio(read, pipe_fd, &padlen, sizeof (padlen)); - - if (len != sizeof (padlen)) - goto pipe_gone; - - plen -= sizeof (padlen); - - buffer_clear(&from_monitor); - buffer_append_space(&from_monitor, plen); - - /* packet data + padding */ - len = atomicio(read, pipe_fd, buffer_ptr(&from_monitor), plen); - - if (len != plen) - goto pipe_gone; - - /* remove padding */ - if (padlen > 0) - buffer_consume_end(&from_monitor, padlen); - - /* packet type */ - return (buffer_get_char(&from_monitor)); - -pipe_gone: - - err = errno; - - (void) close(pipe_fd); - - pipe_fd = -1; - - if (len < 0) - fatal("altpriv_packet_read: Monitor not responding %.100s", - strerror(err)); - - debug2("Monitor pipe closed by monitor"); - return (0); -} - -static void -altprivsep_packet_read_expect(int expected) -{ - int type; - - type = altprivsep_packet_read(); - - if (type <= 0) - fatal("altprivsep_packet_read_expect: Monitor not responding"); - - if (type != expected) - fatal("Protocol error in privilege separation; expected " - "packet type %d, got %d", expected, type); -} - -static u_int -altprivsep_packet_get_char(void) -{ - return (buffer_get_char(&from_monitor)); -} -void -*altprivsep_packet_get_raw(u_int *length_ptr) -{ - if (length_ptr != NULL) - *length_ptr = buffer_len(&from_monitor); - - return (buffer_ptr(&from_monitor)); -} -void -*altprivsep_packet_get_string(u_int *length_ptr) -{ - return (buffer_get_string(&from_monitor, length_ptr)); -} - -/* - * Start and execute the code for the monitor which never returns from this - * function. The child will return and continue in the caller. - */ -void -altprivsep_start_and_do_monitor(int use_engine, int inetd, int newsock, - int statup_pipe) -{ - pid_t aps_child; - Authctxt *authctxt; - - /* - * The monitor will packet_close() in packet_set_monitor() called from - * altprivsep_start_monitor() below to clean up the socket stuff before - * it switches to pipes for communication to the child. The socket fd is - * closed there so we must dup it here - monitor needs that socket to - * shutdown the connection in case of any problem; see comments below. - * Note that current newsock was assigned to connection_(in|out) which - * are the variables used in packet_close() to close the communication - * socket. - */ - newsock = dup(newsock); - - if ((aps_child = altprivsep_start_monitor(&authctxt)) == -1) - fatal("Monitor could not be started."); - - if (aps_child > 0) { - /* ALTPRIVSEP Monitor */ - - /* - * The ALTPRIVSEP monitor here does: - * - * - record keeping and auditing - * - PAM cleanup - */ - - /* this is for MaxStartups and the child takes care of that */ - (void) close(statup_pipe); - (void) pkcs11_engine_load(use_engine); - - /* - * If the monitor fatal()s it will audit/record a logout, so - * we'd better do something to really mean it: shutdown the - * socket but leave the child alone -- it's been disconnected - * and we hope it exits, but killing any pid from a privileged - * monitor could be dangerous. - * - * NOTE: Order matters -- these fatal cleanups must come before - * the audit logout fatal cleanup as these functions are called - * in LIFO. - */ - fatal_add_cleanup((void (*)(void *))altprivsep_shutdown_sock, - (void *)&newsock); - - if (compat20) { - debug3("Recording SSHv2 session login in wtmpx"); - /* - * record_login() relies on connection_in to be the - * socket to get the peer address. The problem is that - * connection_in had to be set to the pipe descriptor in - * altprivsep_start_monitor(). It's not nice but the - * easiest way to get the peer's address is to - * temporarily set connection_in to the socket's file - * descriptor. - */ - packet_set_fds(inetd == 1 ? -1 : newsock, 0); - record_login(getpid(), NULL, "sshd", authctxt->user); - packet_set_fds(0, 1); - } - -#ifdef HAVE_BSM - /* Initialize the group list, audit sometimes needs it. */ - if (initgroups(authctxt->pw->pw_name, - authctxt->pw->pw_gid) < 0) { - perror("initgroups"); - exit (1); - } - - /* - * The monitor process fork()ed before the authentication - * process started so at this point we have an unaudited - * context. Thus we need to obtain the audit session data - * from the authentication process (aps_child) which will - * have the correct audit context for the user logging in. - * To do so we pass along the process-ID of the aps_child - * process so that it is referenced for this audit session - * rather than referencing the monitor's unaudited context. - */ - audit_sshd_login(&ah, aps_child); - - fatal_add_cleanup((void (*)(void *))audit_sshd_logout, - (void *)&ah); -#endif /* HAVE_BSM */ - -#ifdef GSSAPI - fatal_add_cleanup((void (*)(void *))ssh_gssapi_cleanup_creds, - (void *)&xxx_gssctxt); -#endif /* GSSAPI */ - - altprivsep_do_monitor(authctxt, aps_child); - - /* If we got here the connection is dead. */ - fatal_remove_cleanup((void (*)(void *))altprivsep_shutdown_sock, - (void *)&newsock); - - if (compat20) { - debug3("Recording SSHv2 session logout in wtmpx"); - record_logout(getpid(), NULL, "sshd", authctxt->user); - } - - /* - * Make sure the socket is closed. The monitor can't call - * packet_close here as it's done a packet_set_connection() - * with the pipe to the child instead of the socket. - */ - (void) shutdown(newsock, SHUT_RDWR); - -#ifdef GSSAPI - fatal_remove_cleanup((void (*)(void *))ssh_gssapi_cleanup_creds, - &xxx_gssctxt); - ssh_gssapi_cleanup_creds(xxx_gssctxt); - ssh_gssapi_server_mechs(NULL); /* release cached mechs list */ -#endif /* GSSAPI */ - -#ifdef HAVE_BSM - fatal_remove_cleanup((void (*)(void *))audit_sshd_logout, (void *)&ah); - audit_sshd_logout(&ah); -#endif /* HAVE_BSM */ - - exit(0); - } else { - /* - * This is the child, close the dup()ed file descriptor for a - * socket. It's not needed in the child. - */ - close(newsock); - } -} diff --git a/usr/src/cmd/ssh/sshd/auth-bsdauth.c b/usr/src/cmd/ssh/sshd/auth-bsdauth.c deleted file mode 100644 index 090fa0ef39..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-bsdauth.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "includes.h" -RCSID("$OpenBSD: auth-bsdauth.c,v 1.5 2002/06/30 21:59:45 deraadt Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef BSD_AUTH -#include "xmalloc.h" -#include "auth.h" -#include "log.h" - -static void * -bsdauth_init_ctx(Authctxt *authctxt) -{ - return authctxt; -} - -int -bsdauth_query(void *ctx, char **name, char **infotxt, - u_int *numprompts, char ***prompts, u_int **echo_on) -{ - Authctxt *authctxt = ctx; - char *challenge = NULL; - - if (authctxt->as != NULL) { - debug2("bsdauth_query: try reuse session"); - challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE); - if (challenge == NULL) { - auth_close(authctxt->as); - authctxt->as = NULL; - } - } - - if (challenge == NULL) { - debug2("bsdauth_query: new bsd auth session"); - debug3("bsdauth_query: style %s", - authctxt->style ? authctxt->style : "<default>"); - authctxt->as = auth_userchallenge(authctxt->user, - authctxt->style, "auth-ssh", &challenge); - if (authctxt->as == NULL) - challenge = NULL; - debug2("bsdauth_query: <%s>", challenge ? challenge : "empty"); - } - - if (challenge == NULL) - return -1; - - *name = xstrdup(""); - *infotxt = xstrdup(""); - *numprompts = 1; - *prompts = xmalloc(*numprompts * sizeof(char *)); - *echo_on = xmalloc(*numprompts * sizeof(u_int)); - (*echo_on)[0] = 0; - (*prompts)[0] = xstrdup(challenge); - - return 0; -} - -int -bsdauth_respond(void *ctx, u_int numresponses, char **responses) -{ - Authctxt *authctxt = ctx; - int authok; - - if (authctxt->as == 0) - error("bsdauth_respond: no bsd auth session"); - - if (numresponses != 1) - return -1; - - authok = auth_userresponse(authctxt->as, responses[0], 0); - authctxt->as = NULL; - debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok); - - return (authok == 0) ? -1 : 0; -} - -static void -bsdauth_free_ctx(void *ctx) -{ - Authctxt *authctxt = ctx; - - if (authctxt && authctxt->as) { - auth_close(authctxt->as); - authctxt->as = NULL; - } -} - -KbdintDevice bsdauth_device = { - "bsdauth", - bsdauth_init_ctx, - bsdauth_query, - bsdauth_respond, - bsdauth_free_ctx -}; - -KbdintDevice mm_bsdauth_device = { - "bsdauth", - bsdauth_init_ctx, - mm_bsdauth_query, - mm_bsdauth_respond, - bsdauth_free_ctx -}; -#endif diff --git a/usr/src/cmd/ssh/sshd/auth-chall.c b/usr/src/cmd/ssh/sshd/auth-chall.c deleted file mode 100644 index 07073f0d98..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-chall.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth-chall.c,v 1.8 2001/05/18 14:13:28 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "auth.h" -#include "log.h" -#include "xmalloc.h" - -/* limited protocol v1 interface to kbd-interactive authentication */ - -extern KbdintDevice *devices[]; -static KbdintDevice *device; - -char * -get_challenge(Authctxt *authctxt) -{ - char *challenge, *name, *info, **prompts; - u_int i, numprompts; - u_int *echo_on; - - device = devices[0]; /* we always use the 1st device for protocol 1 */ - if (device == NULL) - return NULL; - if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL) - return NULL; - if (device->query(authctxt->kbdintctxt, &name, &info, - &numprompts, &prompts, &echo_on)) { - device->free_ctx(authctxt->kbdintctxt); - authctxt->kbdintctxt = NULL; - return NULL; - } - if (numprompts < 1) - fatal("get_challenge: numprompts < 1"); - challenge = xstrdup(prompts[0]); - for (i = 0; i < numprompts; i++) - xfree(prompts[i]); - xfree(prompts); - xfree(name); - xfree(echo_on); - xfree(info); - - return (challenge); -} -int -verify_response(Authctxt *authctxt, const char *response) -{ - char *resp[1]; - int res; - - if (device == NULL) - return 0; - if (authctxt->kbdintctxt == NULL) - return 0; - resp[0] = (char *)response; - res = device->respond(authctxt->kbdintctxt, 1, resp); - device->free_ctx(authctxt->kbdintctxt); - authctxt->kbdintctxt = NULL; - return res ? 0 : 1; -} diff --git a/usr/src/cmd/ssh/sshd/auth-krb4.c b/usr/src/cmd/ssh/sshd/auth-krb4.c deleted file mode 100644 index 2a9103f232..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-krb4.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * 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" -RCSID("$OpenBSD: auth-krb4.c,v 1.28 2002/09/26 11:38:43 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "ssh.h" -#include "ssh1.h" -#include "packet.h" -#include "xmalloc.h" -#include "log.h" -#include "servconf.h" -#include "uidswap.h" -#include "auth.h" - -#ifdef AFS -#include "radix.h" -#endif - -#ifdef KRB4 -extern ServerOptions options; - -static int -krb4_init(void *context) -{ - static int cleanup_registered = 0; - Authctxt *authctxt = (Authctxt *)context; - const char *tkt_root = TKT_ROOT; - struct stat st; - int fd; - - if (!authctxt->krb4_ticket_file) { - /* Set unique ticket string manually since we're still root. */ - authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN); -#ifdef AFS - if (lstat("/ticket", &st) != -1) - tkt_root = "/ticket/"; -#endif /* AFS */ - snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%ld", - tkt_root, authctxt->pw->pw_uid, (long)getpid()); - krb_set_tkt_string(authctxt->krb4_ticket_file); - } - /* Register ticket cleanup in case of fatal error. */ - if (!cleanup_registered) { - fatal_add_cleanup(krb4_cleanup_proc, authctxt); - cleanup_registered = 1; - } - /* Try to create our ticket file. */ - if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) { - close(fd); - return (1); - } - /* Ticket file exists - make sure user owns it (just passed ticket). */ - if (lstat(authctxt->krb4_ticket_file, &st) != -1) { - if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && - st.st_uid == authctxt->pw->pw_uid) - return (1); - } - /* Failure - cancel cleanup function, leaving ticket for inspection. */ - log("WARNING: bad ticket file %s", authctxt->krb4_ticket_file); - - fatal_remove_cleanup(krb4_cleanup_proc, authctxt); - cleanup_registered = 0; - - xfree(authctxt->krb4_ticket_file); - authctxt->krb4_ticket_file = NULL; - - return (0); -} - -/* - * try krb4 authentication, - * return 1 on success, 0 on failure, -1 if krb4 is not available - */ -int -auth_krb4_password(Authctxt *authctxt, const char *password) -{ - AUTH_DAT adata; - KTEXT_ST tkt; - struct hostent *hp; - struct passwd *pw; - char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ]; - u_int32_t faddr; - int r; - - if ((pw = authctxt->pw) == NULL) - return (0); - - /* - * Try Kerberos password authentication only for non-root - * users and only if Kerberos is installed. - */ - if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { - /* Set up our ticket file. */ - if (!krb4_init(authctxt)) { - log("Couldn't initialize Kerberos ticket file for %s!", - pw->pw_name); - goto failure; - } - /* Try to get TGT using our password. */ - r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm, - "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password); - if (r != INTK_OK) { - debug("Kerberos v4 password authentication for %s " - "failed: %s", pw->pw_name, krb_err_txt[r]); - goto failure; - } - /* Successful authentication. */ - chown(tkt_string(), pw->pw_uid, pw->pw_gid); - - /* - * Now that we have a TGT, try to get a local - * "rcmd" ticket to ensure that we are not talking - * to a bogus Kerberos server. - */ - gethostname(localhost, sizeof(localhost)); - strlcpy(phost, (char *)krb_get_phost(localhost), - sizeof(phost)); - r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); - - if (r == KSUCCESS) { - if ((hp = gethostbyname(localhost)) == NULL) { - log("Couldn't get local host address!"); - goto failure; - } - memmove((void *)&faddr, (void *)hp->h_addr, - sizeof(faddr)); - - /* Verify our "rcmd" ticket. */ - r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, - faddr, &adata, ""); - if (r == RD_AP_UNDEC) { - /* - * Probably didn't have a srvtab on - * 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 failure; - } else if (r != KSUCCESS) { - log("Kerberos v4 %s ticket unverifiable: %s", - KRB4_SERVICE_NAME, krb_err_txt[r]); - goto failure; - } - } else if (r == KDC_PR_UNKNOWN) { - /* - * 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 failure; - } else { - /* - * TGT is bad, forget it. Possibly spoofed! - */ - debug("WARNING: Kerberos v4 TGT possibly spoofed " - "for %s: %s", pw->pw_name, krb_err_txt[r]); - goto failure; - } - /* Authentication succeeded. */ - return (1); - } else - /* Logging in as root or no local Kerberos realm. */ - debug("Unable to authenticate to Kerberos."); - - failure: - krb4_cleanup_proc(authctxt); - - if (!options.kerberos_or_local_passwd) - return (0); - - /* Fall back to ordinary passwd authentication. */ - return (-1); -} - -void -krb4_cleanup_proc(void *context) -{ - Authctxt *authctxt = (Authctxt *)context; - debug("krb4_cleanup_proc called"); - if (authctxt->krb4_ticket_file) { - (void) dest_tkt(); - xfree(authctxt->krb4_ticket_file); - authctxt->krb4_ticket_file = NULL; - } -} - -int -auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply) -{ - AUTH_DAT adat = {0}; - Key_schedule schedule; - struct sockaddr_in local, foreign; - char instance[INST_SZ]; - socklen_t slen; - u_int cksum; - int r, s; - - s = packet_get_connection_in(); - - slen = sizeof(local); - memset(&local, 0, sizeof(local)); - if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) - debug("getsockname failed: %.100s", strerror(errno)); - slen = sizeof(foreign); - memset(&foreign, 0, sizeof(foreign)); - if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { - debug("getpeername failed: %.100s", strerror(errno)); - fatal_cleanup(); - } - instance[0] = '*'; - instance[1] = 0; - - /* Get the encrypted request, challenge, and session key. */ - if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, - 0, &adat, ""))) { - debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]); - return (0); - } - des_key_sched((des_cblock *) adat.session, schedule); - - *client = xmalloc(MAX_K_NAME_SZ); - (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, - *adat.pinst ? "." : "", adat.pinst, adat.prealm); - - /* Check ~/.klogin authorization now. */ - if (kuserok(&adat, authctxt->user) != KSUCCESS) { - log("Kerberos v4 .klogin authorization failed for %s to " - "account %s", *client, authctxt->user); - xfree(*client); - *client = NULL; - return (0); - } - /* Increment the checksum, and return it encrypted with the - session key. */ - cksum = adat.checksum + 1; - cksum = htonl(cksum); - - /* If we can't successfully encrypt the checksum, we send back an - empty message, admitting our failure. */ - if ((r = krb_mk_priv((u_char *) & cksum, reply->dat, sizeof(cksum) + 1, - schedule, &adat.session, &local, &foreign)) < 0) { - debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]); - reply->dat[0] = 0; - reply->length = 0; - } else - reply->length = r; - - /* Clear session key. */ - memset(&adat.session, 0, sizeof(&adat.session)); - return (1); -} -#endif /* KRB4 */ - -#ifdef AFS -int -auth_krb4_tgt(Authctxt *authctxt, const char *string) -{ - CREDENTIALS creds; - struct passwd *pw; - - if ((pw = authctxt->pw) == NULL) - goto failure; - - temporarily_use_uid(pw); - - if (!radix_to_creds(string, &creds)) { - log("Protocol error decoding Kerberos v4 TGT"); - goto failure; - } - if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ - strlcpy(creds.service, "krbtgt", sizeof creds.service); - - if (strcmp(creds.service, "krbtgt")) { - log("Kerberos v4 TGT (%s%s%s@%s) rejected for %s", - creds.pname, creds.pinst[0] ? "." : "", creds.pinst, - creds.realm, pw->pw_name); - goto failure; - } - if (!krb4_init(authctxt)) - goto failure; - - if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) - goto failure; - - if (save_credentials(creds.service, creds.instance, creds.realm, - creds.session, creds.lifetime, creds.kvno, &creds.ticket_st, - creds.issue_date) != KSUCCESS) { - debug("Kerberos v4 TGT refused: couldn't save credentials"); - goto failure; - } - /* Successful authentication, passed all checks. */ - chown(tkt_string(), pw->pw_uid, pw->pw_gid); - - debug("Kerberos v4 TGT accepted (%s%s%s@%s)", - creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm); - memset(&creds, 0, sizeof(creds)); - - restore_uid(); - - return (1); - - failure: - krb4_cleanup_proc(authctxt); - memset(&creds, 0, sizeof(creds)); - restore_uid(); - - return (0); -} - -int -auth_afs_token(Authctxt *authctxt, const char *token_string) -{ - CREDENTIALS creds; - struct passwd *pw; - uid_t uid; - - if ((pw = authctxt->pw) == NULL) - return (0); - - if (!radix_to_creds(token_string, &creds)) { - log("Protocol error decoding AFS token"); - return (0); - } - if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ - strlcpy(creds.service, "afs", sizeof creds.service); - - if (strncmp(creds.pname, "AFS ID ", 7) == 0) - uid = atoi(creds.pname + 7); - else - uid = pw->pw_uid; - - if (kafs_settoken(creds.realm, uid, &creds)) { - log("AFS token (%s@%s) rejected for %s", - creds.pname, creds.realm, pw->pw_name); - memset(&creds, 0, sizeof(creds)); - return (0); - } - debug("AFS token accepted (%s@%s)", creds.pname, creds.realm); - memset(&creds, 0, sizeof(creds)); - - return (1); -} -#endif /* AFS */ diff --git a/usr/src/cmd/ssh/sshd/auth-krb5.c b/usr/src/cmd/ssh/sshd/auth-krb5.c deleted file mode 100644 index 3f5416af41..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-krb5.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Kerberos v5 authentication and ticket-passing routines. - * - * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $ - */ -/* - * Copyright (c) 2002 Daniel Kouril. 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-krb5.c,v 1.9 2002/09/09 06:48:06 itojun Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "ssh.h" -#include "ssh1.h" -#include "packet.h" -#include "xmalloc.h" -#include "log.h" -#include "servconf.h" -#include "uidswap.h" -#include "auth.h" - -#ifdef KRB5 -#include <krb5.h> -#ifndef HEIMDAL -#define krb5_get_err_text(context,code) error_message(code) -#endif /* !HEIMDAL */ - -extern ServerOptions options; - -static int -krb5_init(void *context) -{ - Authctxt *authctxt = (Authctxt *)context; - krb5_error_code problem; - static int cleanup_registered = 0; - - if (authctxt->krb5_ctx == NULL) { - problem = krb5_init_context(&authctxt->krb5_ctx); - if (problem) - return (problem); - krb5_init_ets(authctxt->krb5_ctx); - } - if (!cleanup_registered) { - fatal_add_cleanup(krb5_cleanup_proc, authctxt); - cleanup_registered = 1; - } - return (0); -} - -/* - * Try krb5 authentication. server_user is passed for logging purposes - * only, in auth is received ticket, in client is returned principal - * from the ticket - */ -int -auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply) -{ - krb5_error_code problem; - krb5_principal server; - krb5_ticket *ticket; - int fd, ret; - - ret = 0; - server = NULL; - ticket = NULL; - reply->length = 0; - - problem = krb5_init(authctxt); - if (problem) - goto err; - - problem = krb5_auth_con_init(authctxt->krb5_ctx, - &authctxt->krb5_auth_ctx); - if (problem) - goto err; - - fd = packet_get_connection_in(); -#ifdef HEIMDAL - problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx, &fd); -#else - problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx,fd, - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); -#endif - if (problem) - goto err; - - problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL , - KRB5_NT_SRV_HST, &server); - if (problem) - goto err; - - problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx, - auth, server, NULL, NULL, &ticket); - if (problem) - goto err; - -#ifdef HEIMDAL - problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client, - &authctxt->krb5_user); -#else - problem = krb5_copy_principal(authctxt->krb5_ctx, - ticket->enc_part2->client, - &authctxt->krb5_user); -#endif - if (problem) - goto err; - - /* if client wants mutual auth */ - problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - reply); - if (problem) - goto err; - - /* Check .k5login authorization now. */ - if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, - authctxt->pw->pw_name)) - goto err; - - if (client) - krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user, - client); - - ret = 1; - err: - if (server) - krb5_free_principal(authctxt->krb5_ctx, server); - if (ticket) - krb5_free_ticket(authctxt->krb5_ctx, ticket); - if (!ret && reply->length) { - xfree(reply->data); - memset(reply, 0, sizeof(*reply)); - } - - if (problem) { - if (authctxt->krb5_ctx != NULL) - debug("Kerberos v5 authentication failed: %s", - krb5_get_err_text(authctxt->krb5_ctx, problem)); - else - debug("Kerberos v5 authentication failed: %d", - problem); - } - - return (ret); -} - -int -auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt) -{ - krb5_error_code problem; - krb5_ccache ccache = NULL; - char *pname; - krb5_creds **creds; - - if (authctxt->pw == NULL || authctxt->krb5_user == NULL) - return (0); - - temporarily_use_uid(authctxt->pw); - -#ifdef HEIMDAL - problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache); -#else -{ - char ccname[40]; - int tmpfd; - - snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); - - if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { - log("mkstemp(): %.100s", strerror(errno)); - problem = errno; - goto fail; - } - if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { - log("fchmod(): %.100s", strerror(errno)); - close(tmpfd); - problem = errno; - goto fail; - } - close(tmpfd); - problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache); -} -#endif - if (problem) - goto fail; - - problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache, - authctxt->krb5_user); - if (problem) - goto fail; - -#ifdef HEIMDAL - problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - ccache, tgt); - if (problem) - goto fail; -#else - problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - tgt, &creds, NULL); - if (problem) - goto fail; - problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds); - if (problem) - goto fail; -#endif - - authctxt->krb5_fwd_ccache = ccache; - ccache = NULL; - - authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); - - problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user, - &pname); - if (problem) - goto fail; - - debug("Kerberos v5 TGT accepted (%s)", pname); - - restore_uid(); - - return (1); - - fail: - if (problem) - debug("Kerberos v5 TGT passing failed: %s", - krb5_get_err_text(authctxt->krb5_ctx, problem)); - if (ccache) - krb5_cc_destroy(authctxt->krb5_ctx, ccache); - - restore_uid(); - - return (0); -} - -int -auth_krb5_password(Authctxt *authctxt, const char *password) -{ -#ifndef HEIMDAL - krb5_creds creds; - krb5_principal server; - char ccname[40]; - int tmpfd; -#endif - krb5_error_code problem; - - if (authctxt->pw == NULL) - return (0); - - temporarily_use_uid(authctxt->pw); - - problem = krb5_init(authctxt); - if (problem) - goto out; - - problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name, - &authctxt->krb5_user); - if (problem) - goto out; - -#ifdef HEIMDAL - problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, - &authctxt->krb5_fwd_ccache); - if (problem) - goto out; - - problem = krb5_cc_initialize(authctxt->krb5_ctx, - authctxt->krb5_fwd_ccache, authctxt->krb5_user); - if (problem) - goto out; - - restore_uid(); - problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user, - authctxt->krb5_fwd_ccache, password, 1, NULL); - temporarily_use_uid(authctxt->pw); - - if (problem) - goto out; - -#else - problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds, - authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL); - if (problem) - goto out; - - problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL, - KRB5_NT_SRV_HST, &server); - if (problem) - goto out; - - restore_uid(); - problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server, - NULL, NULL, NULL); - krb5_free_principal(authctxt->krb5_ctx, server); - temporarily_use_uid(authctxt->pw); - if (problem) - goto out; - - if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, - authctxt->pw->pw_name)) { - problem = -1; - goto out; - } - - snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); - - if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { - log("mkstemp(): %.100s", strerror(errno)); - problem = errno; - goto out; - } - - if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { - log("fchmod(): %.100s", strerror(errno)); - close(tmpfd); - problem = errno; - goto out; - } - close(tmpfd); - - problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &authctxt->krb5_fwd_ccache); - if (problem) - goto out; - - problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, - authctxt->krb5_user); - if (problem) - goto out; - - problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, - &creds); - if (problem) - goto out; -#endif - - authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); - - out: - restore_uid(); - - if (problem) { - if (authctxt->krb5_ctx != NULL && problem!=-1) - debug("Kerberos password authentication failed: %s", - krb5_get_err_text(authctxt->krb5_ctx, problem)); - else - debug("Kerberos password authentication failed: %d", - problem); - - krb5_cleanup_proc(authctxt); - - if (options.kerberos_or_local_passwd) - return (-1); - else - return (0); - } - return (1); -} - -void -krb5_cleanup_proc(void *context) -{ - Authctxt *authctxt = (Authctxt *)context; - - debug("krb5_cleanup_proc called"); - if (authctxt->krb5_fwd_ccache) { - krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); - authctxt->krb5_fwd_ccache = NULL; - } - if (authctxt->krb5_user) { - krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); - authctxt->krb5_user = NULL; - } - if (authctxt->krb5_auth_ctx) { - krb5_auth_con_free(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx); - authctxt->krb5_auth_ctx = NULL; - } - if (authctxt->krb5_ctx) { - krb5_free_context(authctxt->krb5_ctx); - authctxt->krb5_ctx = NULL; - } -} - -#endif /* KRB5 */ diff --git a/usr/src/cmd/ssh/sshd/auth-options.c b/usr/src/cmd/ssh/sshd/auth-options.c deleted file mode 100644 index b186cbe045..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-options.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * 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". - */ - -#include "includes.h" -RCSID("$OpenBSD: auth-options.c,v 1.26 2002/07/30 17:03:55 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "xmalloc.h" -#include "match.h" -#include "log.h" -#include "canohost.h" -#include "channels.h" -#include "auth-options.h" -#include "servconf.h" -#include "misc.h" -#include "auth.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; - -extern ServerOptions options; - -void -auth_clear_options(void) -{ - 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; - } - channel_clear_permitted_opens(); - auth_debug_reset(); -} - -/* - * return 1 if access is granted, 0 if not. - * side effect: sets key option flags - */ -int -auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) -{ - const char *cp; - int i; - - /* reset options */ - auth_clear_options(); - - if (!opts) - return 1; - - while (*opts && *opts != ' ' && *opts != '\t') { - cp = "no-port-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Port forwarding disabled."); - no_port_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-agent-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Agent forwarding disabled."); - no_agent_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-X11-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("X11 forwarding disabled."); - no_x11_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-pty"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Pty allocation disabled."); - no_pty_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "command=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - opts += strlen(cp); - forced_command = xmalloc(strlen(opts) + 1); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - forced_command[i++] = '"'; - continue; - } - forced_command[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(forced_command); - forced_command = NULL; - goto bad_option; - } - forced_command[i] = 0; - auth_debug_add("Forced command: %.900s", forced_command); - opts++; - goto next_option; - } - cp = "environment=\""; - if (options.permit_user_env && - strncasecmp(opts, cp, strlen(cp)) == 0) { - char *s; - struct envstring *new_envstring; - - opts += strlen(cp); - s = xmalloc(strlen(opts) + 1); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - s[i++] = '"'; - continue; - } - s[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(s); - goto bad_option; - } - s[i] = 0; - auth_debug_add("Adding to environment: %.900s", s); - debug("Adding to environment: %.900s", s); - opts++; - 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 (strncasecmp(opts, cp, strlen(cp)) == 0) { - const char *remote_ip = get_remote_ipaddr(); - const char *remote_host = get_canonical_hostname( - options.verify_reverse_mapping); - char *patterns = xmalloc(strlen(opts) + 1); - - opts += strlen(cp); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - patterns[i++] = '"'; - continue; - } - patterns[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(patterns); - goto bad_option; - } - patterns[i] = 0; - opts++; - if (match_host_and_ip(remote_host, remote_ip, - patterns) != 1) { - xfree(patterns); - log("Authentication tried for %.100s with " - "correct key but not from a permitted " - "host (host=%.200s, ip=%.200s).", - pw->pw_name, remote_host, remote_ip); - auth_debug_add("Your host '%.200s' is not " - "permitted to use this key for login.", - remote_host); - /* deny access */ - return 0; - } - xfree(patterns); - /* Host name matches. */ - goto next_option; - } - cp = "permitopen=\""; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - char host[256], sport[6]; - u_short port; - char *patterns = xmalloc(strlen(opts) + 1); - - opts += strlen(cp); - i = 0; - while (*opts) { - if (*opts == '"') - break; - if (*opts == '\\' && opts[1] == '"') { - opts += 2; - patterns[i++] = '"'; - continue; - } - patterns[i++] = *opts++; - } - if (!*opts) { - debug("%.100s, line %lu: missing end quote", - file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); - xfree(patterns); - goto bad_option; - } - patterns[i] = 0; - opts++; - if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 && - sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) { - debug("%.100s, line %lu: Bad permitopen specification " - "<%.100s>", file, linenum, patterns); - auth_debug_add("%.100s, line %lu: " - "Bad permitopen specification", file, linenum); - xfree(patterns); - goto bad_option; - } - if ((port = a2port(sport)) == 0) { - debug("%.100s, line %lu: Bad permitopen port <%.100s>", - file, linenum, sport); - auth_debug_add("%.100s, line %lu: " - "Bad permitopen port", file, linenum); - xfree(patterns); - goto bad_option; - } - if (options.allow_tcp_forwarding) - channel_add_permitted_opens(host, port); - xfree(patterns); - goto next_option; - } -next_option: - /* - * Skip the comma, and move to the next option - * (or break out if there are no more). - */ - if (!*opts) - fatal("Bugs in auth-options.c option processing."); - if (*opts == ' ' || *opts == '\t') - break; /* End of options. */ - if (*opts != ',') - goto bad_option; - opts++; - /* Process the next option. */ - } - - auth_debug_send(); - - /* grant access */ - return 1; - -bad_option: - log("Bad options in %.100s file, line %lu: %.50s", - file, linenum, opts); - auth_debug_add("Bad options in %.100s file, line %lu: %.50s", - file, linenum, opts); - - auth_debug_send(); - - /* deny access */ - return 0; -} diff --git a/usr/src/cmd/ssh/sshd/auth-pam.c b/usr/src/cmd/ssh/sshd/auth-pam.c deleted file mode 100644 index c3686b4928..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-pam.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Copyright (c) 2000 Damien Miller. 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) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include "includes.h" - -#ifdef USE_PAM -#include "xmalloc.h" -#include "log.h" -#include "auth.h" -#include "auth-options.h" -#include "auth-pam.h" -#include "buffer.h" -#include "servconf.h" -#include "canohost.h" -#include "compat.h" -#include "misc.h" -#include "sshlogin.h" -#include "ssh-gss.h" - -#include <security/pam_appl.h> - -extern char *__progname; - -extern u_int utmp_len; -extern ServerOptions options; - -extern Authmethod method_kbdint; - -RCSID("$Id: auth-pam.c,v 1.54 2002/07/28 20:24:08 stevesk Exp $"); - -#define NEW_AUTHTOK_MSG \ - "Warning: Your password has expired, please change it now." - -/* PAM conversation for non-interactive userauth methods */ -static int do_pam_conversation(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr); - -static void do_pam_cleanup_proc(void *context); - -static char *get_method_name(Authctxt *authctxt); - -/* PAM conversation for non-interactive userauth methods */ -static struct pam_conv conv = { - (int (*)())do_pam_conversation, - NULL -}; -static char *__pam_msg = NULL; - -static -char * -get_method_name(Authctxt *authctxt) -{ - if (!authctxt) - return "(unknown)"; - - if (!compat20) - return (authctxt->v1_auth_name) ? authctxt->v1_auth_name : - "(sshv1-unknown)"; - - if (!authctxt->method || !authctxt->method->name) - return "(sshv2-unknown)"; - - return authctxt->method->name; -} - -char * -derive_pam_service_name(Authmethod *method) -{ - char *svcname = xmalloc(BUFSIZ); - - /* - * If PamServiceName is set we use that for everything, including - * SSHv1 - */ - if (options.pam_service_name != NULL) { - (void) strlcpy(svcname, options.pam_service_name, BUFSIZ); - return (svcname); - } - - if (compat20 && method) { - char *method_name = method->name; - - if (!method_name) - fatal("Userauth method unknown while starting PAM"); - - /* - * For SSHv2 we use "sshd-<userauth name> - * The "sshd" prefix can be changed via the PAMServicePrefix - * sshd_config option. - */ - if (strcmp(method_name, "none") == 0) { - snprintf(svcname, BUFSIZ, "%s-none", - options.pam_service_prefix); - } - if (strcmp(method_name, "password") == 0) { - snprintf(svcname, BUFSIZ, "%s-password", - options.pam_service_prefix); - } - if (strcmp(method_name, "keyboard-interactive") == 0) { - /* "keyboard-interactive" is too long, shorten it */ - snprintf(svcname, BUFSIZ, "%s-kbdint", - options.pam_service_prefix); - } - if (strcmp(method_name, "publickey") == 0) { - /* "publickey" is too long, shorten it */ - snprintf(svcname, BUFSIZ, "%s-pubkey", - options.pam_service_prefix); - } - if (strcmp(method_name, "hostbased") == 0) { - /* "hostbased" can't really be shortened... */ - snprintf(svcname, BUFSIZ, "%s-hostbased", - options.pam_service_prefix); - } - if (strncmp(method_name, "gss", 3) == 0) { - /* "gss" is too short, elongate it */ - snprintf(svcname, BUFSIZ, "%s-gssapi", - options.pam_service_prefix); - } - return svcname; - } else { - /* SSHv1 doesn't get to be so cool */ - snprintf(svcname, BUFSIZ, "%s-v1", - options.pam_service_prefix); - } - return svcname; -} - -void -new_start_pam(Authctxt *authctxt, struct pam_conv *conv) -{ - int retval; - pam_handle_t *pamh; - const char *rhost; - char *svc; - char *user = NULL; - pam_stuff *pam; - - if (authctxt == NULL) - fatal("Internal error during userauth"); - - if (compat20 && authctxt->method == NULL) - fatal("Userauth method unknown while starting PAM"); - - /* PAM service selected here */ - svc = derive_pam_service_name(authctxt->method); - debug2("Starting PAM service %s for method %s", svc, - get_method_name(authctxt)); - - if (authctxt->user != NULL) - user = authctxt->user; - - /* Cleanup previous PAM state */ - if (authctxt->pam != NULL) { - fatal_remove_cleanup(&do_pam_cleanup_proc, authctxt->pam); - do_pam_cleanup_proc(authctxt->pam); - } - - pam = xmalloc(sizeof(pam_stuff)); - (void) memset(pam, 0, sizeof(pam_stuff)); - - /* - * pam->last_pam_retval has to be and is considered - * along with pam->state. - * - * pam->state = 0; -> no PAM auth, account, etc, work - * done yet. (Set by memset() above.) - * - * pam->last_pam_retval = PAM_SUCCESS; -> meaningless at - * this point. - * - * See finish_userauth_do_pam() below. - */ - pam->authctxt = authctxt; - pam->last_pam_retval = PAM_SUCCESS; - - authctxt->pam = pam; - - /* Free any previously stored text/error PAM prompts */ - if (__pam_msg) { - xfree(__pam_msg); - __pam_msg = NULL; - } - - if ((retval = pam_start(svc, user, conv, &pamh)) != PAM_SUCCESS) { - fatal("PAM initialization failed during %s userauth", - get_method_name(authctxt)); - } - - free(svc); - - fatal_add_cleanup((void (*)(void *)) &do_pam_cleanup_proc, - (void *) authctxt->pam); - - rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping); - if ((retval = pam_set_item(pamh, PAM_RHOST, rhost)) != PAM_SUCCESS) { - (void) pam_end(pamh, retval); - fatal("Could not set PAM_RHOST item during %s userauth", - get_method_name(authctxt)); - } - - if ((retval = pam_set_item(pamh, PAM_TTY, "sshd")) != PAM_SUCCESS) { - (void) pam_end(pamh, retval); - fatal("Could not set PAM_TTY item during %s userauth", - get_method_name(authctxt)); - } - - if (authctxt->cuser != NULL) - if ((retval = pam_set_item(pamh, PAM_AUSER, authctxt->cuser)) != PAM_SUCCESS) { - (void) pam_end(pamh, retval); - fatal("Could not set PAM_AUSER item during %s userauth", - get_method_name(authctxt)); - } - - authctxt->pam->h = pamh; -} - -/* - * To be called from userauth methods, directly (as in keyboard-interactive) or - * indirectly (from auth_pam_password() or from do_pam_non_initial_userauth(). - * - * The caller is responsible for calling new_start_pam() first. - * - * PAM state is not cleaned up here on error. This is left to subsequent calls - * to new_start_pam() or to the cleanup function upon authentication error. - */ -int -finish_userauth_do_pam(Authctxt *authctxt) -{ - int retval; - char *user, *method; - - /* Various checks; fail gracefully */ - if (authctxt == NULL || authctxt->pam == NULL) - return PAM_SYSTEM_ERR; /* shouldn't happen */ - - if (compat20) { - if (authctxt->method == NULL || authctxt->method->name == NULL) - return PAM_SYSTEM_ERR; /* shouldn't happen */ - method = authctxt->method->name; - } else if ((method = authctxt->v1_auth_name) == NULL) - return PAM_SYSTEM_ERR; /* shouldn't happen */ - - if (AUTHPAM_DONE(authctxt)) - return PAM_SYSTEM_ERR; /* shouldn't happen */ - - if (!(authctxt->pam->state & PAM_S_DONE_ACCT_MGMT)) { - retval = pam_acct_mgmt(authctxt->pam->h, 0); - authctxt->pam->last_pam_retval = retval; - if (retval == PAM_NEW_AUTHTOK_REQD) { - userauth_force_kbdint(); - return retval; - } - if (retval != PAM_SUCCESS) - return retval; - authctxt->pam->state |= PAM_S_DONE_ACCT_MGMT; - } - - /* - * Handle PAM_USER change, if any. - * - * We do this before pam_open_session() because we need the PAM_USER's - * UID for: - * - * a) PermitRootLogin checking - * b) to get at the lastlog entry before pam_open_session() updates it. - */ - retval = pam_get_item(authctxt->pam->h, PAM_USER, (void **) &user); - if (retval != PAM_SUCCESS) { - fatal("PAM failure: pam_get_item(PAM_USER) " - "returned %d: %.200s", retval, - PAM_STRERROR(authctxt->pam->h, retval)); - } - - if (user == NULL || *user == '\0') { - debug("PAM set NULL PAM_USER"); - return PAM_PERM_DENIED; - } - - if (strcmp(user, authctxt->user) != 0) { - log("PAM changed the SSH username"); - pwfree(&authctxt->pw); - authctxt->pw = getpwnamallow(user); - authctxt->valid = (authctxt->pw != NULL); - xfree(authctxt->user); - authctxt->user = xstrdup(user); - } - - if (!authctxt->valid) { - debug2("PAM set PAM_USER to unknown user"); - /* - * Return success, userauth_finish() will catch - * this and send back a failure message. - */ - return PAM_SUCCESS; - } - - /* Check PermitRootLogin semantics */ - if (authctxt->pw->pw_uid == 0 && !auth_root_allowed(method)) - return PAM_PERM_DENIED; - - if (!(authctxt->pam->state & PAM_S_DONE_SETCRED)) { - retval = pam_setcred(authctxt->pam->h, - PAM_ESTABLISH_CRED); - authctxt->pam->last_pam_retval = retval; - if (retval != PAM_SUCCESS) - return retval; - authctxt->pam->state |= PAM_S_DONE_SETCRED; - -#ifdef GSSAPI - /* - * Store GSS-API delegated creds after pam_setcred(), which may - * have set the current credential store. - */ - ssh_gssapi_storecreds(NULL, authctxt); -#endif /* GSSAPI */ - } - - /* - * On Solaris pam_unix_session.so updates the lastlog, but does - * not converse a PAM_TEXT_INFO message about it. So we need to - * fetch the lastlog entry here and save it for use later. - */ - authctxt->last_login_time = - get_last_login_time(authctxt->pw->pw_uid, - authctxt->pw->pw_name, - authctxt->last_login_host, - sizeof(authctxt->last_login_host)); - - if (!(authctxt->pam->state & PAM_S_DONE_OPEN_SESSION)) { - retval = pam_open_session(authctxt->pam->h, 0); - authctxt->pam->last_pam_retval = retval; - if (retval != PAM_SUCCESS) - return retval; - authctxt->pam->state |= PAM_S_DONE_OPEN_SESSION; - } - - /* - * All PAM work done successfully. - * - * PAM handle stays around so we can call pam_close_session() on - * it later. - */ - return PAM_SUCCESS; -} - -/* - * PAM conversation function for non-interactive userauth methods that - * really cannot do any prompting. Password userauth and CHANGEREQ can - * always set the PAM_AUTHTOK and PAM_OLDAUTHTOK items to avoid - * conversation (and if they do and nonetheless some module tries to - * converse, then password userauth / CHANGEREQ MUST fail). - * - * Except, PAM_TEXT_INFO and PAM_ERROR_MSG prompts can be squirelled - * away and shown to the user later. - * - * Keyboard-interactive userauth has its own much more interesting - * conversation function. - * - */ -static int -do_pam_conversation(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr) -{ - struct pam_response *reply; - int count; - - /* PAM will free this later */ - reply = xmalloc(num_msg * sizeof(*reply)); - - (void) memset(reply, 0, num_msg * sizeof(*reply)); - - for (count = 0; count < num_msg; count++) { - /* - * We can't use stdio yet, queue messages for - * printing later - */ - switch(PAM_MSG_MEMBER(msg, count, msg_style)) { - case PAM_PROMPT_ECHO_ON: - xfree(reply); - return PAM_CONV_ERR; - case PAM_PROMPT_ECHO_OFF: - xfree(reply); - return PAM_CONV_ERR; - break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - if (PAM_MSG_MEMBER(msg, count, msg) != NULL) { - message_cat(&__pam_msg, - PAM_MSG_MEMBER(msg, count, msg)); - } - reply[count].resp = xstrdup(""); - reply[count].resp_retcode = PAM_SUCCESS; - break; - default: - xfree(reply); - return PAM_CONV_ERR; - } - } - - *resp = reply; - - return PAM_SUCCESS; -} - -/* Called at exit to cleanly shutdown PAM */ -static void -do_pam_cleanup_proc(void *context) -{ - int pam_retval; - pam_stuff *pam = (pam_stuff *) context; - - if (pam == NULL) - return; - - if (pam->authctxt != NULL && pam->authctxt->pam == pam) { - pam->authctxt->pam_retval = pam->last_pam_retval; - pam->authctxt->pam = NULL; - pam->authctxt = NULL; - } - - if (pam->h == NULL) - return; - - /* - * We're in fatal_cleanup() or not in userauth or without a - * channel -- can't converse now, too bad. - */ - pam_retval = pam_set_item(pam->h, PAM_CONV, NULL); - if (pam_retval != PAM_SUCCESS) { - log("Cannot remove PAM conv, close session or delete creds[%d]: %.200s", - pam_retval, PAM_STRERROR(pam->h, pam_retval)); - goto cleanup; - } - - if (pam->state & PAM_S_DONE_OPEN_SESSION) { - pam_retval = pam_close_session(pam->h, 0); - if (pam_retval != PAM_SUCCESS) - log("Cannot close PAM session[%d]: %.200s", - pam_retval, PAM_STRERROR(pam->h, pam_retval)); - } - - if (pam->state & PAM_S_DONE_SETCRED) { - pam_retval = pam_setcred(pam->h, PAM_DELETE_CRED); - if (pam_retval != PAM_SUCCESS) - debug("Cannot delete credentials[%d]: %.200s", - pam_retval, PAM_STRERROR(pam->h, pam_retval)); - } - -cleanup: - - /* Use the previous PAM result, if not PAM_SUCCESS for pam_end() */ - if (pam->last_pam_retval != PAM_SUCCESS) - pam_retval = pam_end(pam->h, pam->last_pam_retval); - else if (pam_retval != PAM_SUCCESS) - pam_retval = pam_end(pam->h, pam_retval); - else - pam_retval = pam_end(pam->h, PAM_ABORT); - - if (pam_retval != PAM_SUCCESS) - log("Cannot release PAM authentication[%d]: %.200s", - pam_retval, PAM_STRERROR(pam->h, pam_retval)); - - xfree(pam); -} - -/* Attempt password authentation using PAM */ -int -auth_pam_password(Authctxt *authctxt, const char *password) -{ - int retval; - - /* Ensure we have a fresh PAM handle / state */ - new_start_pam(authctxt, &conv); - - retval = pam_set_item(authctxt->pam->h, PAM_AUTHTOK, password); - if (retval != PAM_SUCCESS) { - authctxt->pam->last_pam_retval = retval; - return 1; - } - - retval = pam_authenticate(authctxt->pam->h, - options.permit_empty_passwd ? 0 : - PAM_DISALLOW_NULL_AUTHTOK); - - if (retval != PAM_SUCCESS) { - authctxt->pam->last_pam_retval = retval; - return 0; - } - - if ((retval = finish_userauth_do_pam(authctxt)) != PAM_SUCCESS) - return 0; - - if (authctxt->method) - authctxt->method->authenticated = 1; /* SSHv2 */ - - return 1; -} - -int -do_pam_non_initial_userauth(Authctxt *authctxt) -{ - new_start_pam(authctxt, NULL); - return (finish_userauth_do_pam(authctxt) == PAM_SUCCESS); -} - -/* Cleanly shutdown PAM */ -void finish_pam(Authctxt *authctxt) -{ - fatal_remove_cleanup(&do_pam_cleanup_proc, authctxt->pam); - do_pam_cleanup_proc(authctxt->pam); -} - -static -char ** -find_env(char **env, char *var) -{ - char **p; - int len; - - if (strchr(var, '=') == NULL) - len = strlen(var); - else - len = (strchr(var, '=') - var) + 1; - - for ( p = env ; p != NULL && *p != NULL ; p++ ) { - if (strncmp(*p, var, len) == 0) - return (p); - } - - return (NULL); -} - -/* Return list of PAM environment strings */ -char ** -fetch_pam_environment(Authctxt *authctxt) -{ -#ifdef HAVE_PAM_GETENVLIST - char **penv; - - if (authctxt == NULL || authctxt->pam == NULL || - authctxt->pam->h == NULL) - return (NULL); - - penv = pam_getenvlist(authctxt->pam->h); - - return (penv); -#else /* HAVE_PAM_GETENVLIST */ - return(NULL); -#endif /* HAVE_PAM_GETENVLIST */ -} - -void free_pam_environment(char **env) -{ - int i; - - if (env != NULL) { - for (i = 0; env[i] != NULL; i++) - xfree(env[i]); - } - - xfree(env); -} - -/* Print any messages that have been generated during authentication */ -/* or account checking to stderr */ -void print_pam_messages(void) -{ - if (__pam_msg != NULL) - (void) fputs(__pam_msg, stderr); -} - -/* Append a message to buffer */ -void message_cat(char **p, const char *a) -{ - char *cp; - size_t new_len; - - new_len = strlen(a); - - if (*p) { - size_t len = strlen(*p); - - *p = xrealloc(*p, new_len + len + 2); - cp = *p + len; - } else - *p = cp = xmalloc(new_len + 2); - - (void) memcpy(cp, a, new_len); - cp[new_len] = '\n'; - cp[new_len + 1] = '\0'; -} - -#endif /* USE_PAM */ diff --git a/usr/src/cmd/ssh/sshd/auth-passwd.c b/usr/src/cmd/ssh/sshd/auth-passwd.c deleted file mode 100644 index 815231d4d4..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-passwd.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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. - * 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-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); - -#include "packet.h" -#include "log.h" -#include "servconf.h" -#include "auth.h" - -#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) -/* Don't need any of these headers for the PAM or SIA cases */ -# ifdef HAVE_CRYPT_H -# include <crypt.h> -# endif -# ifdef WITH_AIXAUTHENTICATE -# include <login.h> -# endif -# ifdef __hpux -# include <hpsecurity.h> -# include <prot.h> -# endif -# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) -# include <shadow.h> -# endif -# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) -# include <sys/label.h> -# include <sys/audit.h> -# include <pwdadj.h> -# endif -# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) -# include "md5crypt.h" -# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ - -# ifdef HAVE_CYGWIN -# undef ERROR -# include <windows.h> -# include <sys/cygwin.h> -# define is_winnt (GetVersion() < 0x80000000) -# endif -#endif /* !USE_PAM && !HAVE_OSF_SIA */ - -extern ServerOptions options; -#ifdef WITH_AIXAUTHENTICATE -extern char *aixloginmsg; -#endif - -/* - * Tries to authenticate the user using password. Returns true if - * authentication succeeds. - */ -int -auth_password(Authctxt *authctxt, const char *password) -{ -#if defined(USE_PAM) - if (*password == '\0' && options.permit_empty_passwd == 0) - return 0; - return auth_pam_password(authctxt, password); -#elif defined(HAVE_OSF_SIA) - if (*password == '\0' && options.permit_empty_passwd == 0) - return 0; - return auth_sia_password(authctxt, password); -#else - struct passwd * pw = authctxt->pw; - char *encrypted_password; - char *pw_password; - char *salt; -#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) - struct spwd *spw; -#endif -#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) - struct passwd_adjunct *spw; -#endif -#ifdef WITH_AIXAUTHENTICATE - char *authmsg; - int authsuccess; - int reenter = 1; -#endif - - /* deny if no user. */ - if (pw == NULL) - return 0; -#ifndef HAVE_CYGWIN - if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) - return 0; -#endif - if (*password == '\0' && options.permit_empty_passwd == 0) - return 0; -#ifdef KRB5 - if (options.kerberos_authentication == 1) { - int ret = auth_krb5_password(authctxt, password); - if (ret == 1 || ret == 0) - return ret; - /* Fall back to ordinary passwd authentication. */ - } -#endif -#ifdef HAVE_CYGWIN - if (is_winnt) { - HANDLE hToken = cygwin_logon_user(pw, password); - - if (hToken == INVALID_HANDLE_VALUE) - return 0; - cygwin_set_impersonation_token(hToken); - return 1; - } -#endif -#ifdef WITH_AIXAUTHENTICATE - authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); - - if (authsuccess) - /* We don't have a pty yet, so just label the line as "ssh" */ - if (loginsuccess(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh", &aixloginmsg) < 0) - aixloginmsg = NULL; - - return(authsuccess); -#endif -#ifdef KRB4 - if (options.kerberos_authentication == 1) { - int ret = auth_krb4_password(authctxt, password); - if (ret == 1 || ret == 0) - return ret; - /* Fall back to ordinary passwd authentication. */ - } -#endif -#ifdef BSD_AUTH - if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh", - (char *)password) == 0) - return 0; - else - return 1; -#endif - pw_password = pw->pw_passwd; - - /* - * Various interfaces to shadow or protected password data - */ -#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) - spw = getspnam(pw->pw_name); - if (spw != NULL) - pw_password = spw->sp_pwdp; -#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ - -#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) - if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) - pw_password = spw->pwa_passwd; -#endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */ - - /* Check for users with no password. */ - if ((password[0] == '\0') && (pw_password[0] == '\0')) - return 1; - - if (pw_password[0] != '\0') - salt = pw_password; - else - salt = "xx"; - -#ifdef HAVE_MD5_PASSWORDS - if (is_md5_salt(salt)) - encrypted_password = md5_crypt(password, salt); - else - encrypted_password = crypt(password, salt); -#else /* HAVE_MD5_PASSWORDS */ - encrypted_password = crypt(password, salt); -#endif /* HAVE_MD5_PASSWORDS */ - - /* Authentication is accepted if the encrypted passwords are identical. */ - return (strcmp(encrypted_password, pw_password) == 0); -#endif /* !USE_PAM && !HAVE_OSF_SIA */ -} diff --git a/usr/src/cmd/ssh/sshd/auth-rh-rsa.c b/usr/src/cmd/ssh/sshd/auth-rh-rsa.c deleted file mode 100644 index ab10e1738a..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-rh-rsa.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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("$OpenBSD: auth-rh-rsa.c,v 1.34 2002/03/25 09:25:06 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "packet.h" -#include "uidswap.h" -#include "log.h" -#include "servconf.h" -#include "key.h" -#include "hostfile.h" -#include "pathnames.h" -#include "auth.h" -#include "canohost.h" - -/* import */ -extern ServerOptions options; - -int -auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost, - Key *client_host_key) -{ - HostStatus host_status; - - /* Check if we would accept it using rhosts authentication. */ - if (!auth_rhosts(pw, cuser)) - return 0; - - host_status = check_key_in_hostfiles(pw, client_host_key, - chost, _PATH_SSH_SYSTEM_HOSTFILE, - options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE); - - return (host_status == HOST_OK); -} - -/* - * Tries to authenticate the user using the .rhosts file and the host using - * its host key. Returns true if authentication succeeds. - */ -int -auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key) -{ - char *chost; - - debug("Trying rhosts with RSA host authentication for client user %.100s", - cuser); - - if (pw == NULL || client_host_key == NULL || - client_host_key->rsa == NULL) - return 0; - - chost = (char *)get_canonical_hostname(options.verify_reverse_mapping); - debug("Rhosts RSA authentication: canonical host %.900s", chost); - - if (!auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key)) { - debug("Rhosts with RSA host authentication denied: unknown or invalid host key"); - packet_send_debug("Your host key cannot be verified: unknown or invalid host key."); - return 0; - } - /* A matching host key was found and is known. */ - - /* Perform the challenge-response dialog with the client for the host key. */ - if (!auth_rsa_challenge_dialog(client_host_key)) { - log("Client on %.800s failed to respond correctly to host authentication.", - chost); - return 0; - } - /* - * We have authenticated the user using .rhosts or /etc/hosts.equiv, - * and the host using RSA. We accept the authentication. - */ - - verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", - pw->pw_name, cuser, chost); - packet_send_debug("Rhosts with RSA host authentication accepted."); - return 1; -} diff --git a/usr/src/cmd/ssh/sshd/auth-rhosts.c b/usr/src/cmd/ssh/sshd/auth-rhosts.c deleted file mode 100644 index 2326eef8ae..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-rhosts.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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("$OpenBSD: auth-rhosts.c,v 1.28 2002/05/13 21:26:49 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "packet.h" -#include "uidswap.h" -#include "pathnames.h" -#include "log.h" -#include "servconf.h" -#include "canohost.h" -#include "auth.h" - -/* import */ -extern ServerOptions options; - -/* - * This function processes an rhosts-style file (.rhosts, .shosts, or - * /etc/hosts.equiv). This returns true if authentication can be granted - * based on the file, and returns zero otherwise. - */ - -static int -check_rhosts_file(const char *filename, const char *hostname, - const char *ipaddr, const char *client_user, - const char *server_user) -{ - FILE *f; - char buf[1024]; /* Must not be larger than host, user, dummy below. */ - - /* Open the .rhosts file, deny if unreadable */ - f = fopen(filename, "r"); - if (!f) - return 0; - - while (fgets(buf, sizeof(buf), f)) { - /* All three must be at least as big as buf to avoid overflows. */ - char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; - int negated; - - for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) - ; - if (*cp == '#' || *cp == '\n' || !*cp) - continue; - - /* - * NO_PLUS is supported at least on OSF/1. We skip it (we - * don't ever support the plus syntax). - */ - if (strncmp(cp, "NO_PLUS", 7) == 0) - continue; - - /* - * This should be safe because each buffer is as big as the - * whole string, and thus cannot be overwritten. - */ - switch (sscanf(buf, "%1024s %1024s %1024s", - hostbuf, userbuf, dummy)) { - case 0: - auth_debug_add("Found empty line in %.100s.", filename); - continue; - case 1: - /* Host name only. */ - strlcpy(userbuf, server_user, sizeof(userbuf)); - break; - case 2: - /* Got both host and user name. */ - break; - case 3: - auth_debug_add("Found garbage in %.100s.", filename); - continue; - default: - /* Weird... */ - continue; - } - - host = hostbuf; - user = userbuf; - negated = 0; - - /* Process negated host names, or positive netgroups. */ - if (host[0] == '-') { - negated = 1; - host++; - } else if (host[0] == '+') - host++; - - if (user[0] == '-') { - negated = 1; - user++; - } else if (user[0] == '+') - user++; - - /* Check for empty host/user names (particularly '+'). */ - if (!host[0] || !user[0]) { - /* We come here if either was '+' or '-'. */ - auth_debug_add("Ignoring wild host/user names in %.100s.", - filename); - continue; - } - /* Verify that host name matches. */ - if (host[0] == '@') { - if (!innetgr(host + 1, hostname, NULL, NULL) && - !innetgr(host + 1, ipaddr, NULL, NULL)) - continue; - } else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0) - continue; /* Different hostname. */ - - /* Verify that user name matches. */ - if (user[0] == '@') { - if (!innetgr(user + 1, NULL, client_user, NULL)) - continue; - } else if (strcmp(user, client_user) != 0) - continue; /* Different username. */ - - /* Found the user and host. */ - fclose(f); - - /* If the entry was negated, deny access. */ - if (negated) { - auth_debug_add("Matched negative entry in %.100s.", - filename); - return 0; - } - /* Accept authentication. */ - return 1; - } - - /* Authentication using this file denied. */ - fclose(f); - return 0; -} - -/* - * Tries to authenticate the user using the .shosts or .rhosts file. Returns - * true if authentication succeeds. If ignore_rhosts is true, only - * /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored). - */ - -int -auth_rhosts(struct passwd *pw, const char *client_user) -{ - const char *hostname, *ipaddr; - - hostname = get_canonical_hostname(options.verify_reverse_mapping); - ipaddr = get_remote_ipaddr(); - return auth_rhosts2(pw, client_user, hostname, ipaddr); -} - -static int -auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostname, - const char *ipaddr) -{ - char buf[1024]; - struct stat st; - static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; - u_int rhosts_file_index; - - debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s", - client_user, hostname, ipaddr); - - /* no user given */ - if (pw == NULL) - return 0; - - /* Switch to the user's uid. */ - temporarily_use_uid(pw); - /* - * Quick check: if the user has no .shosts or .rhosts files, return - * failure immediately without doing costly lookups from name - * servers. - */ - for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; - rhosts_file_index++) { - /* Check users .rhosts or .shosts. */ - snprintf(buf, sizeof buf, "%.500s/%.100s", - pw->pw_dir, rhosts_files[rhosts_file_index]); - if (stat(buf, &st) >= 0) - break; - } - /* Switch back to privileged uid. */ - restore_uid(); - - /* Deny if The user has no .shosts or .rhosts file and there are no system-wide files. */ - if (!rhosts_files[rhosts_file_index] && - stat(_PATH_RHOSTS_EQUIV, &st) < 0 && - stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) - return 0; - - /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ - if (pw->pw_uid != 0) { - if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, - client_user, pw->pw_name)) { - auth_debug_add("Accepted for %.100s [%.100s] by /etc/hosts.equiv.", - hostname, ipaddr); - return 1; - } - if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr, - client_user, pw->pw_name)) { - auth_debug_add("Accepted for %.100s [%.100s] by %.100s.", - hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV); - return 1; - } - } - /* - * Check that the home directory is owned by root or the user, and is - * not group or world writable. - */ - if (stat(pw->pw_dir, &st) < 0) { - log("Rhosts authentication refused for %.100s: " - "no home directory %.200s", pw->pw_name, pw->pw_dir); - auth_debug_add("Rhosts authentication refused for %.100s: " - "no home directory %.200s", pw->pw_name, pw->pw_dir); - return 0; - } - if (options.strict_modes && - ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || - (st.st_mode & 022) != 0)) { - log("Rhosts authentication refused for %.100s: " - "bad ownership or modes for home directory.", pw->pw_name); - auth_debug_add("Rhosts authentication refused for %.100s: " - "bad ownership or modes for home directory.", pw->pw_name); - return 0; - } - /* Temporarily use the user's uid. */ - temporarily_use_uid(pw); - - /* Check all .rhosts files (currently .shosts and .rhosts). */ - for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; - rhosts_file_index++) { - /* Check users .rhosts or .shosts. */ - snprintf(buf, sizeof buf, "%.500s/%.100s", - pw->pw_dir, rhosts_files[rhosts_file_index]); - if (stat(buf, &st) < 0) - continue; - - /* - * Make sure that the file is either owned by the user or by - * root, and make sure it is not writable by anyone but the - * owner. This is to help avoid novices accidentally - * allowing access to their account by anyone. - */ - if (options.strict_modes && - ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || - (st.st_mode & 022) != 0)) { - log("Rhosts authentication refused for %.100s: bad modes for %.200s", - pw->pw_name, buf); - auth_debug_add("Bad file modes for %.200s", buf); - continue; - } - /* Check if we have been configured to ignore .rhosts and .shosts files. */ - if (options.ignore_rhosts) { - auth_debug_add("Server has been configured to ignore %.100s.", - rhosts_files[rhosts_file_index]); - continue; - } - /* Check if authentication is permitted by the file. */ - if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) { - auth_debug_add("Accepted by %.100s.", - rhosts_files[rhosts_file_index]); - /* Restore the privileged uid. */ - restore_uid(); - auth_debug_add("Accepted host %s ip %s client_user %s server_user %s", - hostname, ipaddr, client_user, pw->pw_name); - return 1; - } - } - - /* Restore the privileged uid. */ - restore_uid(); - return 0; -} - -int -auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, - const char *ipaddr) -{ - int ret; - - auth_debug_reset(); - ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr); - auth_debug_send(); - return ret; -} diff --git a/usr/src/cmd/ssh/sshd/auth-rsa.c b/usr/src/cmd/ssh/sshd/auth-rsa.c deleted file mode 100644 index 3e0e6ea50d..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-rsa.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * 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-rsa.c,v 1.56 2002/06/10 16:53:06 stevesk Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <openssl/rsa.h> -#include <openssl/md5.h> - -#include "rsa.h" -#include "packet.h" -#include "xmalloc.h" -#include "ssh1.h" -#include "mpaux.h" -#include "uidswap.h" -#include "match.h" -#include "auth-options.h" -#include "pathnames.h" -#include "log.h" -#include "servconf.h" -#include "auth.h" -#include "hostfile.h" -#include "ssh.h" - -/* import */ -extern ServerOptions options; - -/* - * Session identifier that is used to bind key exchange and authentication - * responses to a particular session. - */ -extern u_char session_id[16]; - -/* - * The .ssh/authorized_keys file contains public keys, one per line, in the - * following format: - * options bits e n comment - * where bits, e and n are decimal numbers, - * and comment is any string of characters up to newline. The maximum - * length of a line is 8000 characters. See the documentation for a - * description of the options. - */ - -BIGNUM * -auth_rsa_generate_challenge(Key *key) -{ - BIGNUM *challenge; - BN_CTX *ctx; - - if ((challenge = BN_new()) == NULL) - fatal("auth_rsa_generate_challenge: BN_new() failed"); - /* Generate a random challenge. */ - BN_rand(challenge, 256, 0, 0); - if ((ctx = BN_CTX_new()) == NULL) - fatal("auth_rsa_generate_challenge: BN_CTX_new() failed"); - BN_mod(challenge, challenge, key->rsa->n, ctx); - BN_CTX_free(ctx); - - return challenge; -} - -int -auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) -{ - u_char buf[32], mdbuf[16]; - MD5_CTX md; - int len; - - /* don't allow short keys */ - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits", - BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); - return (0); - } - - /* The response is MD5 of decrypted challenge plus session id. */ - len = BN_num_bytes(challenge); - if (len <= 0 || len > 32) - fatal("auth_rsa_verify_response: 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); - - /* Verify that the response is the original challenge. */ - if (memcmp(response, mdbuf, 16) != 0) { - /* Wrong answer. */ - return (0); - } - /* Correct answer. */ - return (1); -} - -/* - * Performs the RSA authentication challenge-response dialog with the client, - * and returns true (non-zero) if the client gave the correct answer to - * our challenge; returns zero if the client gives a wrong answer. - */ - -int -auth_rsa_challenge_dialog(Key *key) -{ - BIGNUM *challenge, *encrypted_challenge; - u_char response[16]; - int i, success; - - if ((encrypted_challenge = BN_new()) == NULL) - fatal("auth_rsa_challenge_dialog: BN_new() failed"); - - challenge = auth_rsa_generate_challenge(key); - - /* Encrypt the challenge with the public key. */ - rsa_public_encrypt(encrypted_challenge, challenge, key->rsa); - - /* Send the encrypted challenge to the client. */ - packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); - packet_put_bignum(encrypted_challenge); - packet_send(); - BN_clear_free(encrypted_challenge); - packet_write_wait(); - - /* Wait for a response. */ - packet_read_expect(SSH_CMSG_AUTH_RSA_RESPONSE); - for (i = 0; i < 16; i++) - response[i] = packet_get_char(); - packet_check_eom(); - - success = auth_rsa_verify_response(key, challenge, response); - BN_clear_free(challenge); - return (success); -} - -/* - * check if there's user key matching client_n, - * return key if login is allowed, NULL otherwise - */ - -int -auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) -{ - char line[8192], *file; - int allowed = 0; - u_int bits; - FILE *f; - u_long linenum = 0; - struct stat st; - Key *key; - - /* Temporarily use the user's uid. */ - temporarily_use_uid(pw); - - /* The authorized keys. */ - file = authorized_keys_file(pw); - debug("trying public RSA key file %s", file); - - /* Fail quietly if file does not exist */ - if (stat(file, &st) < 0) { - /* Restore the privileged uid. */ - restore_uid(); - xfree(file); - return (0); - } - /* Open the file containing the authorized keys. */ - f = fopen(file, "r"); - if (!f) { - /* Restore the privileged uid. */ - restore_uid(); - xfree(file); - return (0); - } - if (options.strict_modes && - secure_filename(f, file, pw, line, sizeof(line)) != 0) { - xfree(file); - fclose(f); - log("Authentication refused: %s", line); - restore_uid(); - return (0); - } - - /* Flag indicating whether the key is allowed. */ - allowed = 0; - - key = key_new(KEY_RSA1); - - /* - * Go though the accepted keys, looking for the current key. If - * found, perform a challenge-response dialog to verify that the - * user really has the corresponding private key. - */ - while (fgets(line, sizeof(line), f)) { - char *cp; - char *options; - - linenum++; - - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '\n' || *cp == '#') - continue; - - /* - * Check if there are options for this key, and if so, - * save their starting address and skip the option part - * for now. If there are no options, set the starting - * address to NULL. - */ - if (*cp < '0' || *cp > '9') { - int quoted = 0; - options = cp; - for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { - if (*cp == '\\' && cp[1] == '"') - cp++; /* Skip both */ - else if (*cp == '"') - quoted = !quoted; - } - } else - options = NULL; - - /* Parse the key from the line. */ - if (hostfile_read_key(&cp, &bits, key) == 0) { - debug("%.100s, line %lu: non ssh1 key syntax", - file, linenum); - continue; - } - /* cp now points to the comment part. */ - - /* Check if the we have found the desired key (identified by its modulus). */ - if (BN_cmp(key->rsa->n, client_n) != 0) - continue; - - /* check the real bits */ - if (bits != BN_num_bits(key->rsa->n)) - log("Warning: %s, line %lu: keysize mismatch: " - "actual %d vs. announced %d.", - file, linenum, BN_num_bits(key->rsa->n), bits); - - /* We have found the desired key. */ - /* - * If our options do not allow this key to be used, - * do not send challenge. - */ - if (!auth_parse_options(pw, options, file, linenum)) - continue; - - /* break out, this key is allowed */ - allowed = 1; - break; - } - - /* Restore the privileged uid. */ - restore_uid(); - - /* Close the file. */ - xfree(file); - fclose(f); - - /* return key if allowed */ - if (allowed && rkey != NULL) - *rkey = key; - else - key_free(key); - return (allowed); -} - -/* - * Performs the RSA authentication dialog with the client. This returns - * 0 if the client could not be authenticated, and 1 if authentication was - * successful. This may exit if there is a serious protocol violation. - */ -int -auth_rsa(struct passwd *pw, BIGNUM *client_n) -{ - Key *key; - char *fp; - - /* no user given */ - if (pw == NULL) - return 0; - - if (!auth_rsa_key_allowed(pw, client_n, &key)) { - auth_clear_options(); - return (0); - } - - /* Perform the challenge-response dialog for this key. */ - if (!auth_rsa_challenge_dialog(key)) { - /* Wrong response. */ - verbose("Wrong response to RSA authentication challenge."); - packet_send_debug("Wrong response to RSA authentication challenge."); - /* - * Break out of the loop. Otherwise we might send - * another challenge and break the protocol. - */ - key_free(key); - return (0); - } - /* - * Correct response. The client has been successfully - * authenticated. Note that we have not yet processed the - * options; this will be reset if the options cause the - * authentication to be rejected. - */ - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); - verbose("Found matching %s key: %s", - key_type(key), fp); - xfree(fp); - key_free(key); - - packet_send_debug("RSA authentication accepted."); - return (1); -} diff --git a/usr/src/cmd/ssh/sshd/auth-sia.c b/usr/src/cmd/ssh/sshd/auth-sia.c deleted file mode 100644 index 6afa02cf75..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-sia.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2002 Chris Adams. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" - -#ifdef HAVE_OSF_SIA -#include "ssh.h" -#include "auth.h" -#include "auth-sia.h" -#include "log.h" -#include "servconf.h" -#include "canohost.h" - -#include <sia.h> -#include <siad.h> -#include <pwd.h> -#include <signal.h> -#include <setjmp.h> -#include <sys/resource.h> -#include <unistd.h> -#include <string.h> - -extern ServerOptions options; -extern int saved_argc; -extern char **saved_argv; - -extern int errno; - -int -auth_sia_password(Authctxt *authctxt, char *pass) -{ - int ret; - SIAENTITY *ent = NULL; - const char *host; - char *user = authctxt->user; - - host = get_canonical_hostname(options.verify_reverse_mapping); - - if (!user || !pass || pass[0] == '\0') - return(0); - - if (sia_ses_init(&ent, saved_argc, saved_argv, host, user, NULL, 0, - NULL) != SIASUCCESS) - return(0); - - if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) { - error("Couldn't authenticate %s from %s", user, host); - if (ret & SIASTOP) - sia_ses_release(&ent); - return(0); - } - - sia_ses_release(&ent); - - return(1); -} - -void -session_setup_sia(char *user, char *tty) -{ - struct passwd *pw; - SIAENTITY *ent = NULL; - const char *host; - - host = get_canonical_hostname (options.verify_reverse_mapping); - - if (sia_ses_init(&ent, saved_argc, saved_argv, host, user, tty, 0, - NULL) != SIASUCCESS) { - fatal("sia_ses_init failed"); - } - - if ((pw = getpwnam(user)) == NULL) { - sia_ses_release(&ent); - fatal("getpwnam: no user: %s", user); - } - if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) { - sia_ses_release(&ent); - fatal("sia_make_entity_pwd failed"); - } - - ent->authtype = SIA_A_NONE; - if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS) { - fatal("Couldn't establish session for %s from %s", user, - host); - } - - if (setpriority(PRIO_PROCESS, 0, 0) == -1) { - sia_ses_release(&ent); - fatal("setpriority: %s", strerror (errno)); - } - - if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS) { - fatal("Couldn't launch session for %s from %s", user, host); - } - - sia_ses_release(&ent); - - if (setreuid(geteuid(), geteuid()) < 0) { - fatal("setreuid: %s", strerror(errno)); - } -} - -#endif /* HAVE_OSF_SIA */ - -#pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/cmd/ssh/sshd/auth-skey.c b/usr/src/cmd/ssh/sshd/auth-skey.c deleted file mode 100644 index 436f66aed8..0000000000 --- a/usr/src/cmd/ssh/sshd/auth-skey.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "includes.h" -RCSID("$OpenBSD: auth-skey.c,v 1.20 2002/06/30 21:59:45 deraadt Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef SKEY - -#include <skey.h> - -#include "xmalloc.h" -#include "auth.h" - -static void * -skey_init_ctx(Authctxt *authctxt) -{ - return authctxt; -} - -int -skey_query(void *ctx, char **name, char **infotxt, - u_int* numprompts, char ***prompts, u_int **echo_on) -{ - Authctxt *authctxt = ctx; - char challenge[1024], *p; - int len; - struct skey skey; - - if (skeychallenge(&skey, authctxt->user, challenge) == -1) - return -1; - - *name = xstrdup(""); - *infotxt = xstrdup(""); - *numprompts = 1; - *prompts = xmalloc(*numprompts * sizeof(char *)); - *echo_on = xmalloc(*numprompts * sizeof(u_int)); - (*echo_on)[0] = 0; - - len = strlen(challenge) + strlen(SKEY_PROMPT) + 1; - p = xmalloc(len); - strlcpy(p, challenge, len); - strlcat(p, SKEY_PROMPT, len); - (*prompts)[0] = p; - - return 0; -} - -int -skey_respond(void *ctx, u_int numresponses, char **responses) -{ - Authctxt *authctxt = ctx; - - if (authctxt->valid && - numresponses == 1 && - skey_haskey(authctxt->pw->pw_name) == 0 && - skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1) - return 0; - return -1; -} - -static void -skey_free_ctx(void *ctx) -{ - /* we don't have a special context */ -} - -KbdintDevice skey_device = { - "skey", - skey_init_ctx, - skey_query, - skey_respond, - skey_free_ctx -}; - -KbdintDevice mm_skey_device = { - "skey", - skey_init_ctx, - mm_skey_query, - mm_skey_respond, - skey_free_ctx -}; -#endif /* SKEY */ diff --git a/usr/src/cmd/ssh/sshd/auth.c b/usr/src/cmd/ssh/sshd/auth.c deleted file mode 100644 index 64e6959ecf..0000000000 --- a/usr/src/cmd/ssh/sshd/auth.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.45 2002/09/20 18:41:29 stevesk Exp $"); - -#ifdef HAVE_LOGIN_H -#include <login.h> -#endif -#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) -#include <shadow.h> -#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ - -#ifdef HAVE_LIBGEN_H -#include <libgen.h> -#endif - -#include "xmalloc.h" -#include "match.h" -#include "groupaccess.h" -#include "log.h" -#include "buffer.h" -#include "servconf.h" -#include "auth.h" -#include "auth-options.h" -#include "canohost.h" -#include "bufaux.h" -#include "uidswap.h" -#include "tildexpand.h" -#include "misc.h" -#include "bufaux.h" -#include "packet.h" -#include "channels.h" -#include "session.h" - -#ifdef HAVE_BSM -#include "bsmaudit.h" -#include <bsm/adt.h> -#endif /* HAVE_BSM */ - -/* import */ -extern ServerOptions options; - -/* Debugging messages */ -Buffer auth_debug; -int auth_debug_init; - -/* - * Check if the user is allowed to log in via ssh. If user is listed - * in DenyUsers or one of user's groups is listed in DenyGroups, false - * will be returned. If AllowUsers isn't empty and user isn't listed - * there, or if AllowGroups isn't empty and one of user's groups isn't - * listed there, false will be returned. - * If the user's shell is not executable, false will be returned. - * Otherwise true is returned. - */ -int -allowed_user(struct passwd * pw) -{ - struct stat st; - const char *hostname = NULL, *ipaddr = NULL; - char *shell; - int i; -#ifdef WITH_AIXAUTHENTICATE - char *loginmsg; -#endif /* WITH_AIXAUTHENTICATE */ -#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ - !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) - struct spwd *spw; - - /* Shouldn't be called if pw is NULL, but better safe than sorry... */ - if (!pw || !pw->pw_name) - return 0; - -#define DAY (24L * 60 * 60) /* 1 day in seconds */ - spw = getspnam(pw->pw_name); - if (spw != NULL) { - time_t today = time(NULL) / DAY; - debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" - " sp_max %d", (int)today, (int)spw->sp_expire, - (int)spw->sp_lstchg, (int)spw->sp_max); - - /* - * We assume account and password expiration occurs the - * day after the day specified. - */ - if (spw->sp_expire != -1 && today > spw->sp_expire) { - log("Account %.100s has expired", pw->pw_name); - return 0; - } - - if (spw->sp_lstchg == 0) { - log("User %.100s password has expired (root forced)", - pw->pw_name); - return 0; - } - - if (spw->sp_max != -1 && - today > spw->sp_lstchg + spw->sp_max) { - log("User %.100s password has expired (password aged)", - pw->pw_name); - return 0; - } - } -#else - /* Shouldn't be called if pw is NULL, but better safe than sorry... */ - if (!pw || !pw->pw_name) - return 0; -#endif - - /* - * 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; - - /* deny if shell does not exists or is not executable */ - if (stat(shell, &st) != 0) { - log("User %.100s not allowed because shell %.100s does not exist", - pw->pw_name, shell); - return 0; - } - if (S_ISREG(st.st_mode) == 0 || - (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { - log("User %.100s not allowed because shell %.100s is not executable", - pw->pw_name, shell); - return 0; - } - - if (options.num_deny_users > 0 || options.num_allow_users > 0) { - hostname = get_canonical_hostname(options.verify_reverse_mapping); - ipaddr = get_remote_ipaddr(); - } - - /* Return false if user is listed in DenyUsers */ - if (options.num_deny_users > 0) { - for (i = 0; i < options.num_deny_users; i++) - if (match_user(pw->pw_name, hostname, ipaddr, - options.deny_users[i])) { - log("User %.100s not allowed because listed in DenyUsers", - pw->pw_name); - return 0; - } - } - /* Return false if AllowUsers isn't empty and user isn't listed there */ - if (options.num_allow_users > 0) { - for (i = 0; i < options.num_allow_users; i++) - if (match_user(pw->pw_name, hostname, ipaddr, - options.allow_users[i])) - break; - /* i < options.num_allow_users iff we break for loop */ - if (i >= options.num_allow_users) { - log("User %.100s not allowed because not listed in AllowUsers", - pw->pw_name); - return 0; - } - } - if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { - /* Get the user's group access list (primary and supplementary) */ - if (ga_init(pw->pw_name, pw->pw_gid) == 0) { - log("User %.100s not allowed because not in any group", - pw->pw_name); - return 0; - } - - /* Return false if one of user's groups is listed in DenyGroups */ - if (options.num_deny_groups > 0) - if (ga_match(options.deny_groups, - options.num_deny_groups)) { - ga_free(); - log("User %.100s not allowed because a group is listed in DenyGroups", - pw->pw_name); - return 0; - } - /* - * Return false if AllowGroups isn't empty and one of user's groups - * isn't listed there - */ - if (options.num_allow_groups > 0) - if (!ga_match(options.allow_groups, - options.num_allow_groups)) { - ga_free(); - log("User %.100s not allowed because none of user's groups are listed in AllowGroups", - pw->pw_name); - return 0; - } - ga_free(); - } - -#ifdef WITH_AIXAUTHENTICATE - if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { - if (loginmsg && *loginmsg) { - /* Remove embedded newlines (if any) */ - char *p; - for (p = loginmsg; *p; p++) { - if (*p == '\n') - *p = ' '; - } - /* Remove trailing newline */ - *--p = '\0'; - log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); - } - return 0; - } -#endif /* WITH_AIXAUTHENTICATE */ - - /* We found no reason not to let this user try to log on... */ - return 1; -} - -Authctxt * -authctxt_new(void) -{ - Authctxt *authctxt = xmalloc(sizeof(*authctxt)); - memset(authctxt, 0, sizeof(*authctxt)); - return authctxt; -} - -void -auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) -{ - void (*authlog) (const char *fmt,...) = verbose; - char *authmsg, *user_str; - - if (authctxt == NULL) - fatal("%s: INTERNAL ERROR", __func__); - - /* Raise logging level */ - if (authenticated == 1 || !authctxt->valid) - authlog = log; - else if (authctxt->failures >= AUTH_FAIL_LOG || - authctxt->attempt >= options.max_auth_tries_log || - authctxt->init_attempt >= options.max_init_auth_tries_log) - authlog = notice; - - if (authctxt->method) { - authmsg = "Failed"; - if (authctxt->method->postponed) - authmsg = "Postponed"; /* shouldn't happen */ - if (authctxt->method->abandoned) - authmsg = "Abandoned"; - if (authctxt->method->authenticated) { - if (userauth_check_partial_failure(authctxt)) - authmsg = "Partially accepted"; - else - authmsg = "Accepted"; - } - else - authmsg = "Failed"; - } - else { - authmsg = authenticated ? "Accepted" : "Failed"; - } - - if (authctxt->user == NULL || *authctxt->user == '\0') - user_str = "<implicit>"; - else if (!authctxt->valid) - user_str = "<invalid username>"; - else - user_str = authctxt->user; - - authlog("%s %s for %s from %.200s port %d%s", - authmsg, - (method != NULL) ? method : "<unknown authentication method>", - user_str, - get_remote_ipaddr(), - get_remote_port(), - info); - -#ifdef WITH_AIXAUTHENTICATE - if (authenticated == 0 && strcmp(method, "password") == 0) - loginfailed(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh"); -#endif /* WITH_AIXAUTHENTICATE */ - -} - -#ifdef HAVE_BSM -void -audit_failed_login_cleanup(void *ctxt) -{ - Authctxt *authctxt = (Authctxt *)ctxt; - adt_session_data_t *ah; - - /* - * This table lists the different variable combinations evaluated and - * what the resulting PAM return value is. As the table shows - * authctxt and authctxt->valid need to be checked before either of - * the authctxt->pam* variables. - * - * authctxt-> authctxt-> - * authctxt valid authctxt->pam pam_retval PAM rval - * -------- ---------- ------------- ------------ -------- - * NULL ANY ANY ANY PAM_ABORT - * OK zero (0) ANY ANY PAM_USER_UNKNOWN - * OK one (1) NULL PAM_SUCCESS PAM_PERM_DENIED - * OK one (1) NULL !PAM_SUCCESS authctxt-> - * pam_retval - * OK one (1) VALID ANY authctxt-> - * pam_retval (+) - * (+) If not set then default to PAM_PERM_DENIED - */ - - if (authctxt == NULL) { - /* Internal error */ - audit_sshd_login_failure(&ah, PAM_ABORT, NULL); - return; - } - - if (authctxt->valid == 0) { - audit_sshd_login_failure(&ah, PAM_USER_UNKNOWN, NULL); - } else if (authctxt->pam == NULL) { - if (authctxt->pam_retval == PAM_SUCCESS) { - audit_sshd_login_failure(&ah, PAM_PERM_DENIED, - authctxt->user); - } else { - audit_sshd_login_failure(&ah, authctxt->pam_retval, - authctxt->user); - } - } else { - audit_sshd_login_failure(&ah, AUTHPAM_ERROR(authctxt, - PAM_PERM_DENIED), authctxt->user); - } -} -#endif /* HAVE_BSM */ - -/* - * Check whether root logins are disallowed. - */ -int -auth_root_allowed(char *method) -{ - switch (options.permit_root_login) { - case PERMIT_YES: - return 1; - break; - case PERMIT_NO_PASSWD: - if (strcmp(method, "password") != 0 && - strcmp(method, "keyboard-interactive") != 0) - return 1; - break; - case PERMIT_FORCED_ONLY: - if (forced_command) { - log("Root login accepted for forced command."); - return 1; - } - break; - } - log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); - return 0; -} - - -/* - * Given a template and a passwd structure, build a filename - * by substituting % tokenised options. Currently, %% becomes '%', - * %h becomes the home directory and %u the username. - * - * This returns a buffer allocated by xmalloc. - */ -char * -expand_filename(const char *filename, struct passwd *pw) -{ - Buffer buffer; - char *file; - const char *cp; - - if (pw == 0) - return NULL; /* shouldn't happen */ - /* - * Build the filename string in the buffer by making the appropriate - * substitutions to the given file name. - */ - buffer_init(&buffer); - for (cp = filename; *cp; cp++) { - if (cp[0] == '%' && cp[1] == '%') { - buffer_append(&buffer, "%", 1); - cp++; - continue; - } - if (cp[0] == '%' && cp[1] == 'h') { - buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir)); - cp++; - continue; - } - if (cp[0] == '%' && cp[1] == 'u') { - buffer_append(&buffer, pw->pw_name, - strlen(pw->pw_name)); - cp++; - continue; - } - buffer_append(&buffer, cp, 1); - } - buffer_append(&buffer, "\0", 1); - - /* - * Ensure that filename starts anchored. If not, be backward - * compatible and prepend the '%h/' - */ - file = xmalloc(MAXPATHLEN); - cp = buffer_ptr(&buffer); - if (*cp != '/') - snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp); - else - strlcpy(file, cp, MAXPATHLEN); - - buffer_free(&buffer); - return file; -} - -char * -authorized_keys_file(struct passwd *pw) -{ - return expand_filename(options.authorized_keys_file, pw); -} - -char * -authorized_keys_file2(struct passwd *pw) -{ - return expand_filename(options.authorized_keys_file2, pw); -} - -/* return ok if key exists in sysfile or userfile */ -HostStatus -check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, - const char *sysfile, const char *userfile) -{ - Key *found; - char *user_hostfile; - struct stat st; - HostStatus host_status; - - /* Check if we know the host and its host key. */ - found = key_new(key->type); - host_status = check_host_in_hostfile(sysfile, host, key, found, NULL); - - if (host_status != HOST_OK && userfile != NULL) { - user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); - if (options.strict_modes && - (stat(user_hostfile, &st) == 0) && - ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || - (st.st_mode & 022) != 0)) { - log("Authentication refused for %.100s: " - "bad owner or modes for %.200s", - pw->pw_name, user_hostfile); - } else { - temporarily_use_uid(pw); - host_status = check_host_in_hostfile(user_hostfile, - host, key, found, NULL); - restore_uid(); - } - xfree(user_hostfile); - } - key_free(found); - - debug2("check_key_in_hostfiles: key %s for %s", host_status == HOST_OK ? - "ok" : "not found", host); - return host_status; -} - - -/* - * Check a given file for security. This is defined as all components - * of the path to the file must be owned by either the owner of - * of the file or root and no directories must be group or world writable. - * - * XXX Should any specific check be done for sym links ? - * - * Takes an open file descriptor, the file name, a uid and and - * error buffer plus max size as arguments. - * - * Returns 0 on success and -1 on failure - */ -int -secure_filename(FILE *f, const char *file, struct passwd *pw, - char *err, size_t errlen) -{ - uid_t uid; - char buf[MAXPATHLEN], homedir[MAXPATHLEN]; - char *cp; - int comparehome = 0; - struct stat st; - - if (pw == NULL) - return 0; - - uid = pw->pw_uid; - - if (realpath(file, buf) == NULL) { - snprintf(err, errlen, "realpath %s failed: %s", file, - strerror(errno)); - return -1; - } - - /* - * A user is not required to have all the files that are subject to - * the strict mode checking in his/her home directory. If the - * directory is not present at the moment, which might be the case if - * the directory is not mounted until the user is authenticated, do - * not perform the home directory check below. - */ - if (realpath(pw->pw_dir, homedir) != NULL) - comparehome = 1; - - /* check the open file to avoid races */ - if (fstat(fileno(f), &st) < 0 || - (st.st_uid != 0 && st.st_uid != uid) || - (st.st_mode & 022) != 0) { - snprintf(err, errlen, "bad ownership or modes for file %s", - buf); - return -1; - } - - /* for each component of the canonical path, walking upwards */ - for (;;) { - if ((cp = dirname(buf)) == NULL) { - snprintf(err, errlen, "dirname() failed"); - return -1; - } - strlcpy(buf, cp, sizeof(buf)); - - debug3("secure_filename: checking '%s'", buf); - if (stat(buf, &st) < 0 || - (st.st_uid != 0 && st.st_uid != uid) || - (st.st_mode & 022) != 0) { - snprintf(err, errlen, - "bad ownership or modes for directory %s", buf); - return -1; - } - - /* If we passed the homedir then we can stop. */ - if (comparehome && strcmp(homedir, buf) == 0) { - debug3("secure_filename: terminating check at '%s'", - buf); - break; - } - /* - * dirname should always complete with a "/" path, - * but we can be paranoid and check for "." too - */ - if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) - break; - } - return 0; -} - -struct passwd * -getpwnamallow(const char *user) -{ -#ifdef HAVE_LOGIN_CAP - extern login_cap_t *lc; -#ifdef BSD_AUTH - auth_session_t *as; -#endif -#endif - struct passwd *pw; - - if (user == NULL || *user == '\0') - return (NULL); /* implicit user, will be set later */ - - parse_server_match_config(&options, user, - get_canonical_hostname(options.verify_reverse_mapping), get_remote_ipaddr()); - - pw = getpwnam(user); - if (pw == NULL) { - log("Illegal user %.100s from %.100s", - user, get_remote_ipaddr()); - return (NULL); - } - if (!allowed_user(pw)) - return (NULL); -#ifdef HAVE_LOGIN_CAP - if ((lc = login_getclass(pw->pw_class)) == NULL) { - debug("unable to get login class: %s", user); - return (NULL); - } -#ifdef BSD_AUTH - if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || - auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { - debug("Approval failure for %s", user); - pw = NULL; - } - if (as != NULL) - auth_close(as); -#endif -#endif - if (pw != NULL) - return (pwcopy(pw)); - return (NULL); -} - - -/* - * The fatal_cleanup method to kill the hook. Since hook has been put into - * new process group all descendants will be killed as well. - */ -static void -kill_hook(void *arg) -{ - pid_t pid; - - pid = *(pid_t*)arg; - debug("killing hook and all it's children, process group: %ld", pid); - xfree(arg); - (void)killpg(pid, SIGTERM); -} - -/* - * Runs the PreUserauthHook. - * Returns -1 on execution error or the exit code of the hook if execution is - * successful. - */ -int -run_auth_hook(const char *path, const char *user, const char *method) -{ - struct stat st; - int i, status, ret = 1; - u_int envsize, argsize; - char buf[256]; - char **env, **args; - pid_t pid, *ppid; - - if (path == NULL || user == NULL || method == NULL) { - return (-1); - } - - /* Initialize the environment/arguments for the hook. */ - envsize = 4; /* 3 env vars + EndOfList marker */ - argsize = 4; /* 2 args + exe name + EndOfList marker */ - env = xmalloc(envsize * sizeof (char *)); - args = xmalloc(argsize * sizeof (char *)); - env[0] = NULL; - - /* we use the SSH env handling scheme */ - child_set_env_silent(&env, &envsize, "PATH", "/usr/bin:/bin"); - child_set_env_silent(&env, &envsize, "IFS", " \t\n"); - - (void) snprintf(buf, sizeof (buf), "%.50s %d %.50s %d", - get_remote_ipaddr(), get_remote_port(), - get_local_ipaddr(packet_get_connection_in()), get_local_port()); - child_set_env_silent(&env, &envsize, "SSH_CONNECTION", buf); - - args[0] = xstrdup(path); - args[1] = xstrdup(method); - args[2] = xstrdup(user); - args[3] = NULL; - - /* - * sanity checks - * note: the checks do not make sure that the file checked is actually - * the same which is executed. However, in this case it shouldn't be a - * major issue since the hook is rather static and the worst case would - * be an uncorrect message in the log or a hook is run even though the - * permissions are not right. - */ - - /* check if script does exist */ - if (stat(path, &st) < 0) { - log("Error executing PreUserauthHook \"%s\": %s", path, - strerror(errno)); - goto cleanup; - } - - /* Check correct permissions for script (uid of SSHD, mode 500) */ - if (st.st_uid != getuid() || ((st.st_mode & 0777) != 0500)) { - log("PreUserauthHook has invalid permissions (should be 500, is" - " %o) or ownership (should be %d, is %d)", - (uint) st.st_mode & 0777, getuid(), st.st_uid); - goto cleanup; - } - - if ((pid = fork()) == 0) { - /* - * We put the hook and all its (possible) descendants into - * a new process group so that in case of a hanging hook - * we can wipe out the whole "family". - */ - if (setpgid(0, 0) != 0) { - log("setpgid: %s", strerror(errno)); - _exit(255); - } - (void) execve(path, args, env); - /* child is gone so we shouldn't get here */ - log("Error executing PreUserauthHook \"%s\": %s", path, - strerror(errno)); - _exit(255); - } else if (pid == -1) { - log("Error executing PreUserauthHook \"%s\": %s", path, - strerror(errno)); - goto cleanup; - } - - /* make preparations to kill hook if it is hanging */ - ppid = xmalloc(sizeof (pid_t)); - *ppid = pid; - fatal_add_cleanup((void (*)(void *))kill_hook, (void *) ppid); - - if (waitpid(pid, &status, 0) == -1) { - log("Error executing PreUserauthHook \"%s\": %s", path, - strerror(errno)); - goto cleanup; - } - - ret = WEXITSTATUS(status); - - if (ret == 255) { - ret = -1; /* execve() failed, error msg already logged */ - } else if (ret != 0) { - log("PreUserauthHook \"%s\" failed with exit code %d", - path, ret); - } else { - debug("PreUserauthHook \"%s\" finished successfully", path); - } - -cleanup: - for (i = 0; args[i] != NULL; i++) { - xfree(args[i]); - } - for (i = 0; env[i] != NULL; i++) { - xfree(env[i]); - } - xfree(args); - xfree(env); - - fatal_remove_cleanup((void (*)(void *))kill_hook, (void *) ppid); - - return (ret); -} - -void -auth_debug_add(const char *fmt,...) -{ - char buf[1024]; - va_list args; - - if (!auth_debug_init) - return; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - buffer_put_cstring(&auth_debug, buf); -} - -void -auth_debug_send(void) -{ - char *msg; - - if (!auth_debug_init) - return; - while (buffer_len(&auth_debug)) { - msg = buffer_get_string(&auth_debug, NULL); - packet_send_debug("%s", msg); - xfree(msg); - } -} - -void -auth_debug_reset(void) -{ - if (auth_debug_init) - buffer_clear(&auth_debug); - else { - buffer_init(&auth_debug); - auth_debug_init = 1; - } -} diff --git a/usr/src/cmd/ssh/sshd/auth1.c b/usr/src/cmd/ssh/sshd/auth1.c deleted file mode 100644 index e77a021393..0000000000 --- a/usr/src/cmd/ssh/sshd/auth1.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * 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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.44 2002/09/26 11:38:43 markus Exp $"); - -#include "xmalloc.h" -#include "rsa.h" -#include "ssh1.h" -#include "packet.h" -#include "buffer.h" -#include "mpaux.h" -#include "log.h" -#include "servconf.h" -#include "compat.h" -#include "auth.h" -#include "channels.h" -#include "session.h" -#include "uidswap.h" - -#ifdef HAVE_BSM -#include "bsmaudit.h" -extern adt_session_data_t *ah; -#endif /* HAVE_BSM */ - -/* import */ -extern ServerOptions options; - -/* - * convert ssh auth msg type into description - */ -static char * -get_authname(int type) -{ - static char buf[1024]; - switch (type) { - case SSH_CMSG_AUTH_PASSWORD: - return "password"; - case SSH_CMSG_AUTH_RSA: - return "rsa"; - case SSH_CMSG_AUTH_RHOSTS_RSA: - return "rhosts-rsa"; - case SSH_CMSG_AUTH_RHOSTS: - return "rhosts"; - case SSH_CMSG_AUTH_TIS: - case SSH_CMSG_AUTH_TIS_RESPONSE: - return "challenge-response"; -#if defined(KRB4) || defined(KRB5) - case SSH_CMSG_AUTH_KERBEROS: - return "kerberos"; -#endif - } - snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); - return buf; -} - -/* - * read packets, try to authenticate the user and - * return only if authentication is successful - */ -static void -do_authloop(Authctxt *authctxt) -{ - int authenticated = 0; - u_int bits; - Key *client_host_key; - BIGNUM *n; - char *client_user, *password; - char info[1024]; - u_int dlen; - u_int ulen; - int type = 0; - struct passwd *pw = authctxt->pw; - - debug("Attempting authentication for %s%.100s.", - authctxt->valid ? "" : "illegal user ", authctxt->user); - - /* If the user has no password, accept authentication immediately. */ - if (options.password_authentication && -#if defined(KRB4) || defined(KRB5) - (!options.kerberos_authentication || options.kerberos_or_local_passwd) && -#endif - auth_password(authctxt, "")) { - auth_log(authctxt, 1, "without authentication", ""); - return; - } - - /* Indicate that authentication is needed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - - client_user = NULL; - - for ( ;; ) { - /* default to fail */ - authenticated = 0; - - info[0] = '\0'; - - /* Get a packet from the client. */ - authctxt->v1_auth_type = type = packet_read(); - authctxt->v1_auth_name = get_authname(type); - - authctxt->attempt++; - - /* Process the packet. */ - switch (type) { - -#if defined(KRB4) || defined(KRB5) - case SSH_CMSG_AUTH_KERBEROS: - if (!options.kerberos_authentication) { - verbose("Kerberos authentication disabled."); - } else { - char *kdata = packet_get_string(&dlen); - packet_check_eom(); - - if (kdata[0] == 4) { /* KRB_PROT_VERSION */ -#ifdef KRB4 - KTEXT_ST tkt, reply; - tkt.length = dlen; - if (tkt.length < MAX_KTXT_LEN) - memcpy(tkt.dat, kdata, tkt.length); - - if (auth_krb4(authctxt, &tkt, - &client_user, &reply)) { - authenticated = 1; - snprintf(info, sizeof(info), - " tktuser %.100s", - client_user); - - packet_start( - SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) - reply.dat, reply.length); - packet_send(); - packet_write_wait(); - } -#endif /* KRB4 */ - } else { -#ifdef KRB5 - krb5_data tkt, reply; - tkt.length = dlen; - tkt.data = kdata; - - if (auth_krb5(authctxt, &tkt, - &client_user, &reply)) { - authenticated = 1; - snprintf(info, sizeof(info), - " tktuser %.100s", - client_user); - - /* Send response to client */ - packet_start( - SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) - reply.data, reply.length); - packet_send(); - packet_write_wait(); - - if (reply.length) - xfree(reply.data); - } -#endif /* KRB5 */ - } - xfree(kdata); - } - break; -#endif /* KRB4 || KRB5 */ - -#if defined(AFS) || defined(KRB5) - /* XXX - punt on backward compatibility here. */ - case SSH_CMSG_HAVE_KERBEROS_TGT: - packet_send_debug("Kerberos TGT passing disabled before authentication."); - break; -#ifdef AFS - case SSH_CMSG_HAVE_AFS_TOKEN: - packet_send_debug("AFS token passing disabled before authentication."); - break; -#endif /* AFS */ -#endif /* AFS || KRB5 */ - - case SSH_CMSG_AUTH_RHOSTS: - if (!options.rhosts_authentication) { - verbose("Rhosts authentication disabled."); - break; - } - /* - * Get client user name. Note that we just have to - * trust the client; this is one reason why rhosts - * authentication is insecure. (Another is - * IP-spoofing on a local network.) - */ - client_user = packet_get_string(&ulen); - packet_check_eom(); - - /* Try to authenticate using /etc/hosts.equiv and .rhosts. */ - authenticated = auth_rhosts(pw, client_user); - - snprintf(info, sizeof info, " ruser %.100s", client_user); - break; - - case SSH_CMSG_AUTH_RHOSTS_RSA: - if (!options.rhosts_rsa_authentication) { - verbose("Rhosts with RSA authentication disabled."); - break; - } - /* - * Get client user name. Note that we just have to - * trust the client; root on the client machine can - * claim to be any user. - */ - client_user = packet_get_string(&ulen); - - /* Get the client host key. */ - client_host_key = key_new(KEY_RSA1); - bits = packet_get_int(); - packet_get_bignum(client_host_key->rsa->e); - packet_get_bignum(client_host_key->rsa->n); - - if (bits != BN_num_bits(client_host_key->rsa->n)) - verbose("Warning: keysize mismatch for client_host_key: " - "actual %d, announced %d", - BN_num_bits(client_host_key->rsa->n), bits); - packet_check_eom(); - - authenticated = auth_rhosts_rsa(pw, client_user, - client_host_key); - key_free(client_host_key); - - snprintf(info, sizeof info, " ruser %.100s", client_user); - break; - - case SSH_CMSG_AUTH_RSA: - if (!options.rsa_authentication) { - verbose("RSA authentication disabled."); - break; - } - /* RSA authentication requested. */ - if ((n = BN_new()) == NULL) - fatal("do_authloop: BN_new failed"); - packet_get_bignum(n); - packet_check_eom(); - authenticated = auth_rsa(pw, n); - BN_clear_free(n); - break; - - case SSH_CMSG_AUTH_PASSWORD: - authctxt->init_attempt++; - - if (!options.password_authentication) { - verbose("Password authentication disabled."); - break; - } - /* - * Read user password. It is in plain text, but was - * transmitted over the encrypted channel so it is - * not visible to an outside observer. - */ - password = packet_get_string(&dlen); - packet_check_eom(); - - /* Try authentication with the password. */ - if (authctxt->init_failures < - options.max_init_auth_tries) - authenticated = - auth_password(authctxt, password); - - memset(password, 0, strlen(password)); - xfree(password); - break; - - case SSH_CMSG_AUTH_TIS: - debug("rcvd SSH_CMSG_AUTH_TIS"); - if (options.challenge_response_authentication == 1) { - char *challenge = get_challenge(authctxt); - if (challenge != NULL) { - debug("sending challenge '%s'", challenge); - packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); - packet_put_cstring(challenge); - xfree(challenge); - packet_send(); - packet_write_wait(); - continue; - } - } - break; - case SSH_CMSG_AUTH_TIS_RESPONSE: - debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); - if (options.challenge_response_authentication == 1) { - char *response = packet_get_string(&dlen); - debug("got response '%s'", response); - packet_check_eom(); - authenticated = verify_response(authctxt, response); - memset(response, 'r', dlen); - xfree(response); - } - break; - - default: - /* - * Any unknown messages will be ignored (and failure - * returned) during authentication. - */ - log("Unknown message during authentication: type %d", type); - break; - } -#ifdef BSD_AUTH - if (authctxt->as) { - auth_close(authctxt->as); - authctxt->as = NULL; - } -#endif - if (!authctxt->valid && authenticated) { - authenticated = 0; - log("Ignoring authenticated invalid user %s", - authctxt->user); - } - -#ifdef _UNICOS - if (type == SSH_CMSG_AUTH_PASSWORD && !authenticated) - cray_login_failure(authctxt->user, IA_UDBERR); - if (authenticated && cray_access_denied(authctxt->user)) { - authenticated = 0; - fatal("Access denied for user %s.",authctxt->user); - } -#endif /* _UNICOS */ - -#ifdef HAVE_CYGWIN - if (authenticated && - !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) { - packet_disconnect("Authentication rejected for uid %d.", - pw == NULL ? -1 : pw->pw_uid); - authenticated = 0; - } -#else - /* Special handling for root */ - if (authenticated && authctxt->pw->pw_uid == 0 && - !auth_root_allowed(get_authname(type))) - authenticated = 0; -#endif -#ifdef USE_PAM - if (authenticated && type != SSH_CMSG_AUTH_PASSWORD) - authenticated = do_pam_non_initial_userauth(authctxt); - else if (authenticated && !AUTHPAM_DONE(authctxt)) - authenticated = 0; - - if (!authenticated) - authctxt->pam_retval = AUTHPAM_ERROR(authctxt, - PAM_PERM_DENIED); -#endif /* USE_PAM */ - - /* Log before sending the reply */ - auth_log(authctxt, authenticated, get_authname(type), info); - - if (client_user != NULL) { - xfree(client_user); - client_user = NULL; - } - - if (authenticated) - return; - - if (type == SSH_CMSG_AUTH_PASSWORD) - authctxt->init_failures++; - - if (authctxt->failures++ > options.max_auth_tries) { -#ifdef HAVE_BSM - fatal_remove_cleanup(audit_failed_login_cleanup, - authctxt); - audit_sshd_login_failure(&ah, PAM_MAXTRIES, - authctxt->user); -#endif /* HAVE_BSM */ - packet_disconnect(AUTH_FAIL_MSG, authctxt->user); - } - - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - } -} - -/* - * Performs authentication of an incoming connection. Session key has already - * been exchanged and encryption is enabled. - */ -Authctxt * -do_authentication(void) -{ - Authctxt *authctxt; - u_int ulen; - char *user, *style = NULL; - - /* Get the name of the user that we wish to log in as. */ - packet_read_expect(SSH_CMSG_USER); - - /* Get the user name. */ - user = packet_get_string(&ulen); - packet_check_eom(); - - if ((style = strchr(user, ':')) != NULL) - *style++ = '\0'; - -#ifdef KRB5 - /* XXX - SSH.com Kerberos v5 braindeath. */ - if ((datafellows & SSH_BUG_K5USER) && - options.kerberos_authentication) { - char *p; - if ((p = strchr(user, '@')) != NULL) - *p = '\0'; - } -#endif - - authctxt = authctxt_new(); - authctxt->user = user; - authctxt->style = style; - -#ifdef HAVE_BSM - fatal_add_cleanup(audit_failed_login_cleanup, authctxt); -#endif /* HAVE_BSM */ - - /* Verify that the user is a valid user. */ - if ((authctxt->pw = getpwnamallow(user)) != NULL) { - authctxt->valid = 1; - } else { - authctxt->valid = 0; - debug("do_authentication: illegal user %s", user); - } - - setproctitle("%s", authctxt->pw ? user : "unknown"); - - /* - * If we are not running as root, the user must have the same uid as - * the server. (Unless you are running Windows) - */ -#ifndef HAVE_CYGWIN - if (getuid() != 0 && authctxt->pw && - authctxt->pw->pw_uid != getuid()) - packet_disconnect("Cannot change user when server not running as root."); -#endif - - /* - * Loop until the user has been authenticated or the connection is - * closed, do_authloop() returns only if authentication is successful - */ - do_authloop(authctxt); - - /* The user has been authenticated and accepted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); - - return (authctxt); -} diff --git a/usr/src/cmd/ssh/sshd/auth2-chall.c b/usr/src/cmd/ssh/sshd/auth2-chall.c deleted file mode 100644 index 72dcc6dc5b..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-chall.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * Copyright (c) 2001 Per Allansson. 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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2-chall.c,v 1.20 2002/06/30 21:59:45 deraadt Exp $"); - -#include "ssh2.h" -#include "auth.h" -#include "buffer.h" -#include "packet.h" -#include "xmalloc.h" -#include "dispatch.h" -#include "auth.h" -#include "log.h" - -#ifndef lint -static void auth2_challenge_start(Authctxt *); -static int send_userauth_info_request(Authctxt *); -static void input_userauth_info_response(int, u_int32_t, void *); - -#ifdef BSD_AUTH -extern KbdintDevice bsdauth_device; -#else -#ifdef SKEY -extern KbdintDevice skey_device; -#endif -#endif - -KbdintDevice *devices[] = { -#ifdef BSD_AUTH - &bsdauth_device, -#else -#ifdef SKEY - &skey_device, -#endif -#endif - NULL -}; - -typedef struct KbdintAuthctxt KbdintAuthctxt; -struct KbdintAuthctxt -{ - char *devices; - void *ctxt; - KbdintDevice *device; - u_int nreq; -}; - -static KbdintAuthctxt * -kbdint_alloc(const char *devs) -{ - KbdintAuthctxt *kbdintctxt; - Buffer b; - int i; - - kbdintctxt = xmalloc(sizeof(KbdintAuthctxt)); - if (strcmp(devs, "") == 0) { - buffer_init(&b); - for (i = 0; devices[i]; i++) { - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - buffer_append(&b, devices[i]->name, - strlen(devices[i]->name)); - } - buffer_append(&b, "\0", 1); - kbdintctxt->devices = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - } else { - kbdintctxt->devices = xstrdup(devs); - } - debug("kbdint_alloc: devices '%s'", kbdintctxt->devices); - kbdintctxt->ctxt = NULL; - kbdintctxt->device = NULL; - kbdintctxt->nreq = 0; - - return kbdintctxt; -} -static void -kbdint_reset_device(KbdintAuthctxt *kbdintctxt) -{ - if (kbdintctxt->ctxt) { - kbdintctxt->device->free_ctx(kbdintctxt->ctxt); - kbdintctxt->ctxt = NULL; - } - kbdintctxt->device = NULL; -} -static void -kbdint_free(KbdintAuthctxt *kbdintctxt) -{ - if (kbdintctxt->device) - kbdint_reset_device(kbdintctxt); - if (kbdintctxt->devices) { - xfree(kbdintctxt->devices); - kbdintctxt->devices = NULL; - } - xfree(kbdintctxt); -} -/* get next device */ -static int -kbdint_next_device(KbdintAuthctxt *kbdintctxt) -{ - size_t len; - char *t; - int i; - - if (kbdintctxt->device) - kbdint_reset_device(kbdintctxt); - do { - len = kbdintctxt->devices ? - strcspn(kbdintctxt->devices, ",") : 0; - - if (len == 0) - break; - for (i = 0; devices[i]; i++) - if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) - kbdintctxt->device = devices[i]; - t = kbdintctxt->devices; - kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; - xfree(t); - debug2("kbdint_next_device: devices %s", kbdintctxt->devices ? - kbdintctxt->devices : "<empty>"); - } while (kbdintctxt->devices && !kbdintctxt->device); - - return kbdintctxt->device ? 1 : 0; -} - -/* - * try challenge-response, set authctxt->method->postponed if we have to - * wait for the response. - */ -void -auth2_challenge(Authctxt *authctxt, char *devs) -{ - debug("auth2_challenge: user=%s devs=%s", - authctxt->user ? authctxt->user : "<nouser>", - devs ? devs : "<no devs>"); - - if (authctxt->user == NULL || !devs) - return; - if (authctxt->method->method_data != NULL) { - auth2_challenge_abandon(authctxt); - authctxt->method->abandoned = 0; - } - authctxt->method->method_data = (void *) kbdint_alloc(devs); - auth2_challenge_start(authctxt); -} - -/* unregister kbd-int callbacks and context */ -static void -auth2_challenge_stop(Authctxt *authctxt) -{ - /* unregister callback */ - dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); - if (authctxt->method->method_data != NULL) { - kbdint_free((KbdintAuthctxt *) authctxt->method->method_data); - authctxt->method->method_data = NULL; - } -} - -void -auth2_challenge_abandon(Authctxt *authctxt) -{ - auth2_challenge_stop(authctxt); - authctxt->method->abandoned = 1; - authctxt->method->postponed = 0; - authctxt->method->authenticated = 0; - authctxt->method->abandons++; - authctxt->method->attempts++; -} - -/* side effect: sets authctxt->method->postponed if a reply was sent*/ -static void -auth2_challenge_start(Authctxt *authctxt) -{ - KbdintAuthctxt *kbdintctxt = (KbdintAuthctxt *) - authctxt->method->method_data; - - debug2("auth2_challenge_start: devices %s", - kbdintctxt->devices ? kbdintctxt->devices : "<empty>"); - - if (kbdint_next_device(kbdintctxt) == 0) { - auth2_challenge_stop(authctxt); - return; - } - debug("auth2_challenge_start: trying authentication method '%s'", - kbdintctxt->device->name); - - if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) { - auth2_challenge_stop(authctxt); - return; - } - if (send_userauth_info_request(authctxt) == 0) { - auth2_challenge_stop(authctxt); - return; - } - dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, - &input_userauth_info_response); - - authctxt->method->postponed = 1; -} - -static int -send_userauth_info_request(Authctxt *authctxt) -{ - KbdintAuthctxt *kbdintctxt; - char *name, *instr, **prompts; - int i; - u_int *echo_on; - - kbdintctxt = (KbdintAuthctxt *) authctxt->method->method_data; - if (kbdintctxt->device->query(kbdintctxt->ctxt, - &name, &instr, &kbdintctxt->nreq, &prompts, &echo_on)) - return 0; - - packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); - packet_put_cstring(name); - packet_put_utf8_cstring(instr); - packet_put_cstring(""); /* language not used */ - packet_put_int(kbdintctxt->nreq); - for (i = 0; i < kbdintctxt->nreq; i++) { - packet_put_utf8_cstring(prompts[i]); - packet_put_char(echo_on[i]); - } - packet_send(); - packet_write_wait(); - - for (i = 0; i < kbdintctxt->nreq; i++) - xfree(prompts[i]); - xfree(prompts); - xfree(echo_on); - xfree(name); - xfree(instr); - return 1; -} - -static void -input_userauth_info_response(int type, u_int32_t seq, void *ctxt) -{ - Authctxt *authctxt = ctxt; - KbdintAuthctxt *kbdintctxt; - int i, res, len; - u_int nresp; - char **response = NULL, *method; - - if (authctxt == NULL) - fatal("input_userauth_info_response: no authctxt"); - kbdintctxt = (KbdintAuthctxt *) authctxt->method->method_data; - if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL) - fatal("input_userauth_info_response: no kbdintctxt"); - if (kbdintctxt->device == NULL) - fatal("input_userauth_info_response: no device"); - - nresp = packet_get_int(); - if (nresp != kbdintctxt->nreq) - fatal("input_userauth_info_response: wrong number of replies"); - if (nresp > 100) - fatal("input_userauth_info_response: too many replies"); - if (nresp > 0) { - response = xmalloc(nresp * sizeof(char *)); - for (i = 0; i < nresp; i++) - response[i] = packet_get_string(NULL); - } - packet_check_eom(); - - if (authctxt->valid) { - res = kbdintctxt->device->respond(kbdintctxt->ctxt, - nresp, response); - } else { - res = -1; - } - - for (i = 0; i < nresp; i++) { - memset(response[i], 'r', strlen(response[i])); - xfree(response[i]); - } - if (response) - xfree(response); - - authctxt->method->postponed = 0; /* reset */ - switch (res) { - case 0: - /* Success! */ - authctxt->method->authenticated = 1; - break; - case 1: - /* Authentication needs further interaction */ - if (send_userauth_info_request(authctxt) == 1) { - authctxt->method->postponed = 1; - } - break; - default: - /* Failure! */ - break; - } - - - len = strlen("keyboard-interactive") + 2 + - strlen(kbdintctxt->device->name); - method = xmalloc(len); - snprintf(method, len, "keyboard-interactive/%s", - kbdintctxt->device->name); - - if (authctxt->method->authenticated || authctxt->method->abandoned) { - auth2_challenge_stop(authctxt); - } else { - /* start next device */ - /* may set authctxt->method->postponed */ - auth2_challenge_start(authctxt); - } - userauth_finish(authctxt, method); - xfree(method); -} - -void -privsep_challenge_enable(void) -{ -#ifdef BSD_AUTH - extern KbdintDevice mm_bsdauth_device; -#endif -#ifdef SKEY - extern KbdintDevice mm_skey_device; -#endif - /* As long as SSHv1 has devices[0] hard coded this is fine */ -#ifdef BSD_AUTH - devices[0] = &mm_bsdauth_device; -#else -#ifdef SKEY - devices[0] = &mm_skey_device; -#endif -#endif -} -#endif /* lint */ diff --git a/usr/src/cmd/ssh/sshd/auth2-gss.c b/usr/src/cmd/ssh/sshd/auth2-gss.c deleted file mode 100644 index 8525707c1e..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-gss.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" - -#ifdef GSSAPI -#include "auth.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "log.h" -#include "dispatch.h" -#include "buffer.h" -#include "servconf.h" -#include "compat.h" -#include "bufaux.h" -#include "packet.h" - -#include <gssapi/gssapi.h> -#include "ssh-gss.h" - -extern ServerOptions options; -extern uchar_t *session_id2; -extern int session_id2_len; -extern Gssctxt *xxx_gssctxt; - -static void userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt); - -static void -userauth_gssapi_keyex(Authctxt *authctxt) -{ - gss_buffer_desc g_mic_data, mic_tok; - Buffer mic_data; - OM_uint32 maj_status, min_status; - - if (authctxt == NULL || authctxt->method == NULL) - fatal("No authentication context during gssapi-keyex userauth"); - - if (xxx_gssctxt == NULL || xxx_gssctxt->context == GSS_C_NO_CONTEXT) { - /* fatal()? or return? */ - debug("No GSS-API context during gssapi-keyex userauth"); - return; - } - - /* Make data buffer to verify MIC with */ - buffer_init(&mic_data); - buffer_put_string(&mic_data, session_id2, session_id2_len); - buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&mic_data, authctxt->user); - buffer_put_cstring(&mic_data, authctxt->service); - buffer_put_cstring(&mic_data, authctxt->method->name); - - g_mic_data.value = buffer_ptr(&mic_data); - g_mic_data.length = buffer_len(&mic_data); - - mic_tok.value = packet_get_string(&mic_tok.length); - - maj_status = gss_verify_mic(&min_status, xxx_gssctxt->context, - &g_mic_data, &mic_tok, NULL); - - packet_check_eom(); - buffer_clear(&mic_data); - - if (maj_status != GSS_S_COMPLETE) - debug2("MIC verification failed, GSSAPI userauth failed"); - else - userauth_gssapi_finish(authctxt, xxx_gssctxt); - - /* Leave Gssctxt around for ssh_gssapi_cleanup/storecreds() */ - if (xxx_gssctxt->deleg_creds == GSS_C_NO_CREDENTIAL) - ssh_gssapi_delete_ctx(&xxx_gssctxt); -} - -static void ssh_gssapi_userauth_error(Gssctxt *ctxt); -static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); -static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); -static void input_gssapi_errtok(int, u_int32_t, void *); -static void input_gssapi_exchange_complete(int type, u_int32_t plen, - void *ctxt); - -static void -userauth_gssapi_abandon(Authctxt *authctxt, Authmethod *method) -{ - ssh_gssapi_delete_ctx((Gssctxt **)&method->method_data); - xxx_gssctxt = NULL; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); -} - -static void -userauth_gssapi(Authctxt *authctxt) -{ - gss_OID_set supported_mechs; - int mechs, present = 0; - OM_uint32 min_status; - uint_t len; - char *doid = NULL; - gss_OID oid = GSS_C_NULL_OID; - - if (datafellows & SSH_OLD_GSSAPI) { - debug("Early drafts of GSSAPI userauth not supported"); - return; - } - - mechs = packet_get_int(); - if (mechs == 0) { - packet_check_eom(); - debug("Mechanism negotiation is not supported"); - return; - } - - ssh_gssapi_server_mechs(&supported_mechs); - - do { - mechs--; - - if (oid != GSS_C_NULL_OID) - ssh_gssapi_release_oid(&oid); - - doid = packet_get_string(&len); - - /* ick */ - if (doid[0] != 0x06 || (len > 2 && doid[1] != len - 2)) { - log("Mechanism OID received using the old " - "encoding form"); - oid = ssh_gssapi_make_oid(len, doid); - } else { - oid = ssh_gssapi_make_oid(len - 2, doid + 2); - } - - (void) gss_test_oid_set_member(&min_status, oid, - supported_mechs, &present); - - debug("Client offered gssapi userauth with %s (%s)", - ssh_gssapi_oid_to_str(oid), - present ? "supported" : "unsupported"); - } while (!present && (mechs > 0)); - - if (!present) { - /* userauth_finish() will send SSH2_MSG_USERAUTH_FAILURE */ - debug2("No mechanism offered by the client is available"); - ssh_gssapi_release_oid(&oid); - return; - } - - ssh_gssapi_build_ctx((Gssctxt **)&authctxt->method->method_data, - 0, oid); - ssh_gssapi_release_oid(&oid); - /* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */ - - packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); - - /* Just return whatever we found -- the matched mech does us no good */ - packet_put_string(doid, len); - xfree(doid); - - packet_send(); - packet_write_wait(); - - /* Setup rest of gssapi userauth conversation */ - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); - authctxt->method->postponed = 1; -} - -static void -input_gssapi_token(int type, u_int32_t plen, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - gss_buffer_desc send_tok, recv_tok; - OM_uint32 maj_status, min_status; - uint_t len; - - if (authctxt == NULL || authctxt->method == NULL || - (authctxt->method->method_data == NULL)) { - fatal("No authentication or GSSAPI context during " - "gssapi-with-mic userauth"); - } - - gssctxt = authctxt->method->method_data; - recv_tok.value = packet_get_string(&len); - recv_tok.length = len; /* u_int vs. size_t */ - - maj_status = ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok); - packet_check_eom(); - - if (GSS_ERROR(maj_status)) { - ssh_gssapi_userauth_error(gssctxt); - if (send_tok.length != 0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); - packet_put_string(send_tok.value, send_tok.length); - packet_send(); - packet_write_wait(); - } - authctxt->method->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - userauth_finish(authctxt, authctxt->method->name); - } else { - if (send_tok.length != 0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); - packet_put_string(send_tok.value, send_tok.length); - packet_send(); - packet_write_wait(); - } - if (maj_status == GSS_S_COMPLETE) { - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, - &input_gssapi_mic); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, - &input_gssapi_exchange_complete); - } - } - - gss_release_buffer(&min_status, &send_tok); -} - -static void -input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - gss_buffer_desc send_tok, recv_tok; - - if (authctxt == NULL || authctxt->method == NULL || - (authctxt->method->method_data == NULL)) { - fatal("No authentication or GSSAPI context during " - "gssapi-with-mic userauth"); - } - - gssctxt = authctxt->method->method_data; - recv_tok.value = packet_get_string(&recv_tok.length); - packet_check_eom(); - - /* Push the error token into GSSAPI to see what it says */ - (void) ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok); - - debug("Client sent GSS-API error token during GSS userauth-- %s", - ssh_gssapi_last_error(gssctxt, NULL, NULL)); - - /* We can't return anything to the client, even if we wanted to */ - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); - - - /* - * The client will have already moved on to the next auth and - * will send a new userauth request. The spec says that the - * server MUST NOT send a SSH_MSG_USERAUTH_FAILURE packet in - * response to this. - * - * We leave authctxt->method->postponed == 1 here so that a call - * to input_userauth_request() will detect this failure (as - * userauth abandonment) and act accordingly. - */ -} - -static void -input_gssapi_mic(int type, u_int32_t plen, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - gss_buffer_desc g_mic_data, mic_tok; - Buffer mic_data; - OM_uint32 maj_status, min_status; - - if (authctxt == NULL || authctxt->method == NULL || - (authctxt->method->method_data == NULL)) { - debug3("No authentication or GSSAPI context during " - "gssapi-with-mic userauth"); - return; - } - - gssctxt = authctxt->method->method_data; - - /* Make data buffer to verify MIC with */ - buffer_init(&mic_data); - buffer_put_string(&mic_data, session_id2, session_id2_len); - buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&mic_data, authctxt->user); - buffer_put_cstring(&mic_data, authctxt->service); - buffer_put_cstring(&mic_data, authctxt->method->name); - - g_mic_data.value = buffer_ptr(&mic_data); - g_mic_data.length = buffer_len(&mic_data); - - mic_tok.value = packet_get_string(&mic_tok.length); - - maj_status = gss_verify_mic(&min_status, gssctxt->context, - &g_mic_data, &mic_tok, NULL); - - packet_check_eom(); - buffer_free(&mic_data); - - if (maj_status != GSS_S_COMPLETE) - debug2("MIC verification failed, GSSAPI userauth failed"); - else - userauth_gssapi_finish(authctxt, gssctxt); - - /* Delete context from keyex */ - if (xxx_gssctxt != gssctxt) - ssh_gssapi_delete_ctx(&xxx_gssctxt); - - /* Leave Gssctxt around for ssh_gssapi_cleanup/storecreds() */ - if (gssctxt->deleg_creds == GSS_C_NO_CREDENTIAL) - ssh_gssapi_delete_ctx(&gssctxt); - - xxx_gssctxt = gssctxt; - - authctxt->method->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); - userauth_finish(authctxt, authctxt->method->name); -} - -/* - * This is called when the client thinks we've completed authentication. - * It should only be enabled in the dispatch handler by the function above, - * which only enables it once the GSSAPI exchange is complete. - */ -static void -input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - - packet_check_eom(); - - if (authctxt == NULL || authctxt->method == NULL || - (authctxt->method->method_data == NULL)) - fatal("No authentication or GSSAPI context"); - - gssctxt = authctxt->method->method_data; - - /* - * SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE -> gssapi userauth - * failure, the client should use SSH2_MSG_USERAUTH_GSSAPI_MIC - * instead. - * - * There's two reasons for this: - * - * 1) we don't have GSS mechs that don't support integrity - * protection, and even if we did we'd not want to use them with - * SSHv2, and, - * - * 2) we currently have no way to dynamically detect whether a - * given mechanism does or does not support integrity - * protection, so when a context's flags do not indicate - * integrity protection we can't know if the client simply - * didn't request it, so we assume it didn't and reject the - * userauth. - * - * We could fail partially (i.e., force the use of other - * userauth methods without counting this one as failed). But - * this will do for now. - */ -#if 0 - authctxt->method->authenticated = ssh_gssapi_userok(gssctxt, - authctxt->user); -#endif - - if (xxx_gssctxt != gssctxt) - ssh_gssapi_delete_ctx(&gssctxt); - ssh_gssapi_delete_ctx(&gssctxt); - authctxt->method->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); - userauth_finish(authctxt, authctxt->method->name); -} - -static void -ssh_gssapi_userauth_error(Gssctxt *ctxt) -{ - char *errstr; - OM_uint32 maj, min; - - errstr = ssh_gssapi_last_error(ctxt, &maj, &min); - if (errstr) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERROR); - packet_put_int(maj); - packet_put_int(min); - packet_put_cstring(errstr); - packet_put_cstring(""); - packet_send(); - packet_write_wait(); - xfree(errstr); - } -} - -/* - * Code common to gssapi-keyex and gssapi-with-mic userauth. - * - * Does authorization, figures out how to store delegated creds. - */ -static void -userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt) -{ - char *local_user = NULL; - gss_buffer_desc dispname; - OM_uint32 major; - - if (*authctxt->user != '\0' && - ssh_gssapi_userok(gssctxt, authctxt->user)) { - - /* - * If the client princ did not map to the requested - * username then we don't want to clobber existing creds - * for the user with the delegated creds. - */ - local_user = ssh_gssapi_localname(gssctxt); - if (local_user == NULL || - strcmp(local_user, authctxt->user) == 0) - gssctxt->default_creds = 1; /* store creds as default */ - - authctxt->method->authenticated = - do_pam_non_initial_userauth(authctxt); - - } else if (*authctxt->user == '\0') { - /* Requested username == ""; derive username from princ name */ - if ((local_user = ssh_gssapi_localname(gssctxt)) == NULL) - return; - - /* Changed username (from implicit, '') */ - userauth_user_svc_change(authctxt, local_user, NULL); - - gssctxt->default_creds = 1; /* store creds as default */ - - authctxt->method->authenticated = - do_pam_non_initial_userauth(authctxt); - } - - if (local_user != NULL) - xfree(local_user); - - if (*authctxt->user != '\0' && authctxt->method->authenticated != 0) { - major = gss_display_name(&gssctxt->minor, gssctxt->src_name, - &dispname, NULL); - if (major == GSS_S_COMPLETE) { - log("Authorized principal %.*s, authenticated with " - "GSS mechanism %s, to: %s", - dispname.length, (char *)dispname.value, - ssh_gssapi_oid_to_name(gssctxt->actual_mech), - authctxt->user); - } - (void) gss_release_buffer(&gssctxt->minor, &dispname); - } -} - -#if 0 -/* Deprecated userauths -- should not be enabled */ -Authmethod method_external = { - "external-keyx", - &options.gss_authentication, - userauth_gssapi_keyex, - NULL, /* no abandon function */ - NULL, - NULL, - /* State counters */ - 0, 0, 0, 0, - /* State flags */ - 0, 0, 0, 0, 0, 0 -}; - -Authmethod method_gssapi = { - "gssapi", - &options.gss_authentication, - userauth_gssapi, - userauth_gssapi_abandon, - NULL, - NULL, - /* State counters */ - 0, 0, 0, 0, - /* State flags */ - 0, 0, 0, 0, 0, 0 -}; -#endif - -Authmethod method_external = { - "gssapi-keyex", - &options.gss_authentication, - userauth_gssapi_keyex, - NULL, /* no abandon function */ - NULL, - NULL, - /* State counters */ - 0, 0, 0, 0, - /* State flags */ - 0, 0, 0, 0, 0, 0 -}; - -Authmethod method_gssapi = { - "gssapi-with-mic", - &options.gss_authentication, - userauth_gssapi, - userauth_gssapi_abandon, - NULL, - NULL, - /* State counters */ - 0, 0, 0, 0, - /* State flags */ - 0, 0, 0, 0, 0, 0 -}; - -#endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/sshd/auth2-hostbased.c b/usr/src/cmd/ssh/sshd/auth2-hostbased.c deleted file mode 100644 index c88e308100..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-hostbased.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "ssh2.h" -#include "xmalloc.h" -#include "packet.h" -#include "buffer.h" -#include "log.h" -#include "servconf.h" -#include "compat.h" -#include "bufaux.h" -#include "auth.h" - -#ifdef USE_PAM -#include "auth-pam.h" -#endif /* USE_PAM */ - -#include "key.h" -#include "canohost.h" -#include "pathnames.h" - -/* import */ -extern ServerOptions options; -extern u_char *session_id2; -extern int session_id2_len; - -static void -userauth_hostbased(Authctxt *authctxt) -{ - Buffer b; - Key *key = NULL; - char *pkalg, *cuser, *chost, *service; - u_char *pkblob, *sig; - u_int alen, blen, slen; - int pktype; - int authenticated = 0; - - if (!authctxt || !authctxt->method) - fatal("%s: missing context", __func__); - - pkalg = packet_get_string(&alen); - pkblob = packet_get_string(&blen); - chost = packet_get_string(NULL); - cuser = packet_get_string(NULL); - sig = packet_get_string(&slen); - - debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d", - cuser, chost, pkalg, slen); -#ifdef DEBUG_PK - debug("signature:"); - buffer_init(&b); - buffer_append(&b, sig, slen); - buffer_dump(&b); - buffer_free(&b); -#endif - pktype = key_type_from_name(pkalg); - if (pktype == KEY_UNSPEC) { - /* this is perfectly legal */ - log("userauth_hostbased: unsupported " - "public key algorithm: %s", pkalg); - goto done; - } - key = key_from_blob(pkblob, blen); - if (key == NULL) { - error("userauth_hostbased: cannot decode key: %s", pkalg); - goto done; - } - if (key->type != pktype) { - error("userauth_hostbased: type mismatch for decoded key " - "(received %d, expected %d)", key->type, pktype); - goto done; - } - service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : - authctxt->service; - buffer_init(&b); - buffer_put_string(&b, session_id2, session_id2_len); - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "hostbased"); - buffer_put_string(&b, pkalg, alen); - buffer_put_string(&b, pkblob, blen); - buffer_put_cstring(&b, chost); - buffer_put_cstring(&b, cuser); -#ifdef DEBUG_PK - buffer_dump(&b); -#endif - /* test for allowed key and correct signature */ - authenticated = 0; - if (hostbased_key_allowed(authctxt->pw, cuser, chost, key) && - key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) - authenticated = 1; - - buffer_clear(&b); -done: - /* - * XXX TODO: Add config options for specifying users for whom - * this userauth is insufficient and what userauths - * may continue. - * - * NOTE: do_pam_non_initial_userauth() does this for - * users with expired passwords. - */ -#ifdef USE_PAM - if (authenticated) { - authctxt->cuser = cuser; - if (!do_pam_non_initial_userauth(authctxt)) - authenticated = 0; - /* Make sure nobody else will use this pointer since we are - * going to free that string. */ - authctxt->cuser = NULL; - } -#endif /* USE_PAM */ - - if (authenticated) - authctxt->method->authenticated = 1; - - debug2("userauth_hostbased: authenticated %d", authenticated); - if (key != NULL) - key_free(key); - xfree(pkalg); - xfree(pkblob); - xfree(cuser); - xfree(chost); - xfree(sig); - return; -} - -/* return 1 if given hostkey is allowed */ -int -hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, - Key *key) -{ - const char *resolvedname, *ipaddr, *lookup; - HostStatus host_status; - int len; - - resolvedname = get_canonical_hostname(options.verify_reverse_mapping); - ipaddr = get_remote_ipaddr(); - - debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", - chost, resolvedname, ipaddr); - - if (pw == NULL) - return 0; - - if (options.hostbased_uses_name_from_packet_only) { - if (auth_rhosts2(pw, cuser, chost, chost) == 0) - return 0; - lookup = chost; - } else { - if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') { - debug2("stripping trailing dot from chost %s", chost); - chost[len - 1] = '\0'; - } - if (strcasecmp(resolvedname, chost) != 0) - log("userauth_hostbased mismatch: " - "client sends %s, but we resolve %s to %s", - chost, ipaddr, resolvedname); - if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) - return 0; - lookup = resolvedname; - } - debug2("userauth_hostbased: access allowed by auth_rhosts2"); - - host_status = check_key_in_hostfiles(pw, key, lookup, - _PATH_SSH_SYSTEM_HOSTFILE, - options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE); - - /* backward compat if no key has been found. */ - if (host_status == HOST_NEW) - host_status = check_key_in_hostfiles(pw, key, lookup, - _PATH_SSH_SYSTEM_HOSTFILE2, - options.ignore_user_known_hosts ? NULL : - _PATH_SSH_USER_HOSTFILE2); - - return (host_status == HOST_OK); -} - -Authmethod method_hostbased = { - "hostbased", - &options.hostbased_authentication, - userauth_hostbased, - NULL, /* no abandon function */ - NULL, NULL, /* method data and hist data */ - 0, /* is not initial userauth */ - 0, 0, 0, /* counters */ - 0, 0, 0, 0, 0, 0 /* state */ -}; diff --git a/usr/src/cmd/ssh/sshd/auth2-kbdint.c b/usr/src/cmd/ssh/sshd/auth2-kbdint.c deleted file mode 100644 index 2ea8104182..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-kbdint.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - */ -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); - -#include "packet.h" -#include "auth.h" -#include "log.h" -#include "servconf.h" -#include "xmalloc.h" - -/* import */ -extern ServerOptions options; - -static void -userauth_kbdint(Authctxt *authctxt) -{ - char *lang, *devs; - - if (!authctxt || !authctxt->method) - fatal("%s: missing contex", __func__); - - lang = packet_get_string(NULL); - devs = packet_get_string(NULL); - packet_check_eom(); - - debug("keyboard-interactive devs %s", devs); - -#ifdef USE_PAM - if (options.kbd_interactive_authentication) - auth2_pam(authctxt); -#else - if (options.challenge_response_authentication) - auth2_challenge(authctxt, devs); -#endif /* USE_PAM */ - xfree(devs); - xfree(lang); -#ifdef HAVE_CYGWIN - if (check_nt_auth(0, authctxt->pw) == 0) { - authctxt->method->authenticated = 0; - return; - } -#endif -} - -static void -userauth_kbdint_abandon(Authctxt *authctxt, Authmethod *method) -{ -#ifdef USE_PAM - kbdint_pam_abandon(authctxt, method); -#else - auth2_challenge_abandon(authctxt); -#endif /* USE_PAM */ -} - -Authmethod method_kbdint = { - "keyboard-interactive", - &options.kbd_interactive_authentication, - userauth_kbdint, - userauth_kbdint_abandon, - NULL, NULL, /* method data and historical data */ - 1, /* initial userauth */ - 0, 0, 0, /* counters */ - 0, 0, 0, 0, 0, 0 /* state */ -}; diff --git a/usr/src/cmd/ssh/sshd/auth2-none.c b/usr/src/cmd/ssh/sshd/auth2-none.c deleted file mode 100644 index 5d49ee95e8..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-none.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2-none.c,v 1.4 2002/06/27 10:35:47 deraadt Exp $"); - -#include "auth.h" -#include "xmalloc.h" -#include "packet.h" -#include "log.h" -#include "servconf.h" -#include "atomicio.h" -#include "compat.h" -#include "ssh2.h" - -/* import */ -extern ServerOptions options; - -/* "none" is allowed only one time */ -static int none_enabled = 1; - -char * -auth2_read_banner(void) -{ - struct stat st; - char *banner, *ubanner, *errstr; - off_t len, n; - int fd; - uint_t ilen; - - if ((fd = open(options.banner, O_RDONLY)) == -1) - return (NULL); - if (fstat(fd, &st) == -1) { - close(fd); - return (NULL); - } - len = st.st_size; - banner = xmalloc(len + 1); - n = atomicio(read, fd, banner, len); - close(fd); - - if (n != len) { - xfree(banner); - return (NULL); - } - banner[n] = '\0'; - - if (datafellows & SSH_BUG_STRING_ENCODING) { - ubanner = banner; - } else { - ilen = (uint_t)n; - ubanner = g11n_convert_to_utf8(banner, &ilen, 1, &errstr); - if (ubanner == NULL) { - if (errstr != NULL) { - error("Can't convert banner contents " - "to UTF-8: %s\n", errstr); - } - ubanner = banner; - } else { - xfree(banner); - } - } - - return (ubanner); -} - -static void -userauth_banner(void) -{ - char *banner = NULL; - - if (options.banner == NULL || (datafellows & SSH_BUG_BANNER)) - return; - - if ((banner = auth2_read_banner()) == NULL) - goto done; - - packet_start(SSH2_MSG_USERAUTH_BANNER); - packet_put_cstring(banner); - packet_put_cstring(""); /* language, unused */ - packet_send(); - debug("userauth_banner: sent"); -done: - if (banner) - xfree(banner); -} - -static void -userauth_none(Authctxt *authctxt) -{ - none_enabled = 0; - - if (!authctxt || !authctxt->method) - fatal("%s: missing context", __func__); - - packet_check_eom(); - userauth_banner(); -#ifdef HAVE_CYGWIN - if (check_nt_auth(1, authctxt->pw) == 0) - return (0); -#endif - authctxt->method->authenticated = auth_password(authctxt, ""); -} - -Authmethod method_none = { - "none", - &none_enabled, - userauth_none, - NULL, /* no abandon function */ - NULL, NULL, /* method data and hist data */ - 0, /* not really initial userauth */ - 0, 0, 0, /* counters */ - 0, 0, 0, 0, 0, 0 /* state */ -}; diff --git a/usr/src/cmd/ssh/sshd/auth2-pam.c b/usr/src/cmd/ssh/sshd/auth2-pam.c deleted file mode 100644 index 1b0fa40f2b..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-pam.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" - -RCSID("$Id: auth2-pam.c,v 1.14 2002/06/28 16:48:12 mouring Exp $"); - -#ifdef USE_PAM -#include <security/pam_appl.h> - -#include "ssh.h" -#include "ssh2.h" -#include "auth.h" -#include "auth-pam.h" -#include "auth-options.h" -#include "packet.h" -#include "xmalloc.h" -#include "dispatch.h" -#include "canohost.h" -#include "log.h" -#include "servconf.h" -#include "misc.h" - -#ifdef HAVE_BSM -#include "bsmaudit.h" -#endif /* HAVE_BSM */ - -extern u_int utmp_len; -extern ServerOptions options; - -extern Authmethod method_kbdint; -extern Authmethod method_passwd; - -#define SSHD_PAM_KBDINT_SVC "sshd-kbdint" -/* Maximum attempts for changing expired password */ -#define DEF_ATTEMPTS 3 - -static int do_pam_conv_kbd_int(int num_msg, - struct pam_message **msg, struct pam_response **resp, - void *appdata_ptr); -static void input_userauth_info_response_pam(int type, - u_int32_t seqnr, - void *ctxt); - -static struct pam_conv conv2 = { - do_pam_conv_kbd_int, - NULL, -}; - -static void do_pam_kbdint_cleanup(pam_handle_t *pamh); -static void do_pam_kbdint(Authctxt *authctxt); - -void -auth2_pam(Authctxt *authctxt) -{ - if (authctxt->user == NULL) - fatal("auth2_pam: internal error: no user"); - if (authctxt->method == NULL) - fatal("auth2_pam: internal error: no method"); - - conv2.appdata_ptr = authctxt; - new_start_pam(authctxt, &conv2); - - authctxt->method->method_data = NULL; /* freed in the conv func */ - dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, - &input_userauth_info_response_pam); - - /* - * Since password userauth and keyboard-interactive userauth - * both use PAM, and since keyboard-interactive is so much - * better than password userauth, we should not allow the user - * to try password userauth after trying keyboard-interactive. - */ - if (method_passwd.enabled) - *method_passwd.enabled = 0; - - do_pam_kbdint(authctxt); - - dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); -} - -static void -do_pam_kbdint(Authctxt *authctxt) -{ - int retval, retval2; - pam_handle_t *pamh = authctxt->pam->h; - const char *where = "authenticating"; - char *text = NULL; - - debug2("Calling pam_authenticate()"); - retval = pam_authenticate(pamh, - options.permit_empty_passwd ? 0 : - PAM_DISALLOW_NULL_AUTHTOK); - - if (retval != PAM_SUCCESS) - goto cleanup; - - debug2("kbd-int: pam_authenticate() succeeded"); - where = "authorizing"; - retval = pam_acct_mgmt(pamh, 0); - - if (retval == PAM_NEW_AUTHTOK_REQD) { - if (authctxt->valid && authctxt->pw != NULL) { - /* send password expiration warning */ - message_cat(&text, - gettext("Warning: Your password has expired," - " please change it now.")); - packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); - packet_put_cstring(""); /* name */ - packet_put_utf8_cstring(text); /* instructions */ - packet_put_cstring(""); /* language, unused */ - packet_put_int(0); - packet_send(); - packet_write_wait(); - debug("expiration message sent"); - if (text) - xfree(text); - /* - * wait for the response so it does not mix - * with the upcoming PAM conversation - */ - packet_read_expect(SSH2_MSG_USERAUTH_INFO_RESPONSE); - /* - * Can't use temporarily_use_uid() and restore_uid() - * here because we need (euid == 0 && ruid == pw_uid) - * whereas temporarily_use_uid() arranges for - * (suid = 0 && euid == pw_uid && ruid == pw_uid). - */ - (void) setreuid(authctxt->pw->pw_uid, -1); - debug2("kbd-int: changing expired password"); - where = "changing authentication tokens (password)"; - /* - * Depending on error returned from pam_chauthtok, we - * need to try to change password a few times before - * we error out and return. - */ - int tries = 0; - while ((retval = pam_chauthtok(pamh, - PAM_CHANGE_EXPIRED_AUTHTOK)) != PAM_SUCCESS) { - if (tries++ < DEF_ATTEMPTS) { - if ((retval == PAM_AUTHTOK_ERR) || - (retval == PAM_TRY_AGAIN)) { - continue; - } - } - break; - } - audit_sshd_chauthtok(retval, authctxt->pw->pw_uid, - authctxt->pw->pw_gid); - (void) setreuid(0, -1); - } else { - retval = PAM_PERM_DENIED; - } - } - - if (retval != PAM_SUCCESS) - goto cleanup; - - authctxt->pam->state |= PAM_S_DONE_ACCT_MGMT; - - retval = finish_userauth_do_pam(authctxt); - - if (retval != PAM_SUCCESS) - goto cleanup; - - /* - * PAM handle stays around so we can call pam_close_session() - * on it later. - */ - authctxt->method->authenticated = 1; - debug2("kbd-int: success (pam->state == %x)", authctxt->pam->state); - return; - -cleanup: - /* - * Check for abandonment and cleanup. When kbdint is abandoned - * authctxt->pam->h is NULLed and by this point a new handle may - * be allocated. - */ - if (authctxt->pam->h != pamh) { - log("Keyboard-interactive (PAM) userauth abandoned " - "while %s", where); - if ((retval2 = pam_end(pamh, retval)) != PAM_SUCCESS) { - log("Cannot close PAM handle after " - "kbd-int userauth abandonment[%d]: %.200s", - retval2, PAM_STRERROR(pamh, retval2)); - } - authctxt->method->abandoned = 1; - - /* - * Avoid double counting; these are incremented in - * kbdint_pam_abandon() so that they reflect the correct - * count when userauth_finish() is called before - * unwinding the dispatch_run() loop, but they are - * incremented again in input_userauth_request() when - * the loop is unwound, right here. - */ - if (authctxt->method->abandons) - authctxt->method->abandons--; - if (authctxt->method->attempts) - authctxt->method->attempts--; - } - else { - /* Save error value for pam_end() */ - authctxt->pam->last_pam_retval = retval; - log("Keyboard-interactive (PAM) userauth failed[%d] " - "while %s: %.200s", retval, where, - PAM_STRERROR(pamh, retval)); - /* pam handle can be reused elsewhere, so no pam_end() here */ - } - - return; -} - -static int -do_pam_conv_kbd_int(int num_msg, struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr) -{ - int i, j; - char *text; - Convctxt *conv_ctxt; - Authctxt *authctxt = (Authctxt *)appdata_ptr; - - if (!authctxt || !authctxt->method) { - debug("Missing state during PAM conversation"); - return PAM_CONV_ERR; - } - - conv_ctxt = xmalloc(sizeof(Convctxt)); - (void) memset(conv_ctxt, 0, sizeof(Convctxt)); - conv_ctxt->finished = 0; - conv_ctxt->num_received = 0; - conv_ctxt->num_expected = 0; - conv_ctxt->prompts = xmalloc(sizeof(int) * num_msg); - conv_ctxt->responses = xmalloc(sizeof(struct pam_response) * num_msg); - (void) memset(conv_ctxt->responses, 0, sizeof(struct pam_response) * num_msg); - - text = NULL; - for (i = 0, conv_ctxt->num_expected = 0; i < num_msg; i++) { - int style = PAM_MSG_MEMBER(msg, i, msg_style); - switch (style) { - case PAM_PROMPT_ECHO_ON: - debug2("PAM echo on prompt: %s", - PAM_MSG_MEMBER(msg, i, msg)); - conv_ctxt->num_expected++; - break; - case PAM_PROMPT_ECHO_OFF: - debug2("PAM echo off prompt: %s", - PAM_MSG_MEMBER(msg, i, msg)); - conv_ctxt->num_expected++; - break; - case PAM_TEXT_INFO: - debug2("PAM text info prompt: %s", - PAM_MSG_MEMBER(msg, i, msg)); - message_cat(&text, PAM_MSG_MEMBER(msg, i, msg)); - break; - case PAM_ERROR_MSG: - debug2("PAM error prompt: %s", - PAM_MSG_MEMBER(msg, i, msg)); - message_cat(&text, PAM_MSG_MEMBER(msg, i, msg)); - break; - default: - /* Capture all these messages to be sent at once */ - message_cat(&text, PAM_MSG_MEMBER(msg, i, msg)); - break; - } - } - - if (conv_ctxt->num_expected == 0 && text == NULL) { - xfree(conv_ctxt->prompts); - xfree(conv_ctxt->responses); - xfree(conv_ctxt); - return PAM_SUCCESS; - } - - authctxt->method->method_data = (void *) conv_ctxt; - - packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); - packet_put_cstring(""); /* Name */ - packet_put_utf8_cstring(text ? text : ""); /* Instructions */ - packet_put_cstring(""); /* Language */ - packet_put_int(conv_ctxt->num_expected); - - if (text) - xfree(text); - - for (i = 0, j = 0; i < num_msg; i++) { - int style = PAM_MSG_MEMBER(msg, i, msg_style); - - /* Skip messages which don't need a reply */ - if (style != PAM_PROMPT_ECHO_ON && style != PAM_PROMPT_ECHO_OFF) - continue; - - conv_ctxt->prompts[j++] = i; - packet_put_utf8_cstring(PAM_MSG_MEMBER(msg, i, msg)); - packet_put_char(style == PAM_PROMPT_ECHO_ON); - } - packet_send(); - packet_write_wait(); - - /* - * Here the dispatch_run() loop is nested. It should be unwound - * if keyboard-interactive userauth is abandoned (or restarted; - * same thing). - * - * The condition for breaking out of the nested dispatch_run() loop is - * ((got kbd-int info reponse) || (kbd-int abandoned)) - * - * conv_ctxt->finished is set in either of those cases. - * - * When abandonment is detected the conv_ctxt->finished is set as - * is conv_ctxt->abandoned, causing this function to signal - * userauth nested dispatch_run() loop unwinding and to return - * PAM_CONV_ERR; - */ - debug2("Nesting dispatch_run loop"); - dispatch_run(DISPATCH_BLOCK, &conv_ctxt->finished, appdata_ptr); - debug2("Nested dispatch_run loop exited"); - - if (conv_ctxt->abandoned) { - authctxt->unwind_dispatch_loop = 1; - xfree(conv_ctxt->prompts); - xfree(conv_ctxt->responses); - xfree(conv_ctxt); - debug("PAM conv function returns PAM_CONV_ERR"); - return PAM_CONV_ERR; - } - - if (conv_ctxt->num_received == conv_ctxt->num_expected) { - *resp = conv_ctxt->responses; - xfree(conv_ctxt->prompts); - xfree(conv_ctxt); - debug("PAM conv function returns PAM_SUCCESS"); - return PAM_SUCCESS; - } - - debug("PAM conv function returns PAM_CONV_ERR"); - xfree(conv_ctxt->prompts); - xfree(conv_ctxt->responses); - xfree(conv_ctxt); - return PAM_CONV_ERR; -} - -static void -input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Convctxt *conv_ctxt; - unsigned int nresp = 0, rlen = 0, i = 0; - char *resp; - - if (authctxt == NULL) - fatal("input_userauth_info_response_pam: no authentication context"); - - /* Check for spurious/unexpected info response */ - if (method_kbdint.method_data == NULL) { - debug("input_userauth_info_response_pam: no method context"); - return; - } - - conv_ctxt = (Convctxt *) method_kbdint.method_data; - - nresp = packet_get_int(); /* Number of responses. */ - debug("got %d responses", nresp); - - -#if 0 - if (nresp != conv_ctxt->num_expected) - fatal("%s: Received incorrect number of responses " - "(expected %d, received %u)", __func__, - conv_ctxt->num_expected, nresp); -#endif - - if (nresp > 100) - fatal("%s: too many replies", __func__); - - for (i = 0; i < nresp && i < conv_ctxt->num_expected ; i++) { - int j = conv_ctxt->prompts[i]; - - /* - * We assume that ASCII charset is used for password - * although the protocol requires UTF-8 encoding for the - * password string. Therefore, we don't perform code - * conversion for the string. - */ - resp = packet_get_string(&rlen); - if (i < conv_ctxt->num_expected) { - conv_ctxt->responses[j].resp_retcode = PAM_SUCCESS; - conv_ctxt->responses[j].resp = xstrdup(resp); - conv_ctxt->num_received++; - } - xfree(resp); - } - - if (nresp < conv_ctxt->num_expected) - fatal("%s: too few replies (%d < %d)", __func__, - nresp, conv_ctxt->num_expected); - - /* XXX - This could make a covert channel... */ - if (nresp > conv_ctxt->num_expected) - debug("Ignoring additional PAM replies"); - - conv_ctxt->finished = 1; - - packet_check_eom(); -} - -#if 0 -int -kbdint_pam_abandon_chk(Authctxt *authctxt, Authmethod *method) -{ - if (!method) - return 0; /* fatal(), really; it'll happen somewhere else */ - - if (!method->method_data) - return 0; - - return 1; -} -#endif - -void -kbdint_pam_abandon(Authctxt *authctxt, Authmethod *method) -{ - Convctxt *conv_ctxt; - - /* - * But, if it ever becomes desirable and possible to support - * kbd-int userauth abandonment, here's what must be done. - */ - if (!method) - return; - - if (!method->method_data) - return; - - conv_ctxt = (Convctxt *) method->method_data; - - /* dispatch_run() loop will exit */ - conv_ctxt->abandoned = 1; - conv_ctxt->finished = 1; - - /* - * The method_data will be free in the corresponding, active - * conversation function - */ - method->method_data = NULL; - - /* update counts that can't be updated elsewhere */ - method->abandons++; - method->attempts++; - - /* Finally, we cannot re-use the current current PAM handle */ - authctxt->pam->h = NULL; /* Let the conv function cleanup */ -} -#endif diff --git a/usr/src/cmd/ssh/sshd/auth2-passwd.c b/usr/src/cmd/ssh/sshd/auth2-passwd.c deleted file mode 100644 index 9a1837fb05..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-passwd.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "xmalloc.h" -#include "packet.h" -#include "log.h" -#include "auth.h" -#include "servconf.h" - -/* import */ -extern ServerOptions options; - -static void -userauth_passwd(Authctxt *authctxt) -{ - char *password; - int change; - u_int len; - - if (!authctxt || !authctxt->method) - fatal("%s: missing context", __func__); - - change = packet_get_char(); - if (change) - log("password change not supported"); - password = packet_get_string(&len); - packet_check_eom(); - if ( -#ifdef HAVE_CYGWIN - check_nt_auth(1, authctxt->pw) && -#endif - auth_password(authctxt, password) == 1) { - authctxt->method->authenticated = 1; - } - memset(password, 0, len); - xfree(password); -} - -Authmethod method_passwd = { - "password", - &options.password_authentication, - userauth_passwd, - NULL, /* no abandon function */ - NULL, NULL, /* method data and hist data */ - 1, /* initial userauth */ - 0, 0, 0, /* counters */ - 0, 0, 0, 0, 0, 0 /* state */ -}; diff --git a/usr/src/cmd/ssh/sshd/auth2-pubkey.c b/usr/src/cmd/ssh/sshd/auth2-pubkey.c deleted file mode 100644 index c1c5f540e4..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2-pubkey.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * 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. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <dlfcn.h> - -#include "includes.h" -RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); - -#include "ssh2.h" -#include "xmalloc.h" -#include "packet.h" -#include "buffer.h" -#include "log.h" -#include "servconf.h" -#include "compat.h" -#include "bufaux.h" -#include "auth.h" -#include "key.h" -#include "pathnames.h" -#include "uidswap.h" -#include "auth-options.h" -#include "canohost.h" - -#ifdef USE_PAM -#include <security/pam_appl.h> -#include "auth-pam.h" -#endif /* USE_PAM */ - -/* import */ -extern ServerOptions options; -extern u_char *session_id2; -extern int session_id2_len; - -/* global plugin function requirements */ -static const char *RSA_SYM_NAME = "sshd_user_rsa_key_allowed"; -static const char *DSA_SYM_NAME = "sshd_user_rsa_key_allowed"; -typedef int (*RSA_SYM)(struct passwd *, RSA *, const char *); -typedef int (*DSA_SYM)(struct passwd *, DSA *, const char *); - - -static void -userauth_pubkey(Authctxt *authctxt) -{ - Buffer b; - Key *key = NULL; - char *pkalg; - u_char *pkblob, *sig; - u_int alen, blen, slen; - int have_sig, pktype; - int authenticated = 0; - - if (!authctxt || !authctxt->method) - fatal("%s: missing context", __func__); - - have_sig = packet_get_char(); - if (datafellows & SSH_BUG_PKAUTH) { - debug2("userauth_pubkey: SSH_BUG_PKAUTH"); - /* no explicit pkalg given */ - pkblob = packet_get_string(&blen); - buffer_init(&b); - buffer_append(&b, pkblob, blen); - /* so we have to extract the pkalg from the pkblob */ - pkalg = buffer_get_string(&b, &alen); - buffer_free(&b); - } else { - pkalg = packet_get_string(&alen); - pkblob = packet_get_string(&blen); - } - pktype = key_type_from_name(pkalg); - if (pktype == KEY_UNSPEC) { - /* this is perfectly legal */ - log("userauth_pubkey: unsupported public key algorithm: %s", - pkalg); - goto done; - } - key = key_from_blob(pkblob, blen); - if (key == NULL) { - error("userauth_pubkey: cannot decode key: %s", pkalg); - goto done; - } - if (key->type != pktype) { - error("userauth_pubkey: type mismatch for decoded key " - "(received %d, expected %d)", key->type, pktype); - goto done; - } - - /* Detect and count abandonment */ - if (authctxt->method->method_data) { - Key *prev_key; - unsigned char *prev_pkblob; - int prev_blen; - - /* - * Check for earlier test of a key that was allowed but - * not followed up with a pubkey req for the same pubkey - * and with a signature. - */ - prev_key = authctxt->method->method_data; - if ((prev_blen = key_to_blob(prev_key, - &prev_pkblob, NULL))) { - if (prev_blen != blen || - memcmp(prev_pkblob, pkblob, blen) != 0) { - authctxt->method->abandons++; - authctxt->method->attempts++; - } - } - key_free(prev_key); - authctxt->method->method_data = NULL; - } - - if (have_sig) { - sig = packet_get_string(&slen); - packet_check_eom(); - buffer_init(&b); - if (datafellows & SSH_OLD_SESSIONID) { - buffer_append(&b, session_id2, session_id2_len); - } else { - buffer_put_string(&b, session_id2, session_id2_len); - } - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, - datafellows & SSH_BUG_PKSERVICE ? - "ssh-userauth" : - authctxt->service); - if (datafellows & SSH_BUG_PKAUTH) { - buffer_put_char(&b, have_sig); - } else { - buffer_put_cstring(&b, "publickey"); - buffer_put_char(&b, have_sig); - buffer_put_cstring(&b, pkalg); - } - buffer_put_string(&b, pkblob, blen); -#ifdef DEBUG_PK - buffer_dump(&b); -#endif - /* test for correct signature */ - if (user_key_allowed(authctxt->pw, key) && - key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b)) == 1) { - authenticated = 1; - } - authctxt->method->postponed = 0; - buffer_free(&b); - xfree(sig); - } else { - debug("test whether pkalg/pkblob are acceptable"); - packet_check_eom(); - - /* XXX fake reply and always send PK_OK ? */ - /* - * XXX this allows testing whether a user is allowed - * to login: if you happen to have a valid pubkey this - * message is sent. the message is NEVER sent at all - * if a user is not allowed to login. is this an - * issue? -markus - */ - if (user_key_allowed(authctxt->pw, key)) { - packet_start(SSH2_MSG_USERAUTH_PK_OK); - packet_put_string(pkalg, alen); - packet_put_string(pkblob, blen); - packet_send(); - packet_write_wait(); - authctxt->method->postponed = 1; - /* - * Remember key that was tried so we can - * correctly detect abandonment. See above. - */ - authctxt->method->method_data = (void *) key; - key = NULL; - } - } - if (authenticated != 1) - auth_clear_options(); - -done: - /* - * XXX TODO: add config options for specifying users for whom - * this userauth is insufficient and what userauths may - * continue. - */ -#ifdef USE_PAM - if (authenticated) { - if (!do_pam_non_initial_userauth(authctxt)) - authenticated = 0; - } -#endif /* USE_PAM */ - - debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); - if (key != NULL) - key_free(key); - xfree(pkalg); - xfree(pkblob); -#ifdef HAVE_CYGWIN - if (check_nt_auth(0, authctxt->pw) == 0) - return; -#endif - if (authenticated) - authctxt->method->authenticated = 1; -} - -/* return 1 if user allows given key */ -static int -user_key_allowed2(struct passwd *pw, Key *key, char *file) -{ - char line[8192]; - int found_key = 0; - FILE *f; - u_long linenum = 0; - struct stat st; - Key *found; - char *fp; - - if (pw == NULL) - return 0; - - /* Temporarily use the user's uid. */ - temporarily_use_uid(pw); - - debug("trying public key file %s", file); - - /* Fail quietly if file does not exist */ - if (stat(file, &st) < 0) { - /* Restore the privileged uid. */ - restore_uid(); - return 0; - } - /* Open the file containing the authorized keys. */ - f = fopen(file, "r"); - if (!f) { - /* Restore the privileged uid. */ - restore_uid(); - return 0; - } - if (options.strict_modes && - secure_filename(f, file, pw, line, sizeof(line)) != 0) { - (void) fclose(f); - log("Authentication refused: %s", line); - restore_uid(); - return 0; - } - - found_key = 0; - found = key_new(key->type); - - while (fgets(line, sizeof(line), f)) { - 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; - - if (key_read(found, &cp) != 1) { - /* no key? check if there are options for this key */ - int quoted = 0; - debug2("user_key_allowed: check options: '%s'", cp); - 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++) - ; - if (key_read(found, &cp) != 1) { - debug2("user_key_allowed: advance: '%s'", cp); - /* still no key? advance to next line*/ - continue; - } - } - if (key_equal(found, key) && - auth_parse_options(pw, options, file, linenum) == 1) { - found_key = 1; - debug("matching key found: file %s, line %lu", - file, linenum); - fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); - verbose("Found matching %s key: %s", - key_type(found), fp); - xfree(fp); - break; - } - } - restore_uid(); - (void) fclose(f); - key_free(found); - if (!found_key) - debug2("key not found"); - return found_key; -} - -/** - * Checks whether or not access is allowed based on a plugin specified - * in sshd_config (PubKeyPlugin). - * - * Note that this expects a symbol in the loaded library that takes - * the current user (pwd entry), the current RSA key and it's fingerprint. - * The symbol is expected to return 1 on success and 0 on failure. - * - * While we could optimize this code to dlopen once in the process' lifetime, - * sshd is already a slow beast, so this is really not a concern. - * The overhead is basically a rounding error compared to everything else, and - * it keeps this code minimally invasive. - */ -static int -user_key_allowed_from_plugin(struct passwd *pw, Key *key) -{ - RSA_SYM rsa_sym = NULL; - DSA_SYM dsa_sym = NULL; - char *fp = NULL; - void *handle = NULL; - int success = 0; - - if (options.pubkey_plugin == NULL || pw == NULL || key == NULL || - (key->type != KEY_RSA && key->type != KEY_RSA1 && - key->type != KEY_DSA && key->type != KEY_ECDSA)) - return success; - - handle = dlopen(options.pubkey_plugin, RTLD_NOW); - if ((handle == NULL)) { - debug("Unable to open library %s: %s", options.pubkey_plugin, - dlerror()); - goto out; - } - - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); - if (fp == NULL) { - debug("failed to generate fingerprint"); - goto out; - } - - switch (key->type) { - case KEY_RSA1: - case KEY_RSA: - rsa_sym = (RSA_SYM)dlsym(handle, RSA_SYM_NAME); - if (rsa_sym == NULL) { - debug("Unable to resolve symbol %s: %s", RSA_SYM_NAME, - dlerror()); - goto out; - } - debug2("Invoking %s from %s", RSA_SYM_NAME, - options.pubkey_plugin); - success = (*rsa_sym)(pw, key->rsa, fp); - break; - case KEY_DSA: - case KEY_ECDSA: - dsa_sym = (DSA_SYM)dlsym(handle, RSA_SYM_NAME); - if (dsa_sym == NULL) { - debug("Unable to resolve symbol %s: %s", DSA_SYM_NAME, - dlerror()); - goto out; - } - debug2("Invoking %s from %s", DSA_SYM_NAME, - options.pubkey_plugin); - success = (*dsa_sym)(pw, key->dsa, fp); - break; - default: - debug2("user_key_plugins only support RSA keys"); - } - - debug("sshd_plugin returned: %d", success); - -out: - if (handle != NULL) { - dlclose(handle); - dsa_sym = NULL; - rsa_sym = NULL; - handle = NULL; - } - - if (success) - verbose("Found matching %s key: %s", key_type(key), fp); - - if (fp != NULL) { - xfree(fp); - fp = NULL; - } - - return success; -} - - -/* check whether given key is in .ssh/authorized_keys or a plugin */ -int -user_key_allowed(struct passwd *pw, Key *key) -{ - int success; - char *file; - - if (pw == NULL) - return 0; - - file = authorized_keys_file(pw); - success = user_key_allowed2(pw, key, file); - xfree(file); - if (success) - return success; - - /* try suffix "2" for backward compat, too */ - file = authorized_keys_file2(pw); - success = user_key_allowed2(pw, key, file); - xfree(file); - - if (success) - return success; - - /* try from a plugin */ - success = user_key_allowed_from_plugin(pw, key); - - return success; -} - -static -void -userauth_pubkey_abandon(Authctxt *authctxt, Authmethod *method) -{ - if (!authctxt || !method) - return; - - if (method->method_data) { - method->abandons++; - method->attempts++; - key_free((Key *) method->method_data); - method->method_data = NULL; - } -} - -Authmethod method_pubkey = { - "publickey", - &options.pubkey_authentication, - userauth_pubkey, - userauth_pubkey_abandon, - NULL, NULL, /* method data and hist data */ - 0, /* not initial userauth */ - 0, 0, 0, /* counters */ - 0, 0, 0, 0, 0, 0 /* state */ -}; diff --git a/usr/src/cmd/ssh/sshd/auth2.c b/usr/src/cmd/ssh/sshd/auth2.c deleted file mode 100644 index bc3f4284f3..0000000000 --- a/usr/src/cmd/ssh/sshd/auth2.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * 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. - */ -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.95 2002/08/22 21:33:58 markus Exp $"); - -#include "ssh2.h" -#include "xmalloc.h" -#include "packet.h" -#include "log.h" -#include "servconf.h" -#include "compat.h" -#include "misc.h" -#include "auth.h" -#include "dispatch.h" -#include "sshlogin.h" -#include "pathnames.h" - -#ifdef HAVE_BSM -#include "bsmaudit.h" -extern adt_session_data_t *ah; -#endif /* HAVE_BSM */ - -#ifdef GSSAPI -#include "ssh-gss.h" -#endif - -/* import */ -extern ServerOptions options; -extern u_char *session_id2; -extern int session_id2_len; - -Authctxt *x_authctxt = NULL; - -/* methods */ - -extern Authmethod method_none; -extern Authmethod method_pubkey; -extern Authmethod method_passwd; -extern Authmethod method_kbdint; -extern Authmethod method_hostbased; -extern Authmethod method_external; -extern Authmethod method_gssapi; - -static Authmethod *authmethods[] = { - &method_none, -#ifdef GSSAPI - &method_external, - &method_gssapi, -#endif - &method_pubkey, - &method_passwd, - &method_kbdint, - &method_hostbased, - NULL -}; - -/* protocol */ - -static void input_service_request(int, u_int32_t, void *); -static void input_userauth_request(int, u_int32_t, void *); - -/* helper */ -static Authmethod *authmethod_lookup(const char *); -static char *authmethods_get(void); -static char *authmethods_check_abandonment(Authctxt *authctxt, - Authmethod *method); -static void authmethod_count_attempt(Authmethod *method); -/*static char *authmethods_get_kbdint(void);*/ -int user_key_allowed(struct passwd *, Key *); -int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); -static int userauth_method_can_run(Authmethod *method); -static void userauth_reset_methods(void); - -/* - * loop until authctxt->success == TRUE - */ - -Authctxt * -do_authentication2(void) -{ - Authctxt *authctxt = authctxt_new(); - - x_authctxt = authctxt; /*XXX*/ - -#ifdef HAVE_BSM - fatal_add_cleanup(audit_failed_login_cleanup, authctxt); -#endif /* HAVE_BSM */ - - dispatch_init(&dispatch_protocol_error); - dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); - dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); - - return (authctxt); -} - -static void -input_service_request(int type, u_int32_t seq, void *ctxt) -{ - Authctxt *authctxt = ctxt; - u_int len; - int acceptit = 0; - char *service = packet_get_string(&len); - packet_check_eom(); - - if (authctxt == NULL) - fatal("input_service_request: no authctxt"); - - if (strcmp(service, "ssh-userauth") == 0) { - if (!authctxt->success) { - acceptit = 1; - /* now we can handle user-auth requests */ - dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); - } - } - /* XXX all other service requests are denied */ - - if (acceptit) { - packet_start(SSH2_MSG_SERVICE_ACCEPT); - packet_put_cstring(service); - packet_send(); - packet_write_wait(); - } else { - debug("bad service request %s", service); - packet_disconnect("bad service request %s", service); - } - xfree(service); -} - -static void -input_userauth_request(int type, u_int32_t seq, void *ctxt) -{ - Authctxt *authctxt = ctxt; - Authmethod *m = NULL; - char *user, *service, *method, *style = NULL; - int valid_attempt; - - if (authctxt == NULL) - fatal("input_userauth_request: no authctxt"); - - user = packet_get_string(NULL); - service = packet_get_string(NULL); - method = packet_get_string(NULL); - debug("userauth-request for user %s service %s method %s", user, - service, method); - debug("attempt %d initial attempt %d failures %d initial failures %d", - authctxt->attempt, authctxt->init_attempt, - authctxt->failures, authctxt->init_failures); - - m = authmethod_lookup(method); - - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; - - authctxt->attempt++; - if (m != NULL && m->is_initial) - authctxt->init_attempt++; - - if (options.pre_userauth_hook != NULL && - run_auth_hook(options.pre_userauth_hook, user, m->name) != 0) { - valid_attempt = 0; - } else { - valid_attempt = 1; - } - - if (authctxt->attempt == 1) { - /* setup auth context */ - authctxt->pw = getpwnamallow(user); - /* May want to abstract SSHv2 services someday */ - if (authctxt->pw && strcmp(service, "ssh-connection")==0) { - /* enforced in userauth_finish() below */ - if (valid_attempt) { - authctxt->valid = 1; - } - debug2("input_userauth_request: setting up authctxt for %s", user); - } else { - log("input_userauth_request: illegal user %s", user); - } - setproctitle("%s", authctxt->pw ? user : "unknown"); - authctxt->user = xstrdup(user); - authctxt->service = xstrdup(service); - authctxt->style = style ? xstrdup(style) : NULL; - userauth_reset_methods(); - } else { - char *abandoned; - - /* - * Check for abandoned [multi-round-trip] userauths - * methods (e.g., kbdint). Userauth method abandonment - * should be treated as userauth method failure and - * counted against max_auth_tries. - */ - abandoned = authmethods_check_abandonment(authctxt, m); - - if (abandoned != NULL && - authctxt->failures > options.max_auth_tries) { - /* userauth_finish() will now packet_disconnect() */ - userauth_finish(authctxt, abandoned); - /* NOTREACHED */ - } - - /* Handle user|service changes, possibly packet_disconnect() */ - userauth_user_svc_change(authctxt, user, service); - } - - authctxt->method = m; - - /* run userauth method, try to authenticate user */ - if (m != NULL && userauth_method_can_run(m)) { - debug2("input_userauth_request: try method %s", method); - - m->postponed = 0; - m->abandoned = 0; - m->authenticated = 0; - - if (!m->is_initial || - authctxt->init_failures < options.max_init_auth_tries) - m->userauth(authctxt); - - authmethod_count_attempt(m); - - if (authctxt->unwind_dispatch_loop) { - /* - * Method ran nested dispatch loop but was - * abandoned. Cleanup and return without doing - * anything else; we're just unwinding the stack. - */ - authctxt->unwind_dispatch_loop = 0; - goto done; - } - - if (m->postponed) - goto done; /* multi-round trip userauth not finished */ - - if (m->abandoned) { - /* multi-round trip userauth abandoned, log failure */ - auth_log(authctxt, 0, method, " ssh2"); - goto done; - } - } - - userauth_finish(authctxt, method); - -done: - xfree(service); - xfree(user); - xfree(method); -} - -void -userauth_finish(Authctxt *authctxt, char *method) -{ - int authenticated, partial; - - if (authctxt == NULL) - fatal("%s: missing context", __func__); - - /* unknown method handling -- must elicit userauth failure msg */ - if (authctxt->method == NULL) { - authenticated = 0; - partial = 0; - goto done_checking; - } - -#ifndef USE_PAM - /* Special handling for root (done elsewhere for PAM) */ - if (authctxt->method->authenticated && - authctxt->pw != NULL && authctxt->pw->pw_uid == 0 && - !auth_root_allowed(method)) - authctxt->method->authenticated = 0; -#endif /* USE_PAM */ - -#ifdef _UNICOS - if (authctxt->method->authenticated && - cray_access_denied(authctxt->user)) { - authctxt->method->authenticated = 0; - fatal("Access denied for user %s.",authctxt->user); - } -#endif /* _UNICOS */ - - partial = userauth_check_partial_failure(authctxt); - authenticated = authctxt->method->authenticated; - -#ifdef USE_PAM - /* - * If the userauth method failed to complete PAM work then force - * partial failure. - */ - if (authenticated && !AUTHPAM_DONE(authctxt)) - partial = 1; -#endif /* USE_PAM */ - - /* - * To properly support invalid userauth method names we set - * authenticated=0, partial=0 above and know that - * authctxt->method == NULL. - * - * No unguarded reference to authctxt->method allowed from here. - * Checking authenticated != 0 is a valid guard; authctxt->method - * MUST NOT be NULL if authenticated. - */ -done_checking: - if (!authctxt->valid && authenticated) { - /* - * We get here if the PreUserauthHook fails but the - * user is otherwise valid. - * An error in the PAM handling could also get us here - * but we need not panic, just treat as a failure. - */ - authctxt->method->authenticated = 0; - authenticated = 0; - log("Ignoring authenticated invalid user %s", - authctxt->user); - auth_log(authctxt, 0, method, " ssh2"); - } - - /* Log before sending the reply */ - auth_log(authctxt, authenticated, method, " ssh2"); - - if (authenticated && !partial) { - - /* turn off userauth */ - dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); - packet_start(SSH2_MSG_USERAUTH_SUCCESS); - packet_send(); - packet_write_wait(); - /* now we can break out */ - authctxt->success = 1; - } else { - char *methods; - - if (authctxt->method && authctxt->method->is_initial) - authctxt->init_failures++; - - authctxt->method = NULL; - -#ifdef USE_PAM - /* - * Keep track of last PAM error (or PERM_DENIED) for BSM - * login failure auditing, which may run after the PAM - * state has been cleaned up. - */ - authctxt->pam_retval = AUTHPAM_ERROR(authctxt, PAM_PERM_DENIED); -#endif /* USE_PAM */ - - if (authctxt->failures++ > options.max_auth_tries) { -#ifdef HAVE_BSM - fatal_remove_cleanup(audit_failed_login_cleanup, - authctxt); - audit_sshd_login_failure(&ah, PAM_MAXTRIES, - authctxt->user); -#endif /* HAVE_BSM */ - packet_disconnect(AUTH_FAIL_MSG, authctxt->user); - } - -#ifdef _UNICOS - if (strcmp(method, "password") == 0) - cray_login_failure(authctxt->user, IA_UDBERR); -#endif /* _UNICOS */ - packet_start(SSH2_MSG_USERAUTH_FAILURE); - - /* - * If (partial) then authmethods_get() will return only - * required methods, likely only "keyboard-interactive;" - * (methods == NULL) implies failure, even if (partial == 1) - */ - methods = authmethods_get(); - packet_put_cstring(methods); - packet_put_char((authenticated && partial && methods) ? 1 : 0); - if (methods) - xfree(methods); - packet_send(); - packet_write_wait(); - } -} - -/* get current user */ - -struct passwd* -auth_get_user(void) -{ - return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL; -} - -#define DELIM "," - -#if 0 -static char * -authmethods_get_kbdint(void) -{ - Buffer b; - int i; - - for (i = 0; authmethods[i] != NULL; i++) { - if (strcmp(authmethods[i]->name, "keyboard-interactive") != 0) - continue; - return xstrdup(authmethods[i]->name); - } - return NULL; -} -#endif - -void -userauth_user_svc_change(Authctxt *authctxt, char *user, char *service) -{ - /* - * NOTE: - * - * SSHv2 services should be abstracted and service changes during - * userauth should be supported as per the userauth draft. In the PAM - * case, support for multiple SSHv2 services means that we have to - * format the PAM service name according to the SSHv2 service *and* the - * SSHv2 userauth being attempted ("passwd", "kbdint" and "other"). - * - * We'll cross that bridge when we come to it. For now disallow service - * changes during userauth if using PAM, but allow username changes. - */ - - /* authctxt->service must == ssh-connection here */ - if (service != NULL && strcmp(service, authctxt->service) != 0) { - packet_disconnect("Change of service not " - "allowed: %s and %s", - authctxt->service, service); - } - if (user != NULL && authctxt->user != NULL && - strcmp(user, authctxt->user) == 0) - return; - - /* All good; update authctxt */ - xfree(authctxt->user); - authctxt->user = xstrdup(user); - pwfree(&authctxt->pw); - authctxt->pw = getpwnamallow(user); - authctxt->valid = (authctxt->pw != NULL); - - /* Forget method state; abandon postponed userauths */ - userauth_reset_methods(); -} - -int -userauth_check_partial_failure(Authctxt *authctxt) -{ - int i; - int required = 0; - int sufficient = 0; - - /* - * v1 does not set authctxt->method - * partial userauth failure is a v2 concept - */ - if (authctxt->method == NULL) - return 0; - - for (i = 0; authmethods[i] != NULL; i++) { - if (authmethods[i]->required) - required++; - if (authmethods[i]->sufficient) - sufficient++; - } - - if (required == 0 && sufficient == 0) - return !authctxt->method->authenticated; - - if (required == 1 && authctxt->method->required) - return !authctxt->method->authenticated; - - if (sufficient && authctxt->method->sufficient) - return !authctxt->method->authenticated; - - return 1; -} - -int -userauth_method_can_run(Authmethod *method) -{ - if (method->not_again) - return 0; - - return 1; -} - -static -void -userauth_reset_methods(void) -{ - int i; - - for (i = 0; authmethods[i] != NULL; i++) { - /* note: counters not reset */ - authmethods[i]->required = 0; - authmethods[i]->sufficient = 0; - authmethods[i]->authenticated = 0; - authmethods[i]->not_again = 0; - authmethods[i]->postponed = 0; - authmethods[i]->abandoned = 0; - } -} - -void -userauth_force_kbdint(void) -{ - int i; - - for (i = 0; authmethods[i] != NULL; i++) { - authmethods[i]->required = 0; - authmethods[i]->sufficient = 0; - } - method_kbdint.required = 1; -} - -/* - * Check to see if a previously run multi-round trip userauth method has - * been abandoned and call its cleanup function. - * - * Abandoned userauth method invocations are counted as userauth failures. - */ -static -char * -authmethods_check_abandonment(Authctxt *authctxt, Authmethod *method) -{ - int i; - - /* optimization: check current method first */ - if (method && method->postponed) { - method->postponed = 0; - if (method->abandon) - method->abandon(authctxt, method); - else - method->abandons++; - authctxt->failures++; /* abandonment -> failure */ - if (method->is_initial) - authctxt->init_failures++; - - /* - * Since we check for abandonment whenever a userauth is - * requested we know only one method could have been - * in postponed state, so we can return now. - */ - return (method->name); - } - for (i = 0; authmethods[i] != NULL; i++) { - if (!authmethods[i]->postponed) - continue; - - /* some method was postponed and a diff one is being started */ - if (method != authmethods[i]) { - authmethods[i]->postponed = 0; - if (authmethods[i]->abandon) - authmethods[i]->abandon(authctxt, - authmethods[i]); - else - authmethods[i]->abandons++; - authctxt->failures++; - if (authmethods[i]->is_initial) - authctxt->init_failures++; - return (authmethods[i]->name); /* see above */ - } - } - - return NULL; -} - -static char * -authmethods_get(void) -{ - Buffer b; - char *list; - int i; - int sufficient = 0; - int required = 0; - int authenticated = 0; - int partial = 0; - - /* - * If at least one method succeeded partially then at least one - * authmethod will be required and only required methods should - * continue. - */ - for (i = 0; authmethods[i] != NULL; i++) { - if (authmethods[i]->authenticated) - authenticated++; - if (authmethods[i]->required) - required++; - if (authmethods[i]->sufficient) - sufficient++; - } - - partial = (required + sufficient) > 0; - - buffer_init(&b); - for (i = 0; authmethods[i] != NULL; i++) { - if (strcmp(authmethods[i]->name, "none") == 0) - continue; - if (required && !authmethods[i]->required) - continue; - if (sufficient && !required && !authmethods[i]->sufficient) - continue; - if (authmethods[i]->not_again) - continue; - - if (authmethods[i]->required) { - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - buffer_append(&b, authmethods[i]->name, - strlen(authmethods[i]->name)); - continue; - } - - /* - * A method can be enabled (marked sufficient) - * dynamically provided that at least one other method - * has succeeded partially. - */ - if ((partial && authmethods[i]->sufficient) || - (authmethods[i]->enabled != NULL && - *(authmethods[i]->enabled) != 0)) { - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - buffer_append(&b, authmethods[i]->name, - strlen(authmethods[i]->name)); - } - } - buffer_append(&b, "\0", 1); - list = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - return list; -} - -static Authmethod * -authmethod_lookup(const char *name) -{ - int i; - - /* - * Method must be sufficient, required or enabled and must not - * be marked as not able to run again - */ - if (name != NULL) - for (i = 0; authmethods[i] != NULL; i++) - if (((authmethods[i]->sufficient || - authmethods[i]->required) || - (authmethods[i]->enabled != NULL && - *(authmethods[i]->enabled) != 0)) && - !authmethods[i]->not_again && - strcmp(name, authmethods[i]->name) == 0) - return authmethods[i]; - debug2("Unrecognized authentication method name: %s", - name ? name : "NULL"); - return NULL; -} - -static void -authmethod_count_attempt(Authmethod *method) -{ - if (!method) - fatal("Internal error in authmethod_count_attempt()"); - - if (method->postponed) - return; - - method->attempts++; - - if (method->abandoned) - method->abandons++; - else if (method->authenticated) - method->successes++; - else - method->failures++; - - return; -} diff --git a/usr/src/cmd/ssh/sshd/bsmaudit.c b/usr/src/cmd/ssh/sshd/bsmaudit.c deleted file mode 100644 index c46d295972..0000000000 --- a/usr/src/cmd/ssh/sshd/bsmaudit.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * usr/src/cmd/ssh/sshd/bsmaudit.c - * - * Taken from the on81 usr/src/lib/libbsm/common/audit_login.c - */ -#include "includes.h" - -#include <sys/systeminfo.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/systeminfo.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <netinet/in.h> -#include <netdb.h> -#include <signal.h> - -#include <stdarg.h> -#include <pwd.h> -#include <shadow.h> -#include <utmpx.h> -#include <unistd.h> -#include <string.h> - -#include <locale.h> - -#include "log.h" -#include "packet.h" -#include "canohost.h" -#include "servconf.h" -#include "xmalloc.h" -#include <errno.h> -#include <bsm/adt.h> -#include <bsm/adt_event.h> - -extern uint_t utmp_len; /* XXX - Yuck; we'll keep this for now */ -extern ServerOptions options; - /* - * XXX - Yuck; we should have a - * get_client_name_or_ip that does the - * right thing wrt reverse lookups - */ - -void -audit_sshd_chauthtok(int pam_retval, uid_t uid, gid_t gid) -{ - adt_session_data_t *ah = NULL; - adt_event_data_t *event = NULL; - const char *how = "couldn't start adt session"; - int saved_errno = 0; - - if (adt_start_session(&ah, NULL, 0) != 0) { - saved_errno = errno; - goto fail; - } - if (adt_set_user(ah, uid, gid, uid, gid, NULL, ADT_NEW) != 0) { - saved_errno = errno; - how = "couldn't set adt user"; - goto fail; - } - - if ((event = adt_alloc_event(ah, ADT_passwd)) == NULL) { - saved_errno = errno; - how = "couldn't allocate adt event"; - goto fail; - } - - if (pam_retval == PAM_SUCCESS) { - if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { - saved_errno = errno; - how = "couldn't put adt event"; - goto fail; - } - } else if (adt_put_event(event, ADT_FAILURE, - ADT_FAIL_PAM + pam_retval) != 0) { - saved_errno = errno; - how = "couldn't put adt event"; - goto fail; - } - - adt_free_event(event); - (void) adt_end_session(ah); - return; - -fail: - adt_free_event(event); - (void) adt_end_session(ah); - - fatal("Auditing of password change failed: %s (%s)", - strerror(saved_errno), how); -} - -void -audit_sshd_login(adt_session_data_t **ah, pid_t pid) -{ - adt_event_data_t *event = NULL; - const char *how; - int saved_errno = 0; - ucred_t *ucred = NULL; - - if (ah == NULL) { - how = "programmer error"; - saved_errno = EINVAL; - goto fail; - } - - if (adt_start_session(ah, NULL, 0) != 0) { - saved_errno = errno; - how = "couldn't start adt session"; - goto fail; - } - - if ((ucred = ucred_get(pid)) == NULL) { - saved_errno = errno; - how = "ucred_get() failed to obtain user credential"; - goto fail; - } - - if (adt_set_from_ucred(*ah, ucred, ADT_NEW)) { - saved_errno = errno; - how = "adt_set_from_ucred() failed to set user credential"; - goto fail; - } - - if ((event = adt_alloc_event(*ah, ADT_ssh)) == NULL) { - saved_errno = errno; - how = "couldn't allocate adt event"; - goto fail; - } - - if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { - saved_errno = errno; - how = "couldn't put adt event"; - goto fail; - } - - adt_free_event(event); - ucred_free(ucred); - /* Don't end adt session - leave for when logging out */ - return; - -fail: - if (ucred != NULL) - ucred_free(ucred); - adt_free_event(event); - (void) adt_end_session(*ah); - - fatal("Auditing of login failed: %s (%s)", - strerror(saved_errno), how); -} - -void -audit_sshd_login_failure(adt_session_data_t **ah, int pam_retval, char *user) -{ - adt_event_data_t *event = NULL; - const char *how; - int saved_errno = 0; - struct passwd pwd; - char *pwdbuf = NULL; - size_t pwdbuf_len; - long pwdbuf_len_max; - uid_t uid = ADT_NO_ATTRIB; - gid_t gid = ADT_NO_ATTRIB; - - if (ah == NULL) { - how = "programmer error"; - saved_errno = EINVAL; - goto fail; - } - - if ((pwdbuf_len_max = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) { - saved_errno = errno; - how = "couldn't determine maximum size of password buffer"; - goto fail; - } - - pwdbuf_len = (size_t)pwdbuf_len_max; - pwdbuf = xmalloc(pwdbuf_len); - - if (adt_start_session(ah, NULL, ADT_USE_PROC_DATA) != 0) { - saved_errno = errno; - how = "couldn't start adt session"; - goto fail; - } - - /* - * Its possible to reach this point with user being invalid so - * we check here to make sure that the user in question has a valid - * password entry. - */ - if ((user != NULL) && - (getpwnam_r(user, &pwd, pwdbuf, pwdbuf_len) != NULL)) { - uid = pwd.pw_uid; - gid = pwd.pw_gid; - } - - if (adt_set_user(*ah, uid, gid, uid, gid, NULL, ADT_NEW) != 0) { - saved_errno = errno; - how = "couldn't set adt user"; - goto fail; - } - - if ((event = adt_alloc_event(*ah, ADT_ssh)) == NULL) { - saved_errno = errno; - how = "couldn't allocate adt event"; - goto fail; - } - - if (adt_put_event(event, ADT_FAILURE, ADT_FAIL_PAM + pam_retval) != 0) { - saved_errno = errno; - how = "couldn't put adt event"; - goto fail; - } - - xfree(pwdbuf); - adt_free_event(event); - (void) adt_end_session(*ah); - *ah = NULL; - return; - -fail: - if (pwdbuf != NULL) - xfree(pwdbuf); - adt_free_event(event); - (void) adt_end_session(*ah); - - fatal("Auditing of login failed: %s (%s)", - strerror(saved_errno), how); -} - -void -audit_sshd_logout(adt_session_data_t **ah) -{ - adt_event_data_t *event = NULL; - const char *how = "programmer error"; - int saved_errno = 0; - - if (!ah) { - saved_errno = EINVAL; - goto fail; - } - - if ((event = adt_alloc_event(*ah, ADT_logout)) == NULL) { - saved_errno = errno; - how = "couldn't allocate adt event"; - goto fail; - } - - if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { - saved_errno = errno; - how = "couldn't put adt event"; - goto fail; - } - - adt_free_event(event); - (void) adt_end_session(*ah); - *ah = NULL; - return; - -fail: - adt_free_event(event); - (void) adt_end_session(*ah); - - fatal("Auditing of logout failed: %s (%s)", - how, strerror(saved_errno)); -} - -/* - * audit_sshd_settid stores the terminal id while it is still - * available. - * - * The failure cases are lack of resources or incorrect permissions. - * libbsm generates syslog messages, so there's no value doing more - * here. ADT_NO_AUDIT leaves the auid at AU_NOAUDITID and will be - * replaced when one of the above functions is called. - */ -void -audit_sshd_settid(int sock) -{ - adt_session_data_t *ah; - adt_termid_t *termid; - - if (adt_start_session(&ah, NULL, 0) == 0) { - if (adt_load_termid(sock, &termid) == 0) { - if (adt_set_user(ah, ADT_NO_AUDIT, - ADT_NO_AUDIT, 0, ADT_NO_AUDIT, - termid, ADT_SETTID) == 0) - (void) adt_set_proc(ah); - free(termid); - } - (void) adt_end_session(ah); - } -} diff --git a/usr/src/cmd/ssh/sshd/bsmaudit.h b/usr/src/cmd/ssh/sshd/bsmaudit.h deleted file mode 100644 index 72f599a240..0000000000 --- a/usr/src/cmd/ssh/sshd/bsmaudit.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - -#ifndef _BSMAUDIT_H -#define _BSMAUDIT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bsm/adt.h> -#include <bsm/adt_event.h> -#include <pwd.h> - -void audit_sshd_chauthtok(int pam_retval, uid_t uid, gid_t gid); -void audit_sshd_login(adt_session_data_t **ah, pid_t pid); -void audit_sshd_login_failure(adt_session_data_t **ah, int pam_retval, - char *user); -void audit_sshd_logout(adt_session_data_t **ah); -void audit_sshd_settid(int); - -#ifdef __cplusplus -} -#endif - -#endif /* _BSMAUDIT_H */ diff --git a/usr/src/cmd/ssh/sshd/groupaccess.c b/usr/src/cmd/ssh/sshd/groupaccess.c deleted file mode 100644 index 2239832e1b..0000000000 --- a/usr/src/cmd/ssh/sshd/groupaccess.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Copyright (c) 2001 Kevin Steves. 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: groupaccess.c,v 1.5 2002/03/04 17:27:39 stevesk Exp $"); - -#include "groupaccess.h" -#include "xmalloc.h" -#include "match.h" -#include "log.h" -#include <alloca.h> - -static int ngroups, ngroups_lim; -static char **groups_byname; - -/* - * Initialize group access list for user with primary (base) and - * supplementary groups. Return the number of groups in the list. - */ -int -ga_init(const char *user, gid_t base) -{ - gid_t *groups_bygid; - int i, j; - struct group *gr; - - if (ngroups_lim == 0) { - /* Add one for the base gid */ - ngroups_lim = sysconf(_SC_NGROUPS_MAX) + 1; - groups_byname = malloc(sizeof (char *) * ngroups_lim); - } else if (ngroups > 0) - ga_free(); - - groups_bygid = alloca(ngroups_lim * sizeof (gid_t)); - - ngroups = ngroups_lim; - if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) - log("getgrouplist: groups list too small"); - for (i = 0, j = 0; i < ngroups; i++) - if ((gr = getgrgid(groups_bygid[i])) != NULL) - groups_byname[j++] = xstrdup(gr->gr_name); - return (ngroups = j); -} - -/* - * Return 1 if one of user's groups is contained in groups. - * Return 0 otherwise. Use match_pattern() for string comparison. - */ -int -ga_match(char * const *groups, int n) -{ - int i, j; - - for (i = 0; i < ngroups; i++) - for (j = 0; j < n; j++) - if (match_pattern(groups_byname[i], groups[j])) - return (1); - return (0); -} - -/* - * Return 1 if one of user's groups matches group_pattern list. - * Return 0 on negated or no match. - */ -int -ga_match_pattern_list(const char *group_pattern) -{ - int i, found = 0; - size_t len = strlen(group_pattern); - - for (i = 0; i < ngroups; i++) { - switch (match_pattern_list(groups_byname[i], - group_pattern, len, 0)) { - case -1: - return (0); /* Negated match wins */ - case 0: - continue; - case 1: - found = 1; - } - } - return (found); -} - -/* - * Free memory allocated for group access list. - */ -void -ga_free(void) -{ - int i; - - if (ngroups > 0) { - for (i = 0; i < ngroups; i++) - xfree(groups_byname[i]); - ngroups = 0; - } -} diff --git a/usr/src/cmd/ssh/sshd/gss-serv.c b/usr/src/cmd/ssh/sshd/gss-serv.c deleted file mode 100644 index 7ff525c306..0000000000 --- a/usr/src/cmd/ssh/sshd/gss-serv.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" - -#ifdef GSSAPI - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "includes.h" -#include "ssh.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "packet.h" -#include "compat.h" -#include <openssl/evp.h> -#include "cipher.h" -#include "kex.h" -#include "auth.h" -#include "log.h" -#include "channels.h" -#include "session.h" -#include "dispatch.h" -#include "servconf.h" -#include "uidswap.h" -#include "compat.h" -#include <pwd.h> - -#include "ssh-gss.h" - -extern char **environ; - -extern ServerOptions options; -extern uchar_t *session_id2; -extern int session_id2_len; - -Gssctxt *xxx_gssctxt; - -void -ssh_gssapi_server_kex_hook(Kex *kex, char **proposal) -{ - gss_OID_set mechs = GSS_C_NULL_OID_SET; - - if (kex == NULL || !kex->server) - fatal("INTERNAL ERROR (%s)", __func__); - - ssh_gssapi_server_mechs(&mechs); - ssh_gssapi_modify_kex(kex, mechs, proposal); -} - -void -ssh_gssapi_server_mechs(gss_OID_set *mechs) -{ - static gss_OID_set supported = GSS_C_NULL_OID_SET; - gss_OID_set s, acquired, indicated = GSS_C_NULL_OID_SET; - gss_cred_id_t creds; - OM_uint32 maj, min; - int i; - - if (!mechs) { - (void) gss_release_oid_set(&min, &supported); - return; - } - - if (supported != GSS_C_NULL_OID_SET) { - *mechs = supported; - return; - } - - *mechs = GSS_C_NULL_OID_SET; - - maj = gss_create_empty_oid_set(&min, &s); - if (GSS_ERROR(maj)) { - debug("Could not allocate GSS-API resources (%s)", - ssh_gssapi_last_error(NULL, &maj, &min)); - return; - } - - maj = gss_indicate_mechs(&min, &indicated); - if (GSS_ERROR(maj)) { - debug("No GSS-API mechanisms are installed"); - return; - } - - maj = gss_acquire_cred(&min, GSS_C_NO_NAME, 0, indicated, - GSS_C_ACCEPT, &creds, &acquired, NULL); - - if (GSS_ERROR(maj)) - debug("Failed to acquire GSS-API credentials for any " - "mechanisms (%s)", ssh_gssapi_last_error(NULL, &maj, &min)); - - (void) gss_release_oid_set(&min, &indicated); - (void) gss_release_cred(&min, &creds); - - if (acquired == GSS_C_NULL_OID_SET || acquired->count == 0) - return; - - for (i = 0; i < acquired->count; i++) { - if (ssh_gssapi_is_spnego(&acquired->elements[i])) - continue; - - maj = gss_add_oid_set_member(&min, &acquired->elements[i], &s); - if (GSS_ERROR(maj)) { - debug("Could not allocate GSS-API resources (%s)", - ssh_gssapi_last_error(NULL, &maj, &min)); - return; - } - } - (void) gss_release_oid_set(&min, &acquired); - - if (s->count) { - supported = s; - *mechs = s; - } -} - -/* - * Wrapper around accept_sec_context. Requires that the context contains: - * - * oid - * credentials (from ssh_gssapi_acquire_cred) - */ -/* Priviledged */ -OM_uint32 -ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok, - gss_buffer_t send_tok) -{ - /* - * Acquiring a cred for the ctx->desired_mech for GSS_C_NO_NAME - * may well be probably better than using GSS_C_NO_CREDENTIAL - * and then checking that ctx->desired_mech agrees with - * ctx->actual_mech... - */ - ctx->major = gss_accept_sec_context(&ctx->minor, &ctx->context, - GSS_C_NO_CREDENTIAL, recv_tok, GSS_C_NO_CHANNEL_BINDINGS, - &ctx->src_name, &ctx->actual_mech, send_tok, &ctx->flags, - NULL, &ctx->deleg_creds); - - if (GSS_ERROR(ctx->major)) - ssh_gssapi_error(ctx, "accepting security context"); - - if (ctx->major == GSS_S_CONTINUE_NEEDED && send_tok->length == 0) - fatal("Zero length GSS context token output when " - "continue needed"); - else if (GSS_ERROR(ctx->major) && send_tok->length == 0) - debug2("Zero length GSS context error token output"); - - if (ctx->major == GSS_S_COMPLETE && - ctx->desired_mech != GSS_C_NULL_OID && - (ctx->desired_mech->length != ctx->actual_mech->length || - memcmp(ctx->desired_mech->elements, ctx->actual_mech->elements, - ctx->desired_mech->length) != 0)) { - - gss_OID_set supported; - OM_uint32 min; - int present = 0; - - debug("The client did not use the GSS-API mechanism it " - "asked for"); - - /* Let it slide as long as the mech is supported */ - ssh_gssapi_server_mechs(&supported); - if (supported != GSS_C_NULL_OID_SET) { - (void) gss_test_oid_set_member(&min, ctx->actual_mech, - supported, &present); - } - if (!present) - ctx->major = GSS_S_BAD_MECH; - } - - if (ctx->deleg_creds) - debug("Received delegated GSS credentials"); - - if (ctx->major == GSS_S_COMPLETE) { - ctx->major = gss_inquire_context(&ctx->minor, ctx->context, - NULL, &ctx->dst_name, NULL, NULL, NULL, NULL, - &ctx->established); - - if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, - "inquiring established sec context"); - return (ctx->major); - } - - xxx_gssctxt = ctx; - } - - return (ctx->major); -} - - -/* As user - called through fatal cleanup hook */ -void -ssh_gssapi_cleanup_creds(Gssctxt *ctx) -{ -#ifdef HAVE_GSS_STORE_CRED - /* pam_setcred() will take care of this */ - return; -#else - return; -/* #error "Portability broken in cleanup of stored creds" */ -#endif /* HAVE_GSS_STORE_CRED */ -} - -void -ssh_gssapi_storecreds(Gssctxt *ctx, Authctxt *authctxt) -{ -#ifdef USE_PAM - char **penv, **tmp_env; -#endif /* USE_PAM */ - - if (authctxt == NULL) { - error("Missing context while storing GSS-API credentials"); - return; - } - - if (ctx == NULL && xxx_gssctxt == NULL) - return; - - if (ctx == NULL) - ctx = xxx_gssctxt; - - if (!options.gss_cleanup_creds || - ctx->deleg_creds == GSS_C_NO_CREDENTIAL) { - debug3("Not storing delegated GSS credentials" - " (none delegated)"); - return; - } - - if (!authctxt->valid || authctxt->pw == NULL) { - debug3("Not storing delegated GSS credentials" - " for invalid user"); - return; - } - - debug("Storing delegated GSS-API credentials"); - - /* - * The GSS-API has a flaw in that it does not provide a - * mechanism by which delegated credentials can be made - * available for acquisition by GSS_Acquire_cred() et. al.; - * gss_store_cred() is the proposed GSS-API extension for - * generically storing delegated credentials. - * - * gss_store_cred() does not speak to how credential stores are - * referenced. Generically this may be done by switching to the - * user context of the user in whose default credential store we - * wish to place delegated credentials. But environment - * variables could conceivably affect the choice of credential - * store as well, and perhaps in a mechanism-specific manner. - * - * SUNW -- On Solaris the euid selects the current credential - * store, but PAM modules could select alternate stores by - * setting, for example, KRB5CCNAME, so we also use the PAM - * environment temporarily. - */ - -#ifdef HAVE_GSS_STORE_CRED -#ifdef USE_PAM - /* - * PAM may have set mechanism-specific variables (e.g., - * KRB5CCNAME). fetch_pam_environment() protects against LD_* - * and other environment variables. - */ - penv = fetch_pam_environment(authctxt); - tmp_env = environ; - environ = penv; -#endif /* USE_PAM */ - if (authctxt->pw->pw_uid != geteuid()) { - temporarily_use_uid(authctxt->pw); - ctx->major = gss_store_cred(&ctx->minor, ctx->deleg_creds, - GSS_C_INITIATE, GSS_C_NULL_OID, 0, ctx->default_creds, - NULL, NULL); - restore_uid(); - } else { - /* only when logging in as the privileged user used by sshd */ - ctx->major = gss_store_cred(&ctx->minor, ctx->deleg_creds, - GSS_C_INITIATE, GSS_C_NULL_OID, 0, ctx->default_creds, - NULL, NULL); - } -#ifdef USE_PAM - environ = tmp_env; - free_pam_environment(penv); -#endif /* USE_PAM */ - if (GSS_ERROR(ctx->major)) - ssh_gssapi_error(ctx, "storing delegated credentials"); - -#else -#ifdef KRB5_GSS -#error "MIT/Heimdal krb5-specific code missing in ssh_gssapi_storecreds()" - if (ssh_gssapi_is_krb5(ctx->mech)) - ssh_gssapi_krb5_storecreds(ctx); -#endif /* KRB5_GSS */ -#ifdef GSI_GSS -#error "GSI krb5-specific code missing in ssh_gssapi_storecreds()" - if (ssh_gssapi_is_gsi(ctx->mech)) - ssh_gssapi_krb5_storecreds(ctx); -#endif /* GSI_GSS */ -/* #error "Mechanism-specific code missing in ssh_gssapi_storecreds()" */ - return; -#endif /* HAVE_GSS_STORE_CRED */ -} - -void -ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, uint_t *envsizep) -{ - /* - * MIT/Heimdal/GSI specific code goes here. - * - * On Solaris there's nothing to do here as the GSS store and - * related environment variables are to be set by PAM, if at all - * (no environment variables are needed to address the default - * credential store -- the euid does that). - */ -#ifdef KRB5_GSS -#error "MIT/Heimdal krb5-specific code missing in ssh_gssapi_storecreds()" -#endif /* KRB5_GSS */ -#ifdef GSI_GSS -#error "GSI krb5-specific code missing in ssh_gssapi_storecreds()" -#endif /* GSI_GSS */ -} - -int -ssh_gssapi_userok(Gssctxt *ctx, char *user) -{ - if (ctx == NULL) { - debug3("INTERNAL ERROR: %s", __func__); - return (0); - } - - if (user == NULL || *user == '\0') - return (0); - -#ifdef HAVE___GSS_USEROK - { - int user_ok = 0; - - ctx->major = __gss_userok(&ctx->minor, ctx->src_name, user, - &user_ok); - if (GSS_ERROR(ctx->major)) { - debug2("__GSS_userok() failed"); - return (0); - } - - if (user_ok) - return (1); - - /* fall through */ - } -#else -#ifdef GSSAPI_SIMPLE_USEROK - { - /* Mechanism-generic */ - OM_uint32 min; - gss_buffer_desc buf, ename1, ename2; - gss_name_t iname, cname; - int eql; - - buf.value = user; - buf.length = strlen(user); - ctx->major = gss_import_name(&ctx->minor, &buf, - GSS_C_NULL_OID, &iname); - if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, - "importing name for authorizing initiator"); - goto failed_simple_userok; - } - - ctx->major = gss_canonicalize_name(&ctx->minor, iname, - ctx->actual_mech, &cname); - (void) gss_release_name(&min, &iname); - if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, "canonicalizing name"); - goto failed_simple_userok; - } - - ctx->major = gss_export_name(&ctx->minor, cname, &ename1); - (void) gss_release_name(&min, &cname); - if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, "exporting name"); - goto failed_simple_userok; - } - - ctx->major = gss_export_name(&ctx->minor, ctx->src_name, - &ename2); - if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, - "exporting client principal name"); - (void) gss_release_buffer(&min, &ename1); - goto failed_simple_userok; - } - - eql = (ename1.length == ename2.length && - memcmp(ename1.value, ename2.value, ename1.length) == 0); - - (void) gss_release_buffer(&min, &ename1); - (void) gss_release_buffer(&min, &ename2); - - if (eql) - return (1); - /* fall through */ - } -failed_simple_userok: -#endif /* GSSAPI_SIMPLE_USEROK */ -#ifdef HAVE_GSSCRED_API - { - /* Mechanism-generic, Solaris-specific */ - OM_uint32 maj; - uid_t uid; - struct passwd *pw; - - maj = gsscred_name_to_unix_cred(ctx->src_name, - ctx->actual_mech, &uid, NULL, NULL, NULL); - - if (GSS_ERROR(maj)) - goto failed_simple_gsscred_userok; - - if ((pw = getpwnam(user)) == NULL) - goto failed_simple_gsscred_userok; - - if (pw->pw_uid == uid) - return (1); - /* fall through */ - } - -failed_simple_gsscred_userok: -#endif /* HAVE_GSSCRED_API */ -#ifdef KRB5_GSS - if (ssh_gssapi_is_krb5(ctx->mech)) - if (ssh_gssapi_krb5_userok(ctx->src_name, user)) - return (1); -#endif /* KRB5_GSS */ -#ifdef GSI_GSS - if (ssh_gssapi_is_gsi(ctx->mech)) - if (ssh_gssapi_gsi_userok(ctx->src_name, user)) - return (1); -#endif /* GSI_GSS */ -#endif /* HAVE___GSS_USEROK */ - - /* default to not authorized */ - return (0); -} - -char * -ssh_gssapi_localname(Gssctxt *ctx) -{ - if (ctx == NULL) { - debug3("INTERNAL ERROR: %s", __func__); - return (NULL); - } - - debug2("Mapping initiator GSS-API principal to local username"); -#ifdef HAVE_GSSCRED_API - { - /* Mechanism-generic, Solaris-specific */ - OM_uint32 maj; - uid_t uid; - struct passwd *pw; - - if (ctx->src_name == GSS_C_NO_NAME) - goto failed_gsscred_localname; - - maj = gsscred_name_to_unix_cred(ctx->src_name, - ctx->actual_mech, &uid, NULL, NULL, NULL); - - if (GSS_ERROR(maj)) - goto failed_gsscred_localname; - - if ((pw = getpwuid(uid)) == NULL) - goto failed_gsscred_localname; - - debug2("Mapped the initiator to: %s", pw->pw_name); - return (xstrdup(pw->pw_name)); - } -failed_gsscred_localname: -#endif /* HAVE_GSSCRED_API */ -#ifdef KRB5_GSS -#error "ssh_gssapi_krb5_localname() not implemented" - if (ssh_gssapi_is_krb5(ctx->mech)) - return (ssh_gssapi_krb5_localname(ctx->src_name)); -#endif /* KRB5_GSS */ -#ifdef GSI_GSS -#error "ssh_gssapi_gsi_localname() not implemented" - if (ssh_gssapi_is_gsi(ctx->mech)) - return (ssh_gssapi_gsi_localname(ctx->src_name)); -#endif /* GSI_GSS */ - return (NULL); -} -#endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/sshd/loginrec.c b/usr/src/cmd/ssh/sshd/loginrec.c deleted file mode 100644 index 33998b02b9..0000000000 --- a/usr/src/cmd/ssh/sshd/loginrec.c +++ /dev/null @@ -1,1533 +0,0 @@ -/* - * Copyright (c) 2000 Andre Lucas. All rights reserved. - * Portions copyright (c) 1998 Todd C. Miller - * Portions copyright (c) 1996 Jason Downs - * Portions copyright (c) 1996 Theo de Raadt - * - * 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 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 - * 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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/** - ** loginrec.c: platform-independent login recording and lastlog retrieval - **/ - -/* - The new login code explained - ============================ - - This code attempts to provide a common interface to login recording - (utmp and friends) and last login time retrieval. - - Its primary means of achieving this is to use 'struct logininfo', a - union of all the useful fields in the various different types of - system login record structures one finds on UNIX variants. - - We depend on autoconf to define which recording methods are to be - used, and which fields are contained in the relevant data structures - on the local system. Many C preprocessor symbols affect which code - gets compiled here. - - The code is designed to make it easy to modify a particular - recording method, without affecting other methods nor requiring so - many nested conditional compilation blocks as were commonplace in - the old code. - - For login recording, we try to use the local system's libraries as - these are clearly most likely to work correctly. For utmp systems - this usually means login() and logout() or setutent() etc., probably - in libutil, along with logwtmp() etc. On these systems, we fall back - to writing the files directly if we have to, though this method - requires very thorough testing so we do not corrupt local auditing - information. These files and their access methods are very system - specific indeed. - - For utmpx systems, the corresponding library functions are - setutxent() etc. To the author's knowledge, all utmpx systems have - these library functions and so no direct write is attempted. If such - a system exists and needs support, direct analogues of the [uw]tmp - code should suffice. - - Retrieving the time of last login ('lastlog') is in some ways even - more problemmatic than login recording. Some systems provide a - simple table of all users which we seek based on uid and retrieve a - relatively standard structure. Others record the same information in - a directory with a separate file, and others don't record the - information separately at all. For systems in the latter category, - we look backwards in the wtmp or wtmpx file for the last login entry - for our user. Naturally this is slower and on busy systems could - incur a significant performance penalty. - - Calling the new code - -------------------- - - In OpenSSH all login recording and retrieval is performed in - login.c. Here you'll find working examples. Also, in the logintest.c - program there are more examples. - - Internal handler calling method - ------------------------------- - - When a call is made to login_login() or login_logout(), both - routines set a struct logininfo flag defining which action (log in, - or log out) is to be taken. They both then call login_write(), which - calls whichever of the many structure-specific handlers autoconf - selects for the local system. - - The handlers themselves handle system data structure specifics. Both - struct utmp and struct utmpx have utility functions (see - construct_utmp*()) to try to make it simpler to add extra systems - that introduce new features to either structure. - - While it may seem terribly wasteful to replicate so much similar - code for each method, experience has shown that maintaining code to - write both struct utmp and utmpx in one function, whilst maintaining - support for all systems whether they have library support or not, is - a difficult and time-consuming task. - - Lastlog support proceeds similarly. Functions login_get_lastlog() - (and its OpenSSH-tuned friend login_get_lastlog_time()) call - getlast_entry(), which tries one of three methods to find the last - login time. It uses local system lastlog support if it can, - otherwise it tries wtmp or wtmpx before giving up and returning 0, - meaning "tilt". - - Maintenance - ----------- - - In many cases it's possible to tweak autoconf to select the correct - methods for a particular platform, either by improving the detection - code (best), or by presetting DISABLE_<method> or CONF_<method>_FILE - symbols for the platform. - - Use logintest to check which symbols are defined before modifying - configure.ac and loginrec.c. (You have to build logintest yourself - with 'make logintest' as it's not built by default.) - - Otherwise, patches to the specific method(s) are very helpful! - -*/ - -/** - ** TODO: - ** homegrown ttyslot() - ** test, test, test - ** - ** Platform status: - ** ---------------- - ** - ** Known good: - ** Linux (Redhat 6.2, Debian) - ** Solaris - ** HP-UX 10.20 (gcc only) - ** IRIX - ** NeXT - M68k/HPPA/Sparc (4.2/3.3) - ** - ** Testing required: Please send reports! - ** NetBSD - ** HP-UX 11 - ** AIX - ** - ** Platforms with known problems: - ** Some variants of Slackware Linux - ** - **/ - -#include "includes.h" - -#include "ssh.h" -#include "xmalloc.h" -#include "loginrec.h" -#include "log.h" -#include "atomicio.h" - -RCSID("$Id: loginrec.c,v 1.44 2002/09/26 00:38:49 tim Exp $"); - -#ifdef HAVE_UTIL_H -# include <util.h> -#endif - -#ifdef HAVE_LIBUTIL_H -# include <libutil.h> -#endif - -/** - ** prototypes for helper functions in this file - **/ - -#if HAVE_UTMP_H -void set_utmp_time(struct logininfo *li, struct utmp *ut); -void construct_utmp(struct logininfo *li, struct utmp *ut); -#endif - -#ifdef HAVE_UTMPX_H -void set_utmpx_time(struct logininfo *li, struct utmpx *ut); -void construct_utmpx(struct logininfo *li, struct utmpx *ut); -#endif - -int utmp_write_entry(struct logininfo *li); -int utmpx_write_entry(struct logininfo *li); -int wtmp_write_entry(struct logininfo *li); -int wtmpx_write_entry(struct logininfo *li); -int lastlog_write_entry(struct logininfo *li); -int syslogin_write_entry(struct logininfo *li); - -int getlast_entry(struct logininfo *li); -int lastlog_get_entry(struct logininfo *li); -int wtmp_get_entry(struct logininfo *li); -int wtmpx_get_entry(struct logininfo *li); - -/* pick the shortest string */ -#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) ) - -/** - ** platform-independent login functions - **/ - -/* login_login(struct logininfo *) -Record a login - * - * Call with a pointer to a struct logininfo initialised with - * login_init_entry() or login_alloc_entry() - * - * Returns: - * >0 if successful - * 0 on failure (will use OpenSSH's logging facilities for diagnostics) - */ -int -login_login (struct logininfo *li) -{ - li->type = LTYPE_LOGIN; - return login_write(li); -} - - -/* login_logout(struct logininfo *) - Record a logout - * - * Call as with login_login() - * - * Returns: - * >0 if successful - * 0 on failure (will use OpenSSH's logging facilities for diagnostics) - */ -int -login_logout(struct logininfo *li) -{ - li->type = LTYPE_LOGOUT; - return login_write(li); -} - -/* login_get_lastlog_time(int) - Retrieve the last login time - * - * Retrieve the last login time for the given uid. Will try to use the - * system lastlog facilities if they are available, but will fall back - * to looking in wtmp/wtmpx if necessary - * - * Returns: - * 0 on failure, or if user has never logged in - * Time in seconds from the epoch if successful - * - * Useful preprocessor symbols: - * DISABLE_LASTLOG: If set, *never* even try to retrieve lastlog - * info - * USE_LASTLOG: If set, indicates the presence of system lastlog - * facilities. If this and DISABLE_LASTLOG are not set, - * try to retrieve lastlog information from wtmp/wtmpx. - */ -#if 0 -unsigned int -login_get_lastlog_time(const int uid) -{ - struct logininfo li; - - if (login_get_lastlog(&li, uid)) - return li.tv_sec; - else - return 0; -} -#endif - -/* login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry - * - * Retrieve a logininfo structure populated (only partially) with - * information from the system lastlog data, or from wtmp/wtmpx if no - * system lastlog information exists. - * - * Note this routine must be given a pre-allocated logininfo. - * - * Returns: - * >0: A pointer to your struct logininfo if successful - * 0 on failure (will use OpenSSH's logging facilities for diagnostics) - * - */ -struct logininfo * -login_get_lastlog(struct logininfo *li, const int uid) -{ - struct passwd *pw; - - (void) memset(li, '\0', sizeof(*li)); - li->uid = uid; - - /* - * If we don't have a 'real' lastlog, we need the username to - * reliably search wtmp(x) for the last login (see - * wtmp_get_entry().) - */ - pw = getpwuid(uid); - if (pw == NULL) - fatal("login_get_lastlog: Cannot find account for uid %i", uid); - - /* No MIN_SIZEOF here - we absolutely *must not* truncate the - * username */ - (void) strlcpy(li->username, pw->pw_name, sizeof(li->username)); - - if (getlast_entry(li)) - return li; - else - return NULL; -} - - -/* login_alloc_entry() - Allocate and initialise a logininfo - * structure - * - * This function creates a new struct logininfo, a data structure - * meant to carry the information required to portably record login info. - * - * Returns a pointer to a newly created struct logininfo. If memory - * allocation fails, the program halts. - */ -struct -logininfo *login_alloc_entry(int pid, const char *username, - const char *hostname, const char *line, - const char *progname) -{ - struct logininfo *newli; - - newli = (struct logininfo *) xmalloc (sizeof(*newli)); - (void)login_init_entry(newli, pid, username, hostname, line, progname); - return newli; -} - - -/* login_free_entry(struct logininfo *) - free struct memory */ -void -login_free_entry(struct logininfo *li) -{ - xfree(li); -} - - -/* login_init_entry() - * - initialise a struct logininfo - * - * Populates a new struct logininfo, a data structure meant to carry - * the information required to portably record login info. - * - * Returns: 1 - */ -int -login_init_entry(struct logininfo *li, int pid, const char *username, - const char *hostname, const char *line, const char *progname) -{ - struct passwd *pw; - - (void) memset(li, 0, sizeof(*li)); - - li->pid = pid; - - /* set the line information */ - if (line) - (void) line_fullname(li->line, line, sizeof(li->line)); - else - li->line_null = 1; - - if (progname) - (void) strlcpy(li->progname, progname, sizeof(li->progname)); - else - li->progname_null = 1; - - if (username) { - (void) strlcpy(li->username, username, sizeof(li->username)); - pw = getpwnam(li->username); - if (pw == NULL) - fatal("login_init_entry: Cannot find user \"%s\"", li->username); - li->uid = pw->pw_uid; - } - - if (hostname) - (void) strlcpy(li->hostname, hostname, sizeof(li->hostname)); - - return 1; -} - -/* login_set_current_time(struct logininfo *) - set the current time - * - * Set the current time in a logininfo structure. This function is - * meant to eliminate the need to deal with system dependencies for - * time handling. - */ -void -login_set_current_time(struct logininfo *li) -{ - struct timeval tv; - - (void) gettimeofday(&tv, NULL); - - li->tv_sec = tv.tv_sec; - li->tv_usec = tv.tv_usec; -} - -/* copy a sockaddr_* into our logininfo */ -void -login_set_addr(struct logininfo *li, const struct sockaddr *sa, - const unsigned int sa_size) -{ - unsigned int bufsize = sa_size; - - /* make sure we don't overrun our union */ - if (sizeof(li->hostaddr) < sa_size) - bufsize = sizeof(li->hostaddr); - - (void) memcpy((void *)&(li->hostaddr.sa), (const void *)sa, bufsize); -} - - -/** - ** login_write: Call low-level recording functions based on autoconf - ** results - **/ -int -login_write (struct logininfo *li) -{ -#ifndef HAVE_CYGWIN - if ((int)geteuid() != 0) { - log("Attempt to write login records by non-root user (aborting)"); - return 1; - } -#endif - - /* set the timestamp */ - login_set_current_time(li); -#ifdef USE_LOGIN - syslogin_write_entry(li); -#endif -#ifdef USE_LASTLOG - if (li->type == LTYPE_LOGIN) { - (void) lastlog_write_entry(li); - } -#endif -#ifdef USE_UTMP - utmp_write_entry(li); -#endif -#ifdef USE_WTMP - wtmp_write_entry(li); -#endif -#ifdef USE_UTMPX - (void) utmpx_write_entry(li); -#endif -#ifdef USE_WTMPX - (void) wtmpx_write_entry(li); -#endif - return 0; -} - -/** - ** getlast_entry: Call low-level functions to retrieve the last login - ** time. - **/ - -/* take the uid in li and return the last login time */ -int -getlast_entry(struct logininfo *li) -{ -#ifdef USE_LASTLOG - return(lastlog_get_entry(li)); -#else /* !USE_LASTLOG */ - -#ifdef DISABLE_LASTLOG - /* On some systems we shouldn't even try to obtain last login - * time, e.g. AIX */ - return 0; -# else /* DISABLE_LASTLOG */ - /* Try to retrieve the last login time from wtmp */ -# if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) - /* retrieve last login time from utmp */ - return (wtmp_get_entry(li)); -# else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */ - /* If wtmp isn't available, try wtmpx */ -# if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) - /* retrieve last login time from utmpx */ - return (wtmpx_get_entry(li)); -# else - /* Give up: No means of retrieving last login time */ - return 0; -# endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */ -# endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */ -# endif /* DISABLE_LASTLOG */ -#endif /* USE_LASTLOG */ -} - - - -/* - * 'line' string utility functions - * - * These functions process the 'line' string into one of three forms: - * - * 1. The full filename (including '/dev') - * 2. The stripped name (excluding '/dev') - * 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00 - * /dev/pts/1 -> ts/1 ) - * - * Form 3 is used on some systems to identify a .tmp.? entry when - * attempting to remove it. Typically both addition and removal is - * performed by one application - say, sshd - so as long as the choice - * uniquely identifies a terminal it's ok. - */ - - -/* line_fullname(): add the leading '/dev/' if it doesn't exist make - * sure dst has enough space, if not just copy src (ugh) */ -char * -line_fullname(char *dst, const char *src, int dstsize) -{ - (void) memset(dst, '\0', dstsize); - /* "sshd" is special, like "ftp" */ - if (strcmp(src, "sshd") || - ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5)))) { - (void) strlcpy(dst, src, dstsize); - } else { - (void) strlcpy(dst, "/dev/", dstsize); - (void) strlcat(dst, src, dstsize); - } - return dst; -} - -/* line_stripname(): strip the leading '/dev' if it exists, return dst */ -char * -line_stripname(char *dst, const char *src, int dstsize) -{ - (void) memset(dst, '\0', dstsize); - if (strncmp(src, "/dev/", 5) == 0) - (void) strlcpy(dst, src + 5, dstsize); - else - (void) strlcpy(dst, src, dstsize); - return dst; -} - -/* line_abbrevname(): Return the abbreviated (usually four-character) - * form of the line (Just use the last <dstsize> characters of the - * full name.) - * - * NOTE: use strncpy because we do NOT necessarily want zero - * termination */ -char * -line_abbrevname(char *dst, const char *src, int dstsize) -{ - size_t len; - - (void) memset(dst, '\0', dstsize); - - /* Always skip prefix if present */ - if (strncmp(src, "/dev/", 5) == 0) - src += 5; - -#ifdef WITH_ABBREV_NO_TTY - if (strncmp(src, "tty", 3) == 0) - src += 3; -#endif - - len = strlen(src); - - if (len > 0) { - if (((int)len - dstsize) > 0) - src += ((int)len - dstsize); - - /* note: _don't_ change this to strlcpy */ - (void) strncpy(dst, src, (size_t)dstsize); - } - - return dst; -} - -/** - ** utmp utility functions - ** - ** These functions manipulate struct utmp, taking system differences - ** into account. - **/ - -#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) - -/* build the utmp structure */ -void -set_utmp_time(struct logininfo *li, struct utmp *ut) -{ -# ifdef HAVE_TV_IN_UTMP - ut->ut_tv.tv_sec = li->tv_sec; - ut->ut_tv.tv_usec = li->tv_usec; -# else -# ifdef HAVE_TIME_IN_UTMP - ut->ut_time = li->tv_sec; -# endif -# endif -} - -void -construct_utmp(struct logininfo *li, - struct utmp *ut) -{ - (void) memset(ut, '\0', sizeof(*ut)); - - /* First fill out fields used for both logins and logouts */ - -# ifdef HAVE_ID_IN_UTMP - (void) line_abbrevname(ut->ut_id, li->line, sizeof(ut->ut_id)); -# endif - -# ifdef HAVE_TYPE_IN_UTMP - /* This is done here to keep utmp constants out of struct logininfo */ - switch (li->type) { - case LTYPE_LOGIN: - ut->ut_type = USER_PROCESS; -#ifdef _UNICOS - cray_set_tmpdir(ut); -#endif - break; - case LTYPE_LOGOUT: - ut->ut_type = DEAD_PROCESS; -#ifdef _UNICOS - cray_retain_utmp(ut, li->pid); -#endif - break; - } -# endif - set_utmp_time(li, ut); - - (void) line_stripname(ut->ut_line, li->line, sizeof(ut->ut_line)); - -# ifdef HAVE_PID_IN_UTMP - ut->ut_pid = li->pid; -# endif - - /* If we're logging out, leave all other fields blank */ - if (li->type == LTYPE_LOGOUT) - return; - - /* - * These fields are only used when logging in, and are blank - * for logouts. - */ - - /* Use strncpy because we don't necessarily want null termination */ - (void) strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username)); -# ifdef HAVE_HOST_IN_UTMP - (void) strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); -# endif -# ifdef HAVE_ADDR_IN_UTMP - /* this is just a 32-bit IP address */ - if (li->hostaddr.sa.sa_family == AF_INET) - ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; -# endif -} -#endif /* USE_UTMP || USE_WTMP || USE_LOGIN */ - -/** - ** utmpx utility functions - ** - ** These functions manipulate struct utmpx, accounting for system - ** variations. - **/ - -#if defined(USE_UTMPX) || defined (USE_WTMPX) -/* build the utmpx structure */ -void -set_utmpx_time(struct logininfo *li, struct utmpx *utx) -{ -# ifdef HAVE_TV_IN_UTMPX - utx->ut_tv.tv_sec = li->tv_sec; - utx->ut_tv.tv_usec = li->tv_usec; -# else /* HAVE_TV_IN_UTMPX */ -# ifdef HAVE_TIME_IN_UTMPX - utx->ut_time = li->tv_sec; -# endif /* HAVE_TIME_IN_UTMPX */ -# endif /* HAVE_TV_IN_UTMPX */ -} - -void -construct_utmpx(struct logininfo *li, struct utmpx *utx) -{ - (void) memset(utx, '\0', sizeof(*utx)); -# ifdef HAVE_ID_IN_UTMPX - (void) line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); -# endif - - /* this is done here to keep utmp constants out of loginrec.h */ - switch (li->type) { - case LTYPE_LOGIN: - utx->ut_type = USER_PROCESS; - break; - case LTYPE_LOGOUT: - utx->ut_type = DEAD_PROCESS; - break; - } - if (!li->line_null) - (void) line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); - else if (!li->progname_null) - (void) line_stripname(utx->ut_line, li->progname, sizeof(utx->ut_line)); - - set_utmpx_time(li, utx); - utx->ut_pid = li->pid; - /* strncpy(): Don't necessarily want null termination */ - (void) strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); - - if (li->type == LTYPE_LOGOUT) - return; - - /* - * These fields are only used when logging in, and are blank - * for logouts. - */ - -# ifdef HAVE_HOST_IN_UTMPX - (void) strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); -# endif -# ifdef HAVE_ADDR_IN_UTMPX - /* this is just a 32-bit IP address */ - if (li->hostaddr.sa.sa_family == AF_INET) - utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; -# endif -# ifdef HAVE_SYSLEN_IN_UTMPX - /* ut_syslen is the length of the utx_host string */ - utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host)); -# endif -} -#endif /* USE_UTMPX || USE_WTMPX */ - -/** - ** Low-level utmp functions - **/ - -/* FIXME: (ATL) utmp_write_direct needs testing */ -#ifdef USE_UTMP - -/* if we can, use pututline() etc. */ -# if !defined(DISABLE_PUTUTLINE) && defined(HAVE_SETUTENT) && \ - defined(HAVE_PUTUTLINE) -# define UTMP_USE_LIBRARY -# endif - - -/* write a utmp entry with the system's help (pututline() and pals) */ -# ifdef UTMP_USE_LIBRARY -static int -utmp_write_library(struct logininfo *li, struct utmp *ut) -{ - setutent(); - pututline(ut); - -# ifdef HAVE_ENDUTENT - endutent(); -# endif - return 1; -} -# else /* UTMP_USE_LIBRARY */ - -/* write a utmp entry direct to the file */ -/* This is a slightly modification of code in OpenBSD's login.c */ -static int -utmp_write_direct(struct logininfo *li, struct utmp *ut) -{ - struct utmp old_ut; - register int fd; - int tty; - - /* FIXME: (ATL) ttyslot() needs local implementation */ - -#if defined(HAVE_GETTTYENT) - register struct ttyent *ty; - - tty=0; - - setttyent(); - while ((struct ttyent *)0 != (ty = getttyent())) { - tty++; - if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) - break; - } - endttyent(); - - if((struct ttyent *)0 == ty) { - log("utmp_write_entry: tty not found"); - return(1); - } -#else /* FIXME */ - - tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ - -#endif /* HAVE_GETTTYENT */ - - if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { - (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); - /* - * Prevent luser from zero'ing out ut_host. - * If the new ut_line is empty but the old one is not - * and ut_line and ut_name match, preserve the old ut_line. - */ - if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && - (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && - (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && - (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { - (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); - } - - (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); - if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) - log("utmp_write_direct: error writing %s: %s", - UTMP_FILE, strerror(errno)); - - (void)close(fd); - return 1; - } else { - return 0; - } -} -# endif /* UTMP_USE_LIBRARY */ - -static int -utmp_perform_login(struct logininfo *li) -{ - struct utmp ut; - - construct_utmp(li, &ut); -# ifdef UTMP_USE_LIBRARY - if (!utmp_write_library(li, &ut)) { - log("utmp_perform_login: utmp_write_library() failed"); - return 0; - } -# else - if (!utmp_write_direct(li, &ut)) { - log("utmp_perform_login: utmp_write_direct() failed"); - return 0; - } -# endif - return 1; -} - - -static int -utmp_perform_logout(struct logininfo *li) -{ - struct utmp ut; - - construct_utmp(li, &ut); -# ifdef UTMP_USE_LIBRARY - if (!utmp_write_library(li, &ut)) { - log("utmp_perform_logout: utmp_write_library() failed"); - return 0; - } -# else - if (!utmp_write_direct(li, &ut)) { - log("utmp_perform_logout: utmp_write_direct() failed"); - return 0; - } -# endif - return 1; -} - - -int -utmp_write_entry(struct logininfo *li) -{ - if (li->line_null) { - debug3("not writing utmp entry"); - return 1; - } - debug3("writing utmp entry"); - - switch(li->type) { - case LTYPE_LOGIN: - return utmp_perform_login(li); - - case LTYPE_LOGOUT: - return utmp_perform_logout(li); - - default: - log("utmp_write_entry: invalid type field"); - return 0; - } -} -#endif /* USE_UTMP */ - - -/** - ** Low-level utmpx functions - **/ - -/* not much point if we don't want utmpx entries */ -#ifdef USE_UTMPX - -/* if we have the wherewithall, use pututxline etc. */ -# if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \ - defined(HAVE_PUTUTXLINE) -# define UTMPX_USE_LIBRARY -# endif - - -/* write a utmpx entry with the system's help (pututxline() and pals) */ -# ifdef UTMPX_USE_LIBRARY -static int -utmpx_write_library(struct logininfo *li, struct utmpx *utx) -{ - setutxent(); - (void) pututxline(utx); - -# ifdef HAVE_ENDUTXENT - endutxent(); -# endif - return 1; -} - -# else /* UTMPX_USE_LIBRARY */ - -/* write a utmp entry direct to the file */ -static int -utmpx_write_direct(struct logininfo *li, struct utmpx *utx) -{ - log("utmpx_write_direct: not implemented!"); - return 0; -} -# endif /* UTMPX_USE_LIBRARY */ - -static int -utmpx_perform_login(struct logininfo *li) -{ - struct utmpx utx; - - construct_utmpx(li, &utx); -# ifdef UTMPX_USE_LIBRARY - if (!utmpx_write_library(li, &utx)) { - log("tmpx_perform_login: utmp_write_library() failed"); - return 0; - } -# else - if (!utmpx_write_direct(li, &ut)) { - log("utmpx_perform_login: utmp_write_direct() failed"); - return 0; - } -# endif - return 1; -} - - -static int -utmpx_perform_logout(struct logininfo *li) -{ - struct utmpx utx; - - construct_utmpx(li, &utx); -# ifdef HAVE_ID_IN_UTMPX - (void) line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id)); -# endif -# ifdef HAVE_TYPE_IN_UTMPX - utx.ut_type = DEAD_PROCESS; -# endif - -# ifdef UTMPX_USE_LIBRARY - (void) utmpx_write_library(li, &utx); -# else - utmpx_write_direct(li, &utx); -# endif - return 1; -} - -int -utmpx_write_entry(struct logininfo *li) -{ - if (li->line_null) { - debug3("not writing utmpx entry"); - return 1; - } - debug3("writing utmpx entry"); - - switch(li->type) { - case LTYPE_LOGIN: - return utmpx_perform_login(li); - case LTYPE_LOGOUT: - return utmpx_perform_logout(li); - default: - log("utmpx_write_entry: invalid type field"); - return 0; - } -} -#endif /* USE_UTMPX */ - - -/** - ** Low-level wtmp functions - **/ - -#ifdef USE_WTMP - -/* write a wtmp entry direct to the end of the file */ -/* This is a slight modification of code in OpenBSD's logwtmp.c */ -static int -wtmp_write(struct logininfo *li, struct utmp *ut) -{ - struct stat buf; - int fd, ret = 1; - - if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { - log("wtmp_write: problem writing %s: %s", - WTMP_FILE, strerror(errno)); - return 0; - } - if (fstat(fd, &buf) == 0) - if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) { - (void) ftruncate(fd, buf.st_size); - log("wtmp_write: problem writing %s: %s", - WTMP_FILE, strerror(errno)); - ret = 0; - } - (void)close(fd); - return ret; -} - -static int -wtmp_perform_login(struct logininfo *li) -{ - struct utmp ut; - - construct_utmp(li, &ut); - return wtmp_write(li, &ut); -} - - -static int -wtmp_perform_logout(struct logininfo *li) -{ - struct utmp ut; - - construct_utmp(li, &ut); - return wtmp_write(li, &ut); -} - - -int -wtmp_write_entry(struct logininfo *li) -{ - switch(li->type) { - case LTYPE_LOGIN: - return wtmp_perform_login(li); - case LTYPE_LOGOUT: - return wtmp_perform_logout(li); - default: - log("wtmp_write_entry: invalid type field"); - return 0; - } -} - - -/* Notes on fetching login data from wtmp/wtmpx - * - * Logouts are usually recorded with (amongst other things) a blank - * username on a given tty line. However, some systems (HP-UX is one) - * leave all fields set, but change the ut_type field to DEAD_PROCESS. - * - * Since we're only looking for logins here, we know that the username - * must be set correctly. On systems that leave it in, we check for - * ut_type==USER_PROCESS (indicating a login.) - * - * Portability: Some systems may set something other than USER_PROCESS - * to indicate a login process. I don't know of any as I write. Also, - * it's possible that some systems may both leave the username in - * place and not have ut_type. - */ - -/* return true if this wtmp entry indicates a login */ -static int -wtmp_islogin(struct logininfo *li, struct utmp *ut) -{ - if (strncmp(li->username, ut->ut_name, - MIN_SIZEOF(li->username, ut->ut_name)) == 0) { -# ifdef HAVE_TYPE_IN_UTMP - if (ut->ut_type & USER_PROCESS) - return 1; -# else - return 1; -# endif - } - return 0; -} - -int -wtmp_get_entry(struct logininfo *li) -{ - struct stat st; - struct utmp ut; - int fd, found=0; - - /* Clear the time entries in our logininfo */ - li->tv_sec = li->tv_usec = 0; - - if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { - log("wtmp_get_entry: problem opening %s: %s", - WTMP_FILE, strerror(errno)); - return 0; - } - if (fstat(fd, &st) != 0) { - log("wtmp_get_entry: couldn't stat %s: %s", - WTMP_FILE, strerror(errno)); - (void) close(fd); - return 0; - } - - /* Seek to the start of the last struct utmp */ - if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_END) == -1) { - /* Looks like we've got a fresh wtmp file */ - (void) close(fd); - return 0; - } - - while (!found) { - if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { - log("wtmp_get_entry: read of %s failed: %s", - WTMP_FILE, strerror(errno)); - (void) close (fd); - return 0; - } - if ( wtmp_islogin(li, &ut) ) { - found = 1; - /* We've already checked for a time in struct - * utmp, in login_getlast(). */ -# ifdef HAVE_TIME_IN_UTMP - li->tv_sec = ut.ut_time; -# else -# if HAVE_TV_IN_UTMP - li->tv_sec = ut.ut_tv.tv_sec; -# endif -# endif - (void) line_fullname(li->line, ut.ut_line, - MIN_SIZEOF(li->line, ut.ut_line)); -# ifdef HAVE_HOST_IN_UTMP - (void) strlcpy(li->hostname, ut.ut_host, - MIN_SIZEOF(li->hostname, ut.ut_host)); -# endif - continue; - } - /* Seek back 2 x struct utmp */ - if (lseek(fd, -(off_t)(2 * sizeof(struct utmp)), SEEK_CUR) == -1) { - /* We've found the start of the file, so quit */ - (void) close (fd); - return 0; - } - } - - /* We found an entry. Tidy up and return */ - (void) close(fd); - return 1; -} -# endif /* USE_WTMP */ - - -/** - ** Low-level wtmpx functions - **/ - -#ifdef USE_WTMPX -/* write a wtmpx entry direct to the end of the file */ -/* This is a slight modification of code in OpenBSD's logwtmp.c */ -static int -wtmpx_write(struct logininfo *li, struct utmpx *utx) -{ - struct stat buf; - int fd, ret = 1; - - if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { - log("wtmpx_write: problem opening %s: %s", - WTMPX_FILE, strerror(errno)); - return 0; - } - - if (fstat(fd, &buf) == 0) - if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) { - (void) ftruncate(fd, buf.st_size); - log("wtmpx_write: problem writing %s: %s", - WTMPX_FILE, strerror(errno)); - ret = 0; - } - (void)close(fd); - - return ret; -} - - -static int -wtmpx_perform_login(struct logininfo *li) -{ - struct utmpx utx; - - construct_utmpx(li, &utx); - return wtmpx_write(li, &utx); -} - - -static int -wtmpx_perform_logout(struct logininfo *li) -{ - struct utmpx utx; - - construct_utmpx(li, &utx); - return wtmpx_write(li, &utx); -} - - -int -wtmpx_write_entry(struct logininfo *li) -{ - switch(li->type) { - case LTYPE_LOGIN: - return wtmpx_perform_login(li); - case LTYPE_LOGOUT: - return wtmpx_perform_logout(li); - default: - log("wtmpx_write_entry: invalid type field"); - return 0; - } -} - -/* Please see the notes above wtmp_islogin() for information about the - next two functions */ - -/* Return true if this wtmpx entry indicates a login */ -static int -wtmpx_islogin(struct logininfo *li, struct utmpx *utx) -{ - if ( strncmp(li->username, utx->ut_name, - MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { -# ifdef HAVE_TYPE_IN_UTMPX - if (utx->ut_type == USER_PROCESS) - return 1; -# else - return 1; -# endif - } - return 0; -} - - -#if 0 -int -wtmpx_get_entry(struct logininfo *li) -{ - struct stat st; - struct utmpx utx; - int fd, found=0; - - /* Clear the time entries */ - li->tv_sec = li->tv_usec = 0; - - if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { - log("wtmpx_get_entry: problem opening %s: %s", - WTMPX_FILE, strerror(errno)); - return 0; - } - if (fstat(fd, &st) != 0) { - log("wtmpx_get_entry: couldn't stat %s: %s", - WTMPX_FILE, strerror(errno)); - (void) close(fd); - return 0; - } - - /* Seek to the start of the last struct utmpx */ - if (lseek(fd, -(off_t)sizeof(struct utmpx), SEEK_END) == -1 ) { - /* probably a newly rotated wtmpx file */ - (void) close(fd); - return 0; - } - - while (!found) { - if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { - log("wtmpx_get_entry: read of %s failed: %s", - WTMPX_FILE, strerror(errno)); - (void) close (fd); - return 0; - } - /* Logouts are recorded as a blank username on a particular line. - * So, we just need to find the username in struct utmpx */ - if ( wtmpx_islogin(li, &utx) ) { - found = 1; -# ifdef HAVE_TV_IN_UTMPX - li->tv_sec = utx.ut_tv.tv_sec; -# else -# ifdef HAVE_TIME_IN_UTMPX - li->tv_sec = utx.ut_time; -# endif -# endif - (void) line_fullname(li->line, utx.ut_line, sizeof(li->line)); -# ifdef HAVE_HOST_IN_UTMPX - (void) strlcpy(li->hostname, utx.ut_host, - MIN_SIZEOF(li->hostname, utx.ut_host)); -# endif - continue; - } - if (lseek(fd, -(off_t)(2 * sizeof(struct utmpx)), SEEK_CUR) == -1) { - (void) close (fd); - return 0; - } - } - - (void) close(fd); - return 1; -} -#endif -#endif /* USE_WTMPX */ - -/** - ** Low-level libutil login() functions - **/ - -#ifdef USE_LOGIN -static int -syslogin_perform_login(struct logininfo *li) -{ - struct utmp *ut; - - if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) { - log("syslogin_perform_login: couldn't malloc()"); - return 0; - } - construct_utmp(li, ut); - login(ut); - - return 1; -} - -static int -syslogin_perform_logout(struct logininfo *li) -{ -# ifdef HAVE_LOGOUT - char line[8]; - - (void)line_stripname(line, li->line, sizeof(line)); - - if (!logout(line)) { - log("syslogin_perform_logout: logout() returned an error"); -# ifdef HAVE_LOGWTMP - } else { - logwtmp(line, "", ""); -# endif - } - /* FIXME: (ATL - if the need arises) What to do if we have - * login, but no logout? what if logout but no logwtmp? All - * routines are in libutil so they should all be there, - * but... */ -# endif - return 1; -} - -int -syslogin_write_entry(struct logininfo *li) -{ - switch (li->type) { - case LTYPE_LOGIN: - return syslogin_perform_login(li); - case LTYPE_LOGOUT: - return syslogin_perform_logout(li); - default: - log("syslogin_write_entry: Invalid type field"); - return 0; - } -} -#endif /* USE_LOGIN */ - -/* end of file log-syslogin.c */ - -/** - ** Low-level lastlog functions - **/ - -#ifdef USE_LASTLOG -#define LL_FILE 1 -#define LL_DIR 2 -#define LL_OTHER 3 - -static void -lastlog_construct(struct logininfo *li, struct lastlog *last) -{ - /* clear the structure */ - (void) memset(last, '\0', sizeof(*last)); - - (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); - (void) strlcpy(last->ll_host, li->hostname, - MIN_SIZEOF(last->ll_host, li->hostname)); - last->ll_time = li->tv_sec; -} - -static int -lastlog_filetype(char *filename) -{ - struct stat st; - - if (stat(LASTLOG_FILE, &st) != 0) { - log("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, - strerror(errno)); - return 0; - } - if (S_ISDIR(st.st_mode)) - return LL_DIR; - else if (S_ISREG(st.st_mode)) - return LL_FILE; - else - return LL_OTHER; -} - - -/* open the file (using filemode) and seek to the login entry */ -static int -lastlog_openseek(struct logininfo *li, int *fd, int filemode) -{ - off_t offset; - int type; - char lastlog_file[1024]; - - type = lastlog_filetype(LASTLOG_FILE); - switch (type) { - case LL_FILE: - (void) strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); - break; - case LL_DIR: - (void) snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", - LASTLOG_FILE, li->username); - break; - default: - log("lastlog_openseek: %.100s is not a file or directory!", - LASTLOG_FILE); - return 0; - } - - *fd = open(lastlog_file, filemode); - if ( *fd < 0) { - debug("lastlog_openseek: Couldn't open %s: %s", - lastlog_file, strerror(errno)); - return 0; - } - - if (type == LL_FILE) { - /* find this uid's offset in the lastlog file */ - offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); - - if ( lseek(*fd, offset, SEEK_SET) != offset ) { - log("lastlog_openseek: %s->lseek(): %s", - lastlog_file, strerror(errno)); - return 0; - } - } - - return 1; -} - -static int -lastlog_perform_login(struct logininfo *li) -{ - struct lastlog last; - int fd; - - /* create our struct lastlog */ - lastlog_construct(li, &last); - - if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) - return(0); - - /* write the entry */ - if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) { - (void) close(fd); - log("lastlog_write_filemode: Error writing to %s: %s", - LASTLOG_FILE, strerror(errno)); - return 0; - } - - (void) close(fd); - return 1; -} - -int -lastlog_write_entry(struct logininfo *li) -{ - switch(li->type) { - case LTYPE_LOGIN: - return lastlog_perform_login(li); - default: - log("lastlog_write_entry: Invalid type field"); - return 0; - } -} - -static void -lastlog_populate_entry(struct logininfo *li, struct lastlog *last) -{ - (void) line_fullname(li->line, last->ll_line, sizeof(li->line)); - (void) strlcpy(li->hostname, last->ll_host, - MIN_SIZEOF(li->hostname, last->ll_host)); - li->tv_sec = last->ll_time; -} - -int -lastlog_get_entry(struct logininfo *li) -{ - struct lastlog last; - int fd, ret; - - if (!lastlog_openseek(li, &fd, O_RDONLY)) - return (0); - - ret = atomicio(read, fd, &last, sizeof(last)); - close(fd); - - switch (ret) { - case 0: - memset(&last, '\0', sizeof(last)); - /* FALLTHRU */ - case sizeof(last): - lastlog_populate_entry(li, &last); - return (1); - case -1: - error("%s: Error reading from %s: %s", __func__, - LASTLOG_FILE, strerror(errno)); - return (0); - default: - error("%s: Error reading from %s: Expecting %d, got %d", - __func__, LASTLOG_FILE, (int)sizeof(last), ret); - return (0); - } - - /* NOTREACHED */ - return (0); -} -#endif /* USE_LASTLOG */ diff --git a/usr/src/cmd/ssh/sshd/mapfile-intf b/usr/src/cmd/ssh/sshd/mapfile-intf deleted file mode 100644 index 6981212730..0000000000 --- a/usr/src/cmd/ssh/sshd/mapfile-intf +++ /dev/null @@ -1,49 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. -# -# sshd defines its own log(), as do various other ssh utilities, thus their -# symbols are reduced to locals via MAPFILE.NGB in Makefile-ssh.common. sshd -# must export some symbols too, thus this mapfile augments the former. - -# -# MAPFILE HEADER START -# -# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. -# Object versioning must comply with the rules detailed in -# -# usr/src/lib/README.mapfiles -# -# You should not be making modifications here until you've read the most current -# copy of that file. If you need help, contact a gatekeeper for guidance. -# -# MAPFILE HEADER END -# - -$mapfile_version 2 - -SYMBOL_SCOPE { - global: - allow_severity; # required by libwrap - deny_severity; # required by libwrap -}; diff --git a/usr/src/cmd/ssh/sshd/servconf.c b/usr/src/cmd/ssh/sshd/servconf.c deleted file mode 100644 index 16f1dcecf7..0000000000 --- a/usr/src/cmd/ssh/sshd/servconf.c +++ /dev/null @@ -1,1501 +0,0 @@ -/* - * 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) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2013 Joyent, Inc. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.115 2002/09/04 18:52:42 stevesk Exp $"); - -#ifdef HAVE_DEFOPEN -#include <deflt.h> -#endif /* HAVE_DEFOPEN */ - -#if defined(KRB4) -#include <krb.h> -#endif -#if defined(KRB5) -#ifdef HEIMDAL -#include <krb.h> -#else -/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V - * keytab */ -#define KEYFILE "/etc/krb5.keytab" -#endif -#endif -#ifdef AFS -#include <kafs.h> -#endif - -#include "ssh.h" -#include "log.h" -#include "buffer.h" -#include "servconf.h" -#include "xmalloc.h" -#include "compat.h" -#include "pathnames.h" -#include "tildexpand.h" -#include "misc.h" -#include "cipher.h" -#include "kex.h" -#include "mac.h" -#include "auth.h" -#include "match.h" -#include "groupaccess.h" - -static void add_listen_addr(ServerOptions *, char *, u_short); -static void add_one_listen_addr(ServerOptions *, char *, u_short); - -extern Buffer cfg; - -/* AF_UNSPEC or AF_INET or AF_INET6 */ -extern int IPv4or6; - -/* - * Initializes the server options to their initial (unset) values. Some of those - * that stay unset after the command line options and configuration files are - * read are set to their default values in fill_default_server_options(). - */ -void -initialize_server_options(ServerOptions *options) -{ - (void) memset(options, 0, sizeof(*options)); - - /* Standard Options */ - options->num_ports = 0; - options->ports_from_cmdline = 0; - options->listen_addrs = NULL; - options->num_host_key_files = 0; - options->pid_file = NULL; - options->server_key_bits = -1; - options->login_grace_time = -1; - options->key_regeneration_time = -1; - options->permit_root_login = PERMIT_NOT_SET; - options->ignore_rhosts = -1; - options->ignore_user_known_hosts = -1; - options->print_motd = -1; - options->print_lastlog = -1; - options->x11_forwarding = -1; - options->x11_display_offset = -1; - options->x11_use_localhost = -1; - options->xauth_location = NULL; - options->strict_modes = -1; - options->keepalives = -1; - options->log_facility = SYSLOG_FACILITY_NOT_SET; - options->log_level = SYSLOG_LEVEL_NOT_SET; - options->rhosts_authentication = -1; - options->rhosts_rsa_authentication = -1; - options->hostbased_authentication = -1; - options->hostbased_uses_name_from_packet_only = -1; - options->rsa_authentication = -1; - options->pubkey_authentication = -1; -#ifdef GSSAPI - options->gss_authentication = -1; - options->gss_keyex = -1; - options->gss_store_creds = -1; - options->gss_use_session_ccache = -1; - options->gss_cleanup_creds = -1; -#endif -#if defined(KRB4) || defined(KRB5) - options->kerberos_authentication = -1; - options->kerberos_or_local_passwd = -1; - options->kerberos_ticket_cleanup = -1; -#endif -#if defined(AFS) || defined(KRB5) - options->kerberos_tgt_passing = -1; -#endif -#ifdef AFS - options->afs_token_passing = -1; -#endif - options->password_authentication = -1; - options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; - options->pam_authentication_via_kbd_int = -1; - options->permit_empty_passwd = -1; - options->permit_user_env = -1; - options->compression = -1; - options->allow_tcp_forwarding = -1; - options->num_allow_users = 0; - options->num_deny_users = 0; - options->num_allow_groups = 0; - options->num_deny_groups = 0; - options->ciphers = NULL; - options->macs = 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; - options->banner = NULL; - options->verify_reverse_mapping = -1; - options->client_alive_interval = -1; - options->client_alive_count_max = -1; - options->authorized_keys_file = NULL; - options->authorized_keys_file2 = NULL; - - options->max_auth_tries = -1; - options->max_auth_tries_log = -1; - - options->max_init_auth_tries = -1; - options->max_init_auth_tries_log = -1; - - options->lookup_client_hostnames = -1; - options->use_openssl_engine = -1; - options->chroot_directory = NULL; - options->pre_userauth_hook = NULL; - options->pam_service_name = NULL; - options->pam_service_prefix = NULL; - options->pubkey_plugin = NULL; -} - -#ifdef HAVE_DEFOPEN -/* - * Reads /etc/default/login and defaults several ServerOptions: - * - * PermitRootLogin - * PermitEmptyPasswords - * LoginGraceTime - * - * CONSOLE=* -> PermitRootLogin=without-password - * #CONSOLE=* -> PermitRootLogin=yes - * - * PASSREQ=YES -> PermitEmptyPasswords=no - * PASSREQ=NO -> PermitEmptyPasswords=yes - * #PASSREQ=* -> PermitEmptyPasswords=no - * - * TIMEOUT=<secs> -> LoginGraceTime=<secs> - * #TIMEOUT=<secs> -> LoginGraceTime=300 - */ -static -void -deflt_fill_default_server_options(ServerOptions *options) -{ - int flags; - char *ptr; - - if (defopen(_PATH_DEFAULT_LOGIN)) - return; - - /* Ignore case */ - flags = defcntl(DC_GETFLAGS, 0); - TURNOFF(flags, DC_CASE); - (void) defcntl(DC_SETFLAGS, flags); - - if (options->permit_root_login == PERMIT_NOT_SET && - (ptr = defread("CONSOLE=")) != NULL) - options->permit_root_login = PERMIT_NO_PASSWD; - - if (options->permit_empty_passwd == -1 && - (ptr = defread("PASSREQ=")) != NULL) { - if (strcasecmp("YES", ptr) == 0) - options->permit_empty_passwd = 0; - else if (strcasecmp("NO", ptr) == 0) - options->permit_empty_passwd = 1; - } - - if (options->max_init_auth_tries == -1 && - (ptr = defread("RETRIES=")) != NULL) { - options->max_init_auth_tries = atoi(ptr); - } - - if (options->max_init_auth_tries_log == -1 && - (ptr = defread("SYSLOG_FAILED_LOGINS=")) != NULL) { - options->max_init_auth_tries_log = atoi(ptr); - } - - if (options->login_grace_time == -1) { - if ((ptr = defread("TIMEOUT=")) != NULL) - options->login_grace_time = (unsigned)atoi(ptr); - else - options->login_grace_time = 300; - } - - (void) defopen((char *)NULL); -} -#endif /* HAVE_DEFOPEN */ - -void -fill_default_server_options(ServerOptions *options) -{ - -#ifdef HAVE_DEFOPEN - deflt_fill_default_server_options(options); -#endif /* HAVE_DEFOPEN */ - - /* Standard Options */ - if (options->protocol == SSH_PROTO_UNKNOWN) - options->protocol = SSH_PROTO_1|SSH_PROTO_2; - if (options->num_host_key_files == 0) { - /* fill default hostkeys for protocols */ - if (options->protocol & SSH_PROTO_1) - options->host_key_files[options->num_host_key_files++] = - _PATH_HOST_KEY_FILE; -#ifndef GSSAPI - /* With GSS keyex we can run v2 w/ no host keys */ - if (options->protocol & SSH_PROTO_2) { - options->host_key_files[options->num_host_key_files++] = - _PATH_HOST_RSA_KEY_FILE; - options->host_key_files[options->num_host_key_files++] = - _PATH_HOST_DSA_KEY_FILE; - } -#endif /* GSSAPI */ - } - if (options->num_ports == 0) - options->ports[options->num_ports++] = SSH_DEFAULT_PORT; - if (options->listen_addrs == NULL) - add_listen_addr(options, NULL, 0); - if (options->pid_file == NULL) - options->pid_file = _PATH_SSH_DAEMON_PID_FILE; - if (options->server_key_bits == -1) - options->server_key_bits = 768; - if (options->login_grace_time == -1) - options->login_grace_time = 120; - if (options->key_regeneration_time == -1) - options->key_regeneration_time = 3600; - if (options->permit_root_login == PERMIT_NOT_SET) - options->permit_root_login = PERMIT_YES; - if (options->ignore_rhosts == -1) - options->ignore_rhosts = 1; - if (options->ignore_user_known_hosts == -1) - options->ignore_user_known_hosts = 0; - if (options->print_motd == -1) - options->print_motd = 1; - if (options->print_lastlog == -1) - options->print_lastlog = 1; - if (options->x11_forwarding == -1) - options->x11_forwarding = 1; - if (options->x11_display_offset == -1) - options->x11_display_offset = 10; - if (options->x11_use_localhost == -1) - options->x11_use_localhost = 1; - if (options->xauth_location == NULL) - options->xauth_location = _PATH_XAUTH; - if (options->strict_modes == -1) - options->strict_modes = 1; - if (options->keepalives == -1) - options->keepalives = 1; - if (options->log_facility == SYSLOG_FACILITY_NOT_SET) - options->log_facility = SYSLOG_FACILITY_AUTH; - if (options->log_level == SYSLOG_LEVEL_NOT_SET) - options->log_level = SYSLOG_LEVEL_INFO; - if (options->rhosts_authentication == -1) - options->rhosts_authentication = 0; - if (options->rhosts_rsa_authentication == -1) - options->rhosts_rsa_authentication = 0; - if (options->hostbased_authentication == -1) - options->hostbased_authentication = 0; - if (options->hostbased_uses_name_from_packet_only == -1) - options->hostbased_uses_name_from_packet_only = 0; - if (options->rsa_authentication == -1) - options->rsa_authentication = 1; - if (options->pubkey_authentication == -1) - options->pubkey_authentication = 1; -#ifdef GSSAPI - if (options->gss_authentication == -1) - options->gss_authentication = 1; - if (options->gss_keyex == -1) - options->gss_keyex = 1; - if (options->gss_store_creds == -1) - options->gss_store_creds = 1; - if (options->gss_use_session_ccache == -1) - options->gss_use_session_ccache = 1; - if (options->gss_cleanup_creds == -1) - options->gss_cleanup_creds = 1; -#endif -#if defined(KRB4) || defined(KRB5) - if (options->kerberos_authentication == -1) - options->kerberos_authentication = 0; - if (options->kerberos_or_local_passwd == -1) - options->kerberos_or_local_passwd = 1; - if (options->kerberos_ticket_cleanup == -1) - options->kerberos_ticket_cleanup = 1; -#endif -#if defined(AFS) || defined(KRB5) - if (options->kerberos_tgt_passing == -1) - options->kerberos_tgt_passing = 0; -#endif -#ifdef AFS - if (options->afs_token_passing == -1) - options->afs_token_passing = 0; -#endif - if (options->password_authentication == -1) - options->password_authentication = 1; - /* - * options->pam_authentication_via_kbd_int has intentionally no default - * value since we do not need it. - */ - if (options->kbd_interactive_authentication == -1) - options->kbd_interactive_authentication = 1; - if (options->challenge_response_authentication == -1) - options->challenge_response_authentication = 1; - if (options->permit_empty_passwd == -1) - options->permit_empty_passwd = 0; - if (options->permit_user_env == -1) - options->permit_user_env = 0; - if (options->compression == -1) - options->compression = 1; - if (options->allow_tcp_forwarding == -1) - options->allow_tcp_forwarding = 1; - 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; - if (options->verify_reverse_mapping == -1) - options->verify_reverse_mapping = 0; - if (options->client_alive_interval == -1) - options->client_alive_interval = 0; - if (options->client_alive_count_max == -1) - options->client_alive_count_max = 3; - if (options->authorized_keys_file2 == NULL) { - /* authorized_keys_file2 falls back to authorized_keys_file */ - if (options->authorized_keys_file != NULL) - options->authorized_keys_file2 = options->authorized_keys_file; - else - options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2; - } - if (options->authorized_keys_file == NULL) - options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; - - if (options->max_auth_tries == -1) - options->max_auth_tries = AUTH_FAIL_MAX; - if (options->max_auth_tries_log == -1) - options->max_auth_tries_log = options->max_auth_tries / 2; - - if (options->max_init_auth_tries == -1) - options->max_init_auth_tries = AUTH_FAIL_MAX; - if (options->max_init_auth_tries_log == -1) - options->max_init_auth_tries_log = options->max_init_auth_tries / 2; - - if (options->lookup_client_hostnames == -1) - options->lookup_client_hostnames = 1; - if (options->use_openssl_engine == -1) - options->use_openssl_engine = 1; - if (options->pam_service_prefix == NULL) - options->pam_service_prefix = _SSH_PAM_SERVICE_PREFIX; - if (options->pam_service_name == NULL) - options->pam_service_name = NULL; -} - -/* Keyword tokens. */ -typedef enum { - sBadOption, /* == unknown option */ - /* Portable-specific options */ - sPAMAuthenticationViaKbdInt, - /* Standard Options */ - sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, -#ifdef GSSAPI - sGssAuthentication, sGssKeyEx, sGssStoreDelegCreds, - sGssUseSessionCredCache, sGssCleanupCreds, -#endif /* GSSAPI */ -#if defined(KRB4) || defined(KRB5) - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -#endif -#if defined(AFS) || defined(KRB5) - sKerberosTgtPassing, -#endif -#ifdef AFS - sAFSTokenPassing, -#endif - sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, - sStrictModes, sEmptyPasswd, sKeepAlives, - sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, - sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, - sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, - sBanner, sVerifyReverseMapping, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, - sMaxAuthTries, sMaxAuthTriesLog, sUsePrivilegeSeparation, - sLookupClientHostnames, sUseOpenSSLEngine, sChrootDirectory, - sPreUserauthHook, sMatch, sPAMServicePrefix, sPAMServiceName, - sMaxStartups, sPubKeyPlugin, - sDeprecated -} ServerOpCodes; - -#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ -#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ -#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) - -/* Textual representation of the tokens. */ -static struct { - const char *name; - ServerOpCodes opcode; - u_int flags; -} keywords[] = { - /* Portable-specific options */ - { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt, SSHCFG_GLOBAL }, - /* Standard Options */ - { "port", sPort, SSHCFG_GLOBAL }, - { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, - { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ - { "pidfile", sPidFile, SSHCFG_GLOBAL }, - { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, - { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, - { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, - { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, - { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, - { "loglevel", sLogLevel, SSHCFG_GLOBAL }, - { "rhostsauthentication", sRhostsAuthentication, SSHCFG_GLOBAL }, - { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, - { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, - { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, - { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, - { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, - { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ -#ifdef GSSAPI - { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, - { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, - { "gssapistoredelegatedcredentials", sGssStoreDelegCreds, SSHCFG_GLOBAL }, - { "gssauthentication", sGssAuthentication, SSHCFG_GLOBAL }, /* alias */ - { "gsskeyex", sGssKeyEx, SSHCFG_GLOBAL }, /* alias */ - { "gssstoredelegcreds", sGssStoreDelegCreds, SSHCFG_GLOBAL }, /* alias */ -#ifndef SUNW_GSSAPI - { "gssusesessionccache", sGssUseSessionCredCache, SSHCFG_GLOBAL }, - { "gssusesessioncredcache", sGssUseSessionCredCache, SSHCFG_GLOBAL }, - { "gsscleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL }, -#endif /* SUNW_GSSAPI */ -#endif -#if defined(KRB4) || defined(KRB5) - { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, - { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, - { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, -#endif -#if defined(AFS) || defined(KRB5) - { "kerberostgtpassing", sKerberosTgtPassing, SSHCFG_GLOBAL }, -#endif -#ifdef AFS - { "afstokenpassing", sAFSTokenPassing, SSHCFG_GLOBAL }, -#endif - { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, - { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, - { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, - { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ - { "checkmail", sDeprecated, SSHCFG_GLOBAL }, - { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, - { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, - { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, - { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, - { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, - { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, - { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, - { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, - { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, - { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, - { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, - { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, - { "uselogin", sUseLogin, SSHCFG_GLOBAL }, - { "compression", sCompression, SSHCFG_GLOBAL }, - { "tcpkeepalive", sKeepAlives, SSHCFG_GLOBAL }, - { "keepalive", sKeepAlives, SSHCFG_GLOBAL }, /* obsolete */ - { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, - { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, - { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, - { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, - { "denygroups", sDenyGroups, SSHCFG_GLOBAL }, - { "ciphers", sCiphers, SSHCFG_GLOBAL }, - { "macs", sMacs, SSHCFG_GLOBAL}, - { "protocol", sProtocol,SSHCFG_GLOBAL }, - { "gatewayports", sGatewayPorts, SSHCFG_ALL }, - { "subsystem", sSubsystem, SSHCFG_GLOBAL}, - { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, - { "banner", sBanner, SSHCFG_ALL }, - { "verifyreversemapping", sVerifyReverseMapping, SSHCFG_GLOBAL }, - { "reversemappingcheck", sVerifyReverseMapping,SSHCFG_GLOBAL }, - { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, - { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, - { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL }, - { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL }, - { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, - { "maxauthtrieslog", sMaxAuthTriesLog, SSHCFG_GLOBAL }, - { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL }, - { "lookupclienthostnames", sLookupClientHostnames, SSHCFG_GLOBAL }, - { "useopensslengine", sUseOpenSSLEngine, SSHCFG_GLOBAL }, - { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, - { "preuserauthhook", sPreUserauthHook, SSHCFG_ALL}, - { "match", sMatch, SSHCFG_ALL }, - { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL }, - { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL }, - { "pubkeyplugin", sPubKeyPlugin, SSHCFG_ALL }, - - { NULL, sBadOption, 0 } -}; - -/* - * Returns the number of the token pointed to by cp or sBadOption. - */ - -static ServerOpCodes -parse_token(const char *cp, const char *filename, - int linenum, u_int *flags) -{ - u_int i; - - for (i = 0; keywords[i].name; i++) - if (strcasecmp(cp, keywords[i].name) == 0) { - *flags = keywords[i].flags; - return keywords[i].opcode; - } - - error("%s: line %d: Bad configuration option: %s", - filename, linenum, cp); - return sBadOption; -} - -static void -add_listen_addr(ServerOptions *options, char *addr, u_short port) -{ - int i; - - if (options->num_ports == 0) - options->ports[options->num_ports++] = SSH_DEFAULT_PORT; - if (port == 0) - for (i = 0; i < options->num_ports; i++) - add_one_listen_addr(options, addr, options->ports[i]); - else - add_one_listen_addr(options, addr, port); -} - -static void -add_one_listen_addr(ServerOptions *options, char *addr, u_short port) -{ - struct addrinfo hints, *ai, *aitop; - char strport[NI_MAXSERV]; - int gaierr; - - (void) memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; - (void) snprintf(strport, sizeof strport, "%u", port); - if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) - fatal("bad addr or host: %s (%s)", - addr ? addr : "<NULL>", - gai_strerror(gaierr)); - for (ai = aitop; ai->ai_next; ai = ai->ai_next) - ; - ai->ai_next = options->listen_addrs; - options->listen_addrs = aitop; -} - -/* - * The strategy for the Match blocks is that the config file is parsed twice. - * - * The first time is at startup. activep is initialized to 1 and the - * directives in the global context are processed and acted on. Hitting a - * Match directive unsets activep and the directives inside the block are - * checked for syntax only. - * - * The second time is after a connection has been established but before - * authentication. activep is initialized to 2 and global config directives - * are ignored since they have already been processed. If the criteria in a - * Match block is met, activep is set and the subsequent directives - * processed and actioned until EOF or another Match block unsets it. Any - * options set are copied into the main server config. - * - * Potential additions/improvements: - * - Add Match support for pre-kex directives, eg Protocol, Ciphers. - * - * - Add a Tag directive (idea from David Leonard) ala pf, eg: - * Match Address 192.168.0.* - * Tag trusted - * Match Group wheel - * Tag trusted - * Match Tag trusted - * AllowTcpForwarding yes - * GatewayPorts clientspecified - * [...] - * - * - Add a PermittedChannelRequests directive - * Match Group shell - * PermittedChannelRequests session,forwarded-tcpip - */ - -static int -match_cfg_line_group(const char *grps, int line, const char *user) -{ - int result = 0; - struct passwd *pw; - - if (user == NULL) - goto out; - - if ((pw = getpwnam(user)) == NULL) { - debug("Can't match group at line %d because user %.100s does " - "not exist", line, user); - } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { - debug("Can't Match group because user %.100s not in any group " - "at line %d", user, line); - } else if (ga_match_pattern_list(grps) != 1) { - debug("user %.100s does not match group list %.100s at line %d", - user, grps, line); - } else { - debug("user %.100s matched group list %.100s at line %d", user, - grps, line); - result = 1; - } -out: - ga_free(); - return result; -} - -static int -match_cfg_line(char **condition, int line, const char *user, const char *host, - const char *address) -{ - int result = 1; - char *arg, *attrib, *cp = *condition; - size_t len; - - if (user == NULL) - debug3("checking syntax for 'Match %s'", cp); - else - debug3("checking match for '%s' user %s host %s addr %s", cp, - user ? user : "(null)", host ? host : "(null)", - address ? address : "(null)"); - - while ((attrib = strdelim(&cp)) != NULL && *attrib != '\0') { - if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { - error("Missing Match criteria for %s", attrib); - return -1; - } - len = strlen(arg); - if (strcasecmp(attrib, "user") == 0) { - if (!user) { - result = 0; - continue; - } - if (match_pattern_list(user, arg, len, 0) != 1) - result = 0; - else - debug("user %.100s matched 'User %.100s' at " - "line %d", user, arg, line); - } else if (strcasecmp(attrib, "group") == 0) { - switch (match_cfg_line_group(arg, line, user)) { - case -1: - return -1; - case 0: - result = 0; - } - } else if (strcasecmp(attrib, "host") == 0) { - if (!host) { - result = 0; - continue; - } - if (match_hostname(host, arg, len) != 1) - result = 0; - else - debug("connection from %.100s matched 'Host " - "%.100s' at line %d", host, arg, line); - } else if (strcasecmp(attrib, "address") == 0) { - switch (addr_match_list(address, arg)) { - case 1: - debug("connection from %.100s matched 'Address " - "%.100s' at line %d", address, arg, line); - break; - case 0: - case -1: - result = 0; - break; - case -2: - return -1; - } - } else { - error("Unsupported Match attribute %s", attrib); - return -1; - } - } - if (user != NULL) - debug3("match %sfound", result ? "" : "not "); - *condition = cp; - return result; -} - -#define WHITESPACE " \t\r\n" - -int -process_server_config_line(ServerOptions *options, char *line, - const char *filename, int linenum, int *activep, const char *user, - const char *host, const char *address) -{ - char *cp, **charptr, *arg, *p; - int cmdline = 0, *intptr, value, n; - ServerOpCodes opcode; - u_int i, flags = 0; - size_t len; - - cp = line; - arg = strdelim(&cp); - /* Ignore leading whitespace */ - if (*arg == '\0') - arg = strdelim(&cp); - if (!arg || !*arg || *arg == '#') - return 0; - intptr = NULL; - charptr = NULL; - opcode = parse_token(arg, filename, linenum, &flags); - - if (activep == NULL) { /* We are processing a command line directive */ - cmdline = 1; - activep = &cmdline; - } - if (*activep && opcode != sMatch) - debug3("%s:%d setting %s %s", filename, linenum, arg, cp); - if (*activep == 0 && !(flags & SSHCFG_MATCH)) { - if (user == NULL) { - fatal("%s line %d: Directive '%s' is not allowed " - "within a Match block", filename, linenum, arg); - } else { /* this is a directive we have already processed */ - while (arg) - arg = strdelim(&cp); - return 0; - } - } - - switch (opcode) { - /* Portable-specific options */ - case sPAMAuthenticationViaKbdInt: - log("%s line %d: PAMAuthenticationViaKbdInt has been " - "deprecated. You should use KbdInteractiveAuthentication " - "instead (which defaults to \"yes\").", filename, linenum); - intptr = &options->pam_authentication_via_kbd_int; - goto parse_flag; - - /* Standard Options */ - case sBadOption: - return -1; - case sPort: - /* ignore ports from configfile if cmdline specifies ports */ - if (options->ports_from_cmdline) - return 0; - if (options->listen_addrs != NULL) - fatal("%s line %d: ports must be specified before " - "ListenAddress.", filename, linenum); - if (options->num_ports >= MAX_PORTS) - fatal("%s line %d: too many ports.", - filename, linenum); - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing port number.", - filename, linenum); - options->ports[options->num_ports++] = a2port(arg); - if (options->ports[options->num_ports-1] == 0) - fatal("%s line %d: Badly formatted port number.", - filename, linenum); - break; - - case sServerKeyBits: - intptr = &options->server_key_bits; -parse_int: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing integer value.", - filename, linenum); - value = atoi(arg); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case sLoginGraceTime: - intptr = &options->login_grace_time; -parse_time: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing time value.", - filename, linenum); - if ((value = convtime(arg)) == -1) - fatal("%s line %d: invalid time value.", - filename, linenum); - if (*intptr == -1) - *intptr = value; - break; - - case sKeyRegenerationTime: - intptr = &options->key_regeneration_time; - goto parse_time; - - case sListenAddress: - arg = strdelim(&cp); - if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) - fatal("%s line %d: missing inet addr.", - filename, linenum); - if (*arg == '[') { - if ((p = strchr(arg, ']')) == NULL) - fatal("%s line %d: bad ipv6 inet addr usage.", - filename, linenum); - arg++; - (void) memmove(p, p+1, strlen(p+1)+1); - } else if (((p = strchr(arg, ':')) == NULL) || - (strchr(p+1, ':') != NULL)) { - add_listen_addr(options, arg, 0); - break; - } - if (*p == ':') { - u_short port; - - p++; - if (*p == '\0') - fatal("%s line %d: bad inet addr:port usage.", - filename, linenum); - else { - *(p-1) = '\0'; - if ((port = a2port(p)) == 0) - fatal("%s line %d: bad port number.", - filename, linenum); - add_listen_addr(options, arg, port); - } - } else if (*p == '\0') - add_listen_addr(options, arg, 0); - else - fatal("%s line %d: bad inet addr usage.", - filename, linenum); - break; - - case sHostKeyFile: - intptr = &options->num_host_key_files; - if (*intptr >= MAX_HOSTKEYS) - fatal("%s line %d: too many host keys specified (max %d).", - filename, linenum, MAX_HOSTKEYS); - charptr = &options->host_key_files[*intptr]; -parse_filename: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing file name.", - filename, linenum); - if (*activep && *charptr == NULL) { - *charptr = tilde_expand_filename(arg, getuid()); - /* increase optional counter */ - if (intptr != NULL) - *intptr = *intptr + 1; - } - break; - - case sPidFile: - charptr = &options->pid_file; - goto parse_filename; - - case sPermitRootLogin: - intptr = &options->permit_root_login; - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing yes/" - "without-password/forced-commands-only/no " - "argument.", filename, linenum); - value = 0; /* silence compiler */ - if (strcmp(arg, "without-password") == 0) - value = PERMIT_NO_PASSWD; - else if (strcmp(arg, "forced-commands-only") == 0) - value = PERMIT_FORCED_ONLY; - else if (strcmp(arg, "yes") == 0) - value = PERMIT_YES; - else if (strcmp(arg, "no") == 0) - value = PERMIT_NO; - else - fatal("%s line %d: Bad yes/" - "without-password/forced-commands-only/no " - "argument: %s", filename, linenum, arg); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case sIgnoreRhosts: - intptr = &options->ignore_rhosts; -parse_flag: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing yes/no argument.", - filename, linenum); - value = 0; /* silence compiler */ - if (strcmp(arg, "yes") == 0) - value = 1; - else if (strcmp(arg, "no") == 0) - value = 0; - else - fatal("%s line %d: Bad yes/no argument: %s", - filename, linenum, arg); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case sIgnoreUserKnownHosts: - intptr = &options->ignore_user_known_hosts; - goto parse_flag; - - case sRhostsAuthentication: - intptr = &options->rhosts_authentication; - goto parse_flag; - - case sRhostsRSAAuthentication: - intptr = &options->rhosts_rsa_authentication; - goto parse_flag; - - case sHostbasedAuthentication: - intptr = &options->hostbased_authentication; - goto parse_flag; - - case sHostbasedUsesNameFromPacketOnly: - intptr = &options->hostbased_uses_name_from_packet_only; - goto parse_flag; - - case sRSAAuthentication: - intptr = &options->rsa_authentication; - goto parse_flag; - - case sPubkeyAuthentication: - intptr = &options->pubkey_authentication; - goto parse_flag; -#ifdef GSSAPI - case sGssAuthentication: - intptr = &options->gss_authentication; - goto parse_flag; - case sGssKeyEx: - intptr = &options->gss_keyex; - goto parse_flag; - case sGssStoreDelegCreds: - intptr = &options->gss_keyex; - goto parse_flag; -#ifndef SUNW_GSSAPI - case sGssUseSessionCredCache: - intptr = &options->gss_use_session_ccache; - goto parse_flag; - case sGssCleanupCreds: - intptr = &options->gss_cleanup_creds; - goto parse_flag; -#endif /* SUNW_GSSAPI */ -#endif /* GSSAPI */ -#if defined(KRB4) || defined(KRB5) - case sKerberosAuthentication: - intptr = &options->kerberos_authentication; - goto parse_flag; - - case sKerberosOrLocalPasswd: - intptr = &options->kerberos_or_local_passwd; - goto parse_flag; - - case sKerberosTicketCleanup: - intptr = &options->kerberos_ticket_cleanup; - goto parse_flag; -#endif -#if defined(AFS) || defined(KRB5) - case sKerberosTgtPassing: - intptr = &options->kerberos_tgt_passing; - goto parse_flag; -#endif -#ifdef AFS - case sAFSTokenPassing: - intptr = &options->afs_token_passing; - goto parse_flag; -#endif - - case sPasswordAuthentication: - intptr = &options->password_authentication; - goto parse_flag; - - case sKbdInteractiveAuthentication: - intptr = &options->kbd_interactive_authentication; - goto parse_flag; - - case sChallengeResponseAuthentication: - intptr = &options->challenge_response_authentication; - goto parse_flag; - - case sPrintMotd: - intptr = &options->print_motd; - goto parse_flag; - - case sPrintLastLog: - intptr = &options->print_lastlog; - goto parse_flag; - - case sX11Forwarding: - intptr = &options->x11_forwarding; - goto parse_flag; - - case sX11DisplayOffset: - intptr = &options->x11_display_offset; - goto parse_int; - - case sX11UseLocalhost: - intptr = &options->x11_use_localhost; - goto parse_flag; - - case sXAuthLocation: - charptr = &options->xauth_location; - goto parse_filename; - - case sStrictModes: - intptr = &options->strict_modes; - goto parse_flag; - - case sKeepAlives: - intptr = &options->keepalives; - goto parse_flag; - - case sEmptyPasswd: - intptr = &options->permit_empty_passwd; - goto parse_flag; - - case sPermitUserEnvironment: - intptr = &options->permit_user_env; - goto parse_flag; - - case sUseLogin: - log("%s line %d: ignoring UseLogin option value." - " This option is always off.", filename, linenum); - while (arg) - arg = strdelim(&cp); - break; - - case sCompression: - intptr = &options->compression; - goto parse_flag; - - case sGatewayPorts: - intptr = &options->gateway_ports; - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: missing yes/no/clientspecified " - "argument.", filename, linenum); - value = 0; /* silence compiler */ - if (strcmp(arg, "clientspecified") == 0) - value = 2; - else if (strcmp(arg, "yes") == 0) - value = 1; - else if (strcmp(arg, "no") == 0) - value = 0; - else - fatal("%s line %d: Bad yes/no/clientspecified " - "argument: %s", filename, linenum, arg); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case sVerifyReverseMapping: - intptr = &options->verify_reverse_mapping; - goto parse_flag; - - case sLogFacility: - intptr = (int *) &options->log_facility; - arg = strdelim(&cp); - value = log_facility_number(arg); - if (value == SYSLOG_FACILITY_NOT_SET) - fatal("%.200s line %d: unsupported log facility '%s'", - filename, linenum, arg ? arg : "<NONE>"); - if (*intptr == -1) - *intptr = (SyslogFacility) value; - break; - - case sLogLevel: - intptr = (int *) &options->log_level; - arg = strdelim(&cp); - value = log_level_number(arg); - if (value == SYSLOG_LEVEL_NOT_SET) - fatal("%.200s line %d: unsupported log level '%s'", - filename, linenum, arg ? arg : "<NONE>"); - if (*intptr == -1) - *intptr = (LogLevel) value; - break; - - case sAllowTcpForwarding: - intptr = &options->allow_tcp_forwarding; - goto parse_flag; - - case sUsePrivilegeSeparation: - log("%s line %d: ignoring UsePrivilegeSeparation option value." - " This option is always on.", filename, linenum); - while (arg) - arg = strdelim(&cp); - break; - - case sAllowUsers: - while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { - if (options->num_allow_users >= MAX_ALLOW_USERS) - fatal("%s line %d: too many allow users.", - filename, linenum); - options->allow_users[options->num_allow_users++] = - xstrdup(arg); - } - break; - - case sDenyUsers: - while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { - if (options->num_deny_users >= MAX_DENY_USERS) - fatal( "%s line %d: too many deny users.", - filename, linenum); - options->deny_users[options->num_deny_users++] = - xstrdup(arg); - } - break; - - case sAllowGroups: - while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { - if (options->num_allow_groups >= MAX_ALLOW_GROUPS) - fatal("%s line %d: too many allow groups.", - filename, linenum); - options->allow_groups[options->num_allow_groups++] = - xstrdup(arg); - } - break; - - case sDenyGroups: - while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') { - if (options->num_deny_groups >= MAX_DENY_GROUPS) - fatal("%s line %d: too many deny groups.", - filename, linenum); - options->deny_groups[options->num_deny_groups++] = xstrdup(arg); - } - break; - - case sCiphers: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - if (!ciphers_valid(arg)) - fatal("%s line %d: Bad SSH2 cipher spec '%s'.", - filename, linenum, arg ? arg : "<NONE>"); - if (options->ciphers == NULL) - options->ciphers = xstrdup(arg); - break; - - case sMacs: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - if (!mac_valid(arg)) - fatal("%s line %d: Bad SSH2 mac spec '%s'.", - filename, linenum, arg ? arg : "<NONE>"); - if (options->macs == NULL) - options->macs = xstrdup(arg); - break; - - case sProtocol: - intptr = &options->protocol; - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - value = proto_spec(arg); - if (value == SSH_PROTO_UNKNOWN) - fatal("%s line %d: Bad protocol spec '%s'.", - 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); - if (!*activep) { - arg = strdelim(&cp); - break; - } - 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); - - /* - * Collect arguments (separate to executable), including the - * name of the executable, in a way that is easier to parse - * later. - */ - p = xstrdup(arg); - len = strlen(p) + 1; - while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { - len += 1 + strlen(arg); - p = xrealloc(p, len); - strlcat(p, " ", len); - strlcat(p, arg, len); - } - options->subsystem_args[options->num_subsystems] = p; - options->num_subsystems++; - break; - - case sMaxStartups: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing MaxStartups spec.", - filename, linenum); - if ((n = 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); - } else if (n != 1) - fatal("%s line %d: Illegal MaxStartups spec.", - filename, linenum); - else - options->max_startups = options->max_startups_begin; - break; - - case sBanner: - charptr = &options->banner; - goto parse_filename; - /* - * These options can contain %X options expanded at - * connect time, so that you can specify paths like: - * - * AuthorizedKeysFile /etc/ssh_keys/%u - */ - case sAuthorizedKeysFile: - case sAuthorizedKeysFile2: - charptr = (opcode == sAuthorizedKeysFile) ? - &options->authorized_keys_file : - &options->authorized_keys_file2; - goto parse_filename; - - case sClientAliveInterval: - intptr = &options->client_alive_interval; - goto parse_time; - - case sClientAliveCountMax: - intptr = &options->client_alive_count_max; - goto parse_int; - - case sMaxAuthTries: - intptr = &options->max_auth_tries; - goto parse_int; - - case sMaxAuthTriesLog: - intptr = &options->max_auth_tries_log; - goto parse_int; - - case sLookupClientHostnames: - intptr = &options->lookup_client_hostnames; - goto parse_flag; - - case sUseOpenSSLEngine: - intptr = &options->use_openssl_engine; - goto parse_flag; - - case sChrootDirectory: - charptr = &options->chroot_directory; - - arg = strdelim(&cp); - if (arg == NULL || *arg == '\0') - fatal("%s line %d: missing directory name for " - "ChrootDirectory.", filename, linenum); - if (*activep && *charptr == NULL) - *charptr = xstrdup(arg); - break; - - case sPreUserauthHook: - charptr = &options->pre_userauth_hook; - goto parse_filename; - - case sMatch: - if (cmdline) - fatal("Match directive not supported as a command-line " - "option"); - value = match_cfg_line(&cp, linenum, user, host, address); - if (value < 0) - fatal("%s line %d: Bad Match condition", filename, - linenum); - *activep = value; - break; - - case sDeprecated: - log("%s line %d: Deprecated option %s", - filename, linenum, arg); - while (arg) - arg = strdelim(&cp); - break; - - case sPAMServicePrefix: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", - filename, linenum); - if (options->pam_service_name != NULL) - fatal("%s line %d: PAMServiceName and PAMServicePrefix " - "are mutually exclusive.", filename, linenum); - if (options->pam_service_prefix == NULL) - options->pam_service_prefix = xstrdup(arg); - break; - - case sPAMServiceName: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", - filename, linenum); - if (options->pam_service_prefix != NULL) - fatal("%s line %d: PAMServiceName and PAMServicePrefix " - "are mutually exclusive.", filename, linenum); - if (options->pam_service_name == NULL) - options->pam_service_name = xstrdup(arg); - break; - - case sPubKeyPlugin: - charptr = &options->pubkey_plugin; - goto parse_filename; - - default: - fatal("%s line %d: Missing handler for opcode %s (%d)", - filename, linenum, arg, opcode); - } - if ((arg = strdelim(&cp)) != NULL && *arg != '\0') - fatal("%s line %d: garbage at end of line; \"%.200s\".", - filename, linenum, arg); - return 0; -} - - -/* Reads the server configuration file. */ - -void -load_server_config(const char *filename, Buffer *conf) -{ - char line[1024], *cp; - FILE *f; - - debug2("%s: filename %s", __func__, filename); - if ((f = fopen(filename, "r")) == NULL) { - perror(filename); - exit(1); - } - buffer_clear(conf); - while (fgets(line, sizeof(line), f)) { - /* - * Trim out comments and strip whitespace - * NB - preserve newlines, they are needed to reproduce - * line numbers later for error messages - */ - if ((cp = strchr(line, '#')) != NULL) - memcpy(cp, "\n", 2); - cp = line + strspn(line, " \t\r"); - - buffer_append(conf, cp, strlen(cp)); - } - buffer_append(conf, "\0", 1); - fclose(f); - debug2("%s: done config len = %d", __func__, buffer_len(conf)); -} - -void -parse_server_match_config(ServerOptions *options, const char *user, - const char *host, const char *address) -{ - ServerOptions mo; - - initialize_server_options(&mo); - parse_server_config(&mo, "reprocess config", &cfg, user, host, address); - copy_set_server_options(options, &mo, 0); -} - - - -/* Helper macros */ -#define M_CP_INTOPT(n) do {\ - if (src->n != -1) \ - dst->n = src->n; \ -} while (0) -#define M_CP_STROPT(n) do {\ - if (src->n != NULL) { \ - if (dst->n != NULL) \ - xfree(dst->n); \ - dst->n = src->n; \ - } \ -} while(0) - -/* - * Copy any supported values that are set. - * - * If the preauth flag is set, we do not bother copying the the string or - * array values that are not used pre-authentication, because any that we - * do use must be explictly sent in mm_getpwnamallow(). - */ -void -copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) -{ - M_CP_INTOPT(password_authentication); - M_CP_INTOPT(gss_authentication); - M_CP_INTOPT(rsa_authentication); - M_CP_INTOPT(pubkey_authentication); - M_CP_INTOPT(hostbased_authentication); - M_CP_INTOPT(kbd_interactive_authentication); - M_CP_INTOPT(permit_root_login); - M_CP_INTOPT(permit_empty_passwd); - M_CP_INTOPT(allow_tcp_forwarding); - M_CP_INTOPT(gateway_ports); - M_CP_INTOPT(x11_display_offset); - M_CP_INTOPT(x11_forwarding); - M_CP_INTOPT(x11_use_localhost); - M_CP_INTOPT(max_auth_tries); - M_CP_STROPT(banner); - - if (preauth) - return; - M_CP_STROPT(chroot_directory); -} - -#undef M_CP_INTOPT -#undef M_CP_STROPT - -void -parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, - const char *user, const char *host, const char *address) -{ - int active, linenum, bad_options = 0; - char *cp, *obuf, *cbuf; - - debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); - - obuf = cbuf = xstrdup(buffer_ptr(conf)); - active = user ? 0 : 1; - linenum = 1; - while ((cp = strsep(&cbuf, "\n")) != NULL) { - if (process_server_config_line(options, cp, filename, - linenum++, &active, user, host, address) != 0) - bad_options++; - } - xfree(obuf); - if (bad_options > 0) - fatal("%s: terminating, %d bad configuration options", - filename, bad_options); -} - - -/* - * Note that "none" is a special path having the same affect on sshd - * configuration as not specifying ChrootDirectory at all. - */ -int -chroot_requested(char *chroot_directory) -{ - return (chroot_directory != NULL && - strcasecmp(chroot_directory, "none") != 0); -} diff --git a/usr/src/cmd/ssh/sshd/serverloop.c b/usr/src/cmd/ssh/sshd/serverloop.c deleted file mode 100644 index 3dae9b1840..0000000000 --- a/usr/src/cmd/ssh/sshd/serverloop.c +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.104 2002/09/19 16:03:15 stevesk Exp $"); - -#include "xmalloc.h" -#include "packet.h" -#include "buffer.h" -#include "log.h" -#include "servconf.h" -#include "canohost.h" -#include "sshpty.h" -#include "channels.h" -#include "compat.h" -#include "ssh1.h" -#include "ssh2.h" -#include "auth.h" -#include "session.h" -#include "dispatch.h" -#include "auth-options.h" -#include "serverloop.h" -#include "misc.h" -#include "kex.h" - -#ifdef ALTPRIVSEP -#include "altprivsep.h" -#endif /* ALTPRIVSEP*/ - -extern ServerOptions options; - -/* XXX */ -extern Kex *xxx_kex; -static Authctxt *xxx_authctxt; - -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 int fdin; /* Descriptor for stdin (for writing) */ -static int fdout; /* Descriptor for stdout (for reading); - May be same number as fdin. */ -static int fderr; /* Descriptor for stderr. May be -1. */ -static long stdin_bytes = 0; /* Number of bytes written to stdin. */ -static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */ -static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */ -static long fdout_bytes = 0; /* Number of stdout bytes read from program. */ -static int stdin_eof = 0; /* EOF message received from client. */ -static int fdout_eof = 0; /* EOF encountered reading from fdout. */ -static int fderr_eof = 0; /* EOF encountered readung from fderr. */ -static int fdin_is_tty = 0; /* fdin points to a tty. */ -static int connection_in; /* Connection to client (input). */ -static int connection_out; /* Connection to client (output). */ -static int connection_closed = 0; /* Connection to client closed. */ -static u_int buffer_high; /* "Soft" max buffer size. */ -static int client_alive_timeouts = 0; - -/* - * This SIGCHLD kludge is used to detect when the child exits. The server - * will exit after that, as soon as forwarded connections have terminated. - */ - -static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */ - -/* prototypes */ -static void server_init_dispatch(void); - -/* - * we write to this pipe if a SIGCHLD is caught in order to avoid - * the race between select() and child_terminated - */ -static int notify_pipe[2]; -static void -notify_setup(void) -{ - if (pipe(notify_pipe) < 0) { - error("pipe(notify_pipe) failed %s", strerror(errno)); - } else if ((fcntl(notify_pipe[0], F_SETFD, FD_CLOEXEC) == -1) || - (fcntl(notify_pipe[1], F_SETFD, FD_CLOEXEC) == -1)) { - error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno)); - (void) close(notify_pipe[0]); - (void) close(notify_pipe[1]); - } else { - set_nonblock(notify_pipe[0]); - set_nonblock(notify_pipe[1]); - return; - } - notify_pipe[0] = -1; /* read end */ - notify_pipe[1] = -1; /* write end */ -} -static void -notify_parent(void) -{ - if (notify_pipe[1] != -1) - (void) write(notify_pipe[1], "", 1); -} -static void -notify_prepare(fd_set *readset) -{ - if (notify_pipe[0] != -1) - FD_SET(notify_pipe[0], readset); -} -static void -notify_done(fd_set *readset) -{ - char c; - - if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) - while (read(notify_pipe[0], &c, 1) != -1) - debug2("notify_done: reading"); -} - -static void -sigchld_handler(int sig) -{ - int save_errno = errno; - debug("Received SIGCHLD."); - child_terminated = 1; -#ifndef _UNICOS - mysignal(SIGCHLD, sigchld_handler); -#endif - notify_parent(); - errno = save_errno; -} - -/* - * Make packets from buffered stderr data, and buffer it for sending - * to the client. - */ -static void -make_packets_from_stderr_data(void) -{ - int len; - - /* Send buffered stderr data to the client. */ - while (buffer_len(&stderr_buffer) > 0 && - packet_not_very_much_data_to_write()) { - len = buffer_len(&stderr_buffer); - if (packet_is_interactive()) { - if (len > 512) - len = 512; - } else { - /* Keep the packets at reasonable size. */ - if (len > packet_get_maxsize()) - len = packet_get_maxsize(); - } - packet_start(SSH_SMSG_STDERR_DATA); - packet_put_string(buffer_ptr(&stderr_buffer), len); - packet_send(); - buffer_consume(&stderr_buffer, len); - stderr_bytes += len; - } -} - -/* - * Make packets from buffered stdout data, and buffer it for sending to the - * client. - */ -static void -make_packets_from_stdout_data(void) -{ - int len; - - /* Send buffered stdout data to the client. */ - while (buffer_len(&stdout_buffer) > 0 && - packet_not_very_much_data_to_write()) { - len = buffer_len(&stdout_buffer); - if (packet_is_interactive()) { - if (len > 512) - len = 512; - } else { - /* Keep the packets at reasonable size. */ - if (len > packet_get_maxsize()) - len = packet_get_maxsize(); - } - packet_start(SSH_SMSG_STDOUT_DATA); - packet_put_string(buffer_ptr(&stdout_buffer), len); - packet_send(); - buffer_consume(&stdout_buffer, len); - stdout_bytes += len; - } -} - -static void -client_alive_check(void) -{ - static int had_channel = 0; - int id; - - id = channel_find_open(); - if (id == -1) { - if (!had_channel) - return; - packet_disconnect("No open channels after timeout!"); - } - had_channel = 1; - - /* timeout, check to see how many we have had */ - if (++client_alive_timeouts > options.client_alive_count_max) - packet_disconnect("Timeout, your session not responding."); - - /* - * send a bogus channel request with "wantreply", - * we should get back a failure - */ - channel_request_start(id, "keepalive@openssh.com", 1); - packet_send(); -} - -/* - * Sleep in select() until we can do something. This will initialize the - * select masks. Upon return, the masks will indicate which descriptors - * have data or can accept data. Optionally, a maximum time can be specified - * for the duration of the wait (0 = infinite). - */ -static void -wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, - int *nallocp, u_int max_time_milliseconds) -{ - struct timeval tv, *tvp; - int ret; - int client_alive_scheduled = 0; - - /* - * if using client_alive, set the max timeout accordingly, - * and indicate that this particular timeout was for client - * alive by setting the client_alive_scheduled flag. - * - * this could be randomized somewhat to make traffic - * analysis more difficult, but we're not doing it yet. - */ - if (compat20 && - max_time_milliseconds == 0 && options.client_alive_interval) { - client_alive_scheduled = 1; - max_time_milliseconds = options.client_alive_interval * 1000; - } - - /* Allocate and update select() masks for channel descriptors. */ - channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 0); - - if (compat20) { -#ifdef ALTPRIVSEP - int pipe_fd; - - if ((pipe_fd = altprivsep_get_pipe_fd()) != -1) { - *maxfdp = MAX(*maxfdp, pipe_fd); - FD_SET(altprivsep_get_pipe_fd(), *readsetp); - } -#endif /* ALTPRIVSEP */ -#if 0 - /* wrong: bad condition XXX */ - if (channel_not_very_much_buffered_data()) -#endif - FD_SET(connection_in, *readsetp); - } else { - /* - * Read packets from the client unless we have too much - * buffered stdin or channel data. - */ - if (buffer_len(&stdin_buffer) < buffer_high && - channel_not_very_much_buffered_data()) - FD_SET(connection_in, *readsetp); - /* - * If there is not too much data already buffered going to - * the client, try to get some more data from the program. - */ - if (packet_not_very_much_data_to_write()) { - if (!fdout_eof) - FD_SET(fdout, *readsetp); - if (!fderr_eof) - FD_SET(fderr, *readsetp); - } - /* - * If we have buffered data, try to write some of that data - * to the program. - */ - if (fdin != -1 && buffer_len(&stdin_buffer) > 0) - FD_SET(fdin, *writesetp); - } - notify_prepare(*readsetp); - - /* - * If we have buffered packet data going to the client, mark that - * descriptor. - */ - if (packet_have_data_to_write()) - FD_SET(connection_out, *writesetp); - - /* - * If child has terminated and there is enough buffer space to read - * from it, then read as much as is available and exit. - */ - if (child_terminated && packet_not_very_much_data_to_write()) - if (max_time_milliseconds == 0 || client_alive_scheduled) - max_time_milliseconds = 100; - - if (max_time_milliseconds == 0) - tvp = NULL; - else { - tv.tv_sec = max_time_milliseconds / 1000; - tv.tv_usec = 1000 * (max_time_milliseconds % 1000); - tvp = &tv; - } - - /* Wait for something to happen, or the timeout to expire. */ - ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); - - if (ret == -1) { - memset(*readsetp, 0, *nallocp); - memset(*writesetp, 0, *nallocp); - if (errno != EINTR) - error("select: %.100s", strerror(errno)); - } else if (ret == 0 && client_alive_scheduled) - client_alive_check(); - - notify_done(*readsetp); -} - -/* - * Processes input from the client and the program. Input data is stored - * in buffers and processed later. - */ -static void -process_input(fd_set * readset) -{ - int len; - char buf[16384]; - - /* Read and buffer any input data from the client. */ - if (FD_ISSET(connection_in, readset)) { - len = read(connection_in, buf, sizeof(buf)); - if (len == 0) { - if (packet_is_monitor()) { - debug("child closed the communication pipe"); - } else { - verbose("Connection closed by %.100s", - get_remote_ipaddr()); - } - connection_closed = 1; - if (compat20) - return; - fatal_cleanup(); - } else if (len < 0) { - if (errno != EINTR && errno != EAGAIN) { - verbose("Read error from remote host " - "%.100s: %.100s", - get_remote_ipaddr(), strerror(errno)); - fatal_cleanup(); - } - } else { - /* Buffer any received data. */ - packet_process_incoming(buf, len); - } - } - if (compat20) - return; - - /* Read and buffer any available stdout data from the program. */ - if (!fdout_eof && FD_ISSET(fdout, readset)) { - len = read(fdout, buf, sizeof(buf)); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) { - /* EMPTY */ - } else if (len <= 0) { - fdout_eof = 1; - } else { - buffer_append(&stdout_buffer, buf, len); - fdout_bytes += len; - } - } - /* Read and buffer any available stderr data from the program. */ - if (!fderr_eof && FD_ISSET(fderr, readset)) { - len = read(fderr, buf, sizeof(buf)); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) { - /* EMPTY */ - } else if (len <= 0) { - fderr_eof = 1; - } else { - buffer_append(&stderr_buffer, buf, len); - } - } -} - -/* - * Sends data from internal buffers to client program stdin. - */ -static void -process_output(fd_set * writeset) -{ - struct termios tio; - u_char *data; - u_int dlen; - int len; - - /* Write buffered data to program stdin. */ - if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { - data = buffer_ptr(&stdin_buffer); - dlen = buffer_len(&stdin_buffer); - len = write(fdin, data, dlen); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) { - /* EMPTY */ - } else if (len <= 0) { - if (fdin != fdout) - (void) close(fdin); - else - (void) shutdown(fdin, SHUT_WR); /* We will no longer send. */ - fdin = -1; - } else { - /* Successful write. */ - if (fdin_is_tty && dlen >= 1 && data[0] != '\r' && - tcgetattr(fdin, &tio) == 0 && - !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { - /* - * Simulate echo to reduce the impact of - * traffic analysis - */ - packet_send_ignore(len); - packet_send(); - } - /* Consume the data from the buffer. */ - buffer_consume(&stdin_buffer, len); - /* Update the count of bytes written to the program. */ - stdin_bytes += len; - } - } - /* Send any buffered packet data to the client. */ - if (FD_ISSET(connection_out, writeset)) - packet_write_poll(); -} - -/* - * Wait until all buffered output has been sent to the client. - * This is used when the program terminates. - */ -static void -drain_output(void) -{ - /* Send any buffered stdout data to the client. */ - if (buffer_len(&stdout_buffer) > 0) { - packet_start(SSH_SMSG_STDOUT_DATA); - packet_put_string(buffer_ptr(&stdout_buffer), - buffer_len(&stdout_buffer)); - packet_send(); - /* Update the count of sent bytes. */ - stdout_bytes += buffer_len(&stdout_buffer); - } - /* Send any buffered stderr data to the client. */ - if (buffer_len(&stderr_buffer) > 0) { - packet_start(SSH_SMSG_STDERR_DATA); - packet_put_string(buffer_ptr(&stderr_buffer), - buffer_len(&stderr_buffer)); - packet_send(); - /* Update the count of sent bytes. */ - stderr_bytes += buffer_len(&stderr_buffer); - } - /* Wait until all buffered data has been written to the client. */ - packet_write_wait(); -} - -static void -process_buffered_input_packets(void) -{ - dispatch_run(DISPATCH_NONBLOCK, NULL, compat20 ? xxx_kex : NULL); -} - -/* - * Performs the interactive session. This handles data transmission between - * the client and the program. Note that the notion of stdin, stdout, and - * stderr in this function is sort of reversed: this function writes to - * stdin (of the child program), and reads from stdout and stderr (of the - * child program). - */ -void -server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) -{ - fd_set *readset = NULL, *writeset = NULL; - int max_fd = 0, nalloc = 0; - int wait_status; /* Status returned by wait(). */ - pid_t wait_pid; /* pid returned by wait(). */ - int waiting_termination = 0; /* Have displayed waiting close message. */ - u_int max_time_milliseconds; - u_int previous_stdout_buffer_bytes; - u_int stdout_buffer_bytes; - int type; - - debug("Entering interactive session."); - - /* Initialize the SIGCHLD kludge. */ - child_terminated = 0; - mysignal(SIGCHLD, sigchld_handler); - - /* Initialize our global variables. */ - fdin = fdin_arg; - fdout = fdout_arg; - fderr = fderr_arg; - - /* nonblocking IO */ - set_nonblock(fdin); - set_nonblock(fdout); - /* we don't have stderr for interactive terminal sessions, see below */ - if (fderr != -1) - set_nonblock(fderr); - - if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) - fdin_is_tty = 1; - - connection_in = packet_get_connection_in(); - connection_out = packet_get_connection_out(); - - notify_setup(); - - previous_stdout_buffer_bytes = 0; - - /* Set approximate I/O buffer size. */ - if (packet_is_interactive()) - buffer_high = 4096; - else - buffer_high = 64 * 1024; - -#if 0 - /* Initialize max_fd to the maximum of the known file descriptors. */ - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, fdin); - max_fd = MAX(max_fd, fdout); - if (fderr != -1) - max_fd = MAX(max_fd, fderr); -#endif - - /* Initialize Initialize buffers. */ - buffer_init(&stdin_buffer); - buffer_init(&stdout_buffer); - buffer_init(&stderr_buffer); - - /* - * If we have no separate fderr (which is the case when we have a pty - * - there we cannot make difference between data sent to stdout and - * stderr), indicate that we have seen an EOF from stderr. This way - * we don\'t need to check the descriptor everywhere. - */ - if (fderr == -1) - fderr_eof = 1; - - server_init_dispatch(); - - /* Main loop of the server for the interactive session mode. */ - for (;;) { - - /* Process buffered packets from the client. */ - process_buffered_input_packets(); - - /* - * If we have received eof, and there is no more pending - * input data, cause a real eof by closing fdin. - */ - if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { - if (fdin != fdout) - (void) close(fdin); - else - (void) shutdown(fdin, SHUT_WR); /* We will no longer send. */ - fdin = -1; - } - /* Make packets from buffered stderr data to send to the client. */ - make_packets_from_stderr_data(); - - /* - * Make packets from buffered stdout data to send to the - * client. If there is very little to send, this arranges to - * not send them now, but to wait a short while to see if we - * are getting more data. This is necessary, as some systems - * wake up readers from a pty after each separate character. - */ - max_time_milliseconds = 0; - stdout_buffer_bytes = buffer_len(&stdout_buffer); - if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && - stdout_buffer_bytes != previous_stdout_buffer_bytes) { - /* try again after a while */ - max_time_milliseconds = 10; - } else { - /* Send it now. */ - make_packets_from_stdout_data(); - } - previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); - - /* Send channel data to the client. */ - if (packet_not_very_much_data_to_write()) - channel_output_poll(); - - /* - * Bail out of the loop if the program has closed its output - * descriptors, and we have no more data to send to the - * client, and there is no pending buffered data. - */ - if (fdout_eof && fderr_eof && !packet_have_data_to_write() && - buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) { - if (!channel_still_open()) - break; - if (!waiting_termination) { - const char *s = "Waiting for forwarded connections to terminate...\r\n"; - char *cp; - waiting_termination = 1; - buffer_append(&stderr_buffer, s, strlen(s)); - - /* Display list of open channels. */ - cp = channel_open_message(); - buffer_append(&stderr_buffer, cp, strlen(cp)); - xfree(cp); - } - } - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, fdin); - max_fd = MAX(max_fd, fdout); - max_fd = MAX(max_fd, fderr); - max_fd = MAX(max_fd, notify_pipe[0]); - - /* Sleep in select() until we can do something. */ - wait_until_can_do_something(&readset, &writeset, &max_fd, - &nalloc, max_time_milliseconds); - - /* Process any channel events. */ - channel_after_select(readset, writeset); - - /* Process input from the client and from program stdout/stderr. */ - process_input(readset); - - /* Process output to the client and to program stdin. */ - process_output(writeset); - } - if (readset) - xfree(readset); - if (writeset) - xfree(writeset); - - /* Cleanup and termination code. */ - - /* Wait until all output has been sent to the client. */ - drain_output(); - - debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.", - stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes); - - /* Free and clear the buffers. */ - buffer_free(&stdin_buffer); - buffer_free(&stdout_buffer); - buffer_free(&stderr_buffer); - - /* Close the file descriptors. */ - if (fdout != -1) - (void) close(fdout); - fdout = -1; - fdout_eof = 1; - if (fderr != -1) - (void) close(fderr); - fderr = -1; - fderr_eof = 1; - if (fdin != -1) - (void) close(fdin); - fdin = -1; - - channel_free_all(); - - /* We no longer want our SIGCHLD handler to be called. */ - mysignal(SIGCHLD, SIG_DFL); - - while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0) - if (errno != EINTR) - packet_disconnect("wait: %.100s", strerror(errno)); - if (wait_pid != pid) - error("Strange, wait returned pid %ld, expected %ld", - (long)wait_pid, (long)pid); - - /* Check if it exited normally. */ - if (WIFEXITED(wait_status)) { - /* Yes, normal exit. Get exit status and send it to the client. */ - debug("Command exited with status %d.", WEXITSTATUS(wait_status)); - packet_start(SSH_SMSG_EXITSTATUS); - packet_put_int(WEXITSTATUS(wait_status)); - packet_send(); - packet_write_wait(); - - /* - * Wait for exit confirmation. Note that there might be - * other packets coming before it; however, the program has - * already died so we just ignore them. The client is - * supposed to respond with the confirmation when it receives - * the exit status. - */ - do { - type = packet_read(); - } - while (type != SSH_CMSG_EXIT_CONFIRMATION); - - debug("Received exit confirmation."); - return; - } - /* Check if the program terminated due to a signal. */ - if (WIFSIGNALED(wait_status)) - packet_disconnect("Command terminated on signal %d.", - WTERMSIG(wait_status)); - - /* Some weird exit cause. Just exit. */ - packet_disconnect("wait returned status %04x.", wait_status); - /* NOTREACHED */ -} - -static void -collect_children(void) -{ - pid_t pid; - sigset_t oset, nset; - int status; - - /* block SIGCHLD while we check for dead children */ - (void) sigemptyset(&nset); - (void) sigaddset(&nset, SIGCHLD); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - if (child_terminated) { - while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || - (pid < 0 && errno == EINTR)) - if (pid > 0) - session_close_by_pid(pid, status); - child_terminated = 0; - } - (void) sigprocmask(SIG_SETMASK, &oset, NULL); -} - -#ifdef ALTPRIVSEP -/* - * For ALTPRIVSEP the wait_until_can_do_something function is very - * simple: select() on the read side of the pipe, and if there's packets - * to send, on the write side, and on the read side of the SIGCHLD - * handler pipe. That's it. - */ -static void -aps_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, - int *maxfdp, int *nallocp, u_int max_time_milliseconds) -{ - int ret; - - /* - * Use channel_prepare_select() to make the fd sets. - * - * This is cheating, really, since because the last argument in - * this call is '1' nothing related to channels will be done -- - * we're using this function only to callocate the fd sets. - */ - channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 1); - - if ((connection_in = packet_get_connection_in()) >= 0 && - !connection_closed) - FD_SET(connection_in, *readsetp); - - notify_prepare(*readsetp); - - if ((connection_out = packet_get_connection_out()) >= 0 && - packet_have_data_to_write() && !connection_closed) - FD_SET(connection_out, *writesetp); - - /* Wait for something to happen, or the timeout to expire. */ - ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL); - - if (ret == -1) { - memset(*readsetp, 0, *nallocp); - memset(*writesetp, 0, *nallocp); - if (errno != EINTR) - error("select: %.100s", strerror(errno)); - } - - notify_done(*readsetp); -} - -/* - * Slightly different than collect_children, aps_collect_child() has - * only the unprivileged sshd to wait for, no sessions, no channells, - * just one process. - */ -static int -aps_collect_child(pid_t child) -{ - pid_t pid; - sigset_t oset, nset; - int status; - - /* block SIGCHLD while we check for dead children */ - (void) sigemptyset(&nset); - (void) sigaddset(&nset, SIGCHLD); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - if (child_terminated) { - while ((pid = waitpid(child, &status, WNOHANG)) > 0 || - (pid < 0 && errno == EINTR)) - if (pid == child) { - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - return (1); - } - child_terminated = 0; - } - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - return (0); -} - -static int killed = 0; - -static void -aps_monitor_kill_handler(int sig) -{ - int save_errno = errno; - killed = 1; - notify_parent(); - mysignal(sig, aps_monitor_kill_handler); - errno = save_errno; -} - -static void -aps_monitor_sigchld_handler(int sig) -{ - int save_errno = errno; - debug("Monitor received SIGCHLD."); - child_terminated = 1; - mysignal(SIGCHLD, aps_monitor_sigchld_handler); - notify_parent(); - errno = save_errno; -} - -void -aps_monitor_loop(Authctxt *authctxt, pid_t child_pid) -{ - fd_set *readset = NULL, *writeset = NULL; - int max_fd, nalloc = 0; - - debug("Entering monitor loop."); - - /* - * Awful hack follows: fake compat20 == 1 to cause process_input() - * and process_output() to behave as they would for SSHv2 because that's - * the behaviour we need in SSHv2. - * - * This same hack is done in packet.c - */ - compat20 = 1; /* causes process_input/output() to ignore stdio */ - - mysignal(SIGHUP, aps_monitor_kill_handler); - mysignal(SIGINT, aps_monitor_kill_handler); - mysignal(SIGTERM, aps_monitor_kill_handler); - - child_terminated = 0; - mysignal(SIGCHLD, aps_monitor_sigchld_handler); - - connection_in = packet_get_connection_in(); - connection_out = packet_get_connection_out(); - - notify_setup(); - - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, notify_pipe[0]); - - dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); - dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_MAX, - &dispatch_protocol_error); - dispatch_set(SSH2_PRIV_MSG_ALTPRIVSEP, &aps_input_altpriv_msg); - - for (;;) { - process_buffered_input_packets(); - - aps_wait_until_can_do_something(&readset, &writeset, &max_fd, - &nalloc, 0); - - if (aps_collect_child(child_pid)) - break; - - if (killed) { - /* fatal cleanups will kill child, audit logout */ - log("Monitor killed; exiting"); - fatal_cleanup(); - } - - /* - * Unlike server_loop2() we don't care if connection_closed - * since we still want to wait for the monitor's child. - */ - process_input(readset); - process_output(writeset); - } - - packet_close(); -} -#endif /* ALTPRIVSEP */ - -/* - * This server loop is for unprivileged child only. Our monitor runs its own - * aps_monitor_loop() funtion. - */ -void -server_loop2(Authctxt *authctxt) -{ - fd_set *readset = NULL, *writeset = NULL; - int rekeying = 0, max_fd, nalloc = 0; - - debug("Entering interactive session for SSH2."); - - mysignal(SIGCHLD, sigchld_handler); - child_terminated = 0; - connection_in = packet_get_connection_in(); - connection_out = packet_get_connection_out(); - - notify_setup(); - - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, notify_pipe[0]); - - xxx_authctxt = authctxt; - - server_init_dispatch(); - - for (;;) { - process_buffered_input_packets(); - - rekeying = (xxx_kex != NULL && !xxx_kex->done); - - if (!rekeying && packet_not_very_much_data_to_write()) - channel_output_poll(); - wait_until_can_do_something(&readset, &writeset, &max_fd, - &nalloc, 0); - - collect_children(); - - if (!rekeying) { - channel_after_select(readset, writeset); - if (packet_need_rekeying()) { - debug("rekey limit reached, need rekeying"); - xxx_kex->done = 0; - debug("poking the monitor to start " - "key re-exchange"); - altprivsep_start_rekex(); - } - } -#ifdef ALTPRIVSEP - else - altprivsep_process_input(readset); -#endif /* ALTPRIVSEP */ - - process_input(readset); - if (connection_closed) - break; - process_output(writeset); - } - collect_children(); - - if (readset) - xfree(readset); - if (writeset) - xfree(writeset); - - /* free all channels, no more reads and writes */ - channel_free_all(); - - /* free remaining sessions, e.g. remove wtmp entries */ - session_destroy_all(NULL); -} - -static void -server_input_channel_failure(int type, u_int32_t seq, void *ctxt) -{ - debug("Got CHANNEL_FAILURE for keepalive"); - /* - * reset timeout, since we got a sane answer from the client. - * even if this was generated by something other than - * the bogus CHANNEL_REQUEST we send for keepalives. - */ - client_alive_timeouts = 0; -} - -static void -server_input_stdin_data(int type, u_int32_t seq, void *ctxt) -{ - char *data; - u_int data_len; - - /* Stdin data from the client. Append it to the buffer. */ - /* Ignore any data if the client has closed stdin. */ - if (fdin == -1) - return; - data = packet_get_string(&data_len); - packet_check_eom(); - buffer_append(&stdin_buffer, data, data_len); - memset(data, 0, data_len); - xfree(data); -} - -static void -server_input_eof(int type, u_int32_t seq, void *ctxt) -{ - /* - * Eof from the client. The stdin descriptor to the - * program will be closed when all buffered data has - * drained. - */ - debug("EOF received for stdin."); - packet_check_eom(); - stdin_eof = 1; -} - -static void -server_input_window_size(int type, u_int32_t seq, void *ctxt) -{ - int row = packet_get_int(); - int col = packet_get_int(); - int xpixel = packet_get_int(); - int ypixel = packet_get_int(); - - debug("Window change received."); - packet_check_eom(); - if (fdin != -1) - pty_change_window_size(fdin, row, col, xpixel, ypixel); -} - -static Channel * -server_request_direct_tcpip(char *ctype) -{ - Channel *c; - int sock; - char *target, *originator; - int target_port, originator_port; - - target = packet_get_string(NULL); - target_port = packet_get_int(); - originator = packet_get_string(NULL); - originator_port = packet_get_int(); - packet_check_eom(); - - debug("server_request_direct_tcpip: originator %s port %d, target %s port %d", - originator, originator_port, target, target_port); - - /* XXX check permission */ - sock = channel_connect_to(target, target_port); - - xfree(target); - xfree(originator); - if (sock < 0) - return NULL; - c = channel_new(ctype, SSH_CHANNEL_CONNECTING, - sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, - CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1); - return c; -} - -static Channel * -server_request_session(char *ctype) -{ - Channel *c; - - debug("input_session_request"); - packet_check_eom(); - /* - * A server session has no fd to read or write until a - * CHANNEL_REQUEST for a shell is made, so we set the type to - * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all - * CHANNEL_REQUEST messages is registered. - */ - c = channel_new(ctype, SSH_CHANNEL_LARVAL, - -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, - 0, xstrdup("server-session"), 1); - if (session_open(xxx_authctxt, c->self) != 1) { - debug("session open failed, free channel %d", c->self); - channel_free(c); - return NULL; - } - channel_register_cleanup(c->self, session_close_by_channel); - return c; -} - -static void -server_input_channel_open(int type, u_int32_t seq, void *ctxt) -{ - Channel *c = NULL; - char *ctype; - int rchan; - u_int rmaxpack, rwindow, len; - - ctype = packet_get_string(&len); - rchan = packet_get_int(); - rwindow = packet_get_int(); - rmaxpack = packet_get_int(); - - debug("server_input_channel_open: ctype %s rchan %d win %d max %d", - ctype, rchan, rwindow, rmaxpack); - - if (strcmp(ctype, "session") == 0) { - c = server_request_session(ctype); - } else if (strcmp(ctype, "direct-tcpip") == 0) { - c = server_request_direct_tcpip(ctype); - } - if (c != NULL) { - debug("server_input_channel_open: confirm %s", ctype); - c->remote_id = rchan; - c->remote_window = rwindow; - c->remote_maxpacket = rmaxpack; - if (c->type != SSH_CHANNEL_CONNECTING) { - packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(c->remote_id); - packet_put_int(c->self); - packet_put_int(c->local_window); - packet_put_int(c->local_maxpacket); - packet_send(); - } - } else { - debug("server_input_channel_open: failure %s", ctype); - packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(rchan); - packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); - if (!(datafellows & SSH_BUG_OPENFAILURE)) { - packet_put_utf8_cstring("open failed"); - packet_put_cstring(""); - } - packet_send(); - } - xfree(ctype); -} - -static void -server_input_global_request(int type, u_int32_t seq, void *ctxt) -{ - char *rtype; - int want_reply; - int success = 0; - - rtype = packet_get_string(NULL); - want_reply = packet_get_char(); - debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply); - - /* -R style forwarding */ - if (strcmp(rtype, "tcpip-forward") == 0) { - struct passwd *pw; - char *listen_address; - u_short listen_port; - - pw = auth_get_user(); - if (pw == NULL) - fatal("server_input_global_request: no user"); - listen_address = packet_get_string(NULL); /* XXX currently ignored */ - listen_port = (u_short)packet_get_int(); - debug("server_input_global_request: tcpip-forward listen %s port %d", - listen_address, listen_port); - - /* check permissions */ - if (!options.allow_tcp_forwarding || - no_port_forwarding_flag -#ifndef NO_IPPORT_RESERVED_CONCEPT - || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0) -#endif - ) { - success = 0; - packet_send_debug("Server has disabled port forwarding."); - } else { - /* Start listening on the port */ - success = channel_setup_remote_fwd_listener( - listen_address, listen_port, options.gateway_ports); - } - xfree(listen_address); - } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { - char *cancel_address; - u_short cancel_port; - - cancel_address = packet_get_string(NULL); - cancel_port = (u_short)packet_get_int(); - debug("%s: cancel-tcpip-forward addr %s port %d", __func__, - cancel_address, cancel_port); - - success = channel_cancel_rport_listener(cancel_address, - cancel_port); - xfree(cancel_address); - } - if (want_reply) { - packet_start(success ? - SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); - packet_send(); - packet_write_wait(); - } - xfree(rtype); -} - -static void -server_input_channel_req(int type, u_int32_t seq, void *ctxt) -{ - Channel *c; - int id, reply, success = 0; - char *rtype; - - id = packet_get_int(); - rtype = packet_get_string(NULL); - reply = packet_get_char(); - - debug("server_input_channel_req: channel %d request %s reply %d", - id, rtype, reply); - - if ((c = channel_lookup(id)) == NULL) - packet_disconnect("server_input_channel_req: " - "unknown channel %d", id); - if (!strcmp(rtype, "eow@openssh.com")) { - packet_check_eom(); - chan_rcvd_eow(c); - } else if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) - success = session_input_channel_req(c, rtype); - if (reply) { - packet_start(success ? - SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); - packet_put_int(c->remote_id); - packet_send(); - } - xfree(rtype); -} - -static void -server_init_dispatch_20(void) -{ - debug("server_init_dispatch_20"); - dispatch_init(&dispatch_protocol_error); - dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); - dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); - dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); - dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); - dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open); - dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); - dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); - dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req); - dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); - dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); - /* client_alive */ - dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_channel_failure); - /* rekeying */ - -#ifdef ALTPRIVSEP - /* unprivileged sshd has a kex packet handler that must not be reset */ - debug3("server_init_dispatch_20 -- should we dispatch_set(KEXINIT) here? %d && !%d", - packet_is_server(), packet_is_monitor()); - if (packet_is_server() && !packet_is_monitor()) { - debug3("server_init_dispatch_20 -- skipping dispatch_set(KEXINIT) in unpriv proc"); - dispatch_range(SSH2_MSG_KEXINIT, SSH2_MSG_TRANSPORT_MAX, - &altprivsep_rekey); - return; - } -#endif /* ALTPRIVSEP */ - dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); -} -static void -server_init_dispatch_13(void) -{ - debug("server_init_dispatch_13"); - dispatch_init(NULL); - dispatch_set(SSH_CMSG_EOF, &server_input_eof); - dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data); - dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size); - dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); - dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); - dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); - dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); - dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); - dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); -} -static void -server_init_dispatch_15(void) -{ - server_init_dispatch_13(); - debug("server_init_dispatch_15"); - dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); - dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose); -} -static void -server_init_dispatch(void) -{ - if (compat20) - server_init_dispatch_20(); - else if (compat13) - server_init_dispatch_13(); - else - server_init_dispatch_15(); -} diff --git a/usr/src/cmd/ssh/sshd/session.c b/usr/src/cmd/ssh/sshd/session.c deleted file mode 100644 index 871b06c758..0000000000 --- a/usr/src/cmd/ssh/sshd/session.c +++ /dev/null @@ -1,2641 +0,0 @@ -/* - * 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, 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: session.c,v 1.150 2002/09/16 19:55:33 stevesk Exp $"); - -#ifdef HAVE_DEFOPEN -#include <deflt.h> -#include <ulimit.h> -#endif /* HAVE_DEFOPEN */ - -#ifdef HAVE_LIBGEN_H -#include <libgen.h> -#endif - -#include <priv.h> - -#include "ssh.h" -#include "ssh1.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "sshpty.h" -#include "packet.h" -#include "buffer.h" -#include "mpaux.h" -#include "uidswap.h" -#include "compat.h" -#include "channels.h" -#include "bufaux.h" -#include "auth.h" -#include "auth-options.h" -#include "pathnames.h" -#include "log.h" -#include "servconf.h" -#include "sshlogin.h" -#include "serverloop.h" -#include "canohost.h" -#include "session.h" -#include "tildexpand.h" -#include "misc.h" -#include "sftp.h" - -#ifdef USE_PAM -#include <security/pam_appl.h> -#endif /* USE_PAM */ - -#ifdef GSSAPI -#include "ssh-gss.h" -#endif - -#ifdef ALTPRIVSEP -#include "altprivsep.h" -#endif /* ALTPRIVSEP */ - -#ifdef HAVE_CYGWIN -#include <windows.h> -#include <sys/cygwin.h> -#define is_winnt (GetVersion() < 0x80000000) -#endif - -/* func */ - -Session *session_new(void); -void session_set_fds(Session *, int, int, int); -void session_pty_cleanup(void *); -void session_xauthfile_cleanup(void *s); -void session_proctitle(Session *); -int session_setup_x11fwd(Session *); -void do_exec_pty(Session *, const char *); -void do_exec_no_pty(Session *, const char *); -void do_exec(Session *, const char *); -void do_login(Session *, const char *); -void do_child(Session *, const char *); -void do_motd(void); -int check_quietlogin(Session *, const char *); - -static void do_authenticated1(Authctxt *); -static void do_authenticated2(Authctxt *); - -static int session_pty_req(Session *); -static int session_env_req(Session *s); -static void session_free_env(char ***envp); -static void safely_chroot(const char *path, uid_t uid); -static void drop_privs(uid_t uid); - -#ifdef USE_PAM -static void session_do_pam(Session *, int); -#endif /* USE_PAM */ - -/* import */ -extern ServerOptions options; -extern char *__progname; -extern int log_stderr; -extern int debug_flag; -extern u_int utmp_len; -extern void destroy_sensitive_data(void); - -#ifdef GSSAPI -extern Gssctxt *xxx_gssctxt; -#endif /* GSSAPI */ - -/* original command from peer. */ -const char *original_command = NULL; - -/* data */ -#define MAX_SESSIONS 10 -Session sessions[MAX_SESSIONS]; - -#define SUBSYSTEM_NONE 0 -#define SUBSYSTEM_EXT 1 -#define SUBSYSTEM_INT_SFTP 2 - -#ifdef HAVE_LOGIN_CAP -login_cap_t *lc; -#endif - -/* Name and directory of socket for authentication agent forwarding. */ -static char *auth_sock_name = NULL; -static char *auth_sock_dir = NULL; - -/* removes the agent forwarding socket */ - -static void -auth_sock_cleanup_proc(void *_pw) -{ - struct passwd *pw = _pw; - - if (auth_sock_name != NULL) { - temporarily_use_uid(pw); - unlink(auth_sock_name); - rmdir(auth_sock_dir); - auth_sock_name = NULL; - restore_uid(); - } -} - -static int -auth_input_request_forwarding(struct passwd * pw) -{ - Channel *nc; - int sock; - struct sockaddr_un sunaddr; - - if (auth_sock_name != NULL) { - error("authentication forwarding requested twice."); - return 0; - } - - /* Temporarily drop privileged uid for mkdir/bind. */ - temporarily_use_uid(pw); - - /* Allocate a buffer for the socket name, and format the name. */ - auth_sock_name = xmalloc(MAXPATHLEN); - auth_sock_dir = xmalloc(MAXPATHLEN); - strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); - - /* Create private directory for socket */ - if (mkdtemp(auth_sock_dir) == NULL) { - packet_send_debug("Agent forwarding disabled: " - "mkdtemp() failed: %.100s", strerror(errno)); - restore_uid(); - xfree(auth_sock_name); - xfree(auth_sock_dir); - auth_sock_name = NULL; - auth_sock_dir = NULL; - return 0; - } - snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld", - auth_sock_dir, (long) getpid()); - - /* delete agent socket on fatal() */ - fatal_add_cleanup(auth_sock_cleanup_proc, pw); - - /* Create the socket. */ - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - packet_disconnect("socket: %.100s", strerror(errno)); - - /* Bind it to the name. */ - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); - - if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) - packet_disconnect("bind: %.100s", strerror(errno)); - - /* Restore the privileged uid. */ - restore_uid(); - - /* Start listening on the socket. */ - if (listen(sock, 5) < 0) - packet_disconnect("listen: %.100s", strerror(errno)); - - /* Allocate a channel for the authentication agent socket. */ - nc = channel_new("auth socket", - SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, - 0, xstrdup("auth socket"), 1); - strlcpy(nc->path, auth_sock_name, sizeof(nc->path)); - return 1; -} - - -void -do_authenticated(Authctxt *authctxt) -{ - /* setup the channel layer */ - if (!no_port_forwarding_flag && options.allow_tcp_forwarding) - channel_permit_all_opens(); - - if (compat20) - do_authenticated2(authctxt); - else - do_authenticated1(authctxt); - - /* remove agent socket */ - if (auth_sock_name != NULL) - auth_sock_cleanup_proc(authctxt->pw); -#ifdef KRB4 - if (options.kerberos_ticket_cleanup) - krb4_cleanup_proc(authctxt); -#endif -#ifdef KRB5 - if (options.kerberos_ticket_cleanup) - krb5_cleanup_proc(authctxt); -#endif -} - -/* - * Prepares for an interactive session. This is called after the user has - * been successfully authenticated. During this message exchange, pseudo - * terminals are allocated, X11, TCP/IP, and authentication agent forwardings - * are requested, etc. - */ -static void -do_authenticated1(Authctxt *authctxt) -{ - Session *s; - char *command; - int success, type, screen_flag; - int enable_compression_after_reply = 0; - u_int proto_len, data_len, dlen, compression_level = 0; - - s = session_new(); - s->authctxt = authctxt; - s->pw = authctxt->pw; - - /* - * We stay in this loop until the client requests to execute a shell - * or a command. - */ - for (;;) { - success = 0; - - /* Get a packet from the client. */ - type = packet_read(); - - /* Process the packet. */ - switch (type) { - case SSH_CMSG_REQUEST_COMPRESSION: - compression_level = packet_get_int(); - packet_check_eom(); - if (compression_level < 1 || compression_level > 9) { - packet_send_debug("Received illegal compression level %d.", - compression_level); - break; - } - if (!options.compression) { - debug2("compression disabled"); - break; - } - /* Enable compression after we have responded with SUCCESS. */ - enable_compression_after_reply = 1; - success = 1; - break; - - case SSH_CMSG_REQUEST_PTY: - success = session_pty_req(s); - break; - - case SSH_CMSG_X11_REQUEST_FORWARDING: - s->auth_proto = packet_get_string(&proto_len); - s->auth_data = packet_get_string(&data_len); - - screen_flag = packet_get_protocol_flags() & - SSH_PROTOFLAG_SCREEN_NUMBER; - debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag); - - if (packet_remaining() == 4) { - if (!screen_flag) - debug2("Buggy client: " - "X11 screen flag missing"); - s->screen = packet_get_int(); - } else { - s->screen = 0; - } - packet_check_eom(); - success = session_setup_x11fwd(s); - if (!success) { - xfree(s->auth_proto); - xfree(s->auth_data); - s->auth_proto = NULL; - s->auth_data = NULL; - } - break; - - case SSH_CMSG_AGENT_REQUEST_FORWARDING: - if (no_agent_forwarding_flag || compat13) { - debug("Authentication agent forwarding not permitted for this authentication."); - break; - } - debug("Received authentication agent forwarding request."); - success = auth_input_request_forwarding(s->pw); - break; - - case SSH_CMSG_PORT_FORWARD_REQUEST: - if (no_port_forwarding_flag) { - debug("Port forwarding not permitted for this authentication."); - break; - } - if (!options.allow_tcp_forwarding) { - debug("Port forwarding not permitted."); - break; - } - debug("Received TCP/IP port forwarding request."); - channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports); - success = 1; - break; - - case SSH_CMSG_MAX_PACKET_SIZE: - if (packet_set_maxsize(packet_get_int()) > 0) - success = 1; - break; - -#if defined(AFS) || defined(KRB5) - case SSH_CMSG_HAVE_KERBEROS_TGT: - if (!options.kerberos_tgt_passing) { - verbose("Kerberos TGT passing disabled."); - } else { - char *kdata = packet_get_string(&dlen); - packet_check_eom(); - - /* XXX - 0x41, see creds_to_radix version */ - if (kdata[0] != 0x41) { -#ifdef KRB5 - krb5_data tgt; - tgt.data = kdata; - tgt.length = dlen; - - if (auth_krb5_tgt(s->authctxt, &tgt)) - success = 1; - else - verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user); -#endif /* KRB5 */ - } else { -#ifdef AFS - if (auth_krb4_tgt(s->authctxt, kdata)) - success = 1; - else - verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user); -#endif /* AFS */ - } - xfree(kdata); - } - break; -#endif /* AFS || KRB5 */ - -#ifdef AFS - case SSH_CMSG_HAVE_AFS_TOKEN: - if (!options.afs_token_passing || !k_hasafs()) { - verbose("AFS token passing disabled."); - } else { - /* Accept AFS token. */ - char *token = packet_get_string(&dlen); - packet_check_eom(); - - if (auth_afs_token(s->authctxt, token)) - success = 1; - else - verbose("AFS token refused for %.100s", - s->authctxt->user); - xfree(token); - } - break; -#endif /* AFS */ - - case SSH_CMSG_EXEC_SHELL: - case SSH_CMSG_EXEC_CMD: - if (type == SSH_CMSG_EXEC_CMD) { - command = packet_get_string(&dlen); - debug("Exec command '%.500s'", command); - do_exec(s, command); - xfree(command); - } else { - do_exec(s, NULL); - } - packet_check_eom(); - session_close(s); - return; - - default: - /* - * Any unknown messages in this phase are ignored, - * and a failure message is returned. - */ - log("Unknown packet type received after authentication: %d", type); - } - packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - - /* Enable compression now that we have replied if appropriate. */ - if (enable_compression_after_reply) { - enable_compression_after_reply = 0; - packet_start_compression(compression_level); - } - } -} - -/* - * This is called to fork and execute a command when we have no tty. This - * will call do_child from the child, and server_loop from the parent after - * setting up file descriptors and such. - */ -void -do_exec_no_pty(Session *s, const char *command) -{ - pid_t pid; - - int inout[2], err[2]; - /* Uses socket pairs to communicate with the program. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || - socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) - packet_disconnect("Could not create socket pairs: %.100s", - strerror(errno)); - if (s == NULL) - fatal("do_exec_no_pty: no session"); - - session_proctitle(s); - - /* Fork the child. */ - if ((pid = fork()) == 0) { - fatal_remove_all_cleanups(); - - /* Child. Reinitialize the log since the pid has changed. */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); - - /* - * Create a new session and process group since the 4.4BSD - * setlogin() affects the entire process group. - */ - if (setsid() < 0) - error("setsid failed: %.100s", strerror(errno)); - - /* - * Redirect stdin, stdout, and stderr. Stdin and stdout will - * use the same socket, as some programs (particularly rdist) - * seem to depend on it. - */ - close(inout[1]); - close(err[1]); - if (dup2(inout[0], 0) < 0) /* stdin */ - perror("dup2 stdin"); - if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ - perror("dup2 stdout"); - if (s->is_subsystem) { - /* - * Redirect the subsystem's stderr to /dev/null. We might send it - * over to the other side but changing that might break existing - * SSH clients. - */ - close(err[0]); - if ((err[0] = open(_PATH_DEVNULL, O_WRONLY)) == -1) - fatal("Cannot open /dev/null: %.100s", strerror(errno)); - } - if (dup2(err[0], 2) < 0) /* stderr */ - perror("dup2 stderr"); - -#ifdef _UNICOS - cray_init_job(s->pw); /* set up cray jid and tmpdir */ -#endif - - /* Do processing for the child (exec command etc). */ - do_child(s, command); - /* NOTREACHED */ - } -#ifdef _UNICOS - signal(WJSIGNAL, cray_job_termination_handler); -#endif /* _UNICOS */ -#ifdef HAVE_CYGWIN - if (is_winnt) - cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); -#endif - if (pid < 0) - packet_disconnect("fork failed: %.100s", strerror(errno)); - - s->pid = pid; - /* Set interactive/non-interactive mode. */ - packet_set_interactive(s->display != NULL); - - /* We are the parent. Close the child sides of the socket pairs. */ - close(inout[0]); - close(err[0]); - - /* - * Enter the interactive session. Note: server_loop must be able to - * handle the case that fdin and fdout are the same. - */ - if (compat20) { - session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]); - if (s->is_subsystem) - close(err[1]); - /* Don't close channel before sending exit-status! */ - channel_set_wait_for_exit(s->chanid, 1); - } else { - server_loop(pid, inout[1], inout[1], err[1]); - /* server_loop has closed inout[1] and err[1]. */ - } -} - -/* - * This is called to fork and execute a command when we have a tty. This - * will call do_child from the child, and server_loop from the parent after - * setting up file descriptors, controlling tty, updating wtmp, utmp, - * lastlog, and other such operations. - */ -void -do_exec_pty(Session *s, const char *command) -{ - int fdout, ptyfd, ttyfd, ptymaster, pipe_fds[2]; - pid_t pid; - - if (s == NULL) - fatal("do_exec_pty: no session"); - ptyfd = s->ptyfd; - ttyfd = s->ttyfd; - -#ifdef USE_PAM - session_do_pam(s, 1); /* pam_open_session() */ -#endif /* USE_PAM */ - - /* - * This pipe lets sshd wait for child to exec or exit. This is - * particularly important for ALTPRIVSEP because the child is - * the one to call the monitor to request a record_login() and - * we don't want the child and the parent to compete for the - * monitor's attention. But this is generic code and doesn't - * hurt to have here even if ALTPRIVSEP is not used. - */ - if (pipe(pipe_fds) != 0) - packet_disconnect("pipe failed: %.100s", strerror(errno)); - - (void) fcntl(pipe_fds[0], F_SETFD, FD_CLOEXEC); - (void) fcntl(pipe_fds[1], F_SETFD, FD_CLOEXEC); - - /* Fork the child. */ - if ((pid = fork()) == 0) { - (void) close(pipe_fds[0]); - - fatal_remove_all_cleanups(); - - /* 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. */ - close(ptyfd); - - /* Make the pseudo tty our controlling tty. */ - pty_make_controlling_tty(&ttyfd, s->tty); - - /* Redirect stdin/stdout/stderr from the pseudo tty. */ - if (dup2(ttyfd, 0) < 0) - error("dup2 stdin: %s", strerror(errno)); - if (dup2(ttyfd, 1) < 0) - error("dup2 stdout: %s", strerror(errno)); - if (dup2(ttyfd, 2) < 0) - error("dup2 stderr: %s", strerror(errno)); - - /* Close the extra descriptor for the pseudo tty. */ - close(ttyfd); - - /* record login, etc. similar to login(1) */ - do_login(s, command); - - /* - * Close the pipe to the parent so it can re-enter its event - * loop and service the ptm; if enough debug messages get - * written to the pty before this happens there will be a - * deadlock. - */ - close(pipe_fds[1]); - - /* - * do_motd() was called originally in do_login(). However, - * when the /etc/motd file is large, a deadlock would happen, - * because - * - The child is blocked at fputs() to pty, when pty buffer - * is full. - * - The parent can not consume the pty buffer, because it is - * still blocked at read(pipe_fds[0]). - * - * To resolve the deadlock issue, we defer do_motd() after - * close(pipe_fds[1]). - */ - do_motd(); - - /* Do common processing for the child, such as execing the command. */ - do_child(s, command); - /* NOTREACHED */ - } - - /* Wait for child to exec() or exit() */ - (void) close(pipe_fds[1]); - (void) read(pipe_fds[0], &pipe_fds[1], sizeof(int)); - -#ifdef _UNICOS - signal(WJSIGNAL, cray_job_termination_handler); -#endif /* _UNICOS */ -#ifdef HAVE_CYGWIN - if (is_winnt) - cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); -#endif - if (pid < 0) - packet_disconnect("fork failed: %.100s", strerror(errno)); - s->pid = pid; - - /* Parent. Close the slave side of the pseudo tty. */ - close(ttyfd); - - /* - * Create another descriptor of the pty master side for use as the - * standard input. We could use the original descriptor, but this - * simplifies code in server_loop. The descriptor is bidirectional. - */ - fdout = dup(ptyfd); - if (fdout < 0) - packet_disconnect("dup #1 failed: %.100s", strerror(errno)); - - /* we keep a reference to the pty master */ - ptymaster = dup(ptyfd); - if (ptymaster < 0) - packet_disconnect("dup #2 failed: %.100s", strerror(errno)); - s->ptymaster = ptymaster; - - /* Enter interactive session. */ - packet_set_interactive(1); - if (compat20) { - session_set_fds(s, ptyfd, fdout, -1); - /* Don't close channel before sending exit-status! */ - channel_set_wait_for_exit(s->chanid, 1); - } else { - server_loop(pid, ptyfd, fdout, -1); - /* server_loop _has_ closed ptyfd and fdout. */ - } -} - -/* - * This is called to fork and execute a command. If another command is - * to be forced, execute that instead. - */ -void -do_exec(Session *s, const char *command) -{ - if (command) - s->command = xstrdup(command); - - if (forced_command) { - original_command = command; - command = forced_command; - debug("Forced command '%.900s'", command); - } - - if (s->ttyfd != -1) - do_exec_pty(s, command); - else - do_exec_no_pty(s, command); - - original_command = NULL; -} - - -/* administrative, login(1)-like work */ -void -do_login(Session *s, const char *command) -{ - char *time_string; -#ifndef ALTPRIVSEP - struct passwd * pw = s->pw; -#endif /* ALTPRIVSEP*/ - pid_t pid = getpid(); - - /* Record that there was a login on that tty from the remote host. */ -#ifdef ALTPRIVSEP - debug3("Recording SSHv2 channel login in utmpx/wtmpx"); - altprivsep_record_login(pid, s->tty); -#endif /* ALTPRIVSEP*/ - - if (check_quietlogin(s, command)) - return; - -#ifdef USE_PAM - print_pam_messages(); -#endif /* USE_PAM */ -#ifdef WITH_AIXAUTHENTICATE - if (aixloginmsg && *aixloginmsg) - printf("%s\n", aixloginmsg); -#endif /* WITH_AIXAUTHENTICATE */ - -#ifndef NO_SSH_LASTLOG - if (options.print_lastlog && s->last_login_time != 0) { - time_string = ctime(&s->last_login_time); - if (strchr(time_string, '\n')) - *strchr(time_string, '\n') = 0; - if (strcmp(s->hostname, "") == 0) - printf("Last login: %s\r\n", time_string); - else - printf("Last login: %s from %s\r\n", time_string, - s->hostname); - } -#endif /* NO_SSH_LASTLOG */ - -} - -/* - * Display the message of the day. - */ -void -do_motd(void) -{ - FILE *f; - char buf[256]; - - 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); - } - } -} - - -/* - * Check for quiet login, either .hushlogin or command given. - */ -int -check_quietlogin(Session *s, const char *command) -{ - char buf[256]; - struct passwd *pw = s->pw; - struct stat st; - - /* Return 1 if .hushlogin exists or a command given. */ - if (command != NULL) - return 1; - snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); -#ifdef HAVE_LOGIN_CAP - if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) - return 1; -#else - if (stat(buf, &st) >= 0) - return 1; -#endif - return 0; -} - -/* - * Sets the value of the given variable in the environment. If the variable - * already exists, its value is overriden. - */ -void -child_set_env(char ***envp, u_int *envsizep, const char *name, - const char *value) -{ - debug3("child_set_env(%s, %s)", name, value); - child_set_env_silent(envp, envsizep, name, value); -} - - -void -child_set_env_silent(char ***envp, u_int *envsizep, const char *name, - const char *value) -{ - u_int i, namelen; - char **env; - - /* - * Find the slot where the value should be stored. If the variable - * already exists, we reuse the slot; otherwise we append a new slot - * at the end of the array, expanding if necessary. - */ - env = *envp; - namelen = strlen(name); - for (i = 0; env[i]; i++) - if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') - break; - if (env[i]) { - /* Reuse the slot. */ - xfree(env[i]); - } else { - /* New variable. Expand if necessary. */ - if (i >= (*envsizep) - 1) { - if (*envsizep >= 1000) - fatal("child_set_env: too many env vars," - " skipping: %.100s", name); - (*envsizep) += 50; - env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); - } - /* Need to set the NULL pointer at end of array beyond the new slot. */ - env[i + 1] = NULL; - } - - /* Allocate space and format the variable in the appropriate slot. */ - env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); - snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); -} - -/* - * Reads environment variables from the given file and adds/overrides them - * into the environment. If the file does not exist, this does nothing. - * Otherwise, it must consist of empty lines, comments (line starts with '#') - * and assignments of the form name=value. No other forms are allowed. - */ -static void -read_environment_file(char ***env, u_int *envsize, - const char *filename) -{ - FILE *f; - char buf[4096]; - char *cp, *value; - u_int lineno = 0; - - f = fopen(filename, "r"); - if (!f) - return; - - while (fgets(buf, sizeof(buf), f)) { - if (++lineno > 1000) - fatal("Too many lines in environment file %s", filename); - for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '#' || *cp == '\n') - continue; - if (strchr(cp, '\n')) - *strchr(cp, '\n') = '\0'; - value = strchr(cp, '='); - if (value == NULL) { - fprintf(stderr, gettext("Bad line %u in %.100s\n"), - lineno, filename); - continue; - } - /* - * Replace the equals sign by nul, and advance value to - * the value string. - */ - *value = '\0'; - value++; - child_set_env(env, envsize, cp, value); - } - fclose(f); -} - -void copy_environment(char **source, char ***env, u_int *envsize) -{ - char *var_name, *var_val; - int i; - - if (source == NULL) - return; - - for(i = 0; source[i] != NULL; i++) { - var_name = xstrdup(source[i]); - if ((var_val = strstr(var_name, "=")) == NULL) { - xfree(var_name); - continue; - } - *var_val++ = '\0'; - - debug3("Copy environment: %s=%s", var_name, var_val); - child_set_env(env, envsize, var_name, var_val); - - xfree(var_name); - } -} - -#ifdef HAVE_DEFOPEN -static -void -deflt_do_setup_env(Session *s, const char *shell, char ***env, u_int *envsize) -{ - int flags; - char *ptr; - mode_t Umask = 022; - - if (defopen(_PATH_DEFAULT_LOGIN)) - return; - - /* Ignore case */ - flags = defcntl(DC_GETFLAGS, 0); - TURNOFF(flags, DC_CASE); - (void) defcntl(DC_SETFLAGS, flags); - - /* TZ & HZ */ - if ((ptr = defread("TIMEZONE=")) != NULL) - child_set_env(env, envsize, "TZ", ptr); - if ((ptr = defread("HZ=")) != NULL) - child_set_env(env, envsize, "HZ", ptr); - - /* PATH */ - if (s->pw->pw_uid != 0 && (ptr = defread("PATH=")) != NULL) - child_set_env(env, envsize, "PATH", ptr); - if (s->pw->pw_uid == 0 && (ptr = defread("SUPATH=")) != NULL) - child_set_env(env, envsize, "PATH", ptr); - - /* SHELL */ - if ((ptr = defread("ALTSHELL=")) != NULL) { - if (strcasecmp("YES", ptr) == 0) - child_set_env(env, envsize, "SHELL", shell); - else - child_set_env(env, envsize, "SHELL", ""); - } - - /* UMASK */ - if ((ptr = defread("UMASK=")) != NULL && - sscanf(ptr, "%lo", &Umask) == 1 && - Umask <= (mode_t)0777) - (void) umask(Umask); - else - (void) umask(022); - - /* ULIMIT */ - if ((ptr = defread("ULIMIT=")) != NULL && atol(ptr) > 0L && - ulimit(UL_SETFSIZE, atol(ptr)) < 0L) - error("Could not set ULIMIT to %ld from %s\n", atol(ptr), - _PATH_DEFAULT_LOGIN); - - (void) defopen(NULL); -} -#endif /* HAVE_DEFOPEN */ - -static char ** -do_setup_env(Session *s, const char *shell) -{ - char buf[256]; - char path_maildir[] = _PATH_MAILDIR; - u_int i, envsize, pm_len; - char **env; - struct passwd *pw = s->pw; - - /* Initialize the environment. */ - envsize = 100; - env = xmalloc(envsize * sizeof(char *)); - env[0] = NULL; - -#ifdef HAVE_CYGWIN - /* - * The Windows environment contains some setting which are - * important for a running system. They must not be dropped. - */ - copy_environment(environ, &env, &envsize); -#endif - -#ifdef GSSAPI - /* Allow any GSSAPI methods that we've used to alter - * the childs environment as they see fit - */ - ssh_gssapi_do_child(xxx_gssctxt, &env,&envsize); -#endif - - /* Set basic environment. */ - 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 - if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) - child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); - else - child_set_env(&env, &envsize, "PATH", getenv("PATH")); -#else /* HAVE_LOGIN_CAP */ -# ifndef HAVE_CYGWIN - /* - * There's no standard path on Windows. The path contains - * important components pointing to the system directories, - * needed for loading shared libraries. So the path better - * remains intact here. - */ -# ifdef SUPERUSER_PATH - child_set_env(&env, &envsize, "PATH", - s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH); -# else - child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); -# endif /* SUPERUSER_PATH */ -# endif /* HAVE_CYGWIN */ -#endif /* HAVE_LOGIN_CAP */ - - pm_len = strlen(path_maildir); - if (path_maildir[pm_len - 1] == '/' && pm_len > 1) - path_maildir[pm_len - 1] = NULL; - snprintf(buf, sizeof buf, "%.200s/%.50s", - path_maildir, pw->pw_name); - child_set_env(&env, &envsize, "MAIL", buf); - - /* Normal systems set SHELL by default. */ - child_set_env(&env, &envsize, "SHELL", shell); - -#ifdef HAVE_DEFOPEN - deflt_do_setup_env(s, shell, &env, &envsize); -#endif /* HAVE_DEFOPEN */ - -#define PASS_ENV(x) \ - if (getenv(x)) \ - child_set_env(&env, &envsize, x, getenv(x)); - - if (getenv("TZ")) - child_set_env(&env, &envsize, "TZ", getenv("TZ")); - - if (s->auth_file != NULL) - child_set_env(&env, &envsize, "XAUTHORITY", s->auth_file); - - PASS_ENV("LANG") - PASS_ENV("LC_ALL") - PASS_ENV("LC_CTYPE") - PASS_ENV("LC_COLLATE") - PASS_ENV("LC_TIME") - PASS_ENV("LC_NUMERIC") - PASS_ENV("LC_MONETARY") - PASS_ENV("LC_MESSAGES") - -#undef PASS_ENV - - if (s->env != NULL) - copy_environment(s->env, &env, &envsize); - - /* Set custom environment options from RSA authentication. */ - while (custom_environment) { - struct envstring *ce = custom_environment; - char *str = ce->s; - - for (i = 0; str[i] != '=' && str[i]; i++) - ; - if (str[i] == '=') { - str[i] = 0; - child_set_env(&env, &envsize, str, str + i + 1); - } - custom_environment = ce->next; - xfree(ce->s); - xfree(ce); - } - - /* SSH_CLIENT deprecated */ - snprintf(buf, sizeof buf, "%.50s %d %d", - get_remote_ipaddr(), get_remote_port(), get_local_port()); - child_set_env(&env, &envsize, "SSH_CLIENT", buf); - - snprintf(buf, sizeof buf, "%.50s %d %.50s %d", - get_remote_ipaddr(), get_remote_port(), - get_local_ipaddr(packet_get_connection_in()), get_local_port()); - child_set_env(&env, &envsize, "SSH_CONNECTION", buf); - - if (s->ttyfd != -1) - child_set_env(&env, &envsize, "SSH_TTY", s->tty); - if (s->term) - child_set_env(&env, &envsize, "TERM", s->term); - if (s->display) - child_set_env(&env, &envsize, "DISPLAY", s->display); - if (original_command) - child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", - original_command); - -#ifdef _UNICOS - if (cray_tmpdir[0] != '\0') - child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir); -#endif /* _UNICOS */ - -#ifdef _AIX - { - char *cp; - - if ((cp = getenv("AUTHSTATE")) != NULL) - child_set_env(&env, &envsize, "AUTHSTATE", cp); - if ((cp = getenv("KRB5CCNAME")) != NULL) - child_set_env(&env, &envsize, "KRB5CCNAME", cp); - read_environment_file(&env, &envsize, "/etc/environment"); - } -#endif -#ifdef KRB4 - if (s->authctxt->krb4_ticket_file) - child_set_env(&env, &envsize, "KRBTKFILE", - s->authctxt->krb4_ticket_file); -#endif -#ifdef KRB5 - if (s->authctxt->krb5_ticket_file) - child_set_env(&env, &envsize, "KRB5CCNAME", - s->authctxt->krb5_ticket_file); -#endif -#ifdef USE_PAM - /* - * Pull in any environment variables that may have - * been set by PAM. - */ - { - char **p; - - p = fetch_pam_environment(s->authctxt); - copy_environment(p, &env, &envsize); - free_pam_environment(p); - } -#endif /* USE_PAM */ - - if (auth_sock_name != NULL) - child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, - auth_sock_name); - - /* read $HOME/.ssh/environment. */ - if (options.permit_user_env) { - snprintf(buf, sizeof buf, "%.200s/.ssh/environment", - strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); - read_environment_file(&env, &envsize, buf); - } - if (debug_flag) { - /* dump the environment */ - fprintf(stderr, gettext("Environment:\n")); - for (i = 0; env[i]; i++) - fprintf(stderr, " %.200s\n", env[i]); - } - return env; -} - -/* - * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found - * first in this order). - */ -static void -do_rc_files(Session *s, const char *shell) -{ - FILE *f = NULL; - char cmd[1024]; - int do_xauth; - struct stat st; - - do_xauth = - s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL; - - /* ignore _PATH_SSH_USER_RC for subsystems */ - if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) { - snprintf(cmd, sizeof cmd, "%s -c '%s %s'", - shell, _PATH_BSHELL, _PATH_SSH_USER_RC); - if (debug_flag) - fprintf(stderr, "Running %s\n", cmd); - f = popen(cmd, "w"); - if (f) { - if (do_xauth) - fprintf(f, "%s %s\n", s->auth_proto, - s->auth_data); - pclose(f); - } else - fprintf(stderr, "Could not run %s\n", - _PATH_SSH_USER_RC); - } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) { - if (debug_flag) - fprintf(stderr, "Running %s %s\n", _PATH_BSHELL, - _PATH_SSH_SYSTEM_RC); - f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w"); - if (f) { - if (do_xauth) - fprintf(f, "%s %s\n", s->auth_proto, - s->auth_data); - pclose(f); - } else - fprintf(stderr, "Could not run %s\n", - _PATH_SSH_SYSTEM_RC); - } else if (do_xauth && options.xauth_location != NULL) { - /* Add authority data to .Xauthority if appropriate. */ - if (debug_flag) { - fprintf(stderr, - "Running %.500s add " - "%.100s %.100s %.100s\n", - options.xauth_location, s->auth_display, - s->auth_proto, s->auth_data); - } - snprintf(cmd, sizeof cmd, "%s -q -", - options.xauth_location); - f = popen(cmd, "w"); - if (f) { - fprintf(f, "add %s %s %s\n", - s->auth_display, s->auth_proto, - s->auth_data); - pclose(f); - } else { - fprintf(stderr, "Could not run %s\n", - cmd); - } - } -} - -/* Disallow logins if /etc/nologin exists. This does not apply to root. */ -static void -do_nologin(struct passwd *pw) -{ - FILE *f = NULL; - char buf[1024]; - struct stat sb; - - if (pw->pw_uid == 0) - return; - - if (stat(_PATH_NOLOGIN, &sb) == -1) - return; - - /* /etc/nologin exists. Print its contents if we can and exit. */ - log("User %.100s not allowed because %s exists.", pw->pw_name, - _PATH_NOLOGIN); - if ((f = fopen(_PATH_NOLOGIN, "r")) != NULL) { - while (fgets(buf, sizeof(buf), f)) - fputs(buf, stderr); - fclose(f); - } - exit(254); -} - -/* Chroot into ChrootDirectory if the option is set. */ -void -chroot_if_needed(struct passwd *pw) -{ - char *chroot_path, *tmp; - - if (chroot_requested(options.chroot_directory)) { - tmp = tilde_expand_filename(options.chroot_directory, - pw->pw_uid); - chroot_path = percent_expand(tmp, "h", pw->pw_dir, - "u", pw->pw_name, (char *)NULL); - safely_chroot(chroot_path, pw->pw_uid); - free(tmp); - free(chroot_path); - } -} - -/* - * Chroot into a directory after checking it for safety: all path components - * must be root-owned directories with strict permissions. - */ -static void -safely_chroot(const char *path, uid_t uid) -{ - const char *cp; - char component[MAXPATHLEN]; - struct stat st; - - if (*path != '/') - fatal("chroot path does not begin at root"); - if (strlen(path) >= sizeof(component)) - fatal("chroot path too long"); - - /* - * Descend the path, checking that each component is a - * root-owned directory with strict permissions. - */ - for (cp = path; cp != NULL;) { - if ((cp = strchr(cp, '/')) == NULL) - strlcpy(component, path, sizeof(component)); - else { - cp++; - memcpy(component, path, cp - path); - component[cp - path] = '\0'; - } - - debug3("%s: checking '%s'", __func__, component); - - if (stat(component, &st) != 0) - fatal("%s: stat(\"%s\"): %s", __func__, - component, strerror(errno)); - if (st.st_uid != 0 || (st.st_mode & 022) != 0) - fatal("bad ownership or modes for chroot " - "directory %s\"%s\"", - cp == NULL ? "" : "component ", component); - if (!S_ISDIR(st.st_mode)) - fatal("chroot path %s\"%s\" is not a directory", - cp == NULL ? "" : "component ", component); - } - - if (chdir(path) == -1) - fatal("Unable to chdir to chroot path \"%s\": " - "%s", path, strerror(errno)); - if (chroot(path) == -1) - fatal("chroot(\"%s\"): %s", path, strerror(errno)); - if (chdir("/") == -1) - fatal("%s: chdir(/) after chroot: %s", - __func__, strerror(errno)); - verbose("Changed root directory to \"%s\"", path); -} - -static void -launch_login(struct passwd *pw, const char *hostname) -{ - /* Launch login(1). */ - - execl(LOGIN_PROGRAM, "login", "-h", hostname, -#ifdef xxxLOGIN_NEEDS_TERM - (s->term ? s->term : "unknown"), -#endif /* LOGIN_NEEDS_TERM */ -#ifdef LOGIN_NO_ENDOPT - "-p", "-f", pw->pw_name, (char *)NULL); -#else - "-p", "-f", "--", pw->pw_name, (char *)NULL); -#endif - - /* Login couldn't be executed, die. */ - - perror("login"); - exit(1); -} - -/* - * Performs common processing for the child, such as setting up the - * environment, closing extra file descriptors, setting the user and group - * ids, and executing the command or shell. - */ -#define ARGV_MAX 10 -void -do_child(Session *s, const char *command) -{ - extern char **environ; - char **env; - char *argv[ARGV_MAX]; - const char *shell, *shell0; - struct passwd *pw = s->pw; - - /* remove hostkey from the child's memory */ - destroy_sensitive_data(); - - do_nologin(pw); - chroot_if_needed(pw); - - /* - * Get the shell from the password data. An empty shell field is - * legal, and means /bin/sh. - */ - shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; -#ifdef HAVE_LOGIN_CAP - shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); -#endif - - env = do_setup_env(s, shell); - - /* - * Close the connection descriptors; note that this is the child, and - * the server will still have the socket open, and it is important - * that we do not shutdown it. Note that the descriptors cannot be - * closed before building the environment, as we call - * get_remote_ipaddr there. - */ - if (packet_get_connection_in() == packet_get_connection_out()) - close(packet_get_connection_in()); - else { - close(packet_get_connection_in()); - close(packet_get_connection_out()); - } - /* - * Close all descriptors related to channels. They will still remain - * open in the parent. - */ - /* XXX better use close-on-exec? -markus */ - channel_close_all(); - - /* - * Close any extra file descriptors. Note that there may still be - * descriptors left by system functions. They will be closed later. - */ - endpwent(); - - /* - * Must switch to the new environment variables so that .ssh/rc, - * /etc/ssh/sshrc, and xauth are run in the proper environment. - */ - environ = env; - - /* - * New environment has been installed. We need to update locale - * so that error messages beyond this point have the proper - * character encoding. - */ - (void) setlocale(LC_ALL, ""); - - /* - * Close any extra open file descriptors so that we don\'t have them - * hanging around in clients. Note that we want to do this after - * initgroups, because at least on Solaris 2.3 it leaves file - * descriptors open. - */ - closefrom(STDERR_FILENO + 1); - -#ifdef AFS - /* Try to get AFS tokens for the local cell. */ - if (k_hasafs()) { - char cell[64]; - - if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) - krb_afslog(cell, 0); - - krb_afslog(0, 0); - } -#endif /* AFS */ - - /* Change current directory to the user's home directory. */ - if (chdir(pw->pw_dir) < 0) { - /* Suppress missing homedir warning for chroot case */ - if (!chroot_requested(options.chroot_directory)) - fprintf(stderr, "Could not chdir to home " - "directory %s: %s\n", pw->pw_dir, - strerror(errno)); - } - - do_rc_files(s, shell); - - /* restore SIGPIPE for child */ - signal(SIGPIPE, SIG_DFL); - - if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { - int i; - char *p, *args; - extern int optind, optreset; - - /* This will set the E/P sets here, simulating exec(2). */ - drop_privs(pw->pw_uid); - - setproctitle("%s@internal-sftp-server", s->pw->pw_name); - args = xstrdup(command ? command : "sftp-server"); - - i = 0; - for ((p = strtok(args, " ")); p != NULL; (p = strtok(NULL, " "))) { - if (i < ARGV_MAX - 1) - argv[i++] = p; - } - - argv[i] = NULL; - optind = optreset = 1; - __progname = argv[0]; - exit(sftp_server_main(i, argv, s->pw)); - } - - /* Get the last component of the shell name. */ - if ((shell0 = strrchr(shell, '/')) != NULL) - shell0++; - else - shell0 = shell; - - /* - * If we have no command, execute the shell. In this case, the shell - * name to be passed in argv[0] is preceded by '-' to indicate that - * this is a login shell. - */ - if (!command) { - char argv0[256]; - - /* Start the shell. Set initial character to '-'. */ - argv0[0] = '-'; - - if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1) - >= sizeof(argv0) - 1) { - errno = EINVAL; - perror(shell); - exit(1); - } - - /* Execute the shell. */ - argv[0] = argv0; - argv[1] = NULL; - execve(shell, argv, env); - - /* Executing the shell failed. */ - perror(shell); - exit(1); - } - /* - * Execute the command using the user's shell. This uses the -c - * option to execute the command. - */ - argv[0] = (char *) shell0; - argv[1] = "-c"; - argv[2] = (char *) command; - argv[3] = NULL; - execve(shell, argv, env); - perror(shell); - exit(1); -} - -Session * -session_new(void) -{ - int i; - static int did_init = 0; - if (!did_init) { - debug("session_new: init"); - for (i = 0; i < MAX_SESSIONS; i++) { - sessions[i].used = 0; - } - did_init = 1; - } - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (! s->used) { - memset(s, 0, sizeof(*s)); - s->chanid = -1; - s->ptyfd = -1; - s->ttyfd = -1; - s->used = 1; - s->self = i; - s->env = NULL; - debug("session_new: session %d", i); - return s; - } - } - return NULL; -} - -static void -session_dump(void) -{ - int i; - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - debug("dump: used %d session %d %p channel %d pid %ld", - s->used, - s->self, - s, - s->chanid, - (long)s->pid); - } -} - -int -session_open(Authctxt *authctxt, int chanid) -{ - Session *s = session_new(); - debug("session_open: channel %d", chanid); - if (s == NULL) { - error("no more sessions"); - return 0; - } - s->authctxt = authctxt; - s->pw = authctxt->pw; - if (s->pw == NULL) - fatal("no user for session %d", s->self); - debug("session_open: session %d: link with channel %d", s->self, chanid); - s->chanid = chanid; - return 1; -} - -#ifndef lint -Session * -session_by_tty(char *tty) -{ - int i; - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { - debug("session_by_tty: session %d tty %s", i, tty); - return s; - } - } - debug("session_by_tty: unknown tty %.100s", tty); - session_dump(); - return NULL; -} -#endif /* lint */ - -static Session * -session_by_channel(int id) -{ - int i; - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (s->used && s->chanid == id) { - debug("session_by_channel: session %d channel %d", i, id); - return s; - } - } - debug("session_by_channel: unknown channel %d", id); - session_dump(); - return NULL; -} - -static Session * -session_by_pid(pid_t pid) -{ - int i; - debug("session_by_pid: pid %ld", (long)pid); - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (s->used && s->pid == pid) - return s; - } - error("session_by_pid: unknown pid %ld", (long)pid); - session_dump(); - return NULL; -} - -static int -session_window_change_req(Session *s) -{ - s->col = packet_get_int(); - s->row = packet_get_int(); - s->xpixel = packet_get_int(); - s->ypixel = packet_get_int(); - packet_check_eom(); - pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); - return 1; -} - -static int -session_pty_req(Session *s) -{ - u_int len; - int n_bytes; - - if (no_pty_flag) { - debug("Allocating a pty not permitted for this authentication."); - return 0; - } - if (s->ttyfd != -1) { - packet_disconnect("Protocol error: you already have a pty."); - return 0; - } - /* Get the time and hostname when the user last logged in. */ - if (options.print_lastlog) { - s->hostname[0] = '\0'; - s->last_login_time = get_last_login_time(s->pw->pw_uid, - s->pw->pw_name, s->hostname, sizeof(s->hostname)); - - /* - * PAM may update the last login date. - * - * Ideally PAM would also show the last login date as a - * PAM_TEXT_INFO conversation message, and then we could just - * always force the use of keyboard-interactive just so we can - * pass any such PAM prompts and messages from the account and - * session stacks, but skip pam_authenticate() if other userauth - * has succeeded and the user's password isn't expired. - * - * Unfortunately this depends on support for keyboard- - * interactive in the client, and support for lastlog messages - * in some PAM module. - * - * As it is Solaris updates the lastlog in PAM, but does - * not show the lastlog date in PAM. If and when this state of - * affairs changes this hack can be reconsidered, and, maybe, - * removed. - * - * So we're stuck with a crude hack: get the lastlog - * time before calling pam_open_session() and store it - * in the Authctxt and then use it here once. After - * that, if the client opens any more pty sessions we'll - * show the last lastlog entry since userauth. - */ - if (s->authctxt != NULL && s->authctxt->last_login_time > 0) { - s->last_login_time = s->authctxt->last_login_time; - (void) strlcpy(s->hostname, - s->authctxt->last_login_host, - sizeof(s->hostname)); - s->authctxt->last_login_time = 0; - s->authctxt->last_login_host[0] = '\0'; - } - } - - s->term = packet_get_string(&len); - - if (compat20) { - s->col = packet_get_int(); - s->row = packet_get_int(); - } else { - s->row = packet_get_int(); - s->col = packet_get_int(); - } - s->xpixel = packet_get_int(); - s->ypixel = packet_get_int(); - - if (strcmp(s->term, "") == 0) { - xfree(s->term); - s->term = NULL; - } - - /* Allocate a pty and open it. */ - debug("Allocating pty."); - if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { - if (s->term) - xfree(s->term); - s->term = NULL; - s->ptyfd = -1; - s->ttyfd = -1; - error("session_pty_req: session %d alloc failed", s->self); - return 0; - } - debug("session_pty_req: session %d alloc %s", s->self, s->tty); - - /* for SSH1 the tty modes length is not given */ - if (!compat20) - n_bytes = packet_remaining(); - tty_parse_modes(s->ttyfd, &n_bytes); - - /* - * Add a cleanup function to clear the utmp entry and record logout - * time in case we call fatal() (e.g., the connection gets closed). - */ - fatal_add_cleanup(session_pty_cleanup, (void *)s); - pty_setowner(s->pw, s->tty); - - /* Set window size from the packet. */ - pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); - - packet_check_eom(); - session_proctitle(s); - return 1; -} - -static int -session_subsystem_req(Session *s) -{ - struct stat st; - u_int len; - int success = 0; - char *prog, *cmd, *subsys = packet_get_string(&len); - u_int i; - - packet_check_eom(); - log("subsystem request for %.100s", subsys); - - for (i = 0; i < options.num_subsystems; i++) { - if (strcmp(subsys, options.subsystem_name[i]) == 0) { - prog = options.subsystem_command[i]; - cmd = options.subsystem_args[i]; - if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) { - s->is_subsystem = SUBSYSTEM_INT_SFTP; - /* - * We must stat(2) the subsystem before we chroot in - * order to be able to send a proper error message. - */ - } else if (chroot_requested(options.chroot_directory)) { - char chdirsub[MAXPATHLEN]; - - strlcpy(chdirsub, options.chroot_directory, - sizeof (chdirsub)); - strlcat(chdirsub, "/", sizeof (chdirsub)); - strlcat(chdirsub, prog, sizeof (chdirsub)); - if (stat(chdirsub, &st) < 0) { - error("subsystem: cannot stat %s under " - "chroot directory %s: %s", prog, - options.chroot_directory, - strerror(errno)); - if (strcmp(subsys, "sftp") == 0) - error("subsystem: please see " - "the Subsystem option in " - "sshd_config(4) for an " - "explanation of '%s'.", - INTERNAL_SFTP_NAME); - break; - } - } else if (stat(prog, &st) < 0) { - error("subsystem: cannot stat %s: %s", prog, - strerror(errno)); - break; - } else { - s->is_subsystem = SUBSYSTEM_EXT; - } - debug("subsystem: exec() %s", cmd); - do_exec(s, cmd); - success = 1; - break; - } - } - - if (!success) - log("subsystem request for %.100s failed, subsystem not found", - subsys); - - xfree(subsys); - return success; -} - -/* - * Serve "x11-req" channel request for X11 forwarding for the current session - * channel. - */ -static int -session_x11_req(Session *s) -{ - int success, fd; - char xauthdir[] = "/tmp/ssh-xauth-XXXXXX"; - - s->single_connection = packet_get_char(); - s->auth_proto = packet_get_string(NULL); - s->auth_data = packet_get_string(NULL); - s->screen = packet_get_int(); - packet_check_eom(); - - success = session_setup_x11fwd(s); - if (!success) { - xfree(s->auth_proto); - xfree(s->auth_data); - s->auth_proto = NULL; - s->auth_data = NULL; - return (success); - } - - /* - * Create per session X authority file so that different sessions - * don't contend for one common file. The reason for this is that - * xauth(1) locking doesn't work too well over network filesystems. - * - * If mkdtemp() or open() fails then s->auth_file remains NULL which - * means that we won't set XAUTHORITY variable in child's environment - * and xauth(1) will use the default location for the authority file. - */ - if (mkdtemp(xauthdir) != NULL) { - s->auth_file = xmalloc(MAXPATHLEN); - snprintf(s->auth_file, MAXPATHLEN, "%s/xauthfile", - xauthdir); - /* - * we don't want that "creating new authority file" message to - * be printed by xauth(1) so we must create that file - * beforehand. - */ - if ((fd = open(s->auth_file, O_CREAT | O_EXCL | O_RDONLY, - S_IRUSR | S_IWUSR)) == -1) { - error("failed to create the temporary X authority " - "file %s: %.100s; will use the default one", - s->auth_file, strerror(errno)); - xfree(s->auth_file); - s->auth_file = NULL; - if (rmdir(xauthdir) == -1) { - error("cannot remove xauth directory %s: %.100s", - xauthdir, strerror(errno)); - } - } else { - close(fd); - debug("temporary X authority file %s created", - s->auth_file); - - /* - * add a cleanup function to remove the temporary - * xauth file in case we call fatal() (e.g., the - * connection gets closed). - */ - fatal_add_cleanup(session_xauthfile_cleanup, (void *)s); - } - } - else { - error("failed to create a directory for the temporary X " - "authority file: %.100s; will use the default xauth file", - strerror(errno)); - } - - return (success); -} - -static int -session_shell_req(Session *s) -{ - packet_check_eom(); - do_exec(s, NULL); - return 1; -} - -static int -session_exec_req(Session *s) -{ - u_int len; - char *command = packet_get_string(&len); - packet_check_eom(); - do_exec(s, command); - xfree(command); - return 1; -} - -static int -session_auth_agent_req(Session *s) -{ - static int called = 0; - packet_check_eom(); - if (no_agent_forwarding_flag) { - debug("session_auth_agent_req: no_agent_forwarding_flag"); - return 0; - } - if (called) { - return 0; - } else { - called = 1; - return auth_input_request_forwarding(s->pw); - } -} - -static int -session_loc_env_check(char *var, char *val) -{ - char *current; - int cat, ret; - - if (strcmp(var, "LANG") == 0) - cat = LC_ALL; - else if (strcmp(var, "LC_ALL") == 0) - cat = LC_ALL; - else if (strcmp(var, "LC_CTYPE") == 0) - cat = LC_CTYPE; - else if (strcmp(var, "LC_COLLATE") == 0) - cat = LC_COLLATE; - else if (strcmp(var, "LC_TIME") == 0) - cat = LC_TIME; - else if (strcmp(var, "LC_NUMERIC") == 0) - cat = LC_NUMERIC; - else if (strcmp(var, "LC_MONETARY") == 0) - cat = LC_MONETARY; - else if (strcmp(var, "LC_MESSAGES") == 0) - cat = LC_MESSAGES; - - current = setlocale(cat, NULL); - - ret = (setlocale(cat, val) != NULL); - (void) setlocale(cat, current); - return (ret); -} - -static int -session_env_req(Session *s) -{ - Channel *c; - char *var, *val, *e; - char **p; - size_t len; - int ret = 0; - - /* Get var/val from the rest of this packet */ - var = packet_get_string(NULL); - val = packet_get_string(NULL); - - /* - * We'll need the channel ID for the packet_send_debug messages, - * so get it now. - */ - if ((c = channel_lookup(s->chanid)) == NULL) - goto done; /* shouldn't happen! */ - - debug2("Received request for environment variable %s=%s", var, val); - - /* For now allow only LANG and LC_* */ - if (strcmp(var, "LANG") != 0 && strncmp(var, "LC_", 3) != 0) { - debug2("Rejecting request for environment variable %s", var); - goto done; - } - - if (!session_loc_env_check(var, val)) { - packet_send_debug(gettext("Missing locale support for %s=%s"), - var, val); - goto done; - } - - packet_send_debug(gettext("Channel %d set: %s=%s"), c->remote_id, - var, val); - - /* - * Always append new environment variables without regard to old - * ones being overriden. The way these are actually added to - * the environment of the session process later settings - * override earlier ones; see copy_environment(). - */ - if (s->env == NULL) { - char **env; - - env = xmalloc(sizeof (char **) * 2); - memset(env, 0, sizeof (char **) * 2); - - s->env = env; - p = env; - } else { - for (p = s->env; *p != NULL ; p++); - - s->env = xrealloc(s->env, (p - s->env + 2) * sizeof (char **)); - - for (p = s->env; *p != NULL ; p++); - } - - len = snprintf(NULL, 0, "%s=%s", var, val); - e = xmalloc(len + 1); - (void) snprintf(e, len + 1, "%s=%s", var, val); - - (*p++) = e; - *p = NULL; - - ret = 1; - -done: - xfree(var); - xfree(val); - - return (ret); -} - -static void -session_free_env(char ***envp) -{ - char **env, **p; - - if (envp == NULL || *envp == NULL) - return; - - env = *envp; - - *envp = NULL; - - for (p = env; *p != NULL; p++) - xfree(*p); - - xfree(env); -} - -int -session_input_channel_req(Channel *c, const char *rtype) -{ - int success = 0; - Session *s; - - if ((s = session_by_channel(c->self)) == NULL) { - log("session_input_channel_req: no session %d req %.100s", - c->self, rtype); - return 0; - } - debug("session_input_channel_req: session %d req %s", s->self, rtype); - - /* - * a session is in LARVAL state until a shell, a command - * or a subsystem is executed - */ - if (c->type == SSH_CHANNEL_LARVAL) { - if (strcmp(rtype, "shell") == 0) { - success = session_shell_req(s); - } else if (strcmp(rtype, "exec") == 0) { - success = session_exec_req(s); - } else if (strcmp(rtype, "pty-req") == 0) { - success = session_pty_req(s); - } else if (strcmp(rtype, "x11-req") == 0) { - success = session_x11_req(s); - } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { - success = session_auth_agent_req(s); - } else if (strcmp(rtype, "subsystem") == 0) { - success = session_subsystem_req(s); - } else if (strcmp(rtype, "env") == 0) { - success = session_env_req(s); - } - } - if (strcmp(rtype, "window-change") == 0) { - success = session_window_change_req(s); - } - return success; -} - -void -session_set_fds(Session *s, int fdin, int fdout, int fderr) -{ - if (!compat20) - fatal("session_set_fds: called for proto != 2.0"); - /* - * now that have a child and a pipe to the child, - * we can activate our channel and register the fd's - */ - if (s->chanid == -1) - fatal("no channel for session %d", s->self); - channel_set_fds(s->chanid, - fdout, fdin, fderr, - fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, - 1, - CHAN_SES_WINDOW_DEFAULT); -} - -/* - * Function to perform pty cleanup. Also called if we get aborted abnormally - * (e.g., due to a dropped connection). - */ -void -session_pty_cleanup2(void *session) -{ - Session *s = session; - - if (s == NULL) { - error("session_pty_cleanup: no session"); - return; - } - if (s->ttyfd == -1) - return; - - debug("session_pty_cleanup: session %d release %s", s->self, s->tty); - -#ifdef USE_PAM - session_do_pam(s, 0); -#endif /* USE_PAM */ - - /* Record that the user has logged out. */ - if (s->pid != 0) { - debug3("Recording SSHv2 channel logout in utmpx/wtmpx"); -#ifdef ALTPRIVSEP - altprivsep_record_logout(s->pid); -#endif /* ALTPRIVSEP */ - } - - /* Release the pseudo-tty. */ - if (getuid() == 0) - pty_release(s->tty); - - /* - * Close the server side of the socket pairs. We must do this after - * the pty cleanup, so that another process doesn't get this pty - * while we're still cleaning up. - */ - if (close(s->ptymaster) < 0) - error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); - - /* unlink pty from session */ - s->ttyfd = -1; -} - -void -session_pty_cleanup(void *session) -{ - session_pty_cleanup2(session); -} - -/* - * We use a different temporary X authority file per every session so we - * should remove those files when fatal() is called. - */ -void -session_xauthfile_cleanup(void *session) -{ - Session *s = session; - - if (s == NULL) { - error("session_xauthfile_cleanup: no session"); - return; - } - - debug("session_xauthfile_cleanup: session %d removing %s", s->self, - s->auth_file); - - if (unlink(s->auth_file) == -1) { - error("session_xauthfile_cleanup: cannot remove xauth file: " - "%.100s", strerror(errno)); - return; - } - - /* dirname() will modify s->auth_file but that's ok */ - if (rmdir(dirname(s->auth_file)) == -1) { - error("session_xauthfile_cleanup: " - "cannot remove xauth directory: %.100s", strerror(errno)); - return; - } -} - -static char * -sig2name(int sig) -{ -#define SSH_SIG(x) if (sig == SIG ## x) return #x - SSH_SIG(ABRT); - SSH_SIG(ALRM); - SSH_SIG(FPE); - SSH_SIG(HUP); - SSH_SIG(ILL); - SSH_SIG(INT); - SSH_SIG(KILL); - SSH_SIG(PIPE); - SSH_SIG(QUIT); - SSH_SIG(SEGV); - SSH_SIG(TERM); - SSH_SIG(USR1); - SSH_SIG(USR2); -#undef SSH_SIG - return "SIG@openssh.com"; -} - -static void -session_exit_message(Session *s, int status) -{ - Channel *c; - - if ((c = channel_lookup(s->chanid)) == NULL) - fatal("session_exit_message: session %d: no channel %d", - s->self, s->chanid); - debug("session_exit_message: session %d channel %d pid %ld", - s->self, s->chanid, (long)s->pid); - - if (WIFEXITED(status)) { - channel_request_start(s->chanid, "exit-status", 0); - packet_put_int(WEXITSTATUS(status)); - packet_send(); - } else if (WIFSIGNALED(status)) { - channel_request_start(s->chanid, "exit-signal", 0); - packet_put_cstring(sig2name(WTERMSIG(status))); -#ifdef WCOREDUMP - packet_put_char(WCOREDUMP(status)); -#else /* WCOREDUMP */ - packet_put_char(0); -#endif /* WCOREDUMP */ - packet_put_cstring(""); - packet_put_cstring(""); - packet_send(); - } else { - /* Some weird exit cause. Just exit. */ - packet_disconnect("wait returned status %04x.", status); - } - - /* Ok to close channel now */ - channel_set_wait_for_exit(s->chanid, 0); - - /* disconnect channel */ - debug("session_exit_message: release channel %d", s->chanid); - channel_cancel_cleanup(s->chanid); - /* - * emulate a write failure with 'chan_write_failed', nobody will be - * interested in data we write. - * Note that we must not call 'chan_read_failed', since there could - * be some more data waiting in the pipe. - */ - if (c->ostate != CHAN_OUTPUT_CLOSED) - chan_write_failed(c); - s->chanid = -1; -} - -void -session_close(Session *s) -{ - debug("session_close: session %d pid %ld", s->self, (long)s->pid); - if (s->ttyfd != -1) { - fatal_remove_cleanup(session_pty_cleanup, (void *)s); - session_pty_cleanup(s); - } - if (s->auth_file != NULL) { - fatal_remove_cleanup(session_xauthfile_cleanup, (void *)s); - session_xauthfile_cleanup(s); - xfree(s->auth_file); - } - if (s->term) - xfree(s->term); - if (s->display) - xfree(s->display); - if (s->auth_display) - xfree(s->auth_display); - if (s->auth_data) - xfree(s->auth_data); - if (s->auth_proto) - xfree(s->auth_proto); - if (s->command) - xfree(s->command); - session_free_env(&s->env); - s->used = 0; - session_proctitle(s); -} - -void -session_close_by_pid(pid_t pid, int status) -{ - Session *s = session_by_pid(pid); - if (s == NULL) { - debug("session_close_by_pid: no session for pid %ld", - (long)pid); - return; - } - if (s->chanid != -1) - session_exit_message(s, status); - session_close(s); -} - -/* - * This is called when a channel dies before the session 'child' itself dies. - * It can happen for example if we exit from an interactive shell before we - * exit from forwarded X11 applications. - */ -void -session_close_by_channel(int id, void *arg) -{ - Session *s = session_by_channel(id); - if (s == NULL) { - debug("session_close_by_channel: no session for id %d", id); - return; - } - debug("session_close_by_channel: channel %d child %ld", - id, (long)s->pid); - if (s->pid != 0) { - debug("session_close_by_channel: channel %d: has child", id); - /* - * delay detach of session, but release pty, since - * the fd's to the child are already closed - */ - if (s->ttyfd != -1) { - fatal_remove_cleanup(session_pty_cleanup, (void *)s); - session_pty_cleanup(s); - } - return; - } - /* detach by removing callback */ - channel_cancel_cleanup(s->chanid); - s->chanid = -1; - session_close(s); -} - -void -session_destroy_all(void (*closefunc)(Session *)) -{ - int i; - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (s->used) { - if (closefunc != NULL) - closefunc(s); - else - session_close(s); - } - } -} - -static char * -session_tty_list(void) -{ - static char buf[1024]; - int i; - buf[0] = '\0'; - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (s->used && s->ttyfd != -1) { - if (buf[0] != '\0') - strlcat(buf, ",", sizeof buf); - strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); - } - } - if (buf[0] == '\0') - strlcpy(buf, "notty", sizeof buf); - return buf; -} - -void -session_proctitle(Session *s) -{ - if (s->pw == NULL) - error("no user for session %d", s->self); - else - setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); -} - -int -session_setup_x11fwd(Session *s) -{ - struct stat st; - char display[512], auth_display[512]; - char hostname[MAXHOSTNAMELEN]; - - if (no_x11_forwarding_flag) { - packet_send_debug("X11 forwarding disabled in user configuration file."); - return 0; - } - if (!options.x11_forwarding) { - debug("X11 forwarding disabled in server configuration file."); - return 0; - } - if (!options.xauth_location || - (stat(options.xauth_location, &st) == -1)) { - packet_send_debug("No xauth program; cannot forward with spoofing."); - return 0; - } - if (s->display != NULL) { - debug("X11 display already set."); - return 0; - } - if (x11_create_display_inet(options.x11_display_offset, - options.x11_use_localhost, s->single_connection, - &s->display_number) == -1) { - debug("x11_create_display_inet failed."); - return 0; - } - - /* Set up a suitable value for the DISPLAY variable. */ - if (gethostname(hostname, sizeof(hostname)) < 0) - fatal("gethostname: %.100s", strerror(errno)); - /* - * auth_display must be used as the displayname when the - * authorization entry is added with xauth(1). This will be - * different than the DISPLAY string for localhost displays. - */ - if (options.x11_use_localhost) { - snprintf(display, sizeof display, "localhost:%u.%u", - s->display_number, s->screen); - snprintf(auth_display, sizeof auth_display, "unix:%u.%u", - s->display_number, s->screen); - s->display = xstrdup(display); - s->auth_display = xstrdup(auth_display); - } else { -#ifdef IPADDR_IN_DISPLAY - struct hostent *he; - struct in_addr my_addr; - - he = gethostbyname(hostname); - if (he == NULL) { - error("Can't get IP address for X11 DISPLAY."); - packet_send_debug("Can't get IP address for X11 DISPLAY."); - return 0; - } - memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); - snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr), - s->display_number, s->screen); -#else - snprintf(display, sizeof display, "%.400s:%u.%u", hostname, - s->display_number, s->screen); -#endif - s->display = xstrdup(display); - s->auth_display = xstrdup(display); - } - - return 1; -} - -#ifdef USE_PAM -int session_do_pam_conv(int, struct pam_message **, - struct pam_response **, void *); - -static struct pam_conv session_pam_conv = { - session_do_pam_conv, - NULL -}; - -static void -session_do_pam(Session *s, int do_open) -{ - int pam_retval; - char *where, *old_tty, *old_tty_copy = NULL; - struct pam_conv old_conv, *old_conv_ptr; - - if (!s || !s->authctxt || !s->authctxt->pam || !s->authctxt->pam->h) - return; - - /* Save current PAM item values */ - where = "getting PAM_CONV"; - pam_retval = pam_get_item(s->authctxt->pam->h, PAM_CONV, - (void **) &old_conv_ptr); - if (pam_retval != PAM_SUCCESS) - goto done; - old_conv = *old_conv_ptr; - - where = "getting PAM_TTY"; - pam_retval = pam_get_item(s->authctxt->pam->h, PAM_TTY, - (void **) &old_tty); - if (pam_retval != PAM_SUCCESS) - goto done; - old_tty_copy = xstrdup(old_tty); - - /* Change PAM_TTY and PAM_CONV items */ - where = "setting PAM_TTY"; - pam_retval = pam_set_item(s->authctxt->pam->h, PAM_TTY, s->tty); - if (pam_retval != PAM_SUCCESS) - goto done; - - where = "setting PAM_CONV"; - session_pam_conv.appdata_ptr = s; - pam_retval = pam_set_item(s->authctxt->pam->h, - PAM_CONV, &session_pam_conv); - if (pam_retval != PAM_SUCCESS) - goto done; - - /* Call pam_open/close_session() */ - if (do_open) { - where = "calling pam_open_session()"; - pam_retval = pam_open_session(s->authctxt->pam->h, 0); - } - else { - where = "calling pam_close_session()"; - pam_retval = pam_close_session(s->authctxt->pam->h, 0); - } - - /* Reset PAM_TTY and PAM_CONV items to previous values */ - where = "setting PAM_TTY"; - pam_retval = pam_set_item(s->authctxt->pam->h, PAM_TTY, old_tty_copy); - if (pam_retval != PAM_SUCCESS) - goto done; - - where = "setting PAM_CONV"; - pam_retval = pam_set_item(s->authctxt->pam->h, PAM_CONV, &old_conv); - if (pam_retval != PAM_SUCCESS) - goto done; - - session_pam_conv.appdata_ptr = NULL; - -done: - if (old_tty_copy) - xfree(old_tty_copy); - - if (pam_retval == PAM_SUCCESS) - return; - - /* fatal()? probably not... */ - log("PAM failed[%d] while %s: %s", pam_retval, where, - PAM_STRERROR(s->authctxt->pam->h, pam_retval)); -} - -int -session_do_pam_conv(int num_prompts, - struct pam_message **prompts, - struct pam_response **resp, - void *app_data) -{ - Session *s = (Session *) app_data; - - struct pam_response *reply; - int count; - char *prompt; - - if (channel_lookup(s->chanid) == NULL) - return PAM_CONV_ERR; - - /* PAM will free this later */ - reply = xmalloc(num_prompts * sizeof(*reply)); - - (void) memset(reply, 0, num_prompts * sizeof(*reply)); - for (count = 0; count < num_prompts; count++) { - switch(PAM_MSG_MEMBER(prompts, count, msg_style)) { - case PAM_TEXT_INFO: - /* Write to stdout of channel */ - prompt = PAM_MSG_MEMBER(prompts, count, msg); - if (prompt != NULL && s->ttyfd != -1) { - debug2("session_do_pam_conv: text info " - "prompt: %s", prompt); - (void) write(s->ttyfd, prompt, strlen(prompt)); - (void) write(s->ttyfd, "\n", 1); - } - reply[count].resp = xstrdup(""); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_ERROR_MSG: - /* Write to stderr of channel */ - prompt = PAM_MSG_MEMBER(prompts, count, msg); - if (prompt != NULL && s->ttyfd != -1) { - debug2("session_do_pam_conv: error " - "prompt: %s", prompt); - (void) write(s->ttyfd, prompt, strlen(prompt)); - (void) write(s->ttyfd, "\n", 1); - } - reply[count].resp = xstrdup(""); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_PROMPT_ECHO_ON: - case PAM_PROMPT_ECHO_OFF: - /* - * XXX Someday add support for echo on/off prompts - * here on sessions with ttys. - */ - default: - xfree(reply); - return PAM_CONV_ERR; - } - } - - *resp = reply; - - return PAM_SUCCESS; -} -#endif /* USE_PAM */ - -static void -do_authenticated2(Authctxt *authctxt) -{ - server_loop2(authctxt); -} - -/* - * Drop the privileges. We need this for the in-process SFTP server only. For - * the shell and the external subsystem the exec(2) call will do the P = E = I - * assignment itself. Never change the privileges if the connecting user is - * root. See privileges(5) if the terminology used here is not known to you. - */ -static void -drop_privs(uid_t uid) -{ - priv_set_t *priv_inherit; - - /* If root is connecting we are done. */ - if (uid == 0) - return; - - if ((priv_inherit = priv_allocset()) == NULL) - fatal("priv_allocset: %s", strerror(errno)); - if (getppriv(PRIV_INHERITABLE, priv_inherit) != 0) - fatal("getppriv: %s", strerror(errno)); - - /* - * This will limit E as well. Note that before this P was a - * superset of I, see permanently_set_uid(). - */ - if (setppriv(PRIV_SET, PRIV_PERMITTED, priv_inherit) == -1) - fatal("setppriv: %s", strerror(errno)); - - priv_freeset(priv_inherit); - - /* - * By manipulating the P set above we entered a PA mode which we - * do not need to retain in. - */ - if (setpflags(PRIV_AWARE, 0) == -1) - fatal("setpflags: %s", strerror(errno)); -} diff --git a/usr/src/cmd/ssh/sshd/sshd.c b/usr/src/cmd/ssh/sshd/sshd.c deleted file mode 100644 index 3be0890a8c..0000000000 --- a/usr/src/cmd/ssh/sshd/sshd.c +++ /dev/null @@ -1,2051 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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. - * - * 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: - * Privilege Separation: - * - * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. - * Copyright (c) 2002 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. - */ -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.260 2002/09/27 10:42:09 mickey Exp $"); - -#include <openssl/dh.h> -#include <openssl/bn.h> -#include <openssl/md5.h> - -#include <openssl/rand.h> - -#include "ssh.h" -#include "ssh1.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "rsa.h" -#include "sshpty.h" -#include "packet.h" -#include "mpaux.h" -#include "log.h" -#include "servconf.h" -#include "uidswap.h" -#include "compat.h" -#include "buffer.h" -#include "cipher.h" -#include "kex.h" -#include "key.h" -#include "dh.h" -#include "myproposal.h" -#include "authfile.h" -#include "pathnames.h" -#include "atomicio.h" -#include "canohost.h" -#include "auth.h" -#include "misc.h" -#include "dispatch.h" -#include "channels.h" -#include "session.h" -#include "g11n.h" -#include "sshlogin.h" -#include "xlist.h" -#include "engine.h" - -#ifdef HAVE_BSM -#include "bsmaudit.h" -#endif /* HAVE_BSM */ - -#ifdef ALTPRIVSEP -#include "altprivsep.h" -#endif /* ALTPRIVSEP */ - -#ifdef HAVE_SOLARIS_CONTRACTS -#include <sys/ctfs.h> -#include <sys/contract.h> -#include <sys/contract/process.h> -#include <libcontract.h> -#endif /* HAVE_SOLARIS_CONTRACTS */ - -#ifdef GSSAPI -#include "ssh-gss.h" -#endif /* GSSAPI */ - -#ifdef LIBWRAP -#include <tcpd.h> -#include <syslog.h> -#ifndef lint -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING; -#endif /* lint */ -#endif /* LIBWRAP */ - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -#ifdef HAVE___PROGNAME -extern char *__progname; -#else -char *__progname; -#endif - -/* Server configuration options. */ -ServerOptions options; - -/* Name of the server configuration file. */ -static char *config_file_name = _PATH_SERVER_CONFIG_FILE; - -/* - * Flag indicating whether IPv4 or IPv6. This can be set on the command line. - * Default value is AF_UNSPEC means both IPv4 and IPv6. - */ -#ifdef IPV4_DEFAULT -int IPv4or6 = AF_INET; -#else -int IPv4or6 = AF_UNSPEC; -#endif - -/* - * Debug mode flag. This can be set on the command line. If debug - * mode is enabled, extra debugging output will be sent to the system - * log, the daemon will not go to background, and will exit after processing - * the first connection. - */ -int debug_flag = 0; - -/* Flag indicating that the daemon should only test the configuration and keys. */ -static int test_flag = 0; - -/* Flag indicating that the daemon is being started from inetd. */ -static int inetd_flag = 0; - -/* Flag indicating that sshd should not detach and become a daemon. */ -static int no_daemon_flag = 0; - -/* debug goes to stderr unless inetd_flag is set */ -int log_stderr = 0; - -/* Saved arguments to main(). */ -static char **saved_argv; -static int saved_argc; - -/* - * The sockets that the server is listening; this is used in the SIGHUP - * signal handler. - */ -#define MAX_LISTEN_SOCKS 16 -static int listen_socks[MAX_LISTEN_SOCKS]; -static int num_listen_socks = 0; - -/* - * the client's version string, passed by sshd2 in compat mode. if != NULL, - * sshd will skip the version-number exchange - */ -static char *client_version_string = NULL; -static char *server_version_string = NULL; - -/* for rekeying XXX fixme */ -Kex *xxx_kex; - -/* - * Any really sensitive data in the application is contained in this - * structure. The idea is that this structure could be locked into memory so - * that the pages do not get written into swap. However, there are some - * problems. The private key contains BIGNUMs, and we do not (in principle) - * have access to the internals of them, and locking just the structure is - * not very useful. Currently, memory locking is not implemented. - */ -static struct { - Key *server_key; /* ephemeral server key */ - Key *ssh1_host_key; /* ssh1 host key */ - Key **host_keys; /* all private host keys */ - int have_ssh1_key; - int have_ssh2_key; - u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; -} sensitive_data; - -/* - * Flag indicating whether the RSA server key needs to be regenerated. - * Is set in the SIGALRM handler and cleared when the key is regenerated. - */ -static volatile sig_atomic_t key_do_regen = 0; - -/* This is set to true when a signal is received. */ -static volatile sig_atomic_t received_sighup = 0; -static volatile sig_atomic_t received_sigterm = 0; - -/* session identifier, used by RSA-auth */ -u_char session_id[16]; - -/* same for ssh2 */ -u_char *session_id2 = NULL; -int session_id2_len = 0; - -/* record remote hostname or ip */ -u_int utmp_len = MAXHOSTNAMELEN; - -/* options.max_startup sized array of fd ints */ -static int *startup_pipes = NULL; -static int startup_pipe = -1; /* in child */ - -/* sshd_config buffer */ -Buffer cfg; - -#ifdef GSSAPI -static gss_OID_set mechs = GSS_C_NULL_OID_SET; -#endif /* GSSAPI */ - -/* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); -static void demote_sensitive_data(void); - -static void do_ssh1_kex(void); -static void do_ssh2_kex(void); - -/* - * Close all listening sockets - */ -static void -close_listen_socks(void) -{ - int i; - - for (i = 0; i < num_listen_socks; i++) - (void) close(listen_socks[i]); - num_listen_socks = -1; -} - -static void -close_startup_pipes(void) -{ - int i; - - if (startup_pipes) - for (i = 0; i < options.max_startups; i++) - if (startup_pipes[i] != -1) - (void) close(startup_pipes[i]); -} - -/* - * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; - * the effect is to reread the configuration file (and to regenerate - * the server key). - */ -static void -sighup_handler(int sig) -{ - int save_errno = errno; - - received_sighup = 1; - (void) signal(SIGHUP, sighup_handler); - errno = save_errno; -} - -/* - * Called from the main program after receiving SIGHUP. - * Restarts the server. - */ -static void -sighup_restart(void) -{ - log("Received SIGHUP; restarting."); - close_listen_socks(); - close_startup_pipes(); - (void) execv(saved_argv[0], saved_argv); - log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], - strerror(errno)); - exit(1); -} - -/* - * Generic signal handler for terminating signals in the master daemon. - */ -static void -sigterm_handler(int sig) -{ - received_sigterm = sig; -} - -/* - * SIGCHLD handler. This is called whenever a child dies. This will then - * reap any zombies left by exited children. - */ -static void -main_sigchld_handler(int sig) -{ - int save_errno = errno; - pid_t pid; - int status; - - while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || - (pid < 0 && errno == EINTR)) - ; - - (void) signal(SIGCHLD, main_sigchld_handler); - errno = save_errno; -} - -/* - * Signal handler for the alarm after the login grace period has expired. This - * is for the (soon-to-be) unprivileged child only. The monitor gets an event on - * the communication pipe and exits as well. - */ -static void -grace_alarm_handler(int sig) -{ - /* Log error and exit. */ - fatal("Timeout before authentication for %.200s", get_remote_ipaddr()); -} - -#ifdef HAVE_SOLARIS_CONTRACTS -static int contracts_fd = -1; -void -contracts_pre_fork() -{ - const char *during = "opening process contract template"; - - /* - * Failure should not be treated as fatal on the theory that - * it's better to start with children in the same contract as - * the master listener than not at all. - */ - - if (contracts_fd == -1) { - if ((contracts_fd = open64(CTFS_ROOT "/process/template", - O_RDWR)) == -1) - goto cleanup; - - during = "setting sundry contract terms"; - if ((errno = ct_pr_tmpl_set_param(contracts_fd, CT_PR_PGRPONLY))) - goto cleanup; - - if ((errno = ct_tmpl_set_informative(contracts_fd, CT_PR_EV_HWERR))) - goto cleanup; - - if ((errno = ct_pr_tmpl_set_fatal(contracts_fd, CT_PR_EV_HWERR))) - goto cleanup; - - if ((errno = ct_tmpl_set_critical(contracts_fd, 0))) - goto cleanup; - } - - during = "setting active template"; - if ((errno = ct_tmpl_activate(contracts_fd))) - goto cleanup; - - debug3("Set active contract"); - return; - -cleanup: - if (contracts_fd != -1) - (void) close(contracts_fd); - - contracts_fd = -1; - - if (errno) - debug2("Error while trying to set up active contract" - " template: %s while %s", strerror(errno), during); -} - -void -contracts_post_fork_child() -{ - /* Clear active template so fork() creates no new contracts. */ - - if (contracts_fd == -1) - return; - - if ((errno = (ct_tmpl_clear(contracts_fd)))) - debug2("Error while trying to clear active contract template" - " (child): %s", strerror(errno)); - else - debug3("Cleared active contract template (child)"); - - (void) close(contracts_fd); - - contracts_fd = -1; -} - -void -contracts_post_fork_parent(int fork_succeeded) -{ - char path[PATH_MAX]; - int cfd, n; - ct_stathdl_t st; - ctid_t latest; - - /* Clear active template, abandon latest contract. */ - if (contracts_fd == -1) - return; - - if ((errno = ct_tmpl_clear(contracts_fd))) - debug2("Error while clearing active contract template: %s", - strerror(errno)); - else - debug3("Cleared active contract template (parent)"); - - if (!fork_succeeded) - return; - - if ((cfd = open64(CTFS_ROOT "/process/latest", O_RDONLY)) == -1) { - debug2("Error while getting latest contract: %s", - strerror(errno)); - return; - } - - if ((errno = ct_status_read(cfd, CTD_COMMON, &st)) != 0) { - debug2("Error while getting latest contract ID: %s", - strerror(errno)); - (void) close(cfd); - return; - } - - latest = ct_status_get_id(st); - ct_status_free(st); - (void) close(cfd); - - n = snprintf(path, PATH_MAX, CTFS_ROOT "/all/%ld/ctl", latest); - - if (n >= PATH_MAX) { - debug2("Error while opening the latest contract ctl file: %s", - strerror(ENAMETOOLONG)); - return; - } - - if ((cfd = open64(path, O_WRONLY)) == -1) { - debug2("Error while opening the latest contract ctl file: %s", - strerror(errno)); - return; - } - - if ((errno = ct_ctl_abandon(cfd))) - debug2("Error while abandoning latest contract: %s", - strerror(errno)); - else - debug3("Abandoned latest contract"); - - (void) close(cfd); -} -#endif /* HAVE_SOLARIS_CONTRACTS */ - -/* - * Signal handler for the key regeneration alarm. Note that this - * alarm only occurs in the daemon waiting for connections, and it does not - * do anything with the private key or random state before forking. - * Thus there should be no concurrency control/asynchronous execution - * problems. - */ -static void -generate_ephemeral_server_key(void) -{ - u_int32_t rnd = 0; - int i; - - verbose("Generating %s%d bit RSA key.", - sensitive_data.server_key ? "new " : "", options.server_key_bits); - if (sensitive_data.server_key != NULL) - key_free(sensitive_data.server_key); - sensitive_data.server_key = key_generate(KEY_RSA1, - options.server_key_bits); - verbose("RSA key generation complete."); - - for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { - if (i % 4 == 0) - rnd = arc4random(); - sensitive_data.ssh1_cookie[i] = rnd & 0xff; - rnd >>= 8; - } - arc4random_stir(); -} - -static void -key_regeneration_alarm(int sig) -{ - int save_errno = errno; - - (void) signal(SIGALRM, SIG_DFL); - errno = save_errno; - key_do_regen = 1; -} - -static void -sshd_exchange_identification(int sock_in, int sock_out) -{ - int i, mismatch; - int remote_major, remote_minor; - int major, minor; - char *s; - char buf[256]; /* Must not be larger than remote_version. */ - char remote_version[256]; /* Must be at least as big as buf. */ - - if ((options.protocol & SSH_PROTO_1) && - (options.protocol & SSH_PROTO_2)) { - major = PROTOCOL_MAJOR_1; - minor = 99; - } else if (options.protocol & SSH_PROTO_2) { - major = PROTOCOL_MAJOR_2; - minor = PROTOCOL_MINOR_2; - } else { - major = PROTOCOL_MAJOR_1; - minor = PROTOCOL_MINOR_1; - } - (void) snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); - server_version_string = xstrdup(buf); - - if (client_version_string == NULL) { - /* Send our protocol version identification. */ - if (atomicio(write, sock_out, server_version_string, - strlen(server_version_string)) - != strlen(server_version_string)) { - log("Could not write ident string to %s", get_remote_ipaddr()); - fatal_cleanup(); - } - - /* Read other sides version identification. */ - (void) memset(buf, 0, sizeof(buf)); - for (i = 0; i < sizeof(buf) - 1; i++) { - if (atomicio(read, sock_in, &buf[i], 1) != 1) { - log("Did not receive identification string from %s", - get_remote_ipaddr()); - fatal_cleanup(); - } - if (buf[i] == '\r') { - buf[i] = 0; - /* Kludge for F-Secure Macintosh < 1.0.2 */ - if (i == 12 && - strncmp(buf, "SSH-1.5-W1.0", 12) == 0) - break; - continue; - } - if (buf[i] == '\n') { - buf[i] = 0; - break; - } - } - buf[sizeof(buf) - 1] = 0; - client_version_string = xstrdup(buf); - } - - /* - * Check that the versions match. In future this might accept - * several versions and set appropriate flags to handle them. - */ - if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", - &remote_major, &remote_minor, remote_version) != 3) { - s = "Protocol mismatch.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); - (void) close(sock_in); - (void) close(sock_out); - log("Bad protocol version identification '%.100s' from %s", - client_version_string, get_remote_ipaddr()); - fatal_cleanup(); - } - debug("Client protocol version %d.%d; client software version %.100s", - remote_major, remote_minor, remote_version); - - compat_datafellows(remote_version); - - if (datafellows & SSH_BUG_PROBE) { - log("probed from %s with %s. Don't panic.", - get_remote_ipaddr(), client_version_string); - fatal_cleanup(); - } - - if (datafellows & SSH_BUG_SCANNER) { - log("scanned from %s with %s. Don't panic.", - get_remote_ipaddr(), client_version_string); - fatal_cleanup(); - } - - mismatch = 0; - switch (remote_major) { - case 1: - if (remote_minor == 99) { - if (options.protocol & SSH_PROTO_2) - enable_compat20(); - else - mismatch = 1; - break; - } - if (!(options.protocol & SSH_PROTO_1)) { - mismatch = 1; - break; - } - if (remote_minor < 3) { - 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 */ - enable_compat13(); - } - break; - case 2: - if (options.protocol & SSH_PROTO_2) { - enable_compat20(); - break; - } - /* FALLTHROUGH */ - default: - mismatch = 1; - break; - } - chop(server_version_string); - debug("Local version string %.200s", server_version_string); - - if (mismatch) { - s = "Protocol major versions differ.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); - (void) close(sock_in); - (void) close(sock_out); - log("Protocol major versions differ for %s: %.200s vs. %.200s", - get_remote_ipaddr(), - server_version_string, client_version_string); - fatal_cleanup(); - } -} - -/* Destroy the host and server keys. They will no longer be needed. */ -void -destroy_sensitive_data(void) -{ - int i; - - if (sensitive_data.server_key) { - key_free(sensitive_data.server_key); - sensitive_data.server_key = NULL; - } - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - key_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = NULL; - } - } - sensitive_data.ssh1_host_key = NULL; - (void) memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); -} - -/* Demote private to public keys for network child */ -static void -demote_sensitive_data(void) -{ - Key *tmp; - int i; - - if (sensitive_data.server_key) { - tmp = key_demote(sensitive_data.server_key); - key_free(sensitive_data.server_key); - sensitive_data.server_key = tmp; - } - - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - tmp = key_demote(sensitive_data.host_keys[i]); - key_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = tmp; - if (tmp->type == KEY_RSA1) - sensitive_data.ssh1_host_key = tmp; - } - } - - /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ -} - -static char * -list_hostkey_types(void) -{ - Buffer b; - char *p; - int i; - - buffer_init(&b); - for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA: - case KEY_DSA: - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - p = key_ssh_name(key); - buffer_append(&b, p, strlen(p)); - break; - } - } - buffer_append(&b, "\0", 1); - p = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - debug("list_hostkey_types: %s", p); - return p; -} - -#ifdef lint -static -#endif /* lint */ -Key * -get_hostkey_by_type(int type) -{ - int i; - - for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; - if (key != NULL && key->type == type) - return key; - } - return NULL; -} - -#ifdef lint -static -#endif /* lint */ -Key * -get_hostkey_by_index(int ind) -{ - if (ind < 0 || ind >= options.num_host_key_files) - return (NULL); - return (sensitive_data.host_keys[ind]); -} - -#ifdef lint -static -#endif /* lint */ -int -get_hostkey_index(Key *key) -{ - int i; - - for (i = 0; i < options.num_host_key_files; i++) { - if (key == sensitive_data.host_keys[i]) - return (i); - } - return (-1); -} - -/* - * 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 - */ -static 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; -} - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("sshd version %s\n"), SSH_VERSION); - (void) fprintf(stderr, - gettext("Usage: %s [options]\n" - "Options:\n" - " -f file Configuration file (default %s)\n" - " -d Debugging mode (multiple -d means more " - "debugging)\n" - " -i Started from inetd\n" - " -D Do not fork into daemon mode\n" - " -t Only test configuration file and keys\n" - " -q Quiet (no logging)\n" - " -p port Listen on the specified port (default: 22)\n" - " -k seconds Regenerate server key every this many seconds " - "(default: 3600)\n" - " -g seconds Grace period for authentication (default: 600)\n" - " -b bits Size of server RSA key (default: 768 bits)\n" - " -h file File from which to read host key (default: %s)\n" - " -4 Use IPv4 only\n" - " -6 Use IPv6 only\n" - " -o option Process the option as if it was read from " - "a configuration file.\n"), - __progname, _PATH_SERVER_CONFIG_FILE, _PATH_HOST_KEY_FILE); - exit(1); -} - -/* - * Main program for the daemon. - */ -int -main(int ac, char **av) -{ - extern char *optarg; - extern int optind; - int opt, j, i, fdsetsz, sock_in = 0, sock_out = 0, newsock = -1, on = 1; - pid_t pid; - socklen_t fromlen; - fd_set *fdset; - struct sockaddr_storage from; - const char *remote_ip; - int remote_port; - FILE *f; - struct addrinfo *ai; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int listen_sock, maxfd; - int startup_p[2]; - int startups = 0; - Authctxt *authctxt = NULL; - Key *key; - int ret, key_used = 0; -#ifdef HAVE_BSM - au_id_t auid = AU_NOAUDITID; -#endif /* HAVE_BSM */ - int mpipe; - - __progname = get_progname(av[0]); - - (void) g11n_setlocale(LC_ALL, ""); - - init_rng(); - - /* Save argv. */ - saved_argc = ac; - saved_argv = av; - - /* Initialize configuration options to their default values. */ - initialize_server_options(&options); - - /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) { - switch (opt) { - case '4': - IPv4or6 = AF_INET; - break; - case '6': - IPv4or6 = AF_INET6; - break; - case 'f': - config_file_name = optarg; - break; - case 'd': - if (0 == debug_flag) { - debug_flag = 1; - options.log_level = SYSLOG_LEVEL_DEBUG1; - } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { - options.log_level++; - } else { - (void) fprintf(stderr, - gettext("Debug level too high.\n")); - exit(1); - } - break; - case 'D': - no_daemon_flag = 1; - break; - case 'e': - log_stderr = 1; - break; - case 'i': - inetd_flag = 1; - break; - case 'Q': - /* ignored */ - break; - case 'q': - options.log_level = SYSLOG_LEVEL_QUIET; - break; - case 'b': - options.server_key_bits = atoi(optarg); - break; - case 'p': - options.ports_from_cmdline = 1; - if (options.num_ports >= MAX_PORTS) { - (void) fprintf(stderr, gettext("too many ports.\n")); - exit(1); - } - options.ports[options.num_ports++] = a2port(optarg); - if (options.ports[options.num_ports-1] == 0) { - (void) fprintf(stderr, gettext("Bad port number.\n")); - exit(1); - } - break; - case 'g': - if ((options.login_grace_time = convtime(optarg)) == -1) { - (void) fprintf(stderr, - gettext("Invalid login grace time.\n")); - exit(1); - } - break; - case 'k': - if ((options.key_regeneration_time = convtime(optarg)) == -1) { - (void) fprintf(stderr, - gettext("Invalid key regeneration " - "interval.\n")); - exit(1); - } - break; - case 'h': - if (options.num_host_key_files >= MAX_HOSTKEYS) { - (void) fprintf(stderr, - gettext("too many host keys.\n")); - exit(1); - } - options.host_key_files[options.num_host_key_files++] = optarg; - break; - case 'V': - client_version_string = optarg; - /* only makes sense with inetd_flag, i.e. no listen() */ - inetd_flag = 1; - break; - case 't': - test_flag = 1; - break; - case 'o': - if (process_server_config_line(&options, optarg, - "command-line", 0, NULL, NULL, NULL, NULL) != 0) - exit(1); - break; - case '?': - default: - usage(); - break; - } - } - - /* - * There is no need to use the PKCS#11 engine in the master SSH process. - */ - SSLeay_add_all_algorithms(); - seed_rng(); - channel_set_af(IPv4or6); - - /* - * Force logging to stderr until we have loaded the private host - * key (unless started from inetd) - */ - log_init(__progname, - options.log_level == SYSLOG_LEVEL_NOT_SET ? - SYSLOG_LEVEL_INFO : options.log_level, - options.log_facility == SYSLOG_FACILITY_NOT_SET ? - SYSLOG_FACILITY_AUTH : options.log_facility, - !inetd_flag); - -#ifdef _UNICOS - /* Cray can define user privs drop all prives now! - * Not needed on PRIV_SU systems! - */ - drop_cray_privs(); -#endif - - /* Fetch our configuration */ - buffer_init(&cfg); - load_server_config(config_file_name, &cfg); - parse_server_config(&options, config_file_name, &cfg, NULL, NULL, NULL); - - /* - * ChallengeResponseAuthentication is deprecated for protocol 2 which is - * the default setting on Solaris. Warn the user about it. Note that - * ChallengeResponseAuthentication is on by default but the option is - * not set until fill_default_server_options() is called. If the option - * is already set now, the user must have set it manually. - */ - if ((options.protocol & SSH_PROTO_2) && - !(options.protocol & SSH_PROTO_1) && - options.challenge_response_authentication != -1) { - log("ChallengeResponseAuthentication has been " - "deprecated for the SSH Protocol 2. You should use " - "KbdInteractiveAuthentication instead (which defaults to " - "\"yes\")."); - } - - /* - * While PAMAuthenticationViaKbdInt was not documented, it was - * previously set in our default sshd_config and also the only way to - * switch off the keyboard-interactive authentication. To maintain - * backward compatibility, if PAMAuthenticationViaKbdInt is manually set - * to "no" and KbdInteractiveAuthentication is not set, switch off the - * keyboard-interactive authentication method as before. As with the - * challenge response auth situation dealt above, we have not called - * fill_default_server_options() yet so if KbdInteractiveAuthentication - * is already set to 1 here the admin must have set it manually and we - * will honour it. - */ - if (options.kbd_interactive_authentication != 1 && - options.pam_authentication_via_kbd_int == 0) { - options.kbd_interactive_authentication = 0; - } - - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - - utmp_len = options.lookup_client_hostnames ? utmp_len : 0; - - /* Check that there are no remaining arguments. */ - if (optind < ac) { - (void) fprintf(stderr, gettext("Extra argument %s.\n"), av[optind]); - exit(1); - } - - debug("sshd version %.100s", SSH_VERSION); - - /* load private host keys */ - if (options.num_host_key_files > 0) - sensitive_data.host_keys = - xmalloc(options.num_host_key_files * sizeof(Key *)); - for (i = 0; i < options.num_host_key_files; i++) - sensitive_data.host_keys[i] = NULL; - sensitive_data.server_key = NULL; - sensitive_data.ssh1_host_key = NULL; - sensitive_data.have_ssh1_key = 0; - sensitive_data.have_ssh2_key = 0; - - for (i = 0; i < options.num_host_key_files; i++) { - key = key_load_private(options.host_key_files[i], "", NULL); - sensitive_data.host_keys[i] = key; - if (key == NULL) { - error("Could not load host key: %s", - options.host_key_files[i]); - sensitive_data.host_keys[i] = NULL; - continue; - } - switch (key->type) { - case KEY_RSA1: - sensitive_data.ssh1_host_key = key; - sensitive_data.have_ssh1_key = 1; - break; - case KEY_RSA: - case KEY_DSA: - sensitive_data.have_ssh2_key = 1; - break; - } - debug("private host key: #%d type %d %s", i, key->type, - key_type(key)); - } - if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { - log("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; - } - if ((options.protocol & SSH_PROTO_2) && - !sensitive_data.have_ssh2_key) { -#ifdef GSSAPI - if (options.gss_keyex) - ssh_gssapi_server_mechs(&mechs); - - if (mechs == GSS_C_NULL_OID_SET) { - log("Disabling protocol version 2. Could not load host" - "key or GSS-API mechanisms"); - options.protocol &= ~SSH_PROTO_2; - } -#else - log("Disabling protocol version 2. Could not load host key"); - options.protocol &= ~SSH_PROTO_2; -#endif /* GSSAPI */ - } - if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { - log("sshd: no hostkeys available -- exiting."); - exit(1); - } - - /* Check certain values for sanity. */ - if (options.protocol & SSH_PROTO_1) { - if (options.server_key_bits < 512 || - options.server_key_bits > 32768) { - (void) fprintf(stderr, gettext("Bad server key size.\n")); - exit(1); - } - /* - * Check that server and host key lengths differ sufficiently. This - * is necessary to make double encryption work with rsaref. Oh, I - * hate software patents. I dont know if this can go? Niels - */ - if (options.server_key_bits > - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - - SSH_KEY_BITS_RESERVED && options.server_key_bits < - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + - SSH_KEY_BITS_RESERVED) { - options.server_key_bits = - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + - SSH_KEY_BITS_RESERVED; - debug("Forcing server key to %d bits to make it differ from host key.", - options.server_key_bits); - } - } - - /* Configuration looks good, so exit if in test mode. */ - if (test_flag) - exit(0); - - /* - * Clear out any supplemental groups we may have inherited. This - * prevents inadvertent creation of files with bad modes (in the - * portable version at least, it's certainly possible for PAM - * to create a file, and we can't control the code in every - * module which might be used). - */ - if (setgroups(0, NULL) < 0) - debug("setgroups() failed: %.200s", strerror(errno)); - - /* Initialize the log (it is reinitialized below in case we forked). */ - if (debug_flag && !inetd_flag) - log_stderr = 1; - log_init(__progname, options.log_level, options.log_facility, log_stderr); - - /* - * Solaris 9 and systems upgraded from it may have the Ciphers option - * explicitly set to "aes128-cbc,blowfish-cbc,3des-cbc" in the - * sshd_config. Since the default server cipher list completely changed - * since then we rather notify the administator on startup. We do this - * check after log_init() so that the message goes to syslogd and not to - * stderr (unless the server is in the debug mode). Note that since - * Solaris 10 we no longer ship sshd_config with explicit settings for - * Ciphers or MACs. Do not try to augment the cipher list here since - * that might end up in a very confusing situation. - */ -#define OLD_DEFAULT_CIPHERS_LIST "aes128-cbc,blowfish-cbc,3des-cbc" - if (options.ciphers != NULL && - strcmp(options.ciphers, OLD_DEFAULT_CIPHERS_LIST) == 0) { - notice("Old default value \"%s\" for the \"Ciphers\" " - "option found in use. In general it is prudent to let " - "the server choose the defaults unless your environment " - "specifically needs an explicit setting. See " - "sshd_config(4) for more information.", - OLD_DEFAULT_CIPHERS_LIST); - } - -#ifdef HAVE_BSM - (void) setauid(&auid); -#endif /* HAVE_BSM */ - - /* - * If not in debugging mode, and not started from inetd, disconnect - * from the controlling terminal, and fork. The original process - * exits. - */ - if (!(debug_flag || inetd_flag || no_daemon_flag)) { -#ifdef TIOCNOTTY - int fd; -#endif /* TIOCNOTTY */ - if (daemon(0, 0) < 0) - fatal("daemon() failed: %.200s", strerror(errno)); - - /* Disconnect from the controlling tty. */ -#ifdef TIOCNOTTY - fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); - if (fd >= 0) { - (void) ioctl(fd, TIOCNOTTY, NULL); - (void) close(fd); - } -#endif /* TIOCNOTTY */ - } - /* Reinitialize the log (because of the fork above). */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); - - /* Initialize the random number generator. */ - arc4random_stir(); - - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - (void) chdir("/"); - - /* ignore SIGPIPE */ - (void) signal(SIGPIPE, SIG_IGN); - - /* Start listening for a socket, unless started from inetd. */ - if (inetd_flag) { - int s1; - s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ - (void) dup(s1); - sock_in = dup(0); - sock_out = dup(1); - startup_pipe = -1; - /* we need this later for setting audit context */ - newsock = sock_in; - /* - * We intentionally do not close the descriptors 0, 1, and 2 - * as our code for setting the descriptors won\'t work if - * ttyfd happens to be one of those. - */ - debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); - if (options.protocol & SSH_PROTO_1) - generate_ephemeral_server_key(); - } else { - for (ai = options.listen_addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) - continue; - if (num_listen_socks >= MAX_LISTEN_SOCKS) - fatal("Too many listen sockets. " - "Enlarge MAX_LISTEN_SOCKS"); - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, - ntop, sizeof(ntop), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("getnameinfo failed"); - continue; - } - /* Create socket for listening. */ - listen_sock = socket(ai->ai_family, SOCK_STREAM, 0); - if (listen_sock < 0) { - /* kernel may not support ipv6 */ - verbose("socket: %.100s", strerror(errno)); - continue; - } - if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) { - error("listen_sock O_NONBLOCK: %s", strerror(errno)); - (void) close(listen_sock); - continue; - } - /* - * Set socket options. - * Allow local port reuse in TIME_WAIT. - */ - if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, - &on, sizeof(on)) == -1) - error("setsockopt SO_REUSEADDR: %s", strerror(errno)); - - debug("Bind to port %s on %s.", strport, ntop); - - /* Bind the socket to the desired port. */ - if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { - if (!ai->ai_next) - error("Bind to port %s on %s failed: %.200s.", - strport, ntop, strerror(errno)); - (void) close(listen_sock); - continue; - } - listen_socks[num_listen_socks] = listen_sock; - num_listen_socks++; - - /* Start listening on the port. */ - log("Server listening on %s port %s.", ntop, strport); - if (listen(listen_sock, 5) < 0) - fatal("listen: %.100s", strerror(errno)); - - } - freeaddrinfo(options.listen_addrs); - - if (!num_listen_socks) - fatal("Cannot bind any address."); - - if (options.protocol & SSH_PROTO_1) - generate_ephemeral_server_key(); - - /* - * Arrange to restart on SIGHUP. The handler needs - * listen_sock. - */ - (void) signal(SIGHUP, sighup_handler); - - (void) signal(SIGTERM, sigterm_handler); - (void) signal(SIGQUIT, sigterm_handler); - - /* Arrange SIGCHLD to be caught. */ - (void) signal(SIGCHLD, main_sigchld_handler); - - /* Write out the pid file after the sigterm handler is setup */ - if (!debug_flag) { - /* - * Record our pid in /var/run/sshd.pid to make it - * easier to kill the correct sshd. We don't want to - * do this before the bind above because the bind will - * fail if there already is a daemon, and this will - * overwrite any old pid in the file. - */ - f = fopen(options.pid_file, "wb"); - if (f) { - (void) fprintf(f, "%ld\n", (long) getpid()); - (void) fclose(f); - } - } - - /* 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]; - /* 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 - * the daemon is killed with a signal. - */ - for (;;) { - if (received_sighup) - sighup_restart(); - if (fdset != NULL) - xfree(fdset); - fdsetsz = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask); - fdset = (fd_set *)xmalloc(fdsetsz); - (void) 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. */ - ret = select(maxfd+1, fdset, NULL, NULL, NULL); - if (ret < 0 && errno != EINTR) - error("select: %.100s", strerror(errno)); - if (received_sigterm) { - log("Received signal %d; terminating.", - (int) received_sigterm); - close_listen_socks(); - (void) unlink(options.pid_file); - exit(255); - } - if (key_used && key_do_regen) { - generate_ephemeral_server_key(); - key_used = 0; - key_do_regen = 0; - } - if (ret < 0) - 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 successful authentication - * or if the child has died - */ - (void) 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)); - (void) close(newsock); - continue; - } - if (drop_connection(startups) == 1) { - debug("drop connection #%d", startups); - (void) close(newsock); - continue; - } - if (pipe(startup_p) == -1) { - (void) 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; - } - - /* - * 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; - startup_pipe = -1; - pid = getpid(); - break; - } else { - /* - * Normal production daemon. Fork, and have - * the child process the connection. The - * parent continues listening. - */ -#ifdef HAVE_SOLARIS_CONTRACTS - /* - * Setup Solaris contract template so - * the child process is in a different - * process contract than the parent; - * prevents established connections from - * being killed when the sshd master - * listener service is stopped. - */ - contracts_pre_fork(); -#endif /* HAVE_SOLARIS_CONTRACTS */ - 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. - */ -#ifdef HAVE_SOLARIS_CONTRACTS - contracts_post_fork_child(); -#endif /* HAVE_SOLARIS_CONTRACTS */ - xfree(fdset); - startup_pipe = startup_p[1]; - close_startup_pipes(); - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - log_init(__progname, 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 %ld.", (long)pid); - -#ifdef HAVE_SOLARIS_CONTRACTS - contracts_post_fork_parent((pid > 0)); -#endif /* HAVE_SOLARIS_CONTRACTS */ - } - - (void) close(startup_p[1]); - - /* Mark that the key has been used (it was "given" to the child). */ - if ((options.protocol & SSH_PROTO_1) && - key_used == 0) { - /* Schedule server key regeneration alarm. */ - (void) signal(SIGALRM, key_regeneration_alarm); - (void) alarm(options.key_regeneration_time); - key_used = 1; - } - - arc4random_stir(); - - /* - * Close the accepted socket since the child - * will now take care of the new connection. - */ - (void) close(newsock); - } - /* child process check (or debug mode) */ - if (num_listen_socks < 0) - break; - } - } - - /* - * This is the child processing a new connection, the SSH master process - * stays in the ( ; ; ) loop above. - */ -#ifdef HAVE_BSM - audit_sshd_settid(newsock); -#endif - /* - * Create a new session and process group since the 4.4BSD - * setlogin() affects the entire process group. We don't - * want the child to be able to affect the parent. - */ -#if 0 - /* XXX: this breaks Solaris */ - if (!debug_flag && !inetd_flag && setsid() < 0) - error("setsid: %.100s", strerror(errno)); -#endif - - /* - * Disable the key regeneration alarm. We will not regenerate the - * key since we are no longer in a position to give it to anyone. We - * will not restart on SIGHUP since it no longer makes sense. - */ - (void) alarm(0); - (void) signal(SIGALRM, SIG_DFL); - (void) signal(SIGHUP, SIG_DFL); - (void) signal(SIGTERM, SIG_DFL); - (void) signal(SIGQUIT, SIG_DFL); - (void) signal(SIGCHLD, SIG_DFL); - (void) signal(SIGINT, SIG_DFL); - - /* Set keepalives if requested. */ - if (options.keepalives && - setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, - sizeof(on)) < 0) - debug2("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); - - /* - * Register our connection. This turns encryption off because we do - * not have a key. - */ - packet_set_connection(sock_in, sock_out); - - remote_port = get_remote_port(); - remote_ip = get_remote_ipaddr(); - -#ifdef LIBWRAP - /* Check whether logins are denied from this host. */ - { - struct request_info req; - - (void) request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); - fromhost(&req); - - if (!hosts_access(&req)) { - debug("Connection refused by tcp wrapper"); - refuse(&req); - /* NOTREACHED */ - fatal("libwrap refuse returns"); - } - } -#endif /* LIBWRAP */ - - /* Log the connection. */ - verbose("Connection from %.500s port %d", remote_ip, remote_port); - - sshd_exchange_identification(sock_in, sock_out); - /* - * Check that the connection comes from a privileged port. - * Rhosts-Authentication only makes sense from privileged - * programs. Of course, if the intruder has root access on his local - * machine, he can connect from any port. So do not use these - * authentication methods from machines that you do not trust. - */ - if (options.rhosts_authentication && - (remote_port >= IPPORT_RESERVED || - remote_port < IPPORT_RESERVED / 2)) { - debug("Rhosts Authentication disabled, " - "originating port %d not trusted.", remote_port); - options.rhosts_authentication = 0; - } -#if defined(KRB4) && !defined(KRB5) - if (!packet_connection_is_ipv4() && - options.kerberos_authentication) { - debug("Kerberos Authentication disabled, only available for IPv4."); - options.kerberos_authentication = 0; - } -#endif /* KRB4 && !KRB5 */ -#ifdef AFS - /* If machine has AFS, set process authentication group. */ - if (k_hasafs()) { - k_setpag(); - k_unlog(); - } -#endif /* AFS */ - - packet_set_nonblocking(); - - /* - * Start the monitor. That way both processes will have their own - * PKCS#11 sessions. See the PKCS#11 standard for more information on - * fork safety and packet.c for information about forking with the - * engine. - * - * Note that the monitor stays in the function while the child is the - * only one that returns. - */ - altprivsep_start_and_do_monitor(options.use_openssl_engine, - inetd_flag, newsock, startup_pipe); - - /* - * We don't want to listen forever unless the other side successfully - * authenticates itself. So we set up an alarm which is cleared after - * successful authentication. A limit of zero indicates no limit. Note - * that we don't set the alarm in debugging mode; it is just annoying to - * have the server exit just when you are about to discover the bug. - */ - (void) signal(SIGALRM, grace_alarm_handler); - if (!debug_flag) - (void) alarm(options.login_grace_time); - - /* - * The child is about to start the first key exchange while the monitor - * stays in altprivsep_start_and_do_monitor() function. - */ - (void) pkcs11_engine_load(options.use_openssl_engine); - - /* perform the key exchange */ - /* authenticate user and start session */ - if (compat20) { - do_ssh2_kex(); - authctxt = do_authentication2(); - } else { - do_ssh1_kex(); - authctxt = do_authentication(); - } - - /* Authentication complete */ - (void) alarm(0); - /* we no longer need an alarm handler */ - (void) signal(SIGALRM, SIG_DFL); - - if (startup_pipe != -1) { - (void) close(startup_pipe); - startup_pipe = -1; - } - - /* ALTPRIVSEP Child */ - - /* - * Drop privileges, access to privileged resources. - * - * Destroy private host keys, if any. - * - * No need to release any GSS credentials -- sshd only acquires - * creds to determine what mechs it can negotiate then releases - * them right away and uses GSS_C_NO_CREDENTIAL to accept - * contexts. - */ - debug2("Unprivileged server process dropping privileges"); - permanently_set_uid(authctxt->pw, options.chroot_directory); - destroy_sensitive_data(); - - /* Just another safety check. */ - if (getuid() != authctxt->pw->pw_uid || - geteuid() != authctxt->pw->pw_uid) { - fatal("Failed to set uids to %u.", (u_int)authctxt->pw->pw_uid); - } - - ssh_gssapi_server_mechs(NULL); /* release cached mechs list */ - packet_set_server(); - - /* now send the authentication context to the monitor */ - altprivsep_send_auth_context(authctxt); - - mpipe = altprivsep_get_pipe_fd(); - if (fcntl(mpipe, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %.100s", strerror(errno)); - -#ifdef HAVE_BSM - fatal_remove_cleanup( - (void (*)(void *))audit_failed_login_cleanup, - (void *)authctxt); -#endif /* HAVE_BSM */ - - if (compat20) { - debug3("setting handler to forward re-key packets to the monitor"); - dispatch_range(SSH2_MSG_KEXINIT, SSH2_MSG_TRANSPORT_MAX, - &altprivsep_rekey); - } - - /* Logged-in session. */ - do_authenticated(authctxt); - - /* The connection has been terminated. */ - verbose("Closing connection to %.100s", remote_ip); - - packet_close(); - -#ifdef USE_PAM - finish_pam(authctxt); -#endif /* USE_PAM */ - - return (0); -} - -/* - * Decrypt session_key_int using our private server key and private host key - * (key with larger modulus first). - */ -int -ssh1_session_key(BIGNUM *session_key_int) -{ - int rsafail = 0; - - if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { - /* Server key has bigger modulus. */ - if (BN_num_bits(sensitive_data.server_key->rsa->n) < - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.server_key->rsa->n), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.server_key->rsa) <= 0) - rsafail++; - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.ssh1_host_key->rsa) <= 0) - rsafail++; - } else { - /* Host key has bigger modulus (or they are equal). */ - if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < - BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), - BN_num_bits(sensitive_data.server_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.ssh1_host_key->rsa) < 0) - rsafail++; - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.server_key->rsa) < 0) - rsafail++; - } - return (rsafail); -} -/* - * SSH1 key exchange - */ -static void -do_ssh1_kex(void) -{ - int i, len; - int rsafail = 0; - BIGNUM *session_key_int; - u_char session_key[SSH_SESSION_KEY_LENGTH]; - u_char cookie[8]; - u_int cipher_type, auth_mask, protocol_flags; - u_int32_t rnd = 0; - - /* - * Generate check bytes that the client must send back in the user - * packet in order for it to be accepted; this is used to defy ip - * spoofing attacks. Note that this only works against somebody - * doing IP spoofing from a remote machine; any machine on the local - * network can still see outgoing packets and catch the random - * cookie. This only affects rhosts authentication, and this is one - * of the reasons why it is inherently insecure. - */ - for (i = 0; i < 8; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cookie[i] = rnd & 0xff; - rnd >>= 8; - } - - /* - * Send our public key. We include in the packet 64 bits of random - * data that must be matched in the reply in order to prevent IP - * spoofing. - */ - packet_start(SSH_SMSG_PUBLIC_KEY); - for (i = 0; i < 8; i++) - packet_put_char(cookie[i]); - - /* Store our public server RSA key. */ - packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); - packet_put_bignum(sensitive_data.server_key->rsa->e); - packet_put_bignum(sensitive_data.server_key->rsa->n); - - /* Store our public host RSA key. */ - packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); - packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); - packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); - - /* Put protocol flags. */ - packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); - - /* Declare which ciphers we support. */ - packet_put_int(cipher_mask_ssh1(0)); - - /* Declare supported authentication types. */ - auth_mask = 0; - if (options.rhosts_authentication) - auth_mask |= 1 << SSH_AUTH_RHOSTS; - if (options.rhosts_rsa_authentication) - auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; - if (options.rsa_authentication) - auth_mask |= 1 << SSH_AUTH_RSA; -#if defined(KRB4) || defined(KRB5) - if (options.kerberos_authentication) - auth_mask |= 1 << SSH_AUTH_KERBEROS; -#endif -#if defined(AFS) || defined(KRB5) - if (options.kerberos_tgt_passing) - auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; -#endif -#ifdef AFS - if (options.afs_token_passing) - auth_mask |= 1 << SSH_PASS_AFS_TOKEN; -#endif - if (options.challenge_response_authentication == 1) - auth_mask |= 1 << SSH_AUTH_TIS; - if (options.password_authentication) - auth_mask |= 1 << SSH_AUTH_PASSWORD; - packet_put_int(auth_mask); - - /* Send the packet and wait for it to be sent. */ - packet_send(); - packet_write_wait(); - - debug("Sent %d bit server key and %d bit host key.", - BN_num_bits(sensitive_data.server_key->rsa->n), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); - - /* Read clients reply (cipher type and session key). */ - packet_read_expect(SSH_CMSG_SESSION_KEY); - - /* Get cipher type and check whether we accept this. */ - cipher_type = packet_get_char(); - - if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) { - packet_disconnect("Warning: client selects unsupported cipher."); - } - - /* Get check bytes from the packet. These must match those we - sent earlier with the public key packet. */ - for (i = 0; i < 8; i++) { - if (cookie[i] != packet_get_char()) { - packet_disconnect("IP Spoofing check bytes do not match."); - } - } - - debug("Encryption type: %.200s", cipher_name(cipher_type)); - - /* Get the encrypted integer. */ - if ((session_key_int = BN_new()) == NULL) - fatal("do_ssh1_kex: BN_new failed"); - packet_get_bignum(session_key_int); - - protocol_flags = packet_get_int(); - packet_set_protocol_flags(protocol_flags); - packet_check_eom(); - - /* Decrypt session_key_int using host/server keys */ - rsafail = ssh1_session_key(session_key_int); - - /* - * Extract session key from the decrypted integer. The key is in the - * least significant 256 bits of the integer; the first byte of the - * key is in the highest bits. - */ - if (!rsafail) { - (void) BN_mask_bits(session_key_int, sizeof(session_key) * 8); - len = BN_num_bytes(session_key_int); - if (len < 0 || len > sizeof(session_key)) { - error("do_connection: bad session key len from %s: " - "session_key_int %d > sizeof(session_key) %lu", - get_remote_ipaddr(), len, (u_long)sizeof(session_key)); - rsafail++; - } else { - (void) memset(session_key, 0, sizeof(session_key)); - (void) BN_bn2bin(session_key_int, - session_key + sizeof(session_key) - len); - - compute_session_id(session_id, cookie, - sensitive_data.ssh1_host_key->rsa->n, - sensitive_data.server_key->rsa->n); - /* - * Xor the first 16 bytes of the session key with the - * session id. - */ - for (i = 0; i < 16; i++) - session_key[i] ^= session_id[i]; - } - } - if (rsafail) { - int bytes = BN_num_bytes(session_key_int); - u_char *buf = xmalloc(bytes); - MD5_CTX md; - - log("do_connection: generating a fake encryption key"); - (void) BN_bn2bin(session_key_int, buf); - MD5_Init(&md); - MD5_Update(&md, buf, bytes); - MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); - MD5_Final(session_key, &md); - MD5_Init(&md); - MD5_Update(&md, session_key, 16); - MD5_Update(&md, buf, bytes); - MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); - MD5_Final(session_key + 16, &md); - (void) memset(buf, 0, bytes); - xfree(buf); - for (i = 0; i < 16; i++) - session_id[i] = session_key[i] ^ session_key[i + 16]; - } - /* Destroy the private and public keys. No longer. */ - destroy_sensitive_data(); - - /* Destroy the decrypted integer. It is no longer needed. */ - BN_clear_free(session_key_int); - - /* Set the session key. From this on all communications will be encrypted. */ - packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); - - /* Destroy our copy of the session key. It is no longer needed. */ - (void) memset(session_key, 0, sizeof(session_key)); - - debug("Received session key; encryption turned on."); - - /* Send an acknowledgment packet. Note that this packet is sent encrypted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); -} - -/* - * Prepare for SSH2 key exchange. - */ -Kex * -prepare_for_ssh2_kex(void) -{ - Kex *kex; - Kex_hook_func kex_hook = NULL; - char **locales; - static char **myproposal; - - myproposal = my_srv_proposal; - - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); - myproposal[PROPOSAL_ENC_ALGS_STOC] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); - - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - } - if (!options.compression) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; - } - - /* - * Prepare kex algs / hostkey algs (excluding GSS, which is - * handled in the kex hook. - * - * XXX This should probably move to the kex hook as well, where - * all non-constant kex offer material belongs. - */ - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); - - /* If we have no host key algs we can't offer KEXDH/KEX_DH_GEX */ - if (myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] == NULL || - *myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] == '\0') - myproposal[PROPOSAL_KEX_ALGS] = ""; - - if ((locales = g11n_getlocales()) != NULL) { - /* Solaris 9 SSH expects a list of locales */ - if (datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS) - myproposal[PROPOSAL_LANG_STOC] = xjoin(locales, ','); - else - myproposal[PROPOSAL_LANG_STOC] = - g11n_locales2langs(locales); - } - - if (locales != NULL) - g11n_freelist(locales); - - if ((myproposal[PROPOSAL_LANG_STOC] != NULL) && - (strcmp(myproposal[PROPOSAL_LANG_STOC], "")) != 0) - myproposal[PROPOSAL_LANG_CTOS] = - xstrdup(myproposal[PROPOSAL_LANG_STOC]); - -#ifdef GSSAPI - if (options.gss_keyex) - kex_hook = ssh_gssapi_server_kex_hook; -#endif /* GSSAPI */ - - kex = kex_setup(NULL, myproposal, kex_hook); - - /* - * Note that the my_srv_proposal variable (ie., myproposal) is staticly - * initialized with "" for the language fields; we must not xfree such - * strings. - */ - if (myproposal[PROPOSAL_LANG_STOC] != NULL && - strcmp(myproposal[PROPOSAL_LANG_STOC], "") != 0) - xfree(myproposal[PROPOSAL_LANG_STOC]); - if (myproposal[PROPOSAL_LANG_CTOS] != NULL && - strcmp(myproposal[PROPOSAL_LANG_STOC], "") != 0) - xfree(myproposal[PROPOSAL_LANG_CTOS]); - - kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; -#ifdef GSSAPI - kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -#endif /* GSSAPI */ - kex->server = 1; - kex->client_version_string = client_version_string; - kex->server_version_string = server_version_string; - kex->load_host_key = &get_hostkey_by_type; - kex->host_key_index = &get_hostkey_index; - - xxx_kex = kex; - return (kex); -} - -/* - * Do SSH2 key exchange. - */ -static void -do_ssh2_kex(void) -{ - Kex *kex; - - kex = prepare_for_ssh2_kex(); - kex_start(kex); - - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); - - if (kex->name) { - xfree(kex->name); - kex->name = NULL; - } - session_id2 = kex->session_id; - session_id2_len = kex->session_id_len; - -#ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - packet_start(SSH2_MSG_IGNORE); - packet_put_cstring("markus"); - packet_send(); - packet_write_wait(); -#endif - debug("KEX done"); -} diff --git a/usr/src/cmd/ssh/sshd/sshlogin.c b/usr/src/cmd/ssh/sshd/sshlogin.c deleted file mode 100644 index c2bd3bacb7..0000000000 --- a/usr/src/cmd/ssh/sshd/sshlogin.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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. - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshlogin.c,v 1.5 2002/08/29 15:57:25 stevesk Exp $"); - -#include "loginrec.h" -#include "log.h" -#include "buffer.h" -#include "servconf.h" -#include "canohost.h" -#include "packet.h" - -extern u_int utmp_len; -extern ServerOptions options; - -/* - * Returns the time when the user last logged in. Returns 0 if the - * information is not available. This must be called before record_login. - * The host the user logged in from will be returned in buf. - */ -u_long -get_last_login_time(uid_t uid, const char *logname, - char *buf, u_int bufsize) -{ - struct logininfo li; - - (void) login_get_lastlog(&li, uid); - (void) strlcpy(buf, li.hostname, bufsize); - return li.tv_sec; -} - -/* - * Records that the user has logged in. If only these parts of operating - * systems were more standardized. - */ -void -record_login(pid_t pid, const char *ttyname, const char *progname, - const char *user) -{ - struct logininfo *li; - static int initialized = 0; - static socklen_t fromlen; - static struct sockaddr_storage from; - static const char *remote_name_or_ip; - - if (pid == 0) - pid = getpid(); - /* - * Get IP address of client. If the connection is not a socket, let - * the address be 0.0.0.0. - */ - if (!initialized) { - (void) 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(); - } - } - remote_name_or_ip = get_remote_ipaddr(); - - initialized = 1; - } - - li = login_alloc_entry(pid, user, remote_name_or_ip, ttyname, progname); - login_set_addr(li, (struct sockaddr*) &from, sizeof(struct sockaddr)); - (void) login_login(li); - login_free_entry(li); -} - -/* Records that the user has logged out. */ -void -record_logout(pid_t pid, const char *ttyname, const char *progname, - const char *user) -{ - struct logininfo *li; - - li = login_alloc_entry(pid, user, NULL, ttyname, progname); - (void) login_logout(li); - login_free_entry(li); -} diff --git a/usr/src/cmd/ssh/sshd/sshpty.c b/usr/src/cmd/ssh/sshd/sshpty.c deleted file mode 100644 index b421798cb5..0000000000 --- a/usr/src/cmd/ssh/sshd/sshpty.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * 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("$OpenBSD: sshpty.c,v 1.7 2002/06/24 17:57:20 deraadt Exp $"); - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef HAVE_UTIL_H -# include <util.h> -#endif /* HAVE_UTIL_H */ - -#include "sshpty.h" -#include "log.h" -#include "misc.h" - -/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ -#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) -#undef HAVE_DEV_PTMX -#endif - -#ifdef HAVE_PTY_H -# include <pty.h> -#endif -#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) -# include <sys/stropts.h> -#endif - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -/* - * Allocates and opens a pty. Returns 0 if no pty could be allocated, or - * nonzero if a pty was successfully allocated. On success, open file - * descriptors for the pty and tty sides and the name of the tty side are - * returned (the buffer must be able to hold at least 64 characters). - */ - -int -pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) -{ -#if defined(HAVE_OPENPTY) || defined(BSD4_4) - /* openpty(3) exists in OSF/1 and some other os'es */ - char *name; - int i; - - i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); - if (i < 0) { - error("openpty: %.100s", strerror(errno)); - return 0; - } - name = ttyname(*ttyfd); - if (!name) - fatal("openpty returns device for which ttyname fails."); - - strlcpy(namebuf, name, namebuflen); /* possible truncation */ - return 1; -#else /* HAVE_OPENPTY */ -#ifdef HAVE__GETPTY - /* - * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more - * pty's automagically when needed - */ - char *slave; - - slave = _getpty(ptyfd, O_RDWR, 0622, 0); - if (slave == NULL) { - error("_getpty: %.100s", strerror(errno)); - return 0; - } - strlcpy(namebuf, slave, namebuflen); - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.200s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; -#else /* HAVE__GETPTY */ -#if defined(HAVE_DEV_PTMX) - /* - * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 - * also has bsd-style ptys, but they simply do not work.) - */ - int ptm; - char *pts; - mysig_t old_signal; - - ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); - if (ptm < 0) { - error("/dev/ptmx: %.100s", strerror(errno)); - return 0; - } - old_signal = mysignal(SIGCHLD, SIG_DFL); - if (grantpt(ptm) < 0) { - error("grantpt: %.100s", strerror(errno)); - return 0; - } - mysignal(SIGCHLD, old_signal); - if (unlockpt(ptm) < 0) { - error("unlockpt: %.100s", strerror(errno)); - return 0; - } - pts = ptsname(ptm); - if (pts == NULL) - error("Slave pty side name could not be obtained."); - strlcpy(namebuf, pts, namebuflen); - *ptyfd = ptm; - - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } -#ifndef HAVE_CYGWIN - /* - * Push the appropriate streams modules, as described in Solaris pts(7). - * HP-UX pts(7) doesn't have ttcompat module. - */ - if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) - error("ioctl I_PUSH ptem: %.100s", strerror(errno)); - if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) - error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); -#ifndef __hpux - if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) - error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); -#endif -#endif - return 1; -#else /* HAVE_DEV_PTMX */ -#ifdef HAVE_DEV_PTS_AND_PTC - /* AIX-style pty code. */ - const char *name; - - *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); - if (*ptyfd < 0) { - error("Could not open /dev/ptc: %.100s", strerror(errno)); - return 0; - } - name = ttyname(*ptyfd); - if (!name) - fatal("Open of /dev/ptc returns device for which ttyname fails."); - strlcpy(namebuf, name, namebuflen); - *ttyfd = open(name, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("Could not open pty slave side %.100s: %.100s", - name, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; -#else /* HAVE_DEV_PTS_AND_PTC */ -#ifdef _UNICOS - char buf[64]; - int i; - int highpty; - -#ifdef _SC_CRAY_NPTY - highpty = sysconf(_SC_CRAY_NPTY); - if (highpty == -1) - highpty = 128; -#else - highpty = 128; -#endif - - for (i = 0; i < highpty; i++) { - snprintf(buf, sizeof(buf), "/dev/pty/%03d", i); - *ptyfd = open(buf, O_RDWR|O_NOCTTY); - if (*ptyfd < 0) - continue; - snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i); - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; - } - return 0; -#else - /* BSD-style pty code. */ - char buf[64]; - int i; - const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; - const char *ptyminors = "0123456789abcdef"; - int num_minors = strlen(ptyminors); - int num_ptys = strlen(ptymajors) * num_minors; - struct termios tio; - - for (i = 0; i < num_ptys; i++) { - snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], - ptyminors[i % num_minors]); - snprintf(namebuf, namebuflen, "/dev/tty%c%c", - ptymajors[i / num_minors], ptyminors[i % num_minors]); - - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) { - /* Try SCO style naming */ - snprintf(buf, sizeof buf, "/dev/ptyp%d", i); - snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) - continue; - } - - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - /* set tty modes to a sane state for broken clients */ - if (tcgetattr(*ptyfd, &tio) < 0) - log("Getting tty modes for pty failed: %.100s", strerror(errno)); - else { - tio.c_lflag |= (ECHO | ISIG | ICANON); - tio.c_oflag |= (OPOST | ONLCR); - tio.c_iflag |= ICRNL; - - /* Set the new modes for the terminal. */ - if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) - log("Setting tty modes for pty failed: %.100s", strerror(errno)); - } - - return 1; - } - return 0; -#endif /* CRAY */ -#endif /* HAVE_DEV_PTS_AND_PTC */ -#endif /* HAVE_DEV_PTMX */ -#endif /* HAVE__GETPTY */ -#endif /* HAVE_OPENPTY */ -} - -/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ - -void -pty_release(const char *ttyname) -{ - if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) - error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); - if (chmod(ttyname, (mode_t) 0666) < 0) - error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); -} - -/* Makes the tty the processes controlling tty and sets it to sane modes. */ - -void -pty_make_controlling_tty(int *ttyfd, const char *ttyname) -{ - int fd; -#ifdef USE_VHANGUP - void *old; -#endif /* USE_VHANGUP */ - -#ifdef _UNICOS - if (setsid() < 0) - error("setsid: %.100s", strerror(errno)); - - fd = open(ttyname, O_RDWR|O_NOCTTY); - if (fd != -1) { - mysignal(SIGHUP, SIG_IGN); - ioctl(fd, TCVHUP, (char *)NULL); - mysignal(SIGHUP, SIG_DFL); - setpgid(0, 0); - close(fd); - } else { - error("Failed to disconnect from controlling tty."); - } - - debug("Setting controlling tty using TCSETCTTY."); - ioctl(*ttyfd, TCSETCTTY, NULL); - fd = open("/dev/tty", O_RDWR); - if (fd < 0) - error("%.100s: %.100s", ttyname, strerror(errno)); - close(*ttyfd); - *ttyfd = fd; -#else /* _UNICOS */ - - /* First disconnect from the old controlling tty. */ -#ifdef TIOCNOTTY - fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); - if (fd >= 0) { - (void) ioctl(fd, TIOCNOTTY, NULL); - close(fd); - } -#endif /* TIOCNOTTY */ - if (setsid() < 0) - error("setsid: %.100s", strerror(errno)); - - /* - * Verify that we are successfully disconnected from the controlling - * tty. - */ - fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); - if (fd >= 0) { - error("Failed to disconnect from controlling tty."); - close(fd); - } - /* Make it our controlling tty. */ -#ifdef TIOCSCTTY - debug("Setting controlling tty using TIOCSCTTY."); - if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) - error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); -#endif /* TIOCSCTTY */ -#ifdef HAVE_NEWS4 - if (setpgrp(0,0) < 0) - error("SETPGRP %s",strerror(errno)); -#endif /* HAVE_NEWS4 */ -#ifdef USE_VHANGUP - old = mysignal(SIGHUP, SIG_IGN); - vhangup(); - mysignal(SIGHUP, old); -#endif /* USE_VHANGUP */ - fd = open(ttyname, O_RDWR); - if (fd < 0) { - error("%.100s: %.100s", ttyname, strerror(errno)); - } else { -#ifdef USE_VHANGUP - close(*ttyfd); - *ttyfd = fd; -#else /* USE_VHANGUP */ - close(fd); -#endif /* USE_VHANGUP */ - } - /* Verify that we now have a controlling tty. */ - fd = open(_PATH_TTY, O_WRONLY); - if (fd < 0) - error("open /dev/tty failed - could not set controlling tty: %.100s", - strerror(errno)); - else - close(fd); -#endif /* _UNICOS */ -} - -/* Changes the window size associated with the pty. */ - -void -pty_change_window_size(int ptyfd, int row, int col, - int xpixel, int ypixel) -{ - struct winsize w; - - w.ws_row = row; - w.ws_col = col; - w.ws_xpixel = xpixel; - w.ws_ypixel = ypixel; - (void) ioctl(ptyfd, TIOCSWINSZ, &w); -} - -void -pty_setowner(struct passwd *pw, const char *ttyname) -{ - struct group *grp; - gid_t gid; - mode_t mode; - struct stat st; - - /* Determine the group to make the owner of the tty. */ - grp = getgrnam("tty"); - if (grp) { - gid = grp->gr_gid; - mode = S_IRUSR | S_IWUSR | S_IWGRP; - } else { - gid = pw->pw_gid; - mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; - } - - /* - * Change owner and mode of the tty as required. - * Warn but continue if filesystem is read-only and the uids match/ - * tty is owned by root. - */ - if (stat(ttyname, &st)) - fatal("stat(%.100s) failed: %.100s", ttyname, - strerror(errno)); - - if (st.st_uid != pw->pw_uid || st.st_gid != gid) { - if (chown(ttyname, pw->pw_uid, gid) < 0) { - if (errno == EROFS && - (st.st_uid == pw->pw_uid || st.st_uid == 0)) - error("chown(%.100s, %u, %u) failed: %.100s", - ttyname, (u_int)pw->pw_uid, (u_int)gid, - strerror(errno)); - else - fatal("chown(%.100s, %u, %u) failed: %.100s", - ttyname, (u_int)pw->pw_uid, (u_int)gid, - strerror(errno)); - } - } - - if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { - if (chmod(ttyname, mode) < 0) { - if (errno == EROFS && - (st.st_mode & (S_IRGRP | S_IROTH)) == 0) - error("chmod(%.100s, 0%o) failed: %.100s", - ttyname, (int)mode, strerror(errno)); - else - fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, (int)mode, strerror(errno)); - } - } -} diff --git a/usr/src/man/man1/Makefile b/usr/src/man/man1/Makefile index 1a27c9a56d..3307298389 100644 --- a/usr/src/man/man1/Makefile +++ b/usr/src/man/man1/Makefile @@ -355,13 +355,6 @@ MANFILES= acctcom.1 \ spell.1 \ split.1 \ srchtxt.1 \ - ssh.1 \ - ssh-add.1 \ - ssh-agent.1 \ - ssh-http-proxy-connect.1 \ - ssh-keygen.1 \ - ssh-keyscan.1 \ - ssh-socks5-proxy-connect.1 \ strchg.1 \ strings.1 \ strip.1 \ diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile index ea7fe4121d..779f1d8a31 100644 --- a/usr/src/man/man1m/Makefile +++ b/usr/src/man/man1m/Makefile @@ -489,8 +489,6 @@ _MANFILES= 6to4relay.1m \ soconfig.1m \ sppptun.1m \ spray.1m \ - ssh-keysign.1m \ - sshd.1m \ statd.1m \ stmfadm.1m \ stmsboot.1m \ diff --git a/usr/src/man/man4/Makefile b/usr/src/man/man4/Makefile index 4ba45bd662..e9c85801bf 100644 --- a/usr/src/man/man4/Makefile +++ b/usr/src/man/man4/Makefile @@ -188,8 +188,6 @@ _MANFILES= Intro.4 \ sndr.4 \ sock2path.d.4 \ space.4 \ - ssh_config.4 \ - sshd_config.4 \ sulog.4 \ syslog.conf.4 \ system.4 \ |