diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 2000-06-03 06:51:31 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 2000-06-03 06:51:31 +0000 |
commit | dd339e60afd7002b651c69351372be32c03ed904 (patch) | |
tree | 157398787f375a608104936ea7ad3de89bd42bb4 | |
parent | 830ccf58ce63a1bb3529be13d5150cd936030f27 (diff) |
This commit was manufactured by cvs2svn to create tagvendor/openssh/2.1.0-2000-06-03
'openssh-vendor-crypto-v_2_1_0_2000_06_03'.
Notes
Notes:
svn path=/vendor-crypto/openssh/dist/; revision=61197
svn path=/vendor-crypto/openssh/2.1.0-2000-06-03/; revision=61198; tag=vendor/openssh/2.1.0-2000-06-03
120 files changed, 0 insertions, 33489 deletions
diff --git a/crypto/openssh/COPYING.Ylonen b/crypto/openssh/COPYING.Ylonen deleted file mode 100644 index 5e681edd2930..000000000000 --- a/crypto/openssh/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. ] -[ 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/crypto/openssh/Makefile b/crypto/openssh/Makefile deleted file mode 100644 index 668900c3bdd6..000000000000 --- a/crypto/openssh/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# $OpenBSD: Makefile,v 1.5 1999/10/25 20:27:26 markus Exp $ - -.include <bsd.own.mk> - -SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp - -distribution: - install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \ - ${DESTDIR}/etc/ssh_config - install -C -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \ - ${DESTDIR}/etc/sshd_config - -.include <bsd.subdir.mk> diff --git a/crypto/openssh/Makefile.inc b/crypto/openssh/Makefile.inc deleted file mode 100644 index fddf3da2feb0..000000000000 --- a/crypto/openssh/Makefile.inc +++ /dev/null @@ -1,11 +0,0 @@ -CFLAGS+= -I${.CURDIR}/.. - -.include <bsd.obj.mk> - -.if exists(${.CURDIR}/../lib/${__objdir}) -LDADD+= -L${.CURDIR}/../lib/${__objdir} -lssh -DPADD+= ${.CURDIR}/../lib/${__objdir}/libssh.a -.else -LDADD+= -L${.CURDIR}/../lib -lssh -DPADD+= ${.CURDIR}/../lib/libssh.a -.endif diff --git a/crypto/openssh/OVERVIEW b/crypto/openssh/OVERVIEW deleted file mode 100644 index 7f34ac45bdf9..000000000000 --- a/crypto/openssh/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/crypto/openssh/README b/crypto/openssh/README deleted file mode 100644 index 70dd61264148..000000000000 --- a/crypto/openssh/README +++ /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 intended 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/crypto/openssh/README.openssh2 b/crypto/openssh/README.openssh2 deleted file mode 100644 index 12c90aa31690..000000000000 --- a/crypto/openssh/README.openssh2 +++ /dev/null @@ -1,44 +0,0 @@ -$Id: README.openssh2,v 1.8 2000/05/07 18:30:03 markus Exp $ - -howto: - 1) generate server key: - $ ssh-keygen -d -f /etc/ssh_host_dsa_key -N '' - 2) enable ssh2: - server: add 'Protocol 2,1' to /etc/sshd_config - client: ssh -o 'Protocol 2,1', or add to .ssh/config - 3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2) - interop w/ ssh.com dsa-keys: - ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2 - and vice versa - ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub - echo Key mykey.pub >> ~/.ssh2/authorization - -works: - secsh-transport: works w/o rekey - proposal exchange, i.e. different enc/mac/comp per direction - encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc - mac: hmac-md5, hmac-sha1, (hmac-ripemd160) - compression: zlib, none - secsh-userauth: passwd and pubkey with DSA - secsh-connection: pty+shell or command, flow control works (window adjust) - tcp-forwarding: -L works, -R incomplete - x11-fwd - dss/dsa: host key database in ~/.ssh/known_hosts2 - client interops w/ sshd2, lshd - server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0, SecureFX (secure ftp) - server supports multiple concurrent sessions (e.g. with SSH.com Windows client) -todo: - re-keying - secsh-connection features: - tcp-forwarding, agent-fwd - auth other than passwd, and DSA-pubkey: - keyboard-interactive, (PGP-pubkey?) - config - server-auth w/ old host-keys - cleanup - advanced key storage? - keynote - sftp - --markus -$Date: 2000/05/07 18:30:03 $ diff --git a/crypto/openssh/RFC.nroff b/crypto/openssh/RFC.nroff deleted file mode 100644 index dccc954c78b9..000000000000 --- a/crypto/openssh/RFC.nroff +++ /dev/null @@ -1,1780 +0,0 @@ -.\" -*- nroff -*- -.\" -.\" $Id: RFC.nroff,v 1.1 1999/09/26 20:53:32 deraadt Exp $ -.\" -.pl 10.0i -.po 0 -.ll 7.2i -.lt 7.2i -.nr LL 7.2i -.nr LT 7.2i -.ds LF Ylonen -.ds RF FORMFEED[Page %] -.ds CF -.ds LH Internet-Draft -.ds RH 15 November 1995 -.ds CH SSH (Secure Shell) Remote Login Protocol -.na -.hy 0 -.in 0 -Network Working Group T. Ylonen -Internet-Draft Helsinki University of Technology -draft-ylonen-ssh-protocol-00.txt 15 November 1995 -Expires: 15 May 1996 - -.in 3 - -.ce -The SSH (Secure Shell) Remote Login Protocol - -.ti 0 -Status of This Memo - -This document is an Internet-Draft. Internet-Drafts are working -documents of the Internet Engineering Task Force (IETF), its areas, -and its working groups. Note that other groups may also distribute -working documents as Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six -months and may be updated, replaced, or obsoleted by other docu- -ments at any time. It is inappropriate to use Internet-Drafts as -reference material or to cite them other than as ``work in pro- -gress.'' - -To learn the current status of any Internet-Draft, please check the -``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow -Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), -munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or -ftp.isi.edu (US West Coast). - -The distribution of this memo is unlimited. - -.ti 0 -Introduction - -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 networks. Its features include -the following: -.IP o -Closes several security holes (e.g., IP, routing, and DNS spoofing). -New authentication methods: .rhosts together with RSA [RSA] based host -authentication, and pure RSA authentication. -.IP o -All communications are automatically and transparently encrypted. -Encryption is also used to protect integrity. -.IP o -X11 connection forwarding provides secure X11 sessions. -.IP o -Arbitrary TCP/IP ports can be redirected over the encrypted channel -in both directions. -.IP 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). -.IP o -An authentication agent, running in the user's local workstation or -laptop, can be used to hold the user's RSA authentication keys. -.RT - -The goal has been to make the software as easy to use as possible for -ordinary users. The protocol has been designed to be as secure as -possible while making it possible to create implementations that -are easy to use and install. The sample implementation has a number -of convenient features that are not described in this document as they -are not relevant for the protocol. - - -.ti 0 -Overview of the Protocol - -The software consists of a server program running on a server machine, -and a client program running on a client machine (plus a few auxiliary -programs). The machines are connected by an insecure IP [RFC0791] -network (that can be monitored, tampered with, and spoofed by hostile -parties). - -A connection is always initiated by the client side. The server -listens on a specific port waiting for connections. Many clients may -connect to the same server machine. - -The client and the server are connected via a TCP/IP [RFC0793] socket -that is used for bidirectional communication. Other types of -transport can be used but are currently not defined. - -When the client connects the server, the server accepts the connection -and responds by sending back its version identification string. The -client parses the server's identification, and sends its own -identification. The purpose of the identification strings is to -validate that the connection was to the correct port, declare the -protocol version number used, and to declare the software version used -on each side (for debugging purposes). The identification strings are -human-readable. If either side fails to understand or support the -other side's version, it closes the connection. - -After the protocol identification phase, both sides switch to a packet -based binary protocol. The server starts by sending its host key -(every host has an RSA key used to authenticate the host), server key -(an RSA key regenerated every hour), and other information to the -client. The client then generates a 256 bit session key, encrypts it -using both RSA keys (see below for details), and sends the encrypted -session key and selected cipher type to the server. Both sides then -turn on encryption using the selected algorithm and key. The server -sends an encrypted confirmation message to the client. - -The client then authenticates itself using any of a number of -authentication methods. The currently supported authentication -methods are .rhosts or /etc/hosts.equiv authentication (disabled by -default), the same with RSA-based host authentication, RSA -authentication, and password authentication. - -After successful authentication, the client makes a number of requests -to prepare for the session. Typical requests include allocating a -pseudo tty, starting X11 [X11] or TCP/IP port forwarding, starting -authentication agent forwarding, and executing the shell or a command. - -When a shell or command is executed, the connection enters interactive -session mode. In this mode, data is passed in both directions, -new forwarded connections may be opened, etc. The interactive session -normally terminates when the server sends the exit status of the -program to the client. - - -The protocol makes several reservations for future extensibility. -First of all, the initial protocol identification messages include the -protocol version number. Second, the first packet by both sides -includes a protocol flags field, which can be used to agree on -extensions in a compatible manner. Third, the authentication and -session preparation phases work so that the client sends requests to -the server, and the server responds with success or failure. If the -client sends a request that the server does not support, the server -simply returns failure for it. This permits compatible addition of -new authentication methods and preparation operations. The -interactive session phase, on the other hand, works asynchronously and -does not permit the use of any extensions (because there is no easy -and reliable way to signal rejection to the other side and problems -would be hard to debug). Any compatible extensions to this phase must -be agreed upon during any of the earlier phases. - -.ti 0 -The Binary Packet Protocol - -After the protocol identification strings, both sides only send -specially formatted packets. The packet layout is as follows: -.IP o -Packet length: 32 bit unsigned integer, coded as four 8-bit bytes, msb -first. Gives the length of the packet, not including the length field -and padding. The maximum length of a packet (not including the length -field and padding) is 262144 bytes. -.IP o -Padding: 1-8 bytes of random data (or zeroes if not encrypting). The -amount of padding is (8 - (length % 8)) bytes (where % stands for the -modulo operator). The rationale for always having some random padding -at the beginning of each packet is to make known plaintext attacks -more difficult. -.IP o -Packet type: 8-bit unsigned byte. The value 255 is reserved for -future extension. -.IP o -Data: binary data bytes, depending on the packet type. The number of -data bytes is the "length" field minus 5. -.IP o -Check bytes: 32-bit crc, four 8-bit bytes, msb first. The crc is the -Cyclic Redundancy Check, with the polynomial 0xedb88320, of the -Padding, Packet type, and Data fields. The crc is computed before -any encryption. -.RT - -The packet, except for the length field, may be encrypted using any of -a number of algorithms. The length of the encrypted part (Padding + -Type + Data + Check) is always a multiple of 8 bytes. Typically the -cipher is used in a chained mode, with all packets chained together as -if it was a single data stream (the length field is never included in -the encryption process). Details of encryption are described below. - -When the session starts, encryption is turned off. Encryption is -enabled after the client has sent the session key. The encryption -algorithm to use is selected by the client. - - -.ti 0 -Packet Compression - -If compression is supported (it is an optional feature, see -SSH_CMSG_REQUEST_COMPRESSION below), the packet type and data fields -of the packet are compressed using the gzip deflate algorithm [GZIP]. -If compression is in effect, the packet length field indicates the -length of the compressed data, plus 4 for the crc. The amount of -padding is computed from the compressed data, so that the amount of -data to be encrypted becomes a multiple of 8 bytes. - -When compressing, the packets (type + data portions) in each direction -are compressed as if they formed a continuous data stream, with only the -current compression block flushed between packets. This corresponds -to the GNU ZLIB library Z_PARTIAL_FLUSH option. The compression -dictionary is not flushed between packets. The two directions are -compressed independently of each other. - - -.ti 0 -Packet Encryption - -The protocol supports several encryption methods. During session -initialization, the server sends a bitmask of all encryption methods -that it supports, and the client selects one of these methods. The -client also generates a 256-bit random session key (32 8-bit bytes) and -sends it to the server. - -The encryption methods supported by the current implementation, and -their codes are: -.TS -center; -l r l. -SSH_CIPHER_NONE 0 No encryption -SSH_CIPHER_IDEA 1 IDEA in CFB mode -SSH_CIPHER_DES 2 DES in CBC mode -SSH_CIPHER_3DES 3 Triple-DES in CBC mode -SSH_CIPHER_TSS 4 An experimental stream cipher -SSH_CIPHER_RC4 5 RC4 -.TE - -All implementations are required to support SSH_CIPHER_DES and -SSH_CIPHER_3DES. Supporting SSH_CIPHER_IDEA, SSH_CIPHER_RC4, and -SSH_CIPHER_NONE is recommended. Support for SSH_CIPHER_TSS is -optional (and it is not described in this document). Other ciphers -may be added at a later time; support for them is optional. - -For encryption, the encrypted portion of the packet is considered a -linear byte stream. The length of the stream is always a multiple of -8. The encrypted portions of consecutive packets (in the same -direction) are encrypted as if they were a continuous buffer (that is, -any initialization vectors are passed from the previous packet to the -next packet). Data in each direction is encrypted independently. -.IP SSH_CIPHER_DES -The key is taken from the first 8 bytes of the session key. The least -significant bit of each byte is ignored. This results in 56 bits of -key data. DES [DES] is used in CBC mode. The iv (initialization vector) is -initialized to all zeroes. -.IP SSH_CIPHER_3DES -The variant of triple-DES used here works as follows: there are three -independent DES-CBC ciphers, with independent initialization vectors. -The data (the whole encrypted data stream) is first encrypted with the -first cipher, then decrypted with the second cipher, and finally -encrypted with the third cipher. All these operations are performed -in CBC mode. - -The key for the first cipher is taken from the first 8 bytes of the -session key; the key for the next cipher from the next 8 bytes, and -the key for the third cipher from the following 8 bytes. All three -initialization vectors are initialized to zero. - -(Note: the variant of 3DES used here differs from some other -descriptions.) -.IP SSH_CIPHER_IDEA -The key is taken from the first 16 bytes of the session key. IDEA -[IDEA] is used in CFB mode. The initialization vector is initialized -to all zeroes. -.IP SSH_CIPHER_TSS -All 32 bytes of the session key are used as the key. - -There is no reference available for the TSS algorithm; it is currently -only documented in the sample implementation source code. The -security of this cipher is unknown (but it is quite fast). The cipher -is basically a stream cipher that uses MD5 as a random number -generator and takes feedback from the data. -.IP SSH_CIPHER_RC4 -The first 16 bytes of the session key are used as the key for the -server to client direction. The remaining 16 bytes are used as the -key for the client to server direction. This gives independent -128-bit keys for each direction. - -This algorithm is the alleged RC4 cipher posted to the Usenet in 1995. -It is widely believed to be equivalent with the original RSADSI RC4 -cipher. This is a very fast algorithm. -.RT - - -.ti 0 -Data Type Encodings - -The Data field of each packet contains data encoded as described in -this section. There may be several data items; each item is coded as -described here, and their representations are concatenated together -(without any alignment or padding). - -Each data type is stored as follows: -.IP "8-bit byte" -The byte is stored directly as a single byte. -.IP "32-bit unsigned integer" -Stored in 4 bytes, msb first. -.IP "Arbitrary length binary string" -First 4 bytes are the length of the string, msb first (not including -the length itself). The following "length" bytes are the string -value. There are no terminating null characters. -.IP "Multiple-precision integer" -First 2 bytes are the number of bits in the integer, msb first (for -example, the value 0x00012345 would have 17 bits). The value zero has -zero bits. It is permissible that the number of bits be larger than the -real number of bits. - -The number of bits is followed by (bits + 7) / 8 bytes of binary data, -msb first, giving the value of the integer. -.RT - - -.ti 0 -TCP/IP Port Number and Other Options - -The server listens for connections on TCP/IP port 22. - -The client may connect the server from any port. However, if the -client wishes to use any form of .rhosts or /etc/hosts.equiv -authentication, it must connect from a privileged port (less than -1024). - -For the IP Type of Service field [RFC0791], it is recommended that -interactive sessions (those having a user terminal or forwarding X11 -connections) use the IPTOS_LOWDELAY, and non-interactive connections -use IPTOS_THROUGHPUT. - -It is recommended that keepalives are used, because otherwise programs -on the server may never notice if the other end of the connection is -rebooted. - - -.ti 0 -Protocol Version Identification - -After the socket is opened, the server sends an identification string, -which is of the form -"SSH-<protocolmajor>.<protocolminor>-<version>\\n", where -<protocolmajor> and <protocolminor> are integers and specify the -protocol version number (not software distribution version). -<version> is server side software version string (max 40 characters); -it is not interpreted by the remote side but may be useful for -debugging. - -The client parses the server's string, and sends a corresponding -string with its own information in response. If the server has lower -version number, and the client contains special code to emulate it, -the client responds with the lower number; otherwise it responds with -its own number. The server then compares the version number the -client sent with its own, and determines whether they can work -together. The server either disconnects, or sends the first packet -using the binary packet protocol and both sides start working -according to the lower of the protocol versions. - -By convention, changes which keep the protocol compatible with -previous versions keep the same major protocol version; changes that -are not compatible increment the major version (which will hopefully -never happen). The version described in this document is 1.3. - -The client will - -.ti 0 -Key Exchange and Server Host Authentication - -The first message sent by the server using the packet protocol is -SSH_SMSG_PUBLIC_KEY. It declares the server's host key, server public -key, supported ciphers, supported authentication methods, and flags -for protocol extensions. It also contains a 64-bit random number -(cookie) that must be returned in the client's reply (to make IP -spoofing more difficult). No encryption is used for this message. - -Both sides compute a session id as follows. The modulus of the server -key is interpreted as a byte string (without explicit length field, -with minimum length able to hold the whole value), most significant -byte first. This string is concatenated with the server host key -interpreted the same way. Additionally, the cookie is concatenated -with this. Both sides compute MD5 of the resulting string. The -resulting 16 bytes (128 bits) are stored by both parties and are -called the session id. - -The client responds with a SSH_CMSG_SESSION_KEY message, which -contains the selected cipher type, a copy of the 64-bit cookie sent by -the server, client's protocol flags, and a session key encrypted -with both the server's host key and server key. No encryption is used -for this message. - -The session key is 32 8-bit bytes (a total of 256 random bits -generated by the client). The client first xors the 16 bytes of the -session id with the first 16 bytes of the session key. The resulting -string is then encrypted using the smaller key (one with smaller -modulus), and the result is then encrypted using the other key. The -number of bits in the public modulus of the two keys must differ by at -least 128 bits. - -At each encryption step, a multiple-precision integer is constructed -from the data to be encrypted as follows (the integer is here -interpreted as a sequence of bytes, msb first; the number of bytes is -the number of bytes needed to represent the modulus). - -The most significant byte (which is only partial as the value must be -less than the public modulus, which is never a power of two) is zero. - -The next byte contains the value 2 (which stands for public-key -encrypted data in the PKCS standard [PKCS#1]). Then, there are -non-zero random bytes to fill any unused space, a zero byte, and the -data to be encrypted in the least significant bytes, the last byte of -the data in the least significant byte. - -This algorithm is used twice. First, it is used to encrypt the 32 -random bytes generated by the client to be used as the session key -(xored by the session id). This value is converted to an integer as -described above, and encrypted with RSA using the key with the smaller -modulus. The resulting integer is converted to a byte stream, msb -first. This byte stream is padded and encrypted identically using the -key with the larger modulus. - -After the client has sent the session key, it starts to use the -selected algorithm and key for decrypting any received packets, and -for encrypting any sent packets. Separate ciphers are used for -different directions (that is, both directions have separate -initialization vectors or other state for the ciphers). - -When the server has received the session key message, and has turned -on encryption, it sends a SSH_SMSG_SUCCESS message to the client. - -The recommended size of the host key is 1024 bits, and 768 bits for -the server key. The minimum size is 512 bits for the smaller key. - - -.ti 0 -Declaring the User Name - -The client then sends a SSH_CMSG_USER message to the server. This -message specifies the user name to log in as. - -The server validates that such a user exists, checks whether -authentication is needed, and responds with either SSH_SMSG_SUCCESS or -SSH_SMSG_FAILURE. SSH_SMSG_SUCCESS indicates that no authentication -is needed for this user (no password), and authentication phase has -now been completed. SSH_SMSG_FAILURE indicates that authentication is -needed (or the user does not exist). - -If the user does not exist, it is recommended that this returns -failure, but the server keeps reading messages from the client, and -responds to any messages (except SSH_MSG_DISCONNECT, SSH_MSG_IGNORE, -and SSH_MSG_DEBUG) with SSH_SMSG_FAILURE. This way the client cannot -be certain whether the user exists. - - -.ti 0 -Authentication Phase - -Provided the server didn't immediately accept the login, an -authentication exchange begins. The client sends messages to the -server requesting different types of authentication in arbitrary order as -many times as desired (however, the server may close the connection -after a timeout). The server always responds with SSH_SMSG_SUCCESS if -it has accepted the authentication, and with SSH_SMSG_FAILURE if it has -denied authentication with the requested method or it does not -recognize the message. Some authentication methods cause an exchange -of further messages before the final result is sent. The -authentication phase ends when the server responds with success. - -The recommended value for the authentication timeout (timeout before -disconnecting if no successful authentication has been made) is 5 -minutes. - -The following authentication methods are currently supported: -.TS -center; -l r l. -SSH_AUTH_RHOSTS 1 .rhosts or /etc/hosts.equiv -SSH_AUTH_RSA 2 pure RSA authentication -SSH_AUTH_PASSWORD 3 password authentication -SSH_AUTH_RHOSTS_RSA 4 .rhosts with RSA host authentication -.TE -.IP SSH_AUTH_RHOSTS - -This is the authentication method used by rlogin and rsh [RFC1282]. - -The client sends SSH_CMSG_AUTH_RHOSTS with the client-side user name -as an argument. - -The server checks whether to permit authentication. On UNIX systems, -this is usually done by checking /etc/hosts.equiv, and .rhosts in the -user's home directory. The connection must come from a privileged -port. - -It is recommended that the server checks that there are no IP options -(such as source routing) specified for the socket before accepting -this type of authentication. The client host name should be -reverse-mapped and then forward mapped to ensure that it has the -proper IP-address. - -This authentication method trusts the remote host (root on the remote -host can pretend to be any other user on that host), the name -services, and partially the network: anyone who can see packets coming -out from the server machine can do IP-spoofing and pretend to be any -machine; however, the protocol prevents blind IP-spoofing (which used -to be possible with rlogin). - -Many sites probably want to disable this authentication method because -of the fundamental insecurity of conventional .rhosts or -/etc/hosts.equiv authentication when faced with spoofing. It is -recommended that this method not be supported by the server by -default. -.IP SSH_AUTH_RHOSTS_RSA - -In addition to conventional .rhosts and hosts.equiv authentication, -this method additionally requires that the client host be -authenticated using RSA. - -The client sends SSH_CMSG_AUTH_RHOSTS_RSA specifying the client-side -user name, and the public host key of the client host. - -The server first checks if normal .rhosts or /etc/hosts.equiv -authentication would be accepted, and if not, responds with -SSH_SMSG_FAILURE. Otherwise, it checks whether it knows the host key -for the client machine (using the same name for the host that was used -for checking the .rhosts and /etc/hosts.equiv files). If it does not -know the RSA key for the client, access is denied and SSH_SMSG_FAILURE -is sent. - -If the server knows the host key of the client machine, it verifies -that the given host key matches that known for the client. If not, -access is denied and SSH_SMSG_FAILURE is sent. - -The server then sends a SSH_SMSG_AUTH_RSA_CHALLENGE message containing -an encrypted challenge for the client. The challenge is 32 8-bit -random bytes (256 bits). When encrypted, the highest (partial) byte -is left as zero, the next byte contains the value 2, the following are -non-zero random bytes, followed by a zero byte, and the challenge put -in the remaining bytes. This is then encrypted using RSA with the -client host's public key. (The padding and encryption algorithm is -the same as that used for the session key.) - -The client decrypts the challenge using its private host key, -concatenates this with the session id, and computes an MD5 checksum -of the resulting 48 bytes. The MD5 output is returned as 16 bytes in -a SSH_CMSG_AUTH_RSA_RESPONSE message. (MD5 is used to deter chosen -plaintext attacks against RSA; the session id binds it to a specific -session). - -The server verifies that the MD5 of the decrypted challenge returned by -the client matches that of the original value, and sends SSH_SMSG_SUCCESS if -so. Otherwise it sends SSH_SMSG_FAILURE and refuses the -authentication attempt. - -This authentication method trusts the client side machine in that root -on that machine can pretend to be any user on that machine. -Additionally, it trusts the client host key. The name and/or IP -address of the client host is only used to select the public host key. -The same host name is used when scanning .rhosts or /etc/hosts.equiv -and when selecting the host key. It would in principle be possible to -eliminate the host name entirely and substitute it directly by the -host key. IP and/or DNS [RFC1034] spoofing can only be used -to pretend to be a host for which the attacker has the private host -key. -.IP SSH_AUTH_RSA - -The idea behind RSA authentication is that the server recognizes the -public key offered by the client, generates a random challenge, and -encrypts the challenge with the public key. The client must then -prove that it has the corresponding private key by decrypting the -challenge. - -The client sends SSH_CMSG_AUTH_RSA with public key modulus (n) as an -argument. - -The server may respond immediately with SSH_SMSG_FAILURE if it does -not permit authentication with this key. Otherwise it generates a -challenge, encrypts it using the user's public key (stored on the -server and identified using the modulus), and sends -SSH_SMSG_AUTH_RSA_CHALLENGE with the challenge (mp-int) as an -argument. - -The challenge is 32 8-bit random bytes (256 bits). When encrypted, -the highest (partial) byte is left as zero, the next byte contains the -value 2, the following are non-zero random bytes, followed by a zero -byte, and the challenge put in the remaining bytes. This is then -encrypted with the public key. (The padding and encryption algorithm -is the same as that used for the session key.) - -The client decrypts the challenge using its private key, concatenates -it with the session id, and computes an MD5 checksum of the resulting -48 bytes. The MD5 output is returned as 16 bytes in a -SSH_CMSG_AUTH_RSA_RESPONSE message. (Note that the MD5 is necessary -to avoid chosen plaintext attacks against RSA; the session id binds it -to a specific session.) - -The server verifies that the MD5 of the decrypted challenge returned -by the client matches that of the original value, and sends -SSH_SMSG_SUCCESS if so. Otherwise it sends SSH_SMSG_FAILURE and -refuses the authentication attempt. - -This authentication method does not trust the remote host, the -network, name services, or anything else. Authentication is based -solely on the possession of the private identification keys. Anyone -in possession of the private keys can log in, but nobody else. - -The server may have additional requirements for a successful -authentiation. For example, to limit damage due to a compromised RSA -key, a server might restrict access to a limited set of hosts. -.IP SSH_AUTH_PASSWORD - -The client sends a SSH_CMSG_AUTH_PASSWORD message with the plain text -password. (Note that even though the password is plain text inside -the message, it is normally encrypted by the packet mechanism.) - -The server verifies the password, and sends SSH_SMSG_SUCCESS if -authentication was accepted and SSH_SMSG_FAILURE otherwise. - -Note that the password is read from the user by the client; the user -never interacts with a login program. - -This authentication method does not trust the remote host, the -network, name services or anything else. Authentication is based -solely on the possession of the password. Anyone in possession of the -password can log in, but nobody else. -.RT - -.ti 0 -Preparatory Operations - -After successful authentication, the server waits for a request from -the client, processes the request, and responds with SSH_SMSG_SUCCESS -whenever a request has been successfully processed. If it receives a -message that it does not recognize or it fails to honor a request, it -returns SSH_SMSG_FAILURE. It is expected that new message types might -be added to this phase in future. - -The following messages are currently defined for this phase. -.IP SSH_CMSG_REQUEST_COMPRESSION -Requests that compression be enabled for this session. A -gzip-compatible compression level (1-9) is passed as an argument. -.IP SSH_CMSG_REQUEST_PTY -Requests that a pseudo terminal device be allocated for this session. -The user terminal type and terminal modes are supplied as arguments. -.IP SSH_CMSG_X11_REQUEST_FORWARDING -Requests forwarding of X11 connections from the remote machine to the -local machine over the secure channel. Causes an internet-domain -socket to be allocated and the DISPLAY variable to be set on the server. -X11 authentication data is automatically passed to the server, and the -client may implement spoofing of authentication data for added -security. The authentication data is passed as arguments. -.IP SSH_CMSG_PORT_FORWARD_REQUEST -Requests forwarding of a TCP/IP port on the server host over the -secure channel. What happens is that whenever a connection is made to -the port on the server, a connection will be made from the client end -to the specified host/port. Any user can forward unprivileged ports; -only the root can forward privileged ports (as determined by -authentication done earlier). -.IP SSH_CMSG_AGENT_REQUEST_FORWARDING -Requests forwarding of the connection to the authentication agent. -.IP SSH_CMSG_EXEC_SHELL -Starts a shell (command interpreter) for the user, and moves into -interactive session mode. -.IP SSH_CMSG_EXEC_CMD -Executes the given command (actually "<shell> -c <command>" or -equivalent) for the user, and moves into interactive session mode. -.RT - - -.ti 0 -Interactive Session and Exchange of Data - -During the interactive session, any data written by the shell or -command running on the server machine is forwarded to stdin or -stderr on the client machine, and any input available from stdin on -the client machine is forwarded to the program on the server machine. - -All exchange is asynchronous; either side can send at any time, and -there are no acknowledgements (TCP/IP already provides reliable -transport, and the packet protocol protects against tampering or IP -spoofing). - -When the client receives EOF from its standard input, it will send -SSH_CMSG_EOF; however, this in no way terminates the exchange. The -exchange terminates and interactive mode is left when the server sends -SSH_SMSG_EXITSTATUS to indicate that the client program has -terminated. Alternatively, either side may disconnect at any time by -sending SSH_MSG_DISCONNECT or closing the connection. - -The server may send any of the following messages: -.IP SSH_SMSG_STDOUT_DATA -Data written to stdout by the program running on the server. The data -is passed as a string argument. The client writes this data to -stdout. -.IP SSH_SMSG_STDERR_DATA -Data written to stderr by the program running on the server. The data -is passed as a string argument. The client writes this data to -stderr. (Note that if the program is running on a tty, it is not -possible to separate stdout and stderr data, and all data will be sent -as stdout data.) -.IP SSH_SMSG_EXITSTATUS -Indicates that the shell or command has exited. Exit status is passed -as an integer argument. This message causes termination of the -interactive session. -.IP SSH_SMSG_AGENT_OPEN -Indicates that someone on the server side is requesting a connection -to the authentication agent. The server-side channel number is passed -as an argument. The client must respond with either -SSH_CHANNEL_OPEN_CONFIRMATION or SSH_CHANNEL_OPEN_FAILURE. -.IP SSH_SMSG_X11_OPEN -Indicates that a connection has been made to the X11 socket on the -server side and should be forwarded to the real X server. An integer -argument indicates the channel number allocated for this connection on -the server side. The client should send back either -SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with -the same server side channel number. -.IP SSH_MSG_PORT_OPEN -Indicates that a connection has been made to a port on the server side -for which forwarding has been requested. Arguments are server side -channel number, host name to connect to, and port to connect to. The -client should send back either -SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with -the same server side channel number. -.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION -This is sent by the server to indicate that it has opened a connection -as requested in a previous message. The first argument indicates the -client side channel number, and the second argument is the channel number -that the server has allocated for this connection. -.IP SSH_MSG_CHANNEL_OPEN_FAILURE -This is sent by the server to indicate that it failed to open a -connection as requested in a previous message. The client-side -channel number is passed as an argument. The client will close the -descriptor associated with the channel and free the channel. -.IP SSH_MSG_CHANNEL_DATA -This packet contains data for a channel from the server. The first -argument is the client-side channel number, and the second argument (a -string) is the data. -.IP SSH_MSG_CHANNEL_CLOSE -This is sent by the server to indicate that whoever was in the other -end of the channel has closed it. The argument is the client side channel -number. The client will let all buffered data in the channel to -drain, and when ready, will close the socket, free the channel, and -send the server a SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the -channel. -.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION -This is send by the server to indicate that a channel previously -closed by the client has now been closed on the server side as well. -The argument indicates the client channel number. The client frees -the channel. -.RT - -The client may send any of the following messages: -.IP SSH_CMSG_STDIN_DATA -This is data to be sent as input to the program running on the server. -The data is passed as a string. -.IP SSH_CMSG_EOF -Indicates that the client has encountered EOF while reading standard -input. The server will allow any buffered input data to drain, and -will then close the input to the program. -.IP SSH_CMSG_WINDOW_SIZE -Indicates that window size on the client has been changed. The server -updates the window size of the tty and causes SIGWINCH to be sent to -the program. The new window size is passed as four integer arguments: -row, col, xpixel, ypixel. -.IP SSH_MSG_PORT_OPEN -Indicates that a connection has been made to a port on the client side -for which forwarding has been requested. Arguments are client side -channel number, host name to connect to, and port to connect to. The -server should send back either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or -SSH_MSG_CHANNEL_OPEN_FAILURE with the same client side channel number. -.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION -This is sent by the client to indicate that it has opened a connection -as requested in a previous message. The first argument indicates the -server side channel number, and the second argument is the channel -number that the client has allocated for this connection. -.IP SSH_MSG_CHANNEL_OPEN_FAILURE -This is sent by the client to indicate that it failed to open a -connection as requested in a previous message. The server side -channel number is passed as an argument. The server will close the -descriptor associated with the channel and free the channel. -.IP SSH_MSG_CHANNEL_DATA -This packet contains data for a channel from the client. The first -argument is the server side channel number, and the second argument (a -string) is the data. -.IP SSH_MSG_CHANNEL_CLOSE -This is sent by the client to indicate that whoever was in the other -end of the channel has closed it. The argument is the server channel -number. The server will allow buffered data to drain, and when ready, -will close the socket, free the channel, and send the client a -SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the channel. -.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION -This is send by the client to indicate that a channel previously -closed by the server has now been closed on the client side as well. -The argument indicates the server channel number. The server frees -the channel. -.RT - -Any unsupported messages during interactive mode cause the connection -to be terminated with SSH_MSG_DISCONNECT and an error message. -Compatible protocol upgrades should agree about any extensions during -the preparation phase or earlier. - - -.ti 0 -Termination of the Connection - -Normal termination of the connection is always initiated by the server -by sending SSH_SMSG_EXITSTATUS after the program has exited. The -client responds to this message by sending SSH_CMSG_EXIT_CONFIRMATION -and closes the socket; the server then closes the socket. There are -two purposes for the confirmation: some systems may lose previously -sent data when the socket is closed, and closing the client side first -causes any TCP/IP TIME_WAIT [RFC0793] waits to occur on the client side, not -consuming server resources. - -If the program terminates due to a signal, the server will send -SSH_MSG_DISCONNECT with an appropriate message. If the connection is -closed, all file descriptors to the program will be closed and the -server will exit. If the program runs on a tty, the kernel sends it -the SIGHUP signal when the pty master side is closed. - -.ti 0 -Protocol Flags - -Both the server and the client pass 32 bits of protocol flags to the -other side. The flags are intended for compatible protocol extension; -the server first announces which added capabilities it supports, and -the client then sends the capabilities that it supports. - -The following flags are currently defined (the values are bit masks): -.IP "1 SSH_PROTOFLAG_SCREEN_NUMBER" -This flag can only be sent by the client. It indicates that the X11 -forwarding requests it sends will include the screen number. -.IP "2 SSH_PROTOFLAG_HOST_IN_FWD_OPEN" -If both sides specify this flag, SSH_SMSG_X11_OPEN and -SSH_MSG_PORT_OPEN messages will contain an additional field containing -a description of the host at the other end of the connection. -.RT - -.ti 0 -Detailed Description of Packet Types and Formats - -The supported packet types and the corresponding message numbers are -given in the following table. Messages with _MSG_ in their name may -be sent by either side. Messages with _CMSG_ are only sent by the -client, and messages with _SMSG_ only by the server. - -A packet may contain additional data after the arguments specified -below. Any such data should be ignored by the receiver. However, it -is recommended that no such data be stored without good reason. (This -helps build compatible extensions.) -.IP "0 SSH_MSG_NONE" -This code is reserved. This message type is never sent. -.IP "1 SSH_MSG_DISCONNECT" -.TS -; -l l. -string Cause of disconnection -.TE -This message may be sent by either party at any time. It causes the -immediate disconnection of the connection. The message is intended to -be displayed to a human, and describes the reason for disconnection. -.IP "2 SSH_SMSG_PUBLIC_KEY" -.TS -; -l l. -8 bytes anti_spoofing_cookie -32-bit int server_key_bits -mp-int server_key_public_exponent -mp-int server_key_public_modulus -32-bit int host_key_bits -mp-int host_key_public_exponent -mp-int host_key_public_modulus -32-bit int protocol_flags -32-bit int supported_ciphers_mask -32-bit int supported_authentications_mask -.TE -Sent as the first message by the server. This message gives the -server's host key, server key, protocol flags (intended for compatible -protocol extension), supported_ciphers_mask (which is the -bitwise or of (1 << cipher_number), where << is the left shift -operator, for all supported ciphers), and -supported_authentications_mask (which is the bitwise or of (1 << -authentication_type) for all supported authentication types). The -anti_spoofing_cookie is 64 random bytes, and must be sent back -verbatim by the client in its reply. It is used to make IP-spoofing -more difficult (encryption and host keys are the real defense against -spoofing). -.IP "3 SSH_CMSG_SESSION_KEY" -.TS -; -l l. -1 byte cipher_type (must be one of the supported values) -8 bytes anti_spoofing_cookie (must match data sent by the server) -mp-int double-encrypted session key -32-bit int protocol_flags -.TE -Sent by the client as the first message in the session. Selects the -cipher to use, and sends the encrypted session key to the server. The -anti_spoofing_cookie must be the same bytes that were sent by the -server. Protocol_flags is intended for negotiating compatible -protocol extensions. -.IP "4 SSH_CMSG_USER" -.TS -; -l l. -string user login name on server -.TE -Sent by the client to begin authentication. Specifies the user name -on the server to log in as. The server responds with SSH_SMSG_SUCCESS -if no authentication is needed for this user, or SSH_SMSG_FAILURE if -authentication is needed (or the user does not exist). [Note to the -implementator: the user name is of arbitrary size. The implementation -must be careful not to overflow internal buffers.] -.IP "5 SSH_CMSG_AUTH_RHOSTS" -.TS -; -l l. -string client-side user name -.TE -Requests authentication using /etc/hosts.equiv and .rhosts (or -equivalent mechanisms). This authentication method is normally -disabled in the server because it is not secure (but this is the -method used by rsh and rlogin). The server responds with -SSH_SMSG_SUCCESS if authentication was successful, and -SSH_SMSG_FAILURE if access was not granted. The server should check -that the client side port number is less than 1024 (a privileged -port), and immediately reject authentication if it is not. Supporting -this authentication method is optional. This method should normally -not be enabled in the server because it is not safe. (However, not -enabling this only helps if rlogind and rshd are disabled.) -.IP "6 SSH_CMSG_AUTH_RSA" -.TS -; -l l. -mp-int identity_public_modulus -.TE -Requests authentication using pure RSA authentication. The server -checks if the given key is permitted to log in, and if so, responds -with SSH_SMSG_AUTH_RSA_CHALLENGE. Otherwise, it responds with -SSH_SMSG_FAILURE. The client often tries several different keys in -sequence until one supported by the server is found. Authentication -is accepted if the client gives the correct response to the challenge. -The server is free to add other criteria for authentication, such as a -requirement that the connection must come from a certain host. Such -additions are not visible at the protocol level. Supporting this -authentication method is optional but recommended. -.IP "7 SSH_SMSG_AUTH_RSA_CHALLENGE" -.TS -; -l l. -mp-int encrypted challenge -.TE -Presents an RSA authentication challenge to the client. The challenge -is a 256-bit random value encrypted as described elsewhere in this -document. The client must decrypt the challenge using the RSA private -key, compute MD5 of the challenge plus session id, and send back the -resulting 16 bytes using SSH_CMSG_AUTH_RSA_RESPONSE. -.IP "8 SSH_CMSG_AUTH_RSA_RESPONSE" -.TS -; -l l. -16 bytes MD5 of decrypted challenge -.TE -This message is sent by the client in response to an RSA challenge. -The MD5 checksum is returned instead of the decrypted challenge to -deter known-plaintext attacks against the RSA key. The server -responds to this message with either SSH_SMSG_SUCCESS or -SSH_SMSG_FAILURE. -.IP "9 SSH_CMSG_AUTH_PASSWORD" -.TS -; -l l. -string plain text password -.TE -Requests password authentication using the given password. Note that -even though the password is plain text inside the packet, the whole -packet is normally encrypted by the packet layer. It would not be -possible for the client to perform password encryption/hashing, -because it cannot know which kind of encryption/hashing, if any, the -server uses. The server responds to this message with -SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE. -.IP "10 SSH_CMSG_REQUEST_PTY" -.TS -; -l l. -string TERM environment variable value (e.g. vt100) -32-bit int terminal height, rows (e.g., 24) -32-bit int terminal width, columns (e.g., 80) -32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) -32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) -n bytes tty modes encoded in binary -.TE -Requests a pseudo-terminal to be allocated for this command. This -message can be used regardless of whether the session will later -execute the shell or a command. If a pty has been requested with this -message, the shell or command will run on a pty. Otherwise it will -communicate with the server using pipes, sockets or some other similar -mechanism. - -The terminal type gives the type of the user's terminal. In the UNIX -environment it is passed to the shell or command in the TERM -environment variable. - -The width and height values give the initial size of the user's -terminal or window. All values can be zero if not supported by the -operating system. The server will pass these values to the kernel if -supported. - -Terminal modes are encoded into a byte stream in a portable format. -The exact format is described later in this document. - -The server responds to the request with either SSH_SMSG_SUCCESS or -SSH_SMSG_FAILURE. If the server does not have the concept of pseudo -terminals, it should return success if it is possible to execute a -shell or a command so that it looks to the client as if it was running -on a pseudo terminal. -.IP "11 SSH_CMSG_WINDOW_SIZE" -.TS -; -l l. -32-bit int terminal height, rows -32-bit int terminal width, columns -32-bit int terminal width, pixels -32-bit int terminal height, pixels -.TE -This message can only be sent by the client during the interactive -session. This indicates that the size of the user's window has -changed, and provides the new size. The server will update the -kernel's notion of the window size, and a SIGWINCH signal or -equivalent will be sent to the shell or command (if supported by the -operating system). -.IP "12 SSH_CMSG_EXEC_SHELL" - -(no arguments) - -Starts a shell (command interpreter), and enters interactive session -mode. -.IP "13 SSH_CMSG_EXEC_CMD" -.TS -; -l l. -string command to execute -.TE -Starts executing the given command, and enters interactive session -mode. On UNIX, the command is run as "<shell> -c <command>", where -<shell> is the user's login shell. -.IP "14 SSH_SMSG_SUCCESS" - -(no arguments) - -This message is sent by the server in response to the session key, a -successful authentication request, and a successfully completed -preparatory operation. -.IP "15 SSH_SMSG_FAILURE" - -(no arguments) - -This message is sent by the server in response to a failed -authentication operation to indicate that the user has not yet been -successfully authenticated, and in response to a failed preparatory -operation. This is also sent in response to an authentication or -preparatory operation request that is not recognized or supported. -.IP "16 SSH_CMSG_STDIN_DATA" -.TS -; -l l. -string data -.TE -Delivers data from the client to be supplied as input to the shell or -program running on the server side. This message can only be used in -the interactive session mode. No acknowledgement is sent for this -message. -.IP "17 SSH_SMSG_STDOUT_DATA" -.TS -; -l l. -string data -.TE -Delivers data from the server that was read from the standard output of -the shell or program running on the server side. This message can -only be used in the interactive session mode. No acknowledgement is -sent for this message. -.IP "18 SSH_SMSG_STDERR_DATA" -.TS -; -l l. -string data -.TE -Delivers data from the server that was read from the standard error of -the shell or program running on the server side. This message can -only be used in the interactive session mode. No acknowledgement is -sent for this message. -.IP "19 SSH_CMSG_EOF" - -(no arguments) - -This message is sent by the client to indicate that EOF has been -reached on the input. Upon receiving this message, and after all -buffered input data has been sent to the shell or program, the server -will close the input file descriptor to the program. This message can -only be used in the interactive session mode. No acknowledgement is -sent for this message. -.IP "20 SSH_SMSG_EXITSTATUS" -.TS -; -l l. -32-bit int exit status of the command -.TE -Returns the exit status of the shell or program after it has exited. -The client should respond with SSH_CMSG_EXIT_CONFIRMATION when it has -received this message. This will be the last message sent by the -server. If the program being executed dies with a signal instead of -exiting normally, the server should terminate the session with -SSH_MSG_DISCONNECT (which can be used to pass a human-readable string -indicating that the program died due to a signal) instead of using -this message. -.IP "21 SSH_MSG_CHANNEL_OPEN_CONFIRMATION" -.TS -; -l l. -32-bit int remote_channel -32-bit int local_channel -.TE -This is sent in response to any channel open request if the channel -has been successfully opened. Remote_channel is the channel number -received in the initial open request; local_channel is the channel -number the side sending this message has allocated for the channel. -Data can be transmitted on the channel after this message. -.IP "22 SSH_MSG_CHANNEL_OPEN_FAILURE" -.TS -; -l l. -32-bit int remote_channel -.TE -This message indicates that an earlier channel open request by the -other side has failed or has been denied. Remote_channel is the -channel number given in the original request. -.IP "23 SSH_MSG_CHANNEL_DATA" -.TS -; -l l. -32-bit int remote_channel -string data -.TE -Data is transmitted in a channel in these messages. A channel is -bidirectional, and both sides can send these messages. There is no -acknowledgement for these messages. It is possible that either side -receives these messages after it has sent SSH_MSG_CHANNEL_CLOSE for -the channel. These messages cannot be received after the party has -sent or received SSH_MSG_CHANNEL_CLOSE_CONFIRMATION. -.IP "24 SSH_MSG_CHANNEL_CLOSE" -.TS -; -l l. -32-bit int remote_channel -.TE -When a channel is closed at one end of the connection, that side sends -this message. Upon receiving this message, the channel should be -closed. When this message is received, if the channel is already -closed (the receiving side has sent this message for the same channel -earlier), the channel is freed and no further action is taken; -otherwise the channel is freed and SSH_MSG_CHANNEL_CLOSE_CONFIRMATION -is sent in response. (It is possible that the channel is closed -simultaneously at both ends.) -.IP "25 SSH_MSG_CHANNEL_CLOSE_CONFIRMATION" -.TS -; -l l. -32-bit int remote_channel -.TE -This message is sent in response to SSH_MSG_CHANNEL_CLOSE unless the -channel was already closed. When this message is sent or received, -the channel is freed. -.IP "26 (OBSOLETED; was unix-domain X11 forwarding) -.IP "27 SSH_SMSG_X11_OPEN" -.TS -; -l l. -32-bit int local_channel -string originator_string (see below) -.TE -This message can be sent by the server during the interactive session -mode to indicate that a client has connected the fake X server. -Local_channel is the channel number that the server has allocated for -the connection. The client should try to open a connection to the -real X server, and respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or -SSH_MSG_CHANNEL_OPEN_FAILURE. - -The field originator_string is present if both sides -specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It -contains a description of the host originating the connection. -.IP "28 SSH_CMSG_PORT_FORWARD_REQUEST" -.TS -; -l l. -32-bit int server_port -string host_to_connect -32-bit int port_to_connect -.TE -Sent by the client in the preparatory phase, this message requests -that server_port on the server machine be forwarded over the secure -channel to the client machine, and from there to the specified host -and port. The server should start listening on the port, and send -SSH_MSG_PORT_OPEN whenever a connection is made to it. Supporting -this message is optional, and the server is free to reject any forward -request. For example, it is highly recommended that unless the user -has been authenticated as root, forwarding any privileged port numbers -(below 1024) is denied. -.IP "29 SSH_MSG_PORT_OPEN" -.TS -; -l l. -32-bit int local_channel -string host_name -32-bit int port -string originator_string (see below) -.TE -Sent by either party in interactive session mode, this message -indicates that a connection has been opened to a forwarded TCP/IP -port. Local_channel is the channel number that the sending party has -allocated for the connection. Host_name is the host the connection -should be be forwarded to, and the port is the port on that host to -connect. The receiving party should open the connection, and respond -with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or -SSH_MSG_CHANNEL_OPEN_FAILURE. It is recommended that the receiving -side check the host_name and port for validity to avoid compromising -local security by compromised remote side software. Particularly, it -is recommended that the client permit connections only to those ports -for which it has requested forwarding with SSH_CMSG_PORT_FORWARD_REQUEST. - -The field originator_string is present if both sides -specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It -contains a description of the host originating the connection. -.IP "30 SSH_CMSG_AGENT_REQUEST_FORWARDING" - -(no arguments) - -Requests that the connection to the authentication agent be forwarded -over the secure channel. The method used by clients to contact the -authentication agent within each machine is implementation and machine -dependent. If the server accepts this request, it should arrange that -any clients run from this session will actually contact the server -program when they try to contact the authentication agent. The server -should then send a SSH_SMSG_AGENT_OPEN to open a channel to the agent, -and the client should forward the connection to the real -authentication agent. Supporting this message is optional. -.IP "31 SSH_SMSG_AGENT_OPEN" -.TS -; -l l. -32-bit int local_channel -.TE -Sent by the server in interactive session mode, this message requests -opening a channel to the authentication agent. The client should open -a channel, and respond with either SSH_MSG_CHANNEL_OPEN_CONFIRMATION -or SSH_MSG_CHANNEL_OPEN_FAILURE. -.IP "32 SSH_MSG_IGNORE" -.TS -; -l l. -string data -.TE -Either party may send this message at any time. This message, and the -argument string, is silently ignored. This message might be used in -some implementations to make traffic analysis more difficult. This -message is not currently sent by the implementation, but all -implementations are required to recognize and ignore it. -.IP "33 SSH_CMSG_EXIT_CONFIRMATION" - -(no arguments) - -Sent by the client in response to SSH_SMSG_EXITSTATUS. This is the -last message sent by the client. -.IP "34 SSH_CMSG_X11_REQUEST_FORWARDING" -.TS -; -l l. -string x11_authentication_protocol -string x11_authentication_data -32-bit int screen number (if SSH_PROTOFLAG_SCREEN_NUMBER) -.TE -Sent by the client during the preparatory phase, this message requests -that the server create a fake X11 display and set the DISPLAY -environment variable accordingly. An internet-domain display is -preferable. The given authentication protocol and the associated data -should be recorded by the server so that it is used as authentication -on connections (e.g., in .Xauthority). The authentication protocol -must be one of the supported X11 authentication protocols, e.g., -"MIT-MAGIC-COOKIE-1". Authentication data must be a lowercase hex -string of even length. Its interpretation is protocol dependent. -The data is in a format that can be used with e.g. the xauth program. -Supporting this message is optional. - -The client is permitted (and recommended) to generate fake -authentication information and send fake information to the server. -This way, a corrupt server will not have access to the user's terminal -after the connection has terminated. The correct authorization codes -will also not be left hanging around in files on the server (many -users keep the same X session for months, thus protecting the -authorization data becomes important). - -X11 authentication spoofing works by initially sending fake (random) -authentication data to the server, and interpreting the first packet -sent by the X11 client after the connection has been opened. The -first packet contains the client's authentication. If the packet -contains the correct fake data, it is replaced by the client by the -correct authentication data, and then sent to the X server. -.IP "35 SSH_CMSG_AUTH_RHOSTS_RSA" -.TS -; -l l. -string clint-side user name -32-bit int client_host_key_bits -mp-int client_host_key_public_exponent -mp-int client_host_key_public_modulus -.TE -Requests authentication using /etc/hosts.equiv and .rhosts (or -equivalent) together with RSA host authentication. The server should -check that the client side port number is less than 1024 (a privileged -port), and immediately reject authentication if it is not. The server -responds with SSH_SMSG_FAILURE or SSH_SMSG_AUTH_RSA_CHALLENGE. The -client must respond to the challenge with the proper -SSH_CMSG_AUTH_RSA_RESPONSE. The server then responds with success if -access was granted, or failure if the client gave a wrong response. -Supporting this authentication method is optional but recommended in -most environments. -.IP "36 SSH_MSG_DEBUG" -.TS -; -l l. -string debugging message sent to the other side -.TE -This message may be sent by either party at any time. It is used to -send debugging messages that may be informative to the user in -solving various problems. For example, if authentication fails -because of some configuration error (e.g., incorrect permissions for -some file), it can be very helpful for the user to make the cause of -failure available. On the other hand, one should not make too much -information available for security reasons. It is recommended that -the client provides an option to display the debugging information -sent by the sender (the user probably does not want to see it by default). -The server can log debugging data sent by the client (if any). Either -party is free to ignore any received debugging data. Every -implementation must be able to receive this message, but no -implementation is required to send these. -.IP "37 SSH_CMSG_REQUEST_COMPRESSION" -.TS -; -l l. -32-bit int gzip compression level (1-9) -.TE -This message can be sent by the client in the preparatory operations -phase. The server responds with SSH_SMSG_FAILURE if it does not -support compression or does not want to compress; it responds with -SSH_SMSG_SUCCESS if it accepted the compression request. In the -latter case the response to this packet will still be uncompressed, -but all further packets in either direction will be compressed by gzip. -.RT - - -.ti 0 -Encoding of Terminal Modes - -Terminal modes (as passed in SSH_CMSG_REQUEST_PTY) are encoded into a -byte stream. It is intended that the coding be portable across -different environments. - -The tty mode description is a stream of bytes. The stream consists of -opcode-argument pairs. It is terminated by opcode TTY_OP_END (0). -Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have 32-bit -integer arguments (stored msb first). Opcodes 160-255 are not yet -defined, and cause parsing to stop (they should only be used after any -other data). - -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 -[POSIX] tty interface. The protocol can support other systems as -well, but the client may need to fill reasonable values for a number -of parameters so the server pty gets set to a reasonable mode (the -server leaves all unspecified mode bits in their default values, and -only some combinations make sense). - -The following opcodes have been defined. The naming of opcodes mostly -follows the POSIX terminal mode flags. -.IP "0 TTY_OP_END" -Indicates end of options. -.IP "1 VINTR" -Interrupt character; 255 if none. Similarly for the other characters. -Not all of these characters are supported on all systems. -.IP "2 VQUIT" -The quit character (sends SIGQUIT signal on UNIX systems). -.IP "3 VERASE" -Erase the character to left of the cursor. -.IP "4 VKILL" -Kill the current input line. -.IP "5 VEOF " -End-of-file character (sends EOF from the terminal). -.IP "6 VEOL " -End-of-line character in addition to carriage return and/or linefeed. -.IP "7 VEOL2" -Additional end-of-line character. -.IP "8 VSTART" -Continues paused output (normally ^Q). -.IP "9 VSTOP" -Pauses output (^S). -.IP "10 VSUSP" -Suspends the current program. -.IP "11 VDSUSP" -Another suspend character. -.IP "12 VREPRINT" -Reprints the current input line. -.IP "13 VWERASE" -Erases a word left of cursor. -.IP "14 VLNEXT" -More special input characters; these are probably not supported on -most systems. -.IP "15 VFLUSH" -.IP "16 VSWTCH" -.IP "17 VSTATUS" -.IP "18 VDISCARD" - -.IP "30 IGNPAR" -The ignore parity flag. The next byte should be 0 if this flag is not -set, and 1 if it is set. -.IP "31 PARMRK" -More flags. The exact definitions can be found in the POSIX standard. -.IP "32 INPCK" -.IP "33 ISTRIP" -.IP "34 INLCR" -.IP "35 IGNCR" -.IP "36 ICRNL" -.IP "37 IUCLC" -.IP "38 IXON" -.IP "39 IXANY" -.IP "40 IXOFF" -.IP "41 IMAXBEL" - -.IP "50 ISIG" -.IP "51 ICANON" -.IP "52 XCASE" -.IP "53 ECHO" -.IP "54 ECHOE" -.IP "55 ECHOK" -.IP "56 ECHONL" -.IP "57 NOFLSH" -.IP "58 TOSTOP" -.IP "59 IEXTEN" -.IP "60 ECHOCTL" -.IP "61 ECHOKE" -.IP "62 PENDIN" - -.IP "70 OPOST" -.IP "71 OLCUC" -.IP "72 ONLCR" -.IP "73 OCRNL" -.IP "74 ONOCR" -.IP "75 ONLRET" - -.IP "90 CS7" -.IP "91 CS8" -.IP "92 PARENB" -.IP "93 PARODD" - -.IP "192 TTY_OP_ISPEED" -Specifies the input baud rate in bits per second. -.IP "193 TTY_OP_OSPEED" -Specifies the output baud rate in bits per second. -.RT - - -.ti 0 -The Authentication Agent Protocol - -The authentication agent is a program that can be used to hold RSA -authentication keys for the user (in future, it might hold data for -other authentication types as well). An authorized program can send -requests to the agent to generate a proper response to an RSA -challenge. How the connection is made to the agent (or its -representative) inside a host and how access control is done inside a -host is implementation-dependent; however, how it is forwarded and how -one interacts with it is specified in this protocol. The connection -to the agent is normally automatically forwarded over the secure -channel. - -A program that wishes to use the agent first opens a connection to its -local representative (typically, the agent itself or an SSH server). -It then writes a request to the connection, and waits for response. -It is recommended that at least five minutes of timeout are provided -waiting for the agent to respond to an authentication challenge (this -gives sufficient time for the user to cut-and-paste the challenge to a -separate machine, perform the computation there, and cut-and-paste the -result back if so desired). - -Messages sent to and by the agent are in the following format: -.TS -; -l l. -4 bytes Length, msb first. Does not include length itself. -1 byte Packet type. The value 255 is reserved for future extensions. -data Any data, depending on packet type. Encoding as in the ssh packet -protocol. -.TE - -The following message types are currently defined: -.IP "1 SSH_AGENTC_REQUEST_RSA_IDENTITIES" - -(no arguments) - -Requests the agent to send a list of all RSA keys for which it can -answer a challenge. -.IP "2 SSH_AGENT_RSA_IDENTITIES_ANSWER" -.TS -; -l l. -32-bit int howmany -howmany times: -32-bit int bits -mp-int public exponent -mp-int public modulus -string comment -.TE -The agent sends this message in response to the to -SSH_AGENTC_REQUEST_RSA_IDENTITIES. The answer lists all RSA keys for -which the agent can answer a challenge. The comment field is intended -to help identify each key; it may be printed by an application to -indicate which key is being used. If the agent is not holding any -keys, howmany will be zero. -.IP "3 SSH_AGENTC_RSA_CHALLENGE -.TS -; -l l. -32-bit int bits -mp-int public exponent -mp-int public modulus -mp-int challenge -16 bytes session_id -32-bit int response_type -.TE -Requests RSA decryption of random challenge to authenticate the other -side. The challenge will be decrypted with the RSA private key -corresponding to the given public key. - -The decrypted challenge must contain a zero in the highest (partial) -byte, 2 in the next byte, followed by non-zero random bytes, a zero -byte, and then the real challenge value in the lowermost bytes. The -real challenge must be 32 8-bit bytes (256 bits). - -Response_type indicates the format of the response to be returned. -Currently the only supported value is 1, which means to compute MD5 of -the real challenge plus session id, and return the resulting 16 bytes -in a SSH_AGENT_RSA_RESPONSE message. -.IP "4 SSH_AGENT_RSA_RESPONSE" -.TS -; -l l. -16 bytes MD5 of decrypted challenge -.TE -Answers an RSA authentication challenge. The response is 16 bytes: -the MD5 checksum of the 32-byte challenge. -.IP "5 SSH_AGENT_FAILURE" - -(no arguments) - -This message is sent whenever the agent fails to answer a request -properly. For example, if the agent cannot answer a challenge (e.g., -no longer has the proper key), it can respond with this. The agent -also responds with this message if it receives a message it does not -recognize. -.IP "6 SSH_AGENT_SUCCESS" - -(no arguments) - -This message is sent by the agent as a response to certain requests -that do not otherwise cause a message be sent. Currently, this is -only sent in response to SSH_AGENTC_ADD_RSA_IDENTITY and -SSH_AGENTC_REMOVE_RSA_IDENTITY. -.IP "7 SSH_AGENTC_ADD_RSA_IDENTITY" -.TS -; -l l. -32-bit int bits -mp-int public modulus -mp-int public exponent -mp-int private exponent -mp-int multiplicative inverse of p mod q -mp-int p -mp-int q -string comment -.TE -Registers an RSA key with the agent. After this request, the agent can -use this RSA key to answer requests. The agent responds with -SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. -.IP "8 SSH_AGENT_REMOVE_RSA_IDENTITY" -.TS -; -l l. -32-bit int bits -mp-int public exponent -mp-int public modulus -.TE -Removes an RSA key from the agent. The agent will no longer accept -challenges for this key and will not list it as a supported identity. -The agent responds with SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. -.RT - -If the agent receives a message that it does not understand, it -responds with SSH_AGENT_FAILURE. This permits compatible future -extensions. - -It is possible that several clients have a connection open to the -authentication agent simultaneously. Each client will use a separate -connection (thus, any SSH connection can have multiple agent -connections active simultaneously). - - -.ti 0 -References - -.IP "[DES] " -FIPS PUB 46-1: Data Encryption Standard. National Bureau of -Standards, January 1988. FIPS PUB 81: DES Modes of Operation. -National Bureau of Standards, December 1980. Bruce Schneier: Applied -Cryptography. John Wiley & Sons, 1994. J. Seberry and J. Pieprzyk: -Cryptography: An Introduction to Computer Security. Prentice-Hall, -1989. -.IP "[GZIP] " -The GNU GZIP program; available for anonymous ftp at prep.ai.mit.edu. -Please let me know if you know a paper describing the algorithm. -.IP "[IDEA] " -Xuejia Lai: On the Design and Security of Block Ciphers, ETH Series in -Information Processing, vol. 1, Hartung-Gorre Verlag, Konstanz, -Switzerland, 1992. Bruce Schneier: Applied Cryptography, John Wiley & -Sons, 1994. See also the following patents: PCT/CH91/00117, EP 0 482 -154 B1, US Pat. 5,214,703. -.IP [PKCS#1] -PKCS #1: RSA Encryption Standard. Version 1.5, RSA Laboratories, -November 1993. Available for anonymous ftp at ftp.rsa.com. -.IP [POSIX] -Portable Operating System Interface (POSIX) - Part 1: Application -Program Interface (API) [C language], ISO/IEC 9945-1, IEEE Std 1003.1, -1990. -.IP [RFC0791] -J. Postel: Internet Protocol, RFC 791, USC/ISI, September 1981. -.IP [RFC0793] -J. Postel: Transmission Control Protocol, RFC 793, USC/ISI, September -1981. -.IP [RFC1034] -P. Mockapetris: Domain Names - Concepts and Facilities, RFC 1034, -USC/ISI, November 1987. -.IP [RFC1282] -B. Kantor: BSD Rlogin, RFC 1258, UCSD, December 1991. -.IP "[RSA] " -Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. See -also R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic -Communications System and Method. US Patent 4,405,829, 1983. -.IP "[X11] " -R. Scheifler: X Window System Protocol, X Consortium Standard, Version -11, Release 6. Massachusetts Institute of Technology, Laboratory of -Computer Science, 1994. -.RT - - -.ti 0 -Security Considerations - -This protocol deals with the very issue of user authentication and -security. - -First of all, as an implementation issue, the server program will have -to run as root (or equivalent) on the server machine. This is because -the server program will need be able to change to an arbitrary user -id. The server must also be able to create a privileged TCP/IP port. - -The client program will need to run as root if any variant of .rhosts -authentication is to be used. This is because the client program will -need to create a privileged port. The client host key is also usually -stored in a file which is readable by root only. The client needs the -host key in .rhosts authentication only. Root privileges can be -dropped as soon as the privileged port has been created and the host -key has been read. - -The SSH protocol offers major security advantages over existing telnet -and rlogin protocols. -.IP o -IP spoofing is restricted to closing a connection (by encryption, host -keys, and the special random cookie). If encryption is not used, IP -spoofing is possible for those who can hear packets going out from the -server. -.IP o -DNS spoofing is made ineffective (by host keys). -.IP o -Routing spoofing is made ineffective (by host keys). -.IP o -All data is encrypted with strong algorithms to make eavesdropping as -difficult as possible. This includes encrypting any authentication -information such as passwords. The information for decrypting session -keys is destroyed every hour. -.IP o -Strong authentication methods: .rhosts combined with RSA host -authentication, and pure RSA authentication. -.IP o -X11 connections and arbitrary TCP/IP ports can be forwarded securely. -.IP o -Man-in-the-middle attacks are deterred by using the server host key to -encrypt the session key. -.IP o -Trojan horses to catch a password by routing manipulation are deterred -by checking that the host key of the server machine matches that -stored on the client host. -.RT - -The security of SSH against man-in-the-middle attacks and the security -of the new form of .rhosts authentication, as well as server host -validation, depends on the integrity of the host key and the files -containing known host keys. - -The host key is normally stored in a root-readable file. If the host -key is compromised, it permits attackers to use IP, DNS and routing -spoofing as with current rlogin and rsh. It should never be any worse -than the current situation. - -The files containing known host keys are not sensitive. However, if an -attacker gets to modify the known host key files, it has the same -consequences as a compromised host key, because the attacker can then -change the recorded host key. - -The security improvements obtained by this protocol for X11 are of -particular significance. Previously, there has been no way to protect -data communicated between an X server and a client running on a remote -machine. By creating a fake display on the server, and forwarding all -X11 requests over the secure channel, SSH can be used to run any X11 -applications securely without any cooperation with the vendors of the -X server or the application. - -Finally, the security of this program relies on the strength of the -underlying cryptographic algorithms. The RSA algorithm is used for -authentication key exchange. It is widely believed to be secure. Of -the algorithms used to encrypt the session, DES has a rather small key -these days, probably permitting governments and organized criminals to -break it in very short time with specialized hardware. 3DES is -probably safe (but slower). IDEA is widely believed to be secure. -People have varying degrees of confidence in the other algorithms. -This program is not secure if used with no encryption at all. - - -.ti 0 -Additional Information - -Additional information (especially on the implementation and mailing -lists) is available via WWW at http://www.cs.hut.fi/ssh. - -Comments should be sent to Tatu Ylonen <ylo@cs.hut.fi> or the SSH -Mailing List <ssh@clinet.fi>. - -.ti 0 -Author's Address - -.TS -; -l. -Tatu Ylonen -Helsinki University of Technology -Otakaari 1 -FIN-02150 Espoo, Finland - -Phone: +358-0-451-3374 -Fax: +358-0-451-3293 -EMail: ylo@cs.hut.fi -.TE diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c deleted file mode 100644 index 668d4900e937..000000000000 --- a/crypto/openssh/atomicio.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1999 Theo de Raadt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$Id: atomicio.c,v 1.3 2000/03/16 20:56:13 markus Exp $"); - -#include "xmalloc.h" -#include "ssh.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: - if (errno == EINTR || errno == EAGAIN) - continue; - case 0: - return (res); - default: - pos += res; - } - } - return (pos); -} diff --git a/crypto/openssh/auth-krb4.c b/crypto/openssh/auth-krb4.c deleted file mode 100644 index a26842713aae..000000000000 --- a/crypto/openssh/auth-krb4.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Dug Song <dugsong@UMICH.EDU> - * Kerberos v4 authentication and ticket-passing routines. - */ - -#include "includes.h" -#include "packet.h" -#include "xmalloc.h" -#include "ssh.h" -#include "servconf.h" - -#ifdef KRB4 -char *ticket = NULL; - -extern ServerOptions options; - -/* - * try krb4 authentication, - * return 1 on success, 0 on failure, -1 if krb4 is not available - */ - -int -auth_krb4_password(struct passwd * pw, const char *password) -{ - AUTH_DAT adata; - KTEXT_ST tkt; - struct hostent *hp; - unsigned long faddr; - char localhost[MAXHOSTNAMELEN]; - char phost[INST_SZ]; - char realm[REALM_SZ]; - int r; - - /* - * 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(pw->pw_uid)) { - log("Couldn't initialize Kerberos ticket file for %s!", - pw->pw_name); - goto kerberos_auth_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) { - packet_send_debug("Kerberos V4 password " - "authentication for %s failed: %s", - pw->pw_name, krb_err_txt[r]); - goto kerberos_auth_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. - */ - (void) gethostname(localhost, sizeof(localhost)); - (void) strlcpy(phost, (char *) krb_get_phost(localhost), - INST_SZ); - r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); - - if (r == KSUCCESS) { - if (!(hp = gethostbyname(localhost))) { - log("Couldn't get local host address!"); - goto kerberos_auth_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. Allow login. - */ - log("Kerberos V4 TGT for %s unverifiable, " - "no srvtab installed? krb_rd_req: %s", - pw->pw_name, krb_err_txt[r]); - } else if (r != KSUCCESS) { - log("Kerberos V4 %s ticket unverifiable: %s", - KRB4_SERVICE_NAME, krb_err_txt[r]); - goto kerberos_auth_failure; - } - } else if (r == KDC_PR_UNKNOWN) { - /* - * Allow login if no rcmd service exists, but - * 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); - } else { - /* - * TGT is bad, forget it. Possibly spoofed! - */ - packet_send_debug("WARNING: Kerberos V4 TGT " - "possibly spoofed for %s: %s", - pw->pw_name, krb_err_txt[r]); - goto kerberos_auth_failure; - } - - /* Authentication succeeded. */ - return 1; - -kerberos_auth_failure: - krb4_cleanup_proc(NULL); - - if (!options.kerberos_or_local_passwd) - return 0; - } else { - /* Logging in as root or no local Kerberos realm. */ - packet_send_debug("Unable to authenticate to Kerberos."); - } - /* Fall back to ordinary passwd authentication. */ - return -1; -} - -void -krb4_cleanup_proc(void *ignore) -{ - debug("krb4_cleanup_proc called"); - if (ticket) { - (void) dest_tkt(); - xfree(ticket); - ticket = NULL; - } -} - -int -krb4_init(uid_t uid) -{ - static int cleanup_registered = 0; - const char *tkt_root = TKT_ROOT; - struct stat st; - int fd; - - if (!ticket) { - /* Set unique ticket string manually since we're still root. */ - ticket = xmalloc(MAXPATHLEN); -#ifdef AFS - if (lstat("/ticket", &st) != -1) - tkt_root = "/ticket/"; -#endif /* AFS */ - snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); - (void) krb_set_tkt_string(ticket); - } - /* Register ticket cleanup in case of fatal error. */ - if (!cleanup_registered) { - fatal_add_cleanup(krb4_cleanup_proc, NULL); - cleanup_registered = 1; - } - /* Try to create our ticket file. */ - if ((fd = mkstemp(ticket)) != -1) { - close(fd); - return 1; - } - /* Ticket file exists - make sure user owns it (just passed ticket). */ - if (lstat(ticket, &st) != -1) { - if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && - st.st_uid == uid) - return 1; - } - /* Failure - cancel cleanup function, leaving bad ticket for inspection. */ - log("WARNING: bad ticket file %s", ticket); - fatal_remove_cleanup(krb4_cleanup_proc, NULL); - cleanup_registered = 0; - xfree(ticket); - ticket = NULL; - - return 0; -} - -int -auth_krb4(const char *server_user, KTEXT auth, char **client) -{ - AUTH_DAT adat = {0}; - KTEXT_ST reply; - char instance[INST_SZ]; - int r, s; - socklen_t slen; - u_int cksum; - Key_schedule schedule; - struct sockaddr_in local, foreign; - - 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, ""))) { - packet_send_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, (char *) server_user) != KSUCCESS) { - packet_send_debug("Kerberos V4 .klogin authorization failed!"); - log("Kerberos V4 .klogin authorization failed for %s to account %s", - *client, server_user); - xfree(*client); - 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) { - packet_send_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)); - - packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) reply.dat, reply.length); - packet_send(); - packet_write_wait(); - return 1; -} -#endif /* KRB4 */ - -#ifdef AFS -int -auth_kerberos_tgt(struct passwd *pw, const char *string) -{ - CREDENTIALS creds; - - if (!radix_to_creds(string, &creds)) { - log("Protocol error decoding Kerberos V4 tgt"); - packet_send_debug("Protocol error decoding Kerberos V4 tgt"); - goto auth_kerberos_tgt_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); - packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", - creds.pname, creds.pinst[0] ? "." : "", creds.pinst, - creds.realm, pw->pw_name); - goto auth_kerberos_tgt_failure; - } - if (!krb4_init(pw->pw_uid)) - goto auth_kerberos_tgt_failure; - - if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) - goto auth_kerberos_tgt_failure; - - if (save_credentials(creds.service, creds.instance, creds.realm, - creds.session, creds.lifetime, creds.kvno, - &creds.ticket_st, creds.issue_date) != KSUCCESS) { - packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); - goto auth_kerberos_tgt_failure; - } - /* Successful authentication, passed all checks. */ - chown(tkt_string(), pw->pw_uid, pw->pw_gid); - - packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", - creds.service, creds.instance, creds.realm, creds.pname, - creds.pinst[0] ? "." : "", creds.pinst, creds.realm); - memset(&creds, 0, sizeof(creds)); - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); - return 1; - -auth_kerberos_tgt_failure: - krb4_cleanup_proc(NULL); - memset(&creds, 0, sizeof(creds)); - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - return 0; -} - -int -auth_afs_token(struct passwd *pw, const char *token_string) -{ - CREDENTIALS creds; - uid_t uid = pw->pw_uid; - - if (!radix_to_creds(token_string, &creds)) { - log("Protocol error decoding AFS token"); - packet_send_debug("Protocol error decoding AFS token"); - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - 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); - - if (kafs_settoken(creds.realm, uid, &creds)) { - log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm, - pw->pw_name); - packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname, - creds.realm, pw->pw_name); - memset(&creds, 0, sizeof(creds)); - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - return 0; - } - packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, - creds.realm, creds.pname, creds.realm); - memset(&creds, 0, sizeof(creds)); - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); - return 1; -} -#endif /* AFS */ diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c deleted file mode 100644 index fea75d925bdf..000000000000 --- a/crypto/openssh/auth-passwd.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Sat Mar 18 05:11:38 1995 ylo - * Password authentication. This file contains the functions to check whether - * the password is valid for the user. - */ - -#include "includes.h" -RCSID("$Id: auth-passwd.c,v 1.15 2000/04/14 10:30:29 markus Exp $"); - -#include "packet.h" -#include "ssh.h" -#include "servconf.h" -#include "xmalloc.h" - -/* - * Tries to authenticate the user using password. Returns true if - * authentication succeeds. - */ -int -auth_password(struct passwd * pw, const char *password) -{ - extern ServerOptions options; - char *encrypted_password; - - /* deny if no user. */ - if (pw == NULL) - return 0; - if (pw->pw_uid == 0 && options.permit_root_login == 2) - return 0; - if (*password == '\0' && options.permit_empty_passwd == 0) - return 0; - -#ifdef SKEY - if (options.skey_authentication == 1) { - int ret = auth_skey_password(pw, password); - if (ret == 1 || ret == 0) - return ret; - /* Fall back to ordinary passwd authentication. */ - } -#endif -#ifdef KRB4 - if (options.kerberos_authentication == 1) { - int ret = auth_krb4_password(pw, password); - if (ret == 1 || ret == 0) - return ret; - /* Fall back to ordinary passwd authentication. */ - } -#endif - - /* Check for users with no password. */ - if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) - return 1; - /* Encrypt the candidate password using the proper salt. */ - encrypted_password = crypt(password, - (pw->pw_passwd[0] && pw->pw_passwd[1]) ? pw->pw_passwd : "xx"); - - /* Authentication is accepted if the encrypted passwords are identical. */ - return (strcmp(encrypted_password, pw->pw_passwd) == 0); -} diff --git a/crypto/openssh/auth-rh-rsa.c b/crypto/openssh/auth-rh-rsa.c deleted file mode 100644 index f251fb9cc3ef..000000000000 --- a/crypto/openssh/auth-rh-rsa.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * auth-rh-rsa.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sun May 7 03:08:06 1995 ylo - * - * Rhosts or /etc/hosts.equiv authentication combined with RSA host - * authentication. - * - */ - -#include "includes.h" -RCSID("$Id: auth-rh-rsa.c,v 1.13 2000/04/14 10:30:29 markus Exp $"); - -#include "packet.h" -#include "ssh.h" -#include "xmalloc.h" -#include "uidswap.h" -#include "servconf.h" - -#include <openssl/rsa.h> -#include <openssl/dsa.h> -#include "key.h" -#include "hostfile.h" - -/* - * 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, const char *client_user, RSA *client_host_key) -{ - extern ServerOptions options; - const char *canonical_hostname; - HostStatus host_status; - Key *client_key, *found; - - debug("Trying rhosts with RSA host authentication for %.100s", client_user); - - if (client_host_key == NULL) - return 0; - - /* Check if we would accept it using rhosts authentication. */ - if (!auth_rhosts(pw, client_user)) - return 0; - - canonical_hostname = get_canonical_hostname(); - - debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname); - - /* wrap the RSA key into a 'generic' key */ - client_key = key_new(KEY_RSA); - BN_copy(client_key->rsa->e, client_host_key->e); - BN_copy(client_key->rsa->n, client_host_key->n); - found = key_new(KEY_RSA); - - /* Check if we know the host and its host key. */ - host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, - client_key, found); - - /* Check user host file unless ignored. */ - if (host_status != HOST_OK && !options.ignore_user_known_hosts) { - struct stat st; - char *user_hostfile = tilde_expand_filename(SSH_USER_HOSTFILE, pw->pw_uid); - /* - * Check file permissions of SSH_USER_HOSTFILE, auth_rsa() - * did already check pw->pw_dir, but there is a race XXX - */ - 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("Rhosts RSA authentication refused for %.100s: bad owner or modes for %.200s", - pw->pw_name, user_hostfile); - } else { - /* XXX race between stat and the following open() */ - temporarily_use_uid(pw->pw_uid); - host_status = check_host_in_hostfile(user_hostfile, canonical_hostname, - client_key, found); - restore_uid(); - } - xfree(user_hostfile); - } - key_free(client_key); - key_free(found); - - if (host_status != HOST_OK) { - 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.", - canonical_hostname); - 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, client_user, canonical_hostname); - packet_send_debug("Rhosts with RSA host authentication accepted."); - return 1; -} diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c deleted file mode 100644 index 3393b86661dd..000000000000 --- a/crypto/openssh/auth-rhosts.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * - * auth-rhosts.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 17 05:12:18 1995 ylo - * - * Rhosts authentication. This file contains code to check whether to admit - * the login based on rhosts authentication. This file also processes - * /etc/hosts.equiv. - * - */ - -#include "includes.h" -RCSID("$Id: auth-rhosts.c,v 1.13 2000/04/14 10:30:29 markus Exp $"); - -#include "packet.h" -#include "ssh.h" -#include "xmalloc.h" -#include "uidswap.h" -#include "servconf.h" - -/* - * 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. - */ - -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, "%s %s %s", hostbuf, userbuf, dummy)) { - case 0: - packet_send_debug("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: - packet_send_debug("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 '-'. */ - packet_send_debug("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) { - packet_send_debug("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) -{ - extern ServerOptions options; - char buf[1024]; - const char *hostname, *ipaddr; - struct stat st; - static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; - unsigned int rhosts_file_index; - - /* Switch to the user's uid. */ - temporarily_use_uid(pw->pw_uid); - /* - * 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("/etc/hosts.equiv", &st) < 0 && - stat(SSH_HOSTS_EQUIV, &st) < 0) - return 0; - - hostname = get_canonical_hostname(); - ipaddr = get_remote_ipaddr(); - - /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ - if (pw->pw_uid != 0) { - if (check_rhosts_file("/etc/hosts.equiv", hostname, ipaddr, client_user, - pw->pw_name)) { - packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.", - hostname, ipaddr); - return 1; - } - if (check_rhosts_file(SSH_HOSTS_EQUIV, hostname, ipaddr, client_user, - pw->pw_name)) { - packet_send_debug("Accepted for %.100s [%.100s] by %.100s.", - hostname, ipaddr, 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); - packet_send_debug("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); - packet_send_debug("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->pw_uid); - - /* 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); - packet_send_debug("Bad file modes for %.200s", buf); - continue; - } - /* Check if we have been configured to ignore .rhosts and .shosts files. */ - if (options.ignore_rhosts) { - packet_send_debug("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)) { - packet_send_debug("Accepted by %.100s.", - rhosts_files[rhosts_file_index]); - /* Restore the privileged uid. */ - restore_uid(); - return 1; - } - } - - /* Restore the privileged uid. */ - restore_uid(); - return 0; -} diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c deleted file mode 100644 index 78d28f0b8c87..000000000000 --- a/crypto/openssh/auth-rsa.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * - * auth-rsa.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Mon Mar 27 01:46:52 1995 ylo - * - * RSA-based authentication. This code determines whether to admit a login - * based on RSA authentication. This file also contains functions to check - * validity of the host key. - * - */ - -#include "includes.h" -RCSID("$Id: auth-rsa.c,v 1.23 2000/04/29 18:11:51 markus Exp $"); - -#include "rsa.h" -#include "packet.h" -#include "xmalloc.h" -#include "ssh.h" -#include "mpaux.h" -#include "uidswap.h" -#include "match.h" -#include "servconf.h" - -#include <openssl/rsa.h> -#include <openssl/md5.h> - -/* Flags that may be set in authorized_keys options. */ -extern int no_port_forwarding_flag; -extern int no_agent_forwarding_flag; -extern int no_x11_forwarding_flag; -extern int no_pty_flag; -extern char *forced_command; -extern struct envstring *custom_environment; - -/* - * Session identifier that is used to bind key exchange and authentication - * responses to a particular session. - */ -extern unsigned 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. - */ - -/* - * 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(RSA *pk) -{ - BIGNUM *challenge, *encrypted_challenge; - BN_CTX *ctx; - unsigned char buf[32], mdbuf[16], response[16]; - MD5_CTX md; - unsigned int i; - int plen, len; - - encrypted_challenge = BN_new(); - challenge = BN_new(); - - /* Generate a random challenge. */ - BN_rand(challenge, 256, 0, 0); - ctx = BN_CTX_new(); - BN_mod(challenge, challenge, pk->n, ctx); - BN_CTX_free(ctx); - - /* Encrypt the challenge with the public key. */ - rsa_public_encrypt(encrypted_challenge, challenge, pk); - - /* 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(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); - packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); - for (i = 0; i < 16; i++) - response[i] = packet_get_char(); - - /* The response is MD5 of decrypted challenge plus session id. */ - len = BN_num_bytes(challenge); - if (len <= 0 || len > 32) - fatal("auth_rsa_challenge_dialog: 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); - BN_clear_free(challenge); - - /* 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 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) -{ - extern ServerOptions options; - char line[8192], file[1024]; - int authenticated; - unsigned int bits; - FILE *f; - unsigned long linenum = 0; - struct stat st; - RSA *pk; - - /* Temporarily use the user's uid. */ - temporarily_use_uid(pw->pw_uid); - - /* The authorized keys. */ - snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, - SSH_USER_PERMITTED_KEYS); - - /* 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(); - packet_send_debug("Could not open %.900s for reading.", file); - packet_send_debug("If your home is on an NFS volume, it may need to be world-readable."); - return 0; - } - if (options.strict_modes) { - int fail = 0; - char buf[1024]; - /* Check open file in order to avoid open/stat races */ - if (fstat(fileno(f), &st) < 0 || - (st.st_uid != 0 && st.st_uid != pw->pw_uid) || - (st.st_mode & 022) != 0) { - snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " - "bad ownership or modes for '%s'.", pw->pw_name, file); - fail = 1; - } else { - /* Check path to SSH_USER_PERMITTED_KEYS */ - int i; - static const char *check[] = { - "", SSH_USER_DIR, NULL - }; - for (i = 0; check[i]; i++) { - snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, check[i]); - if (stat(line, &st) < 0 || - (st.st_uid != 0 && st.st_uid != pw->pw_uid) || - (st.st_mode & 022) != 0) { - snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " - "bad ownership or modes for '%s'.", pw->pw_name, line); - fail = 1; - break; - } - } - } - if (fail) { - fclose(f); - log(buf); - packet_send_debug(buf); - restore_uid(); - return 0; - } - } - /* Flag indicating whether authentication has succeeded. */ - authenticated = 0; - - pk = RSA_new(); - pk->e = BN_new(); - pk->n = BN_new(); - - /* - * 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 (!auth_rsa_read_key(&cp, &bits, pk->e, pk->n)) { - debug("%.100s, line %lu: bad key syntax", - SSH_USER_PERMITTED_KEYS, linenum); - packet_send_debug("%.100s, line %lu: bad key syntax", - SSH_USER_PERMITTED_KEYS, 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(pk->n, client_n) != 0) - continue; - - /* check the real bits */ - if (bits != BN_num_bits(pk->n)) - log("Warning: %s, line %ld: keysize mismatch: " - "actual %d vs. announced %d.", - file, linenum, BN_num_bits(pk->n), bits); - - /* We have found the desired key. */ - - /* Perform the challenge-response dialog for this key. */ - if (!auth_rsa_challenge_dialog(pk)) { - /* Wrong response. */ - verbose("Wrong response to RSA authentication challenge."); - packet_send_debug("Wrong response to RSA authentication challenge."); - continue; - } - /* - * 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. - */ - authenticated = 1; - - /* RSA part of authentication was accepted. Now process the options. */ - if (options) { - while (*options && *options != ' ' && *options != '\t') { - cp = "no-port-forwarding"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("Port forwarding disabled."); - no_port_forwarding_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "no-agent-forwarding"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("Agent forwarding disabled."); - no_agent_forwarding_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "no-X11-forwarding"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("X11 forwarding disabled."); - no_x11_forwarding_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "no-pty"; - if (strncmp(options, cp, strlen(cp)) == 0) { - packet_send_debug("Pty allocation disabled."); - no_pty_flag = 1; - options += strlen(cp); - goto next_option; - } - cp = "command=\""; - if (strncmp(options, cp, strlen(cp)) == 0) { - int i; - options += strlen(cp); - forced_command = xmalloc(strlen(options) + 1); - i = 0; - while (*options) { - if (*options == '"') - break; - if (*options == '\\' && options[1] == '"') { - options += 2; - forced_command[i++] = '"'; - continue; - } - forced_command[i++] = *options++; - } - if (!*options) { - debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - packet_send_debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - continue; - } - forced_command[i] = 0; - packet_send_debug("Forced command: %.900s", forced_command); - options++; - goto next_option; - } - cp = "environment=\""; - if (strncmp(options, cp, strlen(cp)) == 0) { - int i; - char *s; - struct envstring *new_envstring; - options += strlen(cp); - s = xmalloc(strlen(options) + 1); - i = 0; - while (*options) { - if (*options == '"') - break; - if (*options == '\\' && options[1] == '"') { - options += 2; - s[i++] = '"'; - continue; - } - s[i++] = *options++; - } - if (!*options) { - debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - packet_send_debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - continue; - } - s[i] = 0; - packet_send_debug("Adding to environment: %.900s", s); - debug("Adding to environment: %.900s", s); - options++; - new_envstring = xmalloc(sizeof(struct envstring)); - new_envstring->s = s; - new_envstring->next = custom_environment; - custom_environment = new_envstring; - goto next_option; - } - cp = "from=\""; - if (strncmp(options, cp, strlen(cp)) == 0) { - char *patterns = xmalloc(strlen(options) + 1); - int i; - options += strlen(cp); - i = 0; - while (*options) { - if (*options == '"') - break; - if (*options == '\\' && options[1] == '"') { - options += 2; - patterns[i++] = '"'; - continue; - } - patterns[i++] = *options++; - } - if (!*options) { - debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - packet_send_debug("%.100s, line %lu: missing end quote", - SSH_USER_PERMITTED_KEYS, linenum); - continue; - } - patterns[i] = 0; - options++; - if (!match_hostname(get_canonical_hostname(), patterns, - strlen(patterns)) && - !match_hostname(get_remote_ipaddr(), patterns, - strlen(patterns))) { - log("RSA authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).", - pw->pw_name, get_canonical_hostname(), - get_remote_ipaddr()); - packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", - get_canonical_hostname()); - xfree(patterns); - /* key invalid for this host, reset flags */ - authenticated = 0; - no_agent_forwarding_flag = 0; - no_port_forwarding_flag = 0; - no_pty_flag = 0; - no_x11_forwarding_flag = 0; - while (custom_environment) { - struct envstring *ce = custom_environment; - custom_environment = ce->next; - xfree(ce->s); - xfree(ce); - } - if (forced_command) { - xfree(forced_command); - forced_command = NULL; - } - break; - } - xfree(patterns); - /* Host name matches. */ - goto next_option; - } - bad_option: - log("Bad options in %.100s file, line %lu: %.50s", - SSH_USER_PERMITTED_KEYS, linenum, options); - packet_send_debug("Bad options in %.100s file, line %lu: %.50s", - SSH_USER_PERMITTED_KEYS, linenum, options); - authenticated = 0; - break; - - next_option: - /* - * Skip the comma, and move to the next option - * (or break out if there are no more). - */ - if (!*options) - fatal("Bugs in auth-rsa.c option processing."); - if (*options == ' ' || *options == '\t') - break; /* End of options. */ - if (*options != ',') - goto bad_option; - options++; - /* Process the next option. */ - continue; - } - } - /* - * Break out of the loop if authentication was successful; - * otherwise continue searching. - */ - if (authenticated) - break; - } - - /* Restore the privileged uid. */ - restore_uid(); - - /* Close the file. */ - fclose(f); - - RSA_free(pk); - - if (authenticated) - packet_send_debug("RSA authentication accepted."); - - /* Return authentication result. */ - return authenticated; -} diff --git a/crypto/openssh/auth-skey.c b/crypto/openssh/auth-skey.c deleted file mode 100644 index 5f3fe9ee1b96..000000000000 --- a/crypto/openssh/auth-skey.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "includes.h" -RCSID("$Id: auth-skey.c,v 1.6 2000/04/14 10:30:29 markus Exp $"); - -#include "ssh.h" -#include "packet.h" -#include <sha1.h> - -/* - * try skey authentication, - * return 1 on success, 0 on failure, -1 if skey is not available - */ - -int -auth_skey_password(struct passwd * pw, const char *password) -{ - if (strncasecmp(password, "s/key", 5) == 0) { - char *skeyinfo = skey_keyinfo(pw->pw_name); - if (skeyinfo == NULL) { - debug("generating fake skeyinfo for %.100s.", - pw->pw_name); - skeyinfo = skey_fake_keyinfo(pw->pw_name); - } - if (skeyinfo != NULL) - packet_send_debug(skeyinfo); - /* Try again. */ - return 0; - } else if (skey_haskey(pw->pw_name) == 0 && - skey_passcheck(pw->pw_name, (char *) password) != -1) { - /* Authentication succeeded. */ - return 1; - } - /* Fall back to ordinary passwd authentication. */ - return -1; -} - -/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ - -#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ - ((x)[3])) - -/* - * hash_collapse() - */ -static u_int32_t -hash_collapse(s) - u_char *s; -{ - int len, target; - u_int32_t i; - - if ((strlen(s) % sizeof(u_int32_t)) == 0) - target = strlen(s); /* Multiple of 4 */ - else - target = strlen(s) - (strlen(s) % sizeof(u_int32_t)); - - for (i = 0, len = 0; len < target; len += 4) - i ^= ROUND(s + len); - - return i; -} - -char * -skey_fake_keyinfo(char *username) -{ - int i; - u_int ptr; - u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up; - char pbuf[SKEY_MAX_PW_LEN+1]; - static char skeyprompt[SKEY_MAX_CHALLENGE+1]; - char *secret = NULL; - size_t secretlen = 0; - SHA1_CTX ctx; - char *p, *u; - - /* - * Base first 4 chars of seed on hostname. - * Add some filler for short hostnames if necessary. - */ - if (gethostname(pbuf, sizeof(pbuf)) == -1) - *(p = pbuf) = '.'; - else - for (p = pbuf; *p && isalnum(*p); p++) - if (isalpha(*p) && isupper(*p)) - *p = tolower(*p); - if (*p && pbuf - p < 4) - (void)strncpy(p, "asjd", 4 - (pbuf - p)); - pbuf[4] = '\0'; - - /* Hash the username if possible */ - if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) { - struct stat sb; - time_t t; - int fd; - - /* Collapse the hash */ - ptr = hash_collapse(up); - memset(up, 0, strlen(up)); - - /* See if the random file's there, else use ctime */ - if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1 - && fstat(fd, &sb) == 0 && - sb.st_size > (off_t)SKEY_MAX_SEED_LEN && - lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN), - SEEK_SET) != -1 && read(fd, hseed, - SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) { - close(fd); - fd = -1; - secret = hseed; - secretlen = SKEY_MAX_SEED_LEN; - flg = 0; - } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) { - t = sb.st_ctime; - secret = ctime(&t); - secretlen = strlen(secret); - flg = 0; - } - if (fd != -1) - close(fd); - } - - /* Put that in your pipe and smoke it */ - if (flg == 0) { - /* Hash secret value with username */ - SHA1Init(&ctx); - SHA1Update(&ctx, secret, secretlen); - SHA1Update(&ctx, username, strlen(username)); - SHA1End(&ctx, up); - - /* Zero out */ - memset(secret, 0, secretlen); - - /* Now hash the hash */ - SHA1Init(&ctx); - SHA1Update(&ctx, up, strlen(up)); - SHA1End(&ctx, up); - - ptr = hash_collapse(up + 4); - - for (i = 4; i < 9; i++) { - pbuf[i] = (ptr % 10) + '0'; - ptr /= 10; - } - pbuf[i] = '\0'; - - /* Sequence number */ - ptr = ((up[2] + up[3]) % 99) + 1; - - memset(up, 0, 20); /* SHA1 specific */ - free(up); - - (void)snprintf(skeyprompt, sizeof skeyprompt, - "otp-%.*s %d %.*s", - SKEY_MAX_HASHNAME_LEN, - skey_get_algorithm(), - ptr, SKEY_MAX_SEED_LEN, - pbuf); - } else { - /* Base last 8 chars of seed on username */ - u = username; - i = 8; - p = &pbuf[4]; - do { - if (*u == 0) { - /* Pad remainder with zeros */ - while (--i >= 0) - *p++ = '0'; - break; - } - - *p++ = (*u++ % 10) + '0'; - } while (--i != 0); - pbuf[12] = '\0'; - - (void)snprintf(skeyprompt, sizeof skeyprompt, - "otp-%.*s %d %.*s", - SKEY_MAX_HASHNAME_LEN, - skey_get_algorithm(), - 99, SKEY_MAX_SEED_LEN, pbuf); - } - return skeyprompt; -} diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c deleted file mode 100644 index d3425a237a71..000000000000 --- a/crypto/openssh/auth.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Copyright (c) 2000 Markus Friedl. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.6 2000/04/26 21:28:31 markus Exp $"); - -#include "xmalloc.h" -#include "rsa.h" -#include "ssh.h" -#include "pty.h" -#include "packet.h" -#include "buffer.h" -#include "cipher.h" -#include "mpaux.h" -#include "servconf.h" -#include "compat.h" -#include "channels.h" -#include "match.h" - -#include "bufaux.h" -#include "ssh2.h" -#include "auth.h" -#include "session.h" -#include "dispatch.h" - - -/* import */ -extern ServerOptions options; -extern char *forced_command; - -/* - * Check if the user is allowed to log in via ssh. If user is listed in - * DenyUsers or user's primary group 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 user 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; - struct group *grp; - int i; - - /* Shouldn't be called if pw is NULL, but better safe than sorry... */ - if (!pw) - return 0; - - /* deny if shell does not exists or is not executable */ - if (stat(pw->pw_shell, &st) != 0) - return 0; - if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) - return 0; - - /* Return false if user is listed in DenyUsers */ - if (options.num_deny_users > 0) { - if (!pw->pw_name) - return 0; - for (i = 0; i < options.num_deny_users; i++) - if (match_pattern(pw->pw_name, options.deny_users[i])) - return 0; - } - /* Return false if AllowUsers isn't empty and user isn't listed there */ - if (options.num_allow_users > 0) { - if (!pw->pw_name) - return 0; - for (i = 0; i < options.num_allow_users; i++) - if (match_pattern(pw->pw_name, options.allow_users[i])) - break; - /* i < options.num_allow_users iff we break for loop */ - if (i >= options.num_allow_users) - return 0; - } - /* Get the primary group name if we need it. Return false if it fails */ - if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { - grp = getgrgid(pw->pw_gid); - if (!grp) - return 0; - - /* Return false if user's group is listed in DenyGroups */ - if (options.num_deny_groups > 0) { - if (!grp->gr_name) - return 0; - for (i = 0; i < options.num_deny_groups; i++) - if (match_pattern(grp->gr_name, options.deny_groups[i])) - return 0; - } - /* - * Return false if AllowGroups isn't empty and user's group - * isn't listed there - */ - if (options.num_allow_groups > 0) { - if (!grp->gr_name) - return 0; - for (i = 0; i < options.num_allow_groups; i++) - if (match_pattern(grp->gr_name, options.allow_groups[i])) - break; - /* i < options.num_allow_groups iff we break for - loop */ - if (i >= options.num_allow_groups) - return 0; - } - } - /* We found no reason not to let this user try to log on... */ - return 1; -} diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h deleted file mode 100644 index 72126e0992d9..000000000000 --- a/crypto/openssh/auth.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef AUTH_H -#define AUTH_H - -void do_authentication(void); -void do_authentication2(void); - -struct passwd * -auth_get_user(void); - -int allowed_user(struct passwd * pw);; - -#define AUTH_FAIL_MAX 6 -#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) -#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" - -#endif - diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c deleted file mode 100644 index 38114d8c06eb..000000000000 --- a/crypto/openssh/auth1.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - */ - -#include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.2 2000/04/29 18:11:52 markus Exp $"); - -#include "xmalloc.h" -#include "rsa.h" -#include "ssh.h" -#include "packet.h" -#include "buffer.h" -#include "cipher.h" -#include "mpaux.h" -#include "servconf.h" -#include "compat.h" -#include "auth.h" -#include "session.h" - -/* import */ -extern ServerOptions options; -extern char *forced_command; - -/* - * convert ssh auth msg type into description - */ -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"; -#ifdef KRB4 - case SSH_CMSG_AUTH_KERBEROS: - return "kerberos"; -#endif -#ifdef SKEY - case SSH_CMSG_AUTH_TIS_RESPONSE: - return "s/key"; -#endif - } - snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); - return buf; -} - -/* - * The user does not exist or access is denied, - * but fake indication that authentication is needed. - */ -void -do_fake_authloop1(char *user) -{ - int attempt = 0; - - log("Faking authloop for illegal user %.200s from %.200s port %d", - user, - get_remote_ipaddr(), - get_remote_port()); - - /* Indicate that authentication is needed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - - /* - * Keep reading packets, and always respond with a failure. This is - * to avoid disclosing whether such a user really exists. - */ - for (attempt = 1;; attempt++) { - /* Read a packet. This will not return if the client disconnects. */ - int plen; - int type = packet_read(&plen); -#ifdef SKEY - unsigned int dlen; - char *password, *skeyinfo; - password = NULL; - /* Try to send a fake s/key challenge. */ - if (options.skey_authentication == 1 && - (skeyinfo = skey_fake_keyinfo(user)) != NULL) { - if (type == SSH_CMSG_AUTH_TIS) { - packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); - packet_put_string(skeyinfo, strlen(skeyinfo)); - packet_send(); - packet_write_wait(); - continue; - } else if (type == SSH_CMSG_AUTH_PASSWORD && - options.password_authentication && - (password = packet_get_string(&dlen)) != NULL && - dlen == 5 && - strncasecmp(password, "s/key", 5) == 0 ) { - packet_send_debug(skeyinfo); - } - } - if (password != NULL) - xfree(password); -#endif - if (attempt > AUTH_FAIL_MAX) - packet_disconnect(AUTH_FAIL_MSG, user); - - /* - * Send failure. This should be indistinguishable from a - * failed authentication. - */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - } - /* NOTREACHED */ - abort(); -} - -/* - * read packets and try to authenticate local user *pw. - * return if authentication is successfull - */ -void -do_authloop(struct passwd * pw) -{ - int attempt = 0; - unsigned int bits; - RSA *client_host_key; - BIGNUM *n; - char *client_user, *password; - char user[1024]; - unsigned int dlen; - int plen, nlen, elen; - unsigned int ulen; - int type = 0; - void (*authlog) (const char *fmt,...) = verbose; - - /* Indicate that authentication is needed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - - for (attempt = 1;; attempt++) { - int authenticated = 0; - strlcpy(user, "", sizeof user); - - /* Get a packet from the client. */ - type = packet_read(&plen); - - /* Process the packet. */ - switch (type) { -#ifdef AFS - case SSH_CMSG_HAVE_KERBEROS_TGT: - if (!options.kerberos_tgt_passing) { - /* packet_get_all(); */ - verbose("Kerberos tgt passing disabled."); - break; - } else { - /* Accept Kerberos tgt. */ - char *tgt = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - if (!auth_kerberos_tgt(pw, tgt)) - verbose("Kerberos tgt REFUSED for %s", pw->pw_name); - xfree(tgt); - } - continue; - - case SSH_CMSG_HAVE_AFS_TOKEN: - if (!options.afs_token_passing || !k_hasafs()) { - /* packet_get_all(); */ - verbose("AFS token passing disabled."); - break; - } else { - /* Accept AFS token. */ - char *token_string = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - if (!auth_afs_token(pw, token_string)) - verbose("AFS token REFUSED for %s", pw->pw_name); - xfree(token_string); - } - continue; -#endif /* AFS */ -#ifdef KRB4 - case SSH_CMSG_AUTH_KERBEROS: - if (!options.kerberos_authentication) { - /* packet_get_all(); */ - verbose("Kerberos authentication disabled."); - break; - } else { - /* Try Kerberos v4 authentication. */ - KTEXT_ST auth; - char *tkt_user = NULL; - char *kdata = packet_get_string((unsigned int *) &auth.length); - packet_integrity_check(plen, 4 + auth.length, type); - - if (auth.length < MAX_KTXT_LEN) - memcpy(auth.dat, kdata, auth.length); - xfree(kdata); - - authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); - - if (authenticated) { - snprintf(user, sizeof user, " tktuser %s", tkt_user); - xfree(tkt_user); - } - } - break; -#endif /* KRB4 */ - - 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_integrity_check(plen, 4 + ulen, type); - - /* Try to authenticate using /etc/hosts.equiv and - .rhosts. */ - authenticated = auth_rhosts(pw, client_user); - - snprintf(user, sizeof user, " ruser %s", client_user); - xfree(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 = RSA_new(); - if (client_host_key == NULL) - fatal("RSA_new failed"); - client_host_key->e = BN_new(); - client_host_key->n = BN_new(); - if (client_host_key->e == NULL || client_host_key->n == NULL) - fatal("BN_new failed"); - bits = packet_get_int(); - packet_get_bignum(client_host_key->e, &elen); - packet_get_bignum(client_host_key->n, &nlen); - - if (bits != BN_num_bits(client_host_key->n)) - log("Warning: keysize mismatch for client_host_key: " - "actual %d, announced %d", BN_num_bits(client_host_key->n), bits); - packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); - - authenticated = auth_rhosts_rsa(pw, client_user, client_host_key); - RSA_free(client_host_key); - - snprintf(user, sizeof user, " ruser %s", client_user); - xfree(client_user); - break; - - case SSH_CMSG_AUTH_RSA: - if (!options.rsa_authentication) { - verbose("RSA authentication disabled."); - break; - } - /* RSA authentication requested. */ - n = BN_new(); - packet_get_bignum(n, &nlen); - packet_integrity_check(plen, nlen, type); - authenticated = auth_rsa(pw, n); - BN_clear_free(n); - break; - - case SSH_CMSG_AUTH_PASSWORD: - 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_integrity_check(plen, 4 + dlen, type); - - /* Try authentication with the password. */ - authenticated = auth_password(pw, password); - - memset(password, 0, strlen(password)); - xfree(password); - break; - -#ifdef SKEY - case SSH_CMSG_AUTH_TIS: - debug("rcvd SSH_CMSG_AUTH_TIS"); - if (options.skey_authentication == 1) { - char *skeyinfo = skey_keyinfo(pw->pw_name); - if (skeyinfo == NULL) { - debug("generating fake skeyinfo for %.100s.", pw->pw_name); - skeyinfo = skey_fake_keyinfo(pw->pw_name); - } - if (skeyinfo != NULL) { - /* we send our s/key- in tis-challenge messages */ - debug("sending challenge '%s'", skeyinfo); - packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); - packet_put_string(skeyinfo, strlen(skeyinfo)); - packet_send(); - packet_write_wait(); - continue; - } - } - break; - case SSH_CMSG_AUTH_TIS_RESPONSE: - debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); - if (options.skey_authentication == 1) { - char *response = packet_get_string(&dlen); - debug("skey response == '%s'", response); - packet_integrity_check(plen, 4 + dlen, type); - authenticated = (skey_haskey(pw->pw_name) == 0 && - skey_passcheck(pw->pw_name, response) != -1); - xfree(response); - } - break; -#else - case SSH_CMSG_AUTH_TIS: - /* TIS Authentication is unsupported */ - log("TIS authentication unsupported."); - break; -#endif - - default: - /* - * Any unknown messages will be ignored (and failure - * returned) during authentication. - */ - log("Unknown message during authentication: type %d", type); - break; - } - - /* - * Check if the user is logging in as root and root logins - * are disallowed. - * Note that root login is allowed for forced commands. - */ - if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) { - if (forced_command) { - log("Root login accepted for forced command."); - } else { - authenticated = 0; - log("ROOT LOGIN REFUSED FROM %.200s", - get_canonical_hostname()); - } - } - - /* Raise logging level */ - if (authenticated || - attempt == AUTH_FAIL_LOG || - type == SSH_CMSG_AUTH_PASSWORD) - authlog = log; - - authlog("%s %s for %.200s from %.200s port %d%s", - authenticated ? "Accepted" : "Failed", - get_authname(type), - pw->pw_uid == 0 ? "ROOT" : pw->pw_name, - get_remote_ipaddr(), - get_remote_port(), - user); - - if (authenticated) - return; - - if (attempt > AUTH_FAIL_MAX) - packet_disconnect(AUTH_FAIL_MSG, pw->pw_name); - - /* Send a message indicating that the authentication attempt failed. */ - 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. - */ -void -do_authentication() -{ - struct passwd *pw, pwcopy; - int plen; - unsigned int ulen; - char *user; - - /* Get the name of the user that we wish to log in as. */ - packet_read_expect(&plen, SSH_CMSG_USER); - - /* Get the user name. */ - user = packet_get_string(&ulen); - packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); - - setproctitle("%s", user); - -#ifdef AFS - /* If machine has AFS, set process authentication group. */ - if (k_hasafs()) { - k_setpag(); - k_unlog(); - } -#endif /* AFS */ - - /* Verify that the user is a valid user. */ - pw = getpwnam(user); - if (!pw || !allowed_user(pw)) - do_fake_authloop1(user); - xfree(user); - - /* Take a copy of the returned structure. */ - memset(&pwcopy, 0, sizeof(pwcopy)); - pwcopy.pw_name = xstrdup(pw->pw_name); - pwcopy.pw_passwd = xstrdup(pw->pw_passwd); - pwcopy.pw_uid = pw->pw_uid; - pwcopy.pw_gid = pw->pw_gid; - pwcopy.pw_dir = xstrdup(pw->pw_dir); - pwcopy.pw_shell = xstrdup(pw->pw_shell); - pw = &pwcopy; - - /* - * If we are not running as root, the user must have the same uid as - * the server. - */ - if (getuid() != 0 && pw->pw_uid != getuid()) - packet_disconnect("Cannot change user when server not running as root."); - - debug("Attempting authentication for %.100s.", pw->pw_name); - - /* If the user has no password, accept authentication immediately. */ - if (options.password_authentication && -#ifdef KRB4 - (!options.kerberos_authentication || options.kerberos_or_local_passwd) && -#endif /* KRB4 */ - auth_password(pw, "")) { - /* Authentication with empty password succeeded. */ - log("Login for user %s from %.100s, accepted without authentication.", - pw->pw_name, get_remote_ipaddr()); - } else { - /* Loop until the user has been authenticated or the - connection is closed, do_authloop() returns only if - authentication is successfull */ - do_authloop(pw); - } - - /* The user has been authenticated and accepted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); - - /* Perform session preparation. */ - do_authenticated(pw); -} diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c deleted file mode 100644 index 3f8c254080de..000000000000 --- a/crypto/openssh/auth2.c +++ /dev/null @@ -1,467 +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. - * 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. - */ -#include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.8 2000/05/08 17:42:24 markus Exp $"); - -#include <openssl/dsa.h> -#include <openssl/rsa.h> -#include <openssl/evp.h> - -#include "xmalloc.h" -#include "rsa.h" -#include "ssh.h" -#include "pty.h" -#include "packet.h" -#include "buffer.h" -#include "cipher.h" -#include "servconf.h" -#include "compat.h" -#include "channels.h" -#include "bufaux.h" -#include "ssh2.h" -#include "auth.h" -#include "session.h" -#include "dispatch.h" -#include "auth.h" -#include "key.h" -#include "kex.h" - -#include "dsa.h" -#include "uidswap.h" - -/* import */ -extern ServerOptions options; -extern unsigned char *session_id2; -extern int session_id2_len; - -/* protocol */ - -void input_service_request(int type, int plen); -void input_userauth_request(int type, int plen); -void protocol_error(int type, int plen); - -/* auth */ -int ssh2_auth_none(struct passwd *pw); -int ssh2_auth_password(struct passwd *pw); -int ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen); - -/* helper */ -struct passwd* auth_set_user(char *u, char *s); -int user_dsa_key_allowed(struct passwd *pw, Key *key); - -typedef struct Authctxt Authctxt; -struct Authctxt { - char *user; - char *service; - struct passwd pw; - int valid; -}; -static Authctxt *authctxt = NULL; -static int userauth_success = 0; - -/* - * loop until userauth_success == TRUE - */ - -void -do_authentication2() -{ - /* turn off skey/kerberos, not supported by SSH2 */ -#ifdef SKEY - options.skey_authentication = 0; -#endif -#ifdef KRB4 - options.kerberos_authentication = 0; -#endif - - dispatch_init(&protocol_error); - dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); - dispatch_run(DISPATCH_BLOCK, &userauth_success); - do_authenticated2(); -} - -void -protocol_error(int type, int plen) -{ - log("auth: protocol error: type %d plen %d", type, plen); - packet_start(SSH2_MSG_UNIMPLEMENTED); - packet_put_int(0); - packet_send(); - packet_write_wait(); -} - -void -input_service_request(int type, int plen) -{ - unsigned int len; - int accept = 0; - char *service = packet_get_string(&len); - packet_done(); - - if (strcmp(service, "ssh-userauth") == 0) { - if (!userauth_success) { - accept = 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 (accept) { - 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); -} - -void -input_userauth_request(int type, int plen) -{ - static void (*authlog) (const char *fmt,...) = verbose; - static int attempt = 0; - unsigned int len, rlen; - int authenticated = 0; - char *raw, *user, *service, *method, *authmsg = NULL; - struct passwd *pw; - - if (++attempt == AUTH_FAIL_MAX) - packet_disconnect("too many failed userauth_requests"); - - raw = packet_get_raw(&rlen); - if (plen != rlen) - fatal("plen != rlen"); - user = packet_get_string(&len); - service = packet_get_string(&len); - method = packet_get_string(&len); - debug("userauth-request for user %s service %s method %s", user, service, method); - - /* XXX we only allow the ssh-connection service */ - pw = auth_set_user(user, service); - if (pw && strcmp(service, "ssh-connection")==0) { - if (strcmp(method, "none") == 0) { - authenticated = ssh2_auth_none(pw); - } else if (strcmp(method, "password") == 0) { - authenticated = ssh2_auth_password(pw); - } else if (strcmp(method, "publickey") == 0) { - authenticated = ssh2_auth_pubkey(pw, raw, rlen); - } - } - if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) { - authenticated = 0; - log("ROOT LOGIN REFUSED FROM %.200s", - get_canonical_hostname()); - } - - /* Raise logging level */ - if (authenticated == 1 || - attempt == AUTH_FAIL_LOG || - strcmp(method, "password") == 0) - authlog = log; - - /* Log before sending the reply */ - if (authenticated == 1) { - authmsg = "Accepted"; - } else if (authenticated == 0) { - authmsg = "Failed"; - } else { - authmsg = "Postponed"; - } - authlog("%s %s for %.200s from %.200s port %d ssh2", - authmsg, - method, - pw && pw->pw_uid == 0 ? "ROOT" : user, - get_remote_ipaddr(), - get_remote_port()); - - /* XXX todo: check if multiple auth methods are needed */ - if (authenticated == 1) { - /* turn off userauth */ - dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); - packet_start(SSH2_MSG_USERAUTH_SUCCESS); - packet_send(); - packet_write_wait(); - /* now we can break out */ - userauth_success = 1; - } else if (authenticated == 0) { - packet_start(SSH2_MSG_USERAUTH_FAILURE); - packet_put_cstring("publickey,password"); /* XXX dynamic */ - packet_put_char(0); /* XXX partial success, unused */ - packet_send(); - packet_write_wait(); - } - - xfree(service); - xfree(user); - xfree(method); -} - -int -ssh2_auth_none(struct passwd *pw) -{ - packet_done(); - return auth_password(pw, ""); -} -int -ssh2_auth_password(struct passwd *pw) -{ - char *password; - int authenticated = 0; - int change; - unsigned int len; - change = packet_get_char(); - if (change) - log("password change not supported"); - password = packet_get_string(&len); - packet_done(); - if (options.password_authentication && - auth_password(pw, password) == 1) - authenticated = 1; - memset(password, 0, len); - xfree(password); - return authenticated; -} -int -ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen) -{ - Buffer b; - Key *key; - char *pkalg, *pkblob, *sig; - unsigned int alen, blen, slen; - int have_sig; - int authenticated = 0; - - if (options.dsa_authentication == 0) { - debug("pubkey auth disabled"); - return 0; - } - if (datafellows & SSH_BUG_PUBKEYAUTH) { - log("bug compatibility with ssh-2.0.13 pubkey not implemented"); - return 0; - } - have_sig = packet_get_char(); - pkalg = packet_get_string(&alen); - if (strcmp(pkalg, KEX_DSS) != 0) { - xfree(pkalg); - log("bad pkalg %s", pkalg); /*XXX*/ - return 0; - } - pkblob = packet_get_string(&blen); - key = dsa_key_from_blob(pkblob, blen); - if (key != NULL) { - if (have_sig) { - sig = packet_get_string(&slen); - packet_done(); - buffer_init(&b); - buffer_append(&b, session_id2, session_id2_len); - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - if (slen + 4 > rlen) - fatal("bad rlen/slen"); - buffer_append(&b, raw, rlen - slen - 4); -#ifdef DEBUG_DSS - buffer_dump(&b); -#endif - /* test for correct signature */ - if (user_dsa_key_allowed(pw, key) && - dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) - authenticated = 1; - buffer_clear(&b); - xfree(sig); - } else { - packet_done(); - debug("test key..."); - /* test whether pkalg/pkblob are acceptable */ - /* 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_dsa_key_allowed(pw, key)) { - packet_start(SSH2_MSG_USERAUTH_PK_OK); - packet_put_string(pkalg, alen); - packet_put_string(pkblob, blen); - packet_send(); - packet_write_wait(); - authenticated = -1; - } - } - key_free(key); - } - xfree(pkalg); - xfree(pkblob); - return authenticated; -} - -/* set and get current user */ - -struct passwd* -auth_get_user(void) -{ - return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL; -} - -struct passwd* -auth_set_user(char *u, char *s) -{ - struct passwd *pw, *copy; - - if (authctxt == NULL) { - authctxt = xmalloc(sizeof(*authctxt)); - authctxt->valid = 0; - authctxt->user = xstrdup(u); - authctxt->service = xstrdup(s); - setproctitle("%s", u); - pw = getpwnam(u); - if (!pw || !allowed_user(pw)) { - log("auth_set_user: illegal user %s", u); - return NULL; - } - copy = &authctxt->pw; - memset(copy, 0, sizeof(*copy)); - copy->pw_name = xstrdup(pw->pw_name); - copy->pw_passwd = xstrdup(pw->pw_passwd); - copy->pw_uid = pw->pw_uid; - copy->pw_gid = pw->pw_gid; - copy->pw_dir = xstrdup(pw->pw_dir); - copy->pw_shell = xstrdup(pw->pw_shell); - authctxt->valid = 1; - } else { - if (strcmp(u, authctxt->user) != 0 || - strcmp(s, authctxt->service) != 0) { - log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)", - u, s, authctxt->user, authctxt->service); - return NULL; - } - } - return auth_get_user(); -} - -/* return 1 if user allows given key */ -int -user_dsa_key_allowed(struct passwd *pw, Key *key) -{ - char line[8192], file[1024]; - int found_key = 0; - unsigned int bits = -1; - FILE *f; - unsigned long linenum = 0; - struct stat st; - Key *found; - - /* Temporarily use the user's uid. */ - temporarily_use_uid(pw->pw_uid); - - /* The authorized keys. */ - snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, - SSH_USER_PERMITTED_KEYS2); - - /* 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) { - int fail = 0; - char buf[1024]; - /* Check open file in order to avoid open/stat races */ - if (fstat(fileno(f), &st) < 0 || - (st.st_uid != 0 && st.st_uid != pw->pw_uid) || - (st.st_mode & 022) != 0) { - snprintf(buf, sizeof buf, "DSA authentication refused for %.100s: " - "bad ownership or modes for '%s'.", pw->pw_name, file); - fail = 1; - } else { - /* Check path to SSH_USER_PERMITTED_KEYS */ - int i; - static const char *check[] = { - "", SSH_USER_DIR, NULL - }; - for (i = 0; check[i]; i++) { - snprintf(line, sizeof line, "%.500s/%.100s", - pw->pw_dir, check[i]); - if (stat(line, &st) < 0 || - (st.st_uid != 0 && st.st_uid != pw->pw_uid) || - (st.st_mode & 022) != 0) { - snprintf(buf, sizeof buf, - "DSA authentication refused for %.100s: " - "bad ownership or modes for '%s'.", - pw->pw_name, line); - fail = 1; - break; - } - } - } - if (fail) { - log(buf); - fclose(f); - restore_uid(); - return 0; - } - } - found_key = 0; - found = key_new(KEY_DSA); - - while (fgets(line, sizeof(line), f)) { - char *cp; - linenum++; - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '\n' || *cp == '#') - continue; - bits = key_read(found, &cp); - if (bits == 0) - continue; - if (key_equal(found, key)) { - found_key = 1; - debug("matching key found: file %s, line %ld", - file, linenum); - break; - } - } - restore_uid(); - fclose(f); - key_free(found); - return found_key; -} diff --git a/crypto/openssh/authfd.c b/crypto/openssh/authfd.c deleted file mode 100644 index 77d38e00dd37..000000000000 --- a/crypto/openssh/authfd.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * - * authfd.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Mar 29 01:30:28 1995 ylo - * - * Functions for connecting the local authentication agent. - * - */ - -#include "includes.h" -RCSID("$Id: authfd.c,v 1.19 2000/04/29 18:11:52 markus Exp $"); - -#include "ssh.h" -#include "rsa.h" -#include "authfd.h" -#include "buffer.h" -#include "bufaux.h" -#include "xmalloc.h" -#include "getput.h" - -#include <openssl/rsa.h> - -/* Returns the number of the authentication fd, or -1 if there is none. */ - -int -ssh_get_authentication_socket() -{ - 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, 1) == -1) { - close(sock); - return -1; - } - if (connect(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { - close(sock); - return -1; - } - return sock; -} - -/* - * 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() -{ - 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->packet); - 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 *ac) -{ - buffer_free(&ac->packet); - buffer_free(&ac->identities); - close(ac->fd); - xfree(ac); -} - -/* - * Returns the first authentication identity held by the agent. - * Returns true if an identity is available, 0 otherwise. - * The caller must initialize the integers before the call, and free the - * comment after a successful call (before calling ssh_get_next_identity). - */ - -int -ssh_get_first_identity(AuthenticationConnection *auth, - BIGNUM *e, BIGNUM *n, char **comment) -{ - unsigned char msg[8192]; - int len, l; - - /* - * Send a message to the agent requesting for a list of the - * identities it can represent. - */ - msg[0] = 0; - msg[1] = 0; - msg[2] = 0; - msg[3] = 1; - msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES; - if (atomicio(write, auth->fd, msg, 5) != 5) { - error("write auth->fd: %.100s", strerror(errno)); - return 0; - } - /* Read the length of the response. XXX implement timeouts here. */ - len = 4; - while (len > 0) { - l = read(auth->fd, msg + 4 - len, len); - if (l <= 0) { - error("read auth->fd: %.100s", strerror(errno)); - return 0; - } - len -= l; - } - - /* - * Extract the length, and check it for sanity. (We cannot trust - * authentication agents). - */ - len = GET_32BIT(msg); - if (len < 1 || len > 256 * 1024) - fatal("Authentication reply message too long: %d\n", len); - - /* Read the packet itself. */ - buffer_clear(&auth->identities); - while (len > 0) { - l = len; - if (l > sizeof(msg)) - l = sizeof(msg); - l = read(auth->fd, msg, l); - if (l <= 0) - fatal("Incomplete authentication reply."); - buffer_append(&auth->identities, (char *) msg, l); - len -= l; - } - - /* Get message type, and verify that we got a proper answer. */ - buffer_get(&auth->identities, (char *) msg, 1); - if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER) - fatal("Bad authentication reply message type: %d", msg[0]); - - /* Get the number of entries in the response and check it for sanity. */ - auth->howmany = buffer_get_int(&auth->identities); - if (auth->howmany > 1024) - fatal("Too many identities in authentication reply: %d\n", auth->howmany); - - /* Return the first entry (if any). */ - return ssh_get_next_identity(auth, e, n, comment); -} - -/* - * Returns the next authentication identity for the agent. Other functions - * can be called between this and ssh_get_first_identity or two calls of this - * function. This returns 0 if there are no more identities. The caller - * must free comment after a successful return. - */ - -int -ssh_get_next_identity(AuthenticationConnection *auth, - BIGNUM *e, BIGNUM *n, char **comment) -{ - unsigned int bits; - - /* Return failure if no more entries. */ - if (auth->howmany <= 0) - return 0; - - /* - * Get the next entry from the packet. These will abort with a fatal - * error if the packet is too short or contains corrupt data. - */ - bits = buffer_get_int(&auth->identities); - buffer_get_bignum(&auth->identities, e); - buffer_get_bignum(&auth->identities, n); - *comment = buffer_get_string(&auth->identities, NULL); - - if (bits != BN_num_bits(n)) - log("Warning: identity keysize mismatch: actual %d, announced %u", - BN_num_bits(n), bits); - - /* Decrement the number of remaining entries. */ - auth->howmany--; - - return 1; -} - -/* - * 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, - BIGNUM* e, BIGNUM *n, BIGNUM *challenge, - unsigned char session_id[16], - unsigned int response_type, - unsigned char response[16]) -{ - Buffer buffer; - unsigned char buf[8192]; - int len, l, i; - - /* Response type 0 is no longer supported. */ - if (response_type == 0) - fatal("Compatibility with ssh protocol version 1.0 no longer supported."); - - /* Format a message to the agent. */ - buf[0] = SSH_AGENTC_RSA_CHALLENGE; - buffer_init(&buffer); - buffer_append(&buffer, (char *) buf, 1); - buffer_put_int(&buffer, BN_num_bits(n)); - buffer_put_bignum(&buffer, e); - buffer_put_bignum(&buffer, n); - buffer_put_bignum(&buffer, challenge); - buffer_append(&buffer, (char *) session_id, 16); - buffer_put_int(&buffer, response_type); - - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); -error_cleanup: - buffer_free(&buffer); - return 0; - } - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - goto error_cleanup; - } - len -= l; - } - - /* 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 tothe buffer. */ - buffer_clear(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - goto error_cleanup; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - buffer_get(&buffer, (char *) buf, 1); - - /* Check for agent failure message. */ - if (buf[0] == SSH_AGENT_FAILURE) { - log("Agent admitted failure to authenticate using the key."); - goto error_cleanup; - } - /* Now it must be an authentication response packet. */ - if (buf[0] != SSH_AGENT_RSA_RESPONSE) - fatal("Bad authentication response: %d", buf[0]); - - /* - * 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); - - /* The buffer containing the packet is no longer needed. */ - buffer_free(&buffer); - - /* Correct answer. */ - return 1; -} - -/* - * Adds an identity to the authentication server. This call is not meant to - * be used by normal applications. - */ - -int -ssh_add_identity(AuthenticationConnection *auth, - RSA * key, const char *comment) -{ - Buffer buffer; - unsigned char buf[8192]; - int len, l, type; - - /* Format a message to the agent. */ - buffer_init(&buffer); - buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY); - buffer_put_int(&buffer, BN_num_bits(key->n)); - buffer_put_bignum(&buffer, key->n); - buffer_put_bignum(&buffer, key->e); - buffer_put_bignum(&buffer, key->d); - /* To keep within the protocol: p < q for ssh. in SSL p > q */ - buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */ - buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */ - buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */ - buffer_put_string(&buffer, comment, strlen(comment)); - - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); -error_cleanup: - buffer_free(&buffer); - return 0; - } - /* Wait for response from the agent. First read the length of the - response packet. */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - goto error_cleanup; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Add identity response too long: %d", len); - - /* Read the rest of the response in tothe buffer. */ - buffer_clear(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - goto error_cleanup; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - type = buffer_get_char(&buffer); - switch (type) { - case SSH_AGENT_FAILURE: - buffer_free(&buffer); - return 0; - case SSH_AGENT_SUCCESS: - buffer_free(&buffer); - return 1; - default: - fatal("Bad response to add identity from authentication agent: %d", - type); - } - /* NOTREACHED */ - return 0; -} - -/* - * Removes an identity from the authentication server. This call is not - * meant to be used by normal applications. - */ - -int -ssh_remove_identity(AuthenticationConnection *auth, RSA *key) -{ - Buffer buffer; - unsigned char buf[8192]; - int len, l, type; - - /* Format a message to the agent. */ - buffer_init(&buffer); - buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY); - buffer_put_int(&buffer, BN_num_bits(key->n)); - buffer_put_bignum(&buffer, key->e); - buffer_put_bignum(&buffer, key->n); - - /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(&buffer); - PUT_32BIT(buf, len); - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(&buffer), - buffer_len(&buffer)) != buffer_len(&buffer)) { - error("Error writing to authentication socket."); -error_cleanup: - buffer_free(&buffer); - return 0; - } - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - goto error_cleanup; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Remove identity response too long: %d", len); - - /* Read the rest of the response in tothe buffer. */ - buffer_clear(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - goto error_cleanup; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - type = buffer_get_char(&buffer); - switch (type) { - case SSH_AGENT_FAILURE: - buffer_free(&buffer); - return 0; - case SSH_AGENT_SUCCESS: - buffer_free(&buffer); - return 1; - default: - fatal("Bad response to remove identity from authentication agent: %d", - type); - } - /* NOTREACHED */ - return 0; -} - -/* - * Removes all identities from the agent. This call is not meant to be used - * by normal applications. - */ - -int -ssh_remove_all_identities(AuthenticationConnection *auth) -{ - Buffer buffer; - unsigned char buf[8192]; - int len, l, type; - - /* Get the length of the message, and format it in the buffer. */ - PUT_32BIT(buf, 1); - buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES; - - /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 5) != 5) { - error("Error writing to authentication socket."); - return 0; - } - /* - * Wait for response from the agent. First read the length of the - * response packet. - */ - len = 4; - while (len > 0) { - l = read(auth->fd, buf + 4 - len, len); - if (l <= 0) { - error("Error reading response length from authentication socket."); - return 0; - } - len -= l; - } - - /* Extract the length, and check it for sanity. */ - len = GET_32BIT(buf); - if (len > 256 * 1024) - fatal("Remove identity response too long: %d", len); - - /* Read the rest of the response into the buffer. */ - buffer_init(&buffer); - while (len > 0) { - l = len; - if (l > sizeof(buf)) - l = sizeof(buf); - l = read(auth->fd, buf, l); - if (l <= 0) { - error("Error reading response from authentication socket."); - buffer_free(&buffer); - return 0; - } - buffer_append(&buffer, (char *) buf, l); - len -= l; - } - - /* Get the type of the packet. */ - type = buffer_get_char(&buffer); - switch (type) { - case SSH_AGENT_FAILURE: - buffer_free(&buffer); - return 0; - case SSH_AGENT_SUCCESS: - buffer_free(&buffer); - return 1; - default: - fatal("Bad response to remove identity from authentication agent: %d", - type); - } - /* NOTREACHED */ - return 0; -} diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h deleted file mode 100644 index fbeea2334dc8..000000000000 --- a/crypto/openssh/authfd.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * authfd.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Mar 29 01:17:41 1995 ylo - * - * Functions to interface with the SSH_AUTHENTICATION_FD socket. - * - */ - -/* RCSID("$Id: authfd.h,v 1.7 2000/04/14 10:30:30 markus Exp $"); */ - -#ifndef AUTHFD_H -#define AUTHFD_H - -#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 - -typedef struct { - int fd; - Buffer packet; - Buffer identities; - int howmany; -} AuthenticationConnection; -/* Returns the number of the authentication fd, or -1 if there is none. */ -int ssh_get_authentication_socket(); - -/* - * This should be called for any descriptor returned by - * ssh_get_authentication_socket(). Depending on the way the descriptor was - * obtained, this may close the descriptor. - */ -void ssh_close_authentication_socket(int authfd); - -/* - * Opens and connects a private socket for communication with the - * authentication agent. Returns NULL if an error occurred and the - * connection could not be opened. The connection should be closed by the - * caller by calling ssh_close_authentication_connection(). - */ -AuthenticationConnection *ssh_get_authentication_connection(); - -/* - * Closes the connection to the authentication agent and frees any associated - * memory. - */ -void ssh_close_authentication_connection(AuthenticationConnection * ac); - -/* - * Returns the first authentication identity held by the agent. Returns true - * if an identity is available, 0 otherwise. The caller must initialize the - * integers before the call, and free the comment after a successful call - * (before calling ssh_get_next_identity). - */ -int -ssh_get_first_identity(AuthenticationConnection * connection, - BIGNUM * e, BIGNUM * n, char **comment); - -/* - * Returns the next authentication identity for the agent. Other functions - * can be called between this and ssh_get_first_identity or two calls of this - * function. This returns 0 if there are no more identities. The caller - * must free comment after a successful return. - */ -int -ssh_get_next_identity(AuthenticationConnection * connection, - BIGNUM * e, BIGNUM * n, char **comment); - -/* Requests the agent to decrypt the given challenge. Returns true if - the agent claims it was able to decrypt it. */ -int -ssh_decrypt_challenge(AuthenticationConnection * auth, - BIGNUM * e, BIGNUM * n, BIGNUM * challenge, - unsigned char session_id[16], - unsigned int response_type, - unsigned char response[16]); - -/* - * Adds an identity to the authentication server. This call is not meant to - * be used by normal applications. This returns true if the identity was - * successfully added. - */ -int -ssh_add_identity(AuthenticationConnection * connection, RSA * key, - const char *comment); - -/* - * Removes the identity from the authentication server. This call is not - * meant to be used by normal applications. This returns true if the - * identity was successfully added. - */ -int ssh_remove_identity(AuthenticationConnection * connection, RSA * key); - -/* - * Removes all identities from the authentication agent. This call is not - * meant to be used by normal applications. This returns true if the - * operation was successful. - */ -int ssh_remove_all_identities(AuthenticationConnection * connection); - -/* Closes the connection to the authentication agent. */ -void ssh_close_authentication(AuthenticationConnection * connection); - -#endif /* AUTHFD_H */ diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c deleted file mode 100644 index 92740c48a1c2..000000000000 --- a/crypto/openssh/authfile.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * - * authfile.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Mon Mar 27 03:52:05 1995 ylo - * - * This file contains functions for reading and writing identity files, and - * for reading the passphrase from the user. - * - */ - -#include "includes.h" -RCSID("$Id: authfile.c,v 1.16 2000/04/26 21:28:32 markus Exp $"); - -#include <openssl/bn.h> -#include <openssl/dsa.h> -#include <openssl/rsa.h> -#include <openssl/pem.h> -#include <openssl/evp.h> - -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "cipher.h" -#include "ssh.h" -#include "key.h" - -/* Version identification string for identity files. */ -#define 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. - */ - -int -save_private_key_rsa(const char *filename, const char *passphrase, - RSA *key, const char *comment) -{ - Buffer buffer, encrypted; - char buf[100], *cp; - int fd, i; - CipherContext cipher; - int cipher_type; - u_int32_t rand; - - /* - * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting - * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. - */ - if (strcmp(passphrase, "") == 0) - cipher_type = SSH_CIPHER_NONE; - else - cipher_type = SSH_AUTHFILE_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->d); - buffer_put_bignum(&buffer, key->iqmp); - buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ - buffer_put_bignum(&buffer, key->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. */ - cp = AUTHFILE_ID_STRING; - for (i = 0; cp[i]; i++) - buffer_put_char(&encrypted, cp[i]); - buffer_put_char(&encrypted, 0); - - /* Store cipher type. */ - buffer_put_char(&encrypted, cipher_type); - 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->n)); - buffer_put_bignum(&encrypted, key->n); - buffer_put_bignum(&encrypted, key->e); - buffer_put_string(&encrypted, comment, strlen(comment)); - - /* Allocate space for the private part of the key in the buffer. */ - buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); - - cipher_set_key_string(&cipher, cipher_type, passphrase); - cipher_encrypt(&cipher, (unsigned char *) cp, - (unsigned char *) buffer_ptr(&buffer), - buffer_len(&buffer)); - memset(&cipher, 0, sizeof(cipher)); - - /* Destroy temporary data. */ - memset(buf, 0, sizeof(buf)); - buffer_free(&buffer); - - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd < 0) - return 0; - if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) != - buffer_len(&encrypted)) { - debug("Write to key file %.200s failed: %.100s", filename, - strerror(errno)); - buffer_free(&encrypted); - close(fd); - remove(filename); - return 0; - } - close(fd); - buffer_free(&encrypted); - return 1; -} - -/* save DSA key in OpenSSL PEM format */ - -int -save_private_key_dsa(const char *filename, const char *passphrase, - DSA *dsa, const char *comment) -{ - FILE *fp; - int fd; - int success = 1; - int len = strlen(passphrase); - - if (len > 0 && len <= 4) { - error("passphrase too short: %d bytes", len); - errno = 0; - return 0; - } - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd < 0) { - debug("open %s failed", filename); - return 0; - } - fp = fdopen(fd, "w"); - if (fp == NULL ) { - debug("fdopen %s failed", filename); - close(fd); - return 0; - } - if (len > 0) { - if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(), - (char *)passphrase, strlen(passphrase), NULL, NULL)) - success = 0; - } else { - if (!PEM_write_DSAPrivateKey(fp, dsa, NULL, - NULL, 0, NULL, NULL)) - success = 0; - } - fclose(fp); - return success; -} - -int -save_private_key(const char *filename, const char *passphrase, Key *key, - const char *comment) -{ - switch (key->type) { - case KEY_RSA: - return save_private_key_rsa(filename, passphrase, key->rsa, comment); - break; - case KEY_DSA: - return save_private_key_dsa(filename, passphrase, key->dsa, comment); - break; - default: - break; - } - return 0; -} - -/* - * Loads the public part of the key file. Returns 0 if an error was - * encountered (the file does not exist or is not readable), and non-zero - * otherwise. - */ - -int -load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) -{ - int fd, i; - off_t len; - Buffer buffer; - char *cp; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return 0; - len = lseek(fd, (off_t) 0, SEEK_END); - lseek(fd, (off_t) 0, SEEK_SET); - - buffer_init(&buffer); - buffer_append_space(&buffer, &cp, 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 0; - } - close(fd); - - /* Check that it is at least big enought to contain the ID string. */ - if (len < strlen(AUTHFILE_ID_STRING) + 1) { - debug("Bad key file %.200s.", filename); - buffer_free(&buffer); - return 0; - } - /* - * Make sure it begins with the id string. Consume the id string - * from the buffer. - */ - for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) - if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { - debug("Bad key file %.200s.", filename); - buffer_free(&buffer); - return 0; - } - /* 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. */ - buffer_get_int(&buffer); - /* XXX alloc */ - if (pub->n == NULL) - pub->n = BN_new(); - buffer_get_bignum(&buffer, pub->n); - /* XXX alloc */ - if (pub->e == NULL) - pub->e = BN_new(); - buffer_get_bignum(&buffer, pub->e); - if (comment_return) - *comment_return = buffer_get_string(&buffer, NULL); - /* The encrypted private part is not parsed by this function. */ - - buffer_free(&buffer); - - return 1; -} - -int -load_public_key(const char *filename, Key * key, char **comment_return) -{ - switch (key->type) { - case KEY_RSA: - return load_public_key_rsa(filename, key->rsa, comment_return); - break; - case KEY_DSA: - default: - break; - } - return 0; -} - -/* - * 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. - */ - -int -load_private_key_rsa(int fd, const char *filename, - const char *passphrase, RSA * prv, char **comment_return) -{ - int i, check1, check2, cipher_type; - off_t len; - Buffer buffer, decrypted; - char *cp; - CipherContext cipher; - BN_CTX *ctx; - BIGNUM *aux; - - len = lseek(fd, (off_t) 0, SEEK_END); - lseek(fd, (off_t) 0, SEEK_SET); - - buffer_init(&buffer); - buffer_append_space(&buffer, &cp, 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 0; - } - close(fd); - - /* Check that it is at least big enought to contain the ID string. */ - if (len < strlen(AUTHFILE_ID_STRING) + 1) { - debug("Bad key file %.200s.", filename); - buffer_free(&buffer); - return 0; - } - /* - * Make sure it begins with the id string. Consume the id string - * from the buffer. - */ - for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) - if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { - debug("Bad key file %.200s.", filename); - buffer_free(&buffer); - return 0; - } - /* Read cipher type. */ - cipher_type = buffer_get_char(&buffer); - (void) buffer_get_int(&buffer); /* Reserved data. */ - - /* Read the public key from the buffer. */ - buffer_get_int(&buffer); - prv->n = BN_new(); - buffer_get_bignum(&buffer, prv->n); - prv->e = BN_new(); - buffer_get_bignum(&buffer, prv->e); - if (comment_return) - *comment_return = buffer_get_string(&buffer, NULL); - else - xfree(buffer_get_string(&buffer, NULL)); - - /* Check that it is a supported cipher. */ - if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) & - (1 << cipher_type)) == 0) { - debug("Unsupported cipher %.100s used in key file %.200s.", - cipher_name(cipher_type), filename); - buffer_free(&buffer); - goto fail; - } - /* Initialize space for decrypted data. */ - buffer_init(&decrypted); - buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); - - /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ - cipher_set_key_string(&cipher, cipher_type, passphrase); - cipher_decrypt(&cipher, (unsigned char *) cp, - (unsigned char *) buffer_ptr(&buffer), - buffer_len(&buffer)); - - 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); -fail: - BN_clear_free(prv->n); - prv->n = NULL; - BN_clear_free(prv->e); - prv->e = NULL; - if (comment_return) - xfree(*comment_return); - return 0; - } - /* Read the rest of the private key. */ - prv->d = BN_new(); - buffer_get_bignum(&decrypted, prv->d); - prv->iqmp = BN_new(); - buffer_get_bignum(&decrypted, prv->iqmp); /* u */ - /* in SSL and SSH p and q are exchanged */ - prv->q = BN_new(); - buffer_get_bignum(&decrypted, prv->q); /* p */ - prv->p = BN_new(); - buffer_get_bignum(&decrypted, prv->p); /* q */ - - ctx = BN_CTX_new(); - aux = BN_new(); - - BN_sub(aux, prv->q, BN_value_one()); - prv->dmq1 = BN_new(); - BN_mod(prv->dmq1, prv->d, aux, ctx); - - BN_sub(aux, prv->p, BN_value_one()); - prv->dmp1 = BN_new(); - BN_mod(prv->dmp1, prv->d, aux, ctx); - - BN_clear_free(aux); - BN_CTX_free(ctx); - - buffer_free(&decrypted); - - return 1; -} - -int -load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return) -{ - DSA *dsa; - BIO *in; - FILE *fp; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - error("BIO_new failed"); - return 0; - } - fp = fdopen(fd, "r"); - if (fp == NULL) { - error("fdopen failed"); - return 0; - } - BIO_set_fp(in, fp, BIO_NOCLOSE); - dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase); - if (dsa == NULL) { - debug("PEM_read_bio_DSAPrivateKey failed"); - } else { - /* replace k->dsa with loaded key */ - DSA_free(k->dsa); - k->dsa = dsa; - } - BIO_free(in); - fclose(fp); - if (comment_return) - *comment_return = xstrdup("dsa w/o comment"); - debug("read DSA private key done"); -#ifdef DEBUG_DSS - DSA_print_fp(stderr, dsa, 8); -#endif - return dsa != NULL ? 1 : 0; -} - -int -load_private_key(const char *filename, const char *passphrase, Key *key, - char **comment_return) -{ - int fd; - int ret = 0; - struct stat st; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return 0; - - /* check owner and modes */ - if (fstat(fd, &st) < 0 || - (st.st_uid != 0 && st.st_uid != getuid()) || - (st.st_mode & 077) != 0) { - close(fd); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("Bad ownership or mode(0%3.3o) for '%s'.", - st.st_mode & 0777, filename); - error("It is recommended that your private key files are NOT accessible by others."); - return 0; - } - switch (key->type) { - case KEY_RSA: - if (key->rsa->e != NULL) { - BN_clear_free(key->rsa->e); - key->rsa->e = NULL; - } - if (key->rsa->n != NULL) { - BN_clear_free(key->rsa->n); - key->rsa->n = NULL; - } - ret = load_private_key_rsa(fd, filename, passphrase, - key->rsa, comment_return); - break; - case KEY_DSA: - ret = load_private_key_dsa(fd, passphrase, key, comment_return); - default: - break; - } - close(fd); - return ret; -} diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h deleted file mode 100644 index afec27d5433e..000000000000 --- a/crypto/openssh/authfile.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef AUTHFILE_H -#define AUTHFILE_H - -/* - * Saves the authentication (private) key in a file, encrypting it with - * passphrase. - * For RSA keys: The identification of the file (lowest 64 bits of n) - * will precede the key to provide identification of the key without - * needing a passphrase. - */ -int -save_private_key(const char *filename, const char *passphrase, - Key * private_key, const char *comment); - -/* - * Loads the public part of the key file (public key and comment). Returns 0 - * if an error occurred; zero if the public key was successfully read. The - * comment of the key is returned in comment_return if it is non-NULL; the - * caller must free the value with xfree. - */ -int -load_public_key(const char *filename, Key * pub, - char **comment_return); - -/* - * 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. The comment of the key is returned in - * comment_return if it is non-NULL; the caller must free the value with - * xfree. - */ -int -load_private_key(const char *filename, const char *passphrase, - Key * private_key, char **comment_return); - -#endif diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c deleted file mode 100644 index 922acc4e1146..000000000000 --- a/crypto/openssh/bufaux.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * - * bufaux.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Mar 29 02:24:47 1995 ylo - * - * Auxiliary functions for storing and retrieving various data types to/from - * Buffers. - * - * SSH2 packet format added by Markus Friedl - * - */ - -#include "includes.h" -RCSID("$Id: bufaux.c,v 1.11 2000/04/14 10:30:30 markus Exp $"); - -#include "ssh.h" -#include <openssl/bn.h> -#include "bufaux.h" -#include "xmalloc.h" -#include "getput.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. - */ -void -buffer_put_bignum(Buffer *buffer, BIGNUM *value) -{ - int bits = BN_num_bits(value); - int bin_size = (bits + 7) / 8; - char unsigned *buf = xmalloc(bin_size); - int oi; - char msg[2]; - - /* Get the value of in binary */ - oi = BN_bn2bin(value, buf); - if (oi != bin_size) - fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", - oi, bin_size); - - /* 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); -} - -/* - * Retrieves an BIGNUM from the buffer. - */ -int -buffer_get_bignum(Buffer *buffer, BIGNUM *value) -{ - int bits, bytes; - unsigned char buf[2], *bin; - - /* Get the number for bits. */ - buffer_get(buffer, (char *) buf, 2); - bits = GET_16BIT(buf); - /* Compute the number of binary bytes that follow. */ - bytes = (bits + 7) / 8; - if (buffer_len(buffer) < bytes) - fatal("buffer_get_bignum: input buffer too small"); - bin = (unsigned char*) buffer_ptr(buffer); - BN_bin2bn(bin, bytes, value); - buffer_consume(buffer, bytes); - - return 2 + bytes; -} - -/* - * Stores an BIGNUM in the buffer in SSH2 format. - */ -void -buffer_put_bignum2(Buffer *buffer, BIGNUM *value) -{ - int bytes = BN_num_bytes(value) + 1; - unsigned char *buf = xmalloc(bytes); - int oi; - int hasnohigh = 0; - buf[0] = '\0'; - /* Get the value of in binary */ - oi = BN_bn2bin(value, buf+1); - if (oi != bytes-1) - fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", - oi, bytes); - hasnohigh = (buf[1] & 0x80) ? 0 : 1; - if (value->neg) { - /**XXX should be two's-complement */ - int i, carry; - unsigned char *uc = buf; - log("negativ!"); - for(i = bytes-1, carry = 1; i>=0; i--) { - uc[i] ^= 0xff; - if(carry) - carry = !++uc[i]; - } - } - buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); - memset(buf, 0, bytes); - xfree(buf); -} - -int -buffer_get_bignum2(Buffer *buffer, BIGNUM *value) -{ - /**XXX should be two's-complement */ - int len; - unsigned char *bin = (unsigned char *)buffer_get_string(buffer, (unsigned int *)&len); - BN_bin2bn(bin, len, value); - xfree(bin); - return len; -} - -/* - * Returns an integer from the buffer (4 bytes, msb first). - */ -unsigned int -buffer_get_int(Buffer *buffer) -{ - unsigned char buf[4]; - buffer_get(buffer, (char *) buf, 4); - return GET_32BIT(buf); -} - -/* - * Stores an integer in the buffer in 4 bytes, msb first. - */ -void -buffer_put_int(Buffer *buffer, unsigned int value) -{ - char buf[4]; - PUT_32BIT(buf, value); - buffer_append(buffer, buf, 4); -} - -/* - * 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. - */ -char * -buffer_get_string(Buffer *buffer, unsigned int *length_ptr) -{ - unsigned int len; - char *value; - /* Get the length. */ - len = buffer_get_int(buffer); - if (len > 256 * 1024) - fatal("Received packet with bad string length %d", len); - /* Allocate space for the string. Add one byte for a null character. */ - value = xmalloc(len + 1); - /* Get the string. */ - buffer_get(buffer, value, len); - /* 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; -} - -/* - * Stores and arbitrary binary string in the buffer. - */ -void -buffer_put_string(Buffer *buffer, const void *buf, unsigned int len) -{ - buffer_put_int(buffer, len); - buffer_append(buffer, buf, len); -} -void -buffer_put_cstring(Buffer *buffer, const char *s) -{ - buffer_put_string(buffer, s, strlen(s)); -} - -/* - * Returns a character from the buffer (0 - 255). - */ -int -buffer_get_char(Buffer *buffer) -{ - char ch; - buffer_get(buffer, &ch, 1); - return (unsigned 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/crypto/openssh/bufaux.h b/crypto/openssh/bufaux.h deleted file mode 100644 index 8ba92f8b5925..000000000000 --- a/crypto/openssh/bufaux.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * bufaux.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Mar 29 02:18:23 1995 ylo - * - */ - -/* RCSID("$Id: bufaux.h,v 1.6 2000/04/14 10:30:30 markus Exp $"); */ - -#ifndef BUFAUX_H -#define BUFAUX_H - -#include "buffer.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. - */ -void buffer_put_bignum(Buffer * buffer, BIGNUM * value); -void buffer_put_bignum2(Buffer * buffer, BIGNUM * value); - -/* Retrieves an BIGNUM from the buffer. */ -int buffer_get_bignum(Buffer * buffer, BIGNUM * value); -int buffer_get_bignum2(Buffer *buffer, BIGNUM * value); - -/* Returns an integer from the buffer (4 bytes, msb first). */ -unsigned int buffer_get_int(Buffer * buffer); - -/* Stores an integer in the buffer in 4 bytes, msb first. */ -void buffer_put_int(Buffer * buffer, unsigned int value); - -/* Returns a character from the buffer (0 - 255). */ -int buffer_get_char(Buffer * buffer); - -/* Stores a character in the buffer. */ -void buffer_put_char(Buffer * buffer, int value); - -/* - * 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. - */ -char *buffer_get_string(Buffer * buffer, unsigned int *length_ptr); - -/* Stores and arbitrary binary string in the buffer. */ -void buffer_put_string(Buffer * buffer, const void *buf, unsigned int len); -void buffer_put_cstring(Buffer *buffer, const char *s); - -#endif /* BUFAUX_H */ diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c deleted file mode 100644 index 4d8343322cdf..000000000000 --- a/crypto/openssh/buffer.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * - * buffer.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sat Mar 18 04:15:33 1995 ylo - * - * Functions for manipulating fifo buffers (that can grow if needed). - * - */ - -#include "includes.h" -RCSID("$Id: buffer.c,v 1.6 2000/04/14 10:30:30 markus Exp $"); - -#include "xmalloc.h" -#include "buffer.h" -#include "ssh.h" - -/* Initializes the buffer structure. */ - -void -buffer_init(Buffer *buffer) -{ - buffer->alloc = 4096; - buffer->buf = xmalloc(buffer->alloc); - buffer->offset = 0; - buffer->end = 0; -} - -/* Frees any memory used for the buffer. */ - -void -buffer_free(Buffer *buffer) -{ - memset(buffer->buf, 0, buffer->alloc); - 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 char *data, unsigned int len) -{ - char *cp; - buffer_append_space(buffer, &cp, len); - memcpy(cp, data, len); -} - -/* - * 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, char **datap, unsigned int 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) { - *datap = buffer->buf + buffer->end; - buffer->end += len; - return; - } - /* - * If the buffer is quite empty, but all data is at the end, move the - * data to the beginning and retry. - */ - if (buffer->offset > buffer->alloc / 2) { - memmove(buffer->buf, buffer->buf + buffer->offset, - buffer->end - buffer->offset); - buffer->end -= buffer->offset; - buffer->offset = 0; - goto restart; - } - /* Increase the size of the buffer and retry. */ - buffer->alloc += len + 32768; - buffer->buf = xrealloc(buffer->buf, buffer->alloc); - goto restart; -} - -/* Returns the number of bytes of data in the buffer. */ - -unsigned int -buffer_len(Buffer *buffer) -{ - return buffer->end - buffer->offset; -} - -/* Gets data from the beginning of the buffer. */ - -void -buffer_get(Buffer *buffer, char *buf, unsigned int len) -{ - if (len > buffer->end - buffer->offset) - fatal("buffer_get: trying to get more bytes than in buffer"); - memcpy(buf, buffer->buf + buffer->offset, len); - buffer->offset += len; -} - -/* Consumes the given number of bytes from the beginning of the buffer. */ - -void -buffer_consume(Buffer *buffer, unsigned int bytes) -{ - if (bytes > buffer->end - buffer->offset) - fatal("buffer_consume: trying to get more bytes than in buffer"); - buffer->offset += bytes; -} - -/* Consumes the given number of bytes from the end of the buffer. */ - -void -buffer_consume_end(Buffer *buffer, unsigned int bytes) -{ - if (bytes > buffer->end - buffer->offset) - fatal("buffer_consume_end: trying to get more bytes than in buffer"); - buffer->end -= bytes; -} - -/* Returns a pointer to the first used byte in the buffer. */ - -char * -buffer_ptr(Buffer *buffer) -{ - return buffer->buf + buffer->offset; -} - -/* Dumps the contents of the buffer to stderr. */ - -void -buffer_dump(Buffer *buffer) -{ - int i; - unsigned char *ucp = (unsigned char *) buffer->buf; - - for (i = buffer->offset; i < buffer->end; i++) - fprintf(stderr, " %02x", ucp[i]); - fprintf(stderr, "\n"); -} diff --git a/crypto/openssh/buffer.h b/crypto/openssh/buffer.h deleted file mode 100644 index be4fdc3cabd5..000000000000 --- a/crypto/openssh/buffer.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * buffer.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sat Mar 18 04:12:25 1995 ylo - * - * Code for manipulating FIFO buffers. - * - */ - -/* RCSID("$Id: buffer.h,v 1.4 2000/04/14 10:30:30 markus Exp $"); */ - -#ifndef BUFFER_H -#define BUFFER_H - -typedef struct { - char *buf; /* Buffer for data. */ - unsigned int alloc; /* Number of bytes allocated for data. */ - unsigned int offset; /* Offset of first byte containing data. */ - unsigned int end; /* Offset of last byte containing data. */ -} Buffer; -/* Initializes the buffer structure. */ -void buffer_init(Buffer * buffer); - -/* Frees any memory used for the buffer. */ -void buffer_free(Buffer * buffer); - -/* Clears any data from the buffer, making it empty. This does not actually - zero the memory. */ -void buffer_clear(Buffer * buffer); - -/* Appends data to the buffer, expanding it if necessary. */ -void buffer_append(Buffer * buffer, const char *data, unsigned int len); - -/* - * 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, char **datap, unsigned int len); - -/* Returns the number of bytes of data in the buffer. */ -unsigned int buffer_len(Buffer * buffer); - -/* Gets data from the beginning of the buffer. */ -void buffer_get(Buffer * buffer, char *buf, unsigned int len); - -/* Consumes the given number of bytes from the beginning of the buffer. */ -void buffer_consume(Buffer * buffer, unsigned int bytes); - -/* Consumes the given number of bytes from the end of the buffer. */ -void buffer_consume_end(Buffer * buffer, unsigned int bytes); - -/* Returns a pointer to the first used byte in the buffer. */ -char *buffer_ptr(Buffer * buffer); - -/* - * Dumps the contents of the buffer to stderr in hex. This intended for - * debugging purposes only. - */ -void buffer_dump(Buffer * buffer); - -#endif /* BUFFER_H */ diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c deleted file mode 100644 index a73f8d0ecf2d..000000000000 --- a/crypto/openssh/canohost.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * - * canohost.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sun Jul 2 17:52:22 1995 ylo - * - * Functions for returning the canonical host name of the remote site. - * - */ - -#include "includes.h" -RCSID("$Id: canohost.c,v 1.12 2000/04/14 10:30:30 markus Exp $"); - -#include "packet.h" -#include "xmalloc.h" -#include "ssh.h" - -/* - * Return the canonical name of the host at the other end of the socket. The - * caller should free the returned string with xfree. - */ - -char * -get_remote_hostname(int socket) -{ - struct sockaddr_storage from; - int i; - socklen_t fromlen; - struct addrinfo hints, *ai, *aitop; - char name[MAXHOSTNAMELEN]; - char 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 (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), - NULL, 0, NI_NUMERICHOST) != 0) - fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); - - /* Map the IP address to a host name. */ - if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), - NULL, 0, NI_NAMEREQD) == 0) { - /* 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); - strlcpy(name, ntop, sizeof name); - goto check_ip_options; - } - /* 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); - strlcpy(name, ntop, sizeof name); - goto check_ip_options; - } - /* Address was found for the host name. We accept the host name. */ - } else { - /* Host name not found. Use ascii representation of the address. */ - strlcpy(name, ntop, sizeof name); - log("Could not reverse map address %.100s.", name); - } - -check_ip_options: - - /* - * If IP options are supported, make sure there are none (log and - * disconnect them if any are found). Basically we are worried about - * source routing; it can be used to pretend you are somebody - * (ip-address) you are not. That itself may be "almost acceptable" - * under certain circumstances, but rhosts autentication is useless - * if source routing is accepted. Notice also that if we just dropped - * source routing here, the other side could use IP spoofing to do - * rest of the interaction and could still bypass security. So we - * exit here if we detect any IP options. - */ - /* IP options -- IPv4 only */ - if (from.ss_family == AF_INET) { - unsigned char options[200], *ucp; - char text[1024], *cp; - socklen_t option_size; - int ipproto; - struct protoent *ip; - - if ((ip = getprotobyname("ip")) != NULL) - ipproto = ip->p_proto; - else - ipproto = IPPROTO_IP; - option_size = sizeof(options); - if (getsockopt(0, ipproto, IP_OPTIONS, (char *) options, - &option_size) >= 0 && option_size != 0) { - cp = text; - /* Note: "text" buffer must be at least 3x as big as options. */ - for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3) - sprintf(cp, " %2.2x", *ucp); - log("Connection from %.100s with IP options:%.800s", - ntop, text); - packet_disconnect("Connection from %.100s with IP options:%.800s", - ntop, text); - } - } - - 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() -{ - static char *canonical_host_name = NULL; - - /* Check if we have previously retrieved this same name. */ - if (canonical_host_name != NULL) - 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()); - else - canonical_host_name = xstrdup("UNKNOWN"); - - return canonical_host_name; -} - -/* - * Returns the IP-address of the remote host as a string. The returned - * string must not be freed. - */ - -const char * -get_remote_ipaddr() -{ - static char *canonical_host_ip = NULL; - struct sockaddr_storage from; - socklen_t fromlen; - int socket; - char ntop[NI_MAXHOST]; - - /* Check whether we have chached the name. */ - if (canonical_host_ip != NULL) - return canonical_host_ip; - - /* If not a socket, return UNKNOWN. */ - if (!packet_connection_is_on_socket()) { - canonical_host_ip = xstrdup("UNKNOWN"); - return canonical_host_ip; - } - /* Get client socket. */ - socket = packet_get_connection_in(); - - /* 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(); - } - /* Get the IP address in ascii. */ - if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), - NULL, 0, NI_NUMERICHOST) != 0) - fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); - - canonical_host_ip = xstrdup(ntop); - - /* Return ip address string. */ - return canonical_host_ip; -} - -/* Returns the local/remote port for the socket. */ - -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. */ - -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() -{ - return get_port(0); -} - -int -get_local_port() -{ - return get_port(1); -} diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c deleted file mode 100644 index 5bf1e5b7aea7..000000000000 --- a/crypto/openssh/channels.c +++ /dev/null @@ -1,2277 +0,0 @@ -/* - * - * channels.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 24 16:35:24 1995 ylo - * - * This file contains functions for generic socket connection forwarding. - * There is also code for initiating connection forwarding for X11 connections, - * arbitrary tcp/ip connections, and the authentication agent connection. - * - * SSH2 support added by Markus Friedl. - */ - -#include "includes.h" -RCSID("$Id: channels.c,v 1.57 2000/05/08 17:42:24 markus Exp $"); - -#include "ssh.h" -#include "packet.h" -#include "xmalloc.h" -#include "buffer.h" -#include "authfd.h" -#include "uidswap.h" -#include "readconf.h" -#include "servconf.h" - -#include "channels.h" -#include "nchan.h" -#include "compat.h" - -#include "ssh2.h" - -/* Maximum number of fake X11 displays to try. */ -#define MAX_DISPLAYS 1000 - -/* Max len of agent socket */ -#define MAX_SOCKET_NAME 100 - -/* default window/packet sizes for tcp/x11-fwd-channel */ -#define CHAN_TCP_WINDOW_DEFAULT (8*1024) -#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2) -#define CHAN_X11_WINDOW_DEFAULT (4*1024) -#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) - -/* - * Pointer to an array containing all allocated channels. The array is - * dynamically extended as needed. - */ -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 are marked with type - * SSH_CHANNEL_FREE. - */ -static int channels_alloc = 0; - -/* - * Maximum file descriptor value used in any of the channels. This is - * updated in channel_allocate. - */ -static int channel_max_fd_value = 0; - -/* Name and directory of socket for authentication agent forwarding. */ -static char *channel_forwarded_auth_socket_name = NULL; -static char *channel_forwarded_auth_socket_dir = NULL; - -/* Saved X11 authentication protocol name. */ -char *x11_saved_proto = NULL; - -/* Saved X11 authentication data. This is the real data. */ -char *x11_saved_data = NULL; -unsigned 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. - */ -char *x11_fake_data = NULL; -unsigned int x11_fake_data_len; - -/* - * 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; - -/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */ -static int have_hostname_in_open = 0; - -/* Sets specific protocol options. */ - -void -channel_set_options(int hostname_in_open) -{ - have_hostname_in_open = hostname_in_open; -} - -/* - * Permits opening to any host/port in SSH_MSG_PORT_OPEN. 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() -{ - all_opens_permitted = 1; -} - -/* lookup channel by id */ - -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->type == SSH_CHANNEL_FREE) { - log("channel_lookup: %d: bad id: channel free", id); - return NULL; - } - return c; -} - -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) - return; - debug("fd %d setting O_NONBLOCK", fd); - val |= O_NONBLOCK; - if (fcntl(fd, F_SETFL, val) == -1) - error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno)); -} - -/* - * Register filedescriptors for a channel, used when allocating a channel or - * when the channel consumer/producer is ready, e.g. shell exec'd - */ - -void -channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage) -{ - /* Update the maximum file descriptor value. */ - if (rfd > channel_max_fd_value) - channel_max_fd_value = rfd; - if (wfd > channel_max_fd_value) - channel_max_fd_value = wfd; - if (efd > channel_max_fd_value) - channel_max_fd_value = 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; - 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. - */ - -int -channel_new(char *ctype, int type, int rfd, int wfd, int efd, - int window, int maxpack, int extusage, char *remote_name) -{ - int i, found; - Channel *c; - - /* Do initial allocation if this is the first call. */ - if (channels_alloc == 0) { - chan_init(); - channels_alloc = 10; - channels = xmalloc(channels_alloc * sizeof(Channel)); - for (i = 0; i < channels_alloc; i++) - channels[i].type = SSH_CHANNEL_FREE; - /* - * Kludge: arrange a call to channel_stop_listening if we - * terminate with fatal(). - */ - fatal_add_cleanup((void (*) (void *)) channel_stop_listening, 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].type == SSH_CHANNEL_FREE) { - /* 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; - channels_alloc += 10; - debug("channel: expanding %d", channels_alloc); - channels = xrealloc(channels, channels_alloc * sizeof(Channel)); - for (i = found; i < channels_alloc; i++) - channels[i].type = SSH_CHANNEL_FREE; - } - /* Initialize and return new channel number. */ - c = &channels[found]; - buffer_init(&c->input); - buffer_init(&c->output); - buffer_init(&c->extended); - chan_init_iostates(c); - channel_register_fds(c, rfd, wfd, efd, extusage); - 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->cb_fn = NULL; - c->cb_arg = NULL; - c->cb_event = 0; - c->dettach_user = NULL; - debug("channel %d: new [%s]", found, remote_name); - return found; -} -/* old interface XXX */ -int -channel_allocate(int type, int sock, char *remote_name) -{ - return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); -} - - -/* Close all channel fd/socket. */ - -void -channel_close_fds(Channel *c) -{ - if (c->sock != -1) { - close(c->sock); - c->sock = -1; - } - if (c->rfd != -1) { - close(c->rfd); - c->rfd = -1; - } - if (c->wfd != -1) { - close(c->wfd); - c->wfd = -1; - } - if (c->efd != -1) { - close(c->efd); - c->efd = -1; - } -} - -/* Free the channel and close its fd/socket. */ - -void -channel_free(int id) -{ - Channel *c = channel_lookup(id); - if (c == NULL) - packet_disconnect("channel free: bad local channel %d", id); - debug("channel_free: channel %d: status: %s", id, channel_open_message()); - if (c->dettach_user != NULL) { - debug("channel_free: channel %d: dettaching channel user", id); - c->dettach_user(c->self, NULL); - } - 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); - c->type = SSH_CHANNEL_FREE; - if (c->remote_name) { - xfree(c->remote_name); - c->remote_name = NULL; - } -} - -/* - * '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]; - -void -channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - FD_SET(c->sock, readset); -} - -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); -} - -void -channel_pre_open_15(Channel *c, fd_set * readset, fd_set * writeset) -{ - /* test whether sockets are 'alive' for read/write */ - if (c->istate == CHAN_INPUT_OPEN) - if (buffer_len(&c->input) < packet_get_maxsize()) - FD_SET(c->sock, readset); - if (c->ostate == CHAN_OUTPUT_OPEN || - c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { - if (buffer_len(&c->output) > 0) { - FD_SET(c->sock, writeset); - } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { - chan_obuf_empty(c); - } - } -} - -void -channel_pre_open_20(Channel *c, fd_set * readset, fd_set * writeset) -{ - if (c->istate == CHAN_INPUT_OPEN && - c->remote_window > 0 && - buffer_len(&c->input) < c->remote_window) - 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) { - chan_obuf_empty(c); - } - } - /** XXX check close conditions, too */ - if (c->efd != -1) { - if (c->extended_usage == CHAN_EXTENDED_WRITE && - buffer_len(&c->extended) > 0) - FD_SET(c->efd, writeset); - else if (c->extended_usage == CHAN_EXTENDED_READ && - buffer_len(&c->extended) < c->remote_window) - FD_SET(c->efd, readset); - } -} - -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("Closing channel %d after input drain.", c->self); - } -} - -void -channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) -{ - if (buffer_len(&c->output) == 0) - channel_free(c->self); - 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. - */ -int -x11_open_helper(Channel *c) -{ - unsigned char *ucp; - unsigned int proto_len, data_len; - - /* Check if the fixed size part of the packet is in buffer. */ - if (buffer_len(&c->output) < 12) - return 0; - - /* Parse the lengths of variable-length fields. */ - ucp = (unsigned char *) buffer_ptr(&c->output); - 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(&c->output) < - 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; -} - -void -channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) -{ - int ret = x11_open_helper(c); - 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.\r\n"); - buffer_clear(&c->input); - buffer_clear(&c->output); - close(c->sock); - c->sock = -1; - c->type = SSH_CHANNEL_CLOSED; - packet_start(SSH_MSG_CHANNEL_CLOSE); - packet_put_int(c->remote_id); - packet_send(); - } -} - -void -channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) -{ - int ret = x11_open_helper(c); - if (ret == 1) { - c->type = SSH_CHANNEL_OPEN; - if (compat20) - channel_pre_open_20(c, readset, writeset); - else - channel_pre_open_15(c, readset, writeset); - } else if (ret == -1) { - debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); - chan_read_failed(c); /** force close? */ - chan_write_failed(c); - debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); - } -} - -/* This is our fake X11 server socket. */ -void -channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - struct sockaddr addr; - int newsock, newch; - socklen_t addrlen; - char buf[16384], *remote_hostname; - int remote_port; - - if (FD_ISSET(c->sock, readset)) { - debug("X11 connection requested."); - addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); - if (newsock < 0) { - error("accept: %.100s", strerror(errno)); - return; - } - remote_hostname = get_remote_hostname(newsock); - remote_port = get_peer_port(newsock); - snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", - remote_hostname, remote_port); - - newch = channel_new("x11", - SSH_CHANNEL_OPENING, newsock, newsock, -1, - c->local_window_max, c->local_maxpacket, - 0, xstrdup(buf)); - if (compat20) { - packet_start(SSH2_MSG_CHANNEL_OPEN); - packet_put_cstring("x11"); - packet_put_int(newch); - packet_put_int(c->local_window_max); - packet_put_int(c->local_maxpacket); - /* originator host and port */ - packet_put_cstring(remote_hostname); - 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(newch); - if (have_hostname_in_open) - packet_put_string(buf, strlen(buf)); - packet_send(); - } - xfree(remote_hostname); - } -} - -/* - * This socket is listening for connections to a forwarded TCP/IP port. - */ -void -channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - struct sockaddr addr; - int newsock, newch; - socklen_t addrlen; - char buf[1024], *remote_hostname; - int remote_port; - - 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); - addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); - if (newsock < 0) { - error("accept: %.100s", strerror(errno)); - return; - } - remote_hostname = get_remote_hostname(newsock); - remote_port = get_peer_port(newsock); - snprintf(buf, sizeof buf, - "listen port %d for %.100s port %d, " - "connect from %.200s port %d", - c->listening_port, c->path, c->host_port, - remote_hostname, remote_port); - newch = channel_new("direct-tcpip", - SSH_CHANNEL_OPENING, newsock, newsock, -1, - c->local_window_max, c->local_maxpacket, - 0, xstrdup(buf)); - if (compat20) { - packet_start(SSH2_MSG_CHANNEL_OPEN); - packet_put_cstring("direct-tcpip"); - packet_put_int(newch); - packet_put_int(c->local_window_max); - packet_put_int(c->local_maxpacket); - /* target host and port */ - packet_put_string(c->path, strlen(c->path)); - packet_put_int(c->host_port); - /* originator host and port */ - packet_put_cstring(remote_hostname); - packet_put_int(remote_port); - packet_send(); - } else { - packet_start(SSH_MSG_PORT_OPEN); - packet_put_int(newch); - packet_put_string(c->path, strlen(c->path)); - packet_put_int(c->host_port); - if (have_hostname_in_open) { - packet_put_string(buf, strlen(buf)); - } - packet_send(); - } - xfree(remote_hostname); - } -} - -/* - * This is the authentication agent socket listening for connections from - * clients. - */ -void -channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) -{ - struct sockaddr addr; - int newsock, newch; - 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; - } - newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, - xstrdup("accepted auth socket")); - packet_start(SSH_SMSG_AGENT_OPEN); - packet_put_int(newch); - packet_send(); - } -} - -int -channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) -{ - char buf[16*1024]; - 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 (compat13) { - buffer_consume(&c->output, buffer_len(&c->output)); - c->type = SSH_CHANNEL_INPUT_DRAINING; - debug("Channel %d status set to input draining.", c->self); - } else { - chan_read_failed(c); - } - return -1; - } - buffer_append(&c->input, buf, len); - } - return 1; -} -int -channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) -{ - int len; - - /* Send buffered output data to the socket. */ - if (c->wfd != -1 && - FD_ISSET(c->wfd, writeset) && - buffer_len(&c->output) > 0) { - len = write(c->wfd, buffer_ptr(&c->output), - buffer_len(&c->output)); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) - return 1; - if (len <= 0) { - if (compat13) { - buffer_consume(&c->output, buffer_len(&c->output)); - debug("Channel %d status set to input draining.", c->self); - c->type = SSH_CHANNEL_INPUT_DRAINING; - } else { - chan_write_failed(c); - } - return -1; - } - buffer_consume(&c->output, len); - if (compat20 && len > 0) { - c->local_consumed += len; - } - } - return 1; -} -int -channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) -{ - char buf[16*1024]; - 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)); - debug("channel %d: written %d to efd %d", - c->self, len, c->efd); - if (len > 0) { - 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)); - debug("channel %d: read %d from efd %d", - c->self, len, c->efd); - if (len == 0) { - debug("channel %d: closing efd %d", - c->self, c->efd); - close(c->efd); - c->efd = -1; - } else if (len > 0) - buffer_append(&c->extended, buf, len); - } - } - return 1; -} -int -channel_check_window(Channel *c, fd_set * readset, fd_set * writeset) -{ - if (!(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(); - debug("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; -} - -void -channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset) -{ - channel_handle_rfd(c, readset, writeset); - channel_handle_wfd(c, readset, writeset); -} - -void -channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset) -{ - channel_handle_rfd(c, readset, writeset); - channel_handle_wfd(c, readset, writeset); - channel_handle_efd(c, readset, writeset); - channel_check_window(c, readset, writeset); -} - -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_consume(&c->output, buffer_len(&c->output)); - else - buffer_consume(&c->output, len); - } -} - -void -channel_handler_init_20(void) -{ - channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; - channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; - channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; - channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; - - channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; - channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; - channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; -} - -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_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; - 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; -} - -void -channel_handler_init_15(void) -{ - channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15; - 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_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_1; -} - -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(); -} - -void -channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) -{ - static int did_init = 0; - int i; - Channel *c; - - if (!did_init) { - channel_handler_init(); - did_init = 1; - } - for (i = 0; i < channels_alloc; i++) { - c = &channels[i]; - if (c->type == SSH_CHANNEL_FREE) - continue; - if (ftab[c->type] == NULL) - continue; - (*ftab[c->type])(c, readset, writeset); - chan_delete_if_full_closed(c); - } -} - -void -channel_prepare_select(fd_set * readset, fd_set * writeset) -{ - channel_handler(channel_pre, readset, writeset); -} - -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, send some of it now. */ - -void -channel_output_poll() -{ - int len, i; - Channel *c; - - for (i = 0; i < channels_alloc; i++) { - c = &channels[i]; - - /* 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 (c->istate != CHAN_INPUT_OPEN && - c->istate != CHAN_INPUT_WAIT_DRAIN) - continue; - } - if (compat20 && - (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { - debug("channel: %d: no data after CLOSE", c->self); - continue; - } - - /* Get the amount of buffered data for this channel. */ - len = buffer_len(&c->input); - if (len > 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; - debug("channel %d: send data len %d", c->self, 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 - */ - chan_ibuf_empty(c); - } - /* Send extended data, i.e. stderr */ - if (compat20 && - c->remote_window > 0 && - (len = buffer_len(&c->extended)) > 0 && - c->extended_usage == CHAN_EXTENDED_READ) { - 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; - } - } -} - -/* - * This is called when a packet of type CHANNEL_DATA has just been received. - * The message type has already been consumed, but channel number and data is - * still there. - */ - -void -channel_input_data(int type, int plen) -{ - int id; - char *data; - unsigned 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); - packet_done(); - - 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; - }else{ - packet_integrity_check(plen, 4 + 4 + data_len, type); - } - buffer_append(&c->output, data, data_len); - xfree(data); -} -void -channel_input_extended_data(int type, int plen) -{ - int id; - int tcode; - char *data; - unsigned 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 extended_data for bad channel %d.", id); - if (c->type != SSH_CHANNEL_OPEN) { - log("channel %d: ext data for non open", id); - return; - } - 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_done(); - 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; - } - debug("channel %d: rcvd ext data %d", c->self, data_len); - c->local_window -= data_len; - buffer_append(&c->extended, data, data_len); - xfree(data); -} - - -/* - * 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() -{ - unsigned int i; - Channel *c; - - for (i = 0; i < channels_alloc; i++) { - c = &channels[i]; - if (c->type == SSH_CHANNEL_OPEN) { - if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) { - debug("channel %d: big input buffer %d", - c->self, buffer_len(&c->input)); - return 0; - } - if (buffer_len(&c->output) > packet_get_maxsize()) { - debug("channel %d: big output buffer %d", - c->self, buffer_len(&c->output)); - return 0; - } - } - } - return 1; -} - -void -channel_input_ieof(int type, int plen) -{ - int id; - Channel *c; - - packet_integrity_check(plen, 4, type); - - id = packet_get_int(); - c = channel_lookup(id); - if (c == NULL) - packet_disconnect("Received ieof for nonexistent channel %d.", id); - chan_rcvd_ieof(c); -} - -void -channel_input_close(int type, int plen) -{ - int id; - Channel *c; - - packet_integrity_check(plen, 4, type); - - id = packet_get_int(); - 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_consume(&c->input, buffer_len(&c->input)); - c->type = SSH_CHANNEL_OUTPUT_DRAINING; - } -} - -/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ -void -channel_input_oclose(int type, int plen) -{ - int id = packet_get_int(); - Channel *c = channel_lookup(id); - packet_integrity_check(plen, 4, type); - if (c == NULL) - packet_disconnect("Received oclose for nonexistent channel %d.", id); - chan_rcvd_oclose(c); -} - -void -channel_input_close_confirmation(int type, int plen) -{ - int id = packet_get_int(); - Channel *c = channel_lookup(id); - - packet_done(); - 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->self); -} - -void -channel_input_open_confirmation(int type, int plen) -{ - int id, remote_id; - Channel *c; - - if (!compat20) - packet_integrity_check(plen, 4 + 4, type); - - 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(); - packet_done(); - if (c->cb_fn != NULL && c->cb_event == type) { - debug("callback start"); - c->cb_fn(c->self, c->cb_arg); - debug("callback done"); - } - debug("channel %d: open confirm rwindow %d rmax %d", c->self, - c->remote_window, c->remote_maxpacket); - } -} - -void -channel_input_open_failure(int type, int plen) -{ - int id; - Channel *c; - - if (!compat20) - packet_integrity_check(plen, 4, type); - - 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) { - int reason = packet_get_int(); - char *msg = packet_get_string(NULL); - char *lang = packet_get_string(NULL); - log("channel_open_failure: %d: reason %d: %s", id, reason, msg); - packet_done(); - xfree(msg); - xfree(lang); - } - /* Free the channel. This will also close the socket. */ - channel_free(id); -} - -void -channel_input_channel_request(int type, int plen) -{ - int id; - Channel *c; - - id = packet_get_int(); - c = channel_lookup(id); - - if (c == NULL || - (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_LARVAL)) - packet_disconnect("Received request for " - "non-open channel %d.", id); - if (c->cb_fn != NULL && c->cb_event == type) { - debug("callback start"); - c->cb_fn(c->self, c->cb_arg); - debug("callback done"); - } else { - char *service = packet_get_string(NULL); - debug("channel: %d rcvd request for %s", c->self, service); -debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event); - xfree(service); - } -} - -void -channel_input_window_adjust(int type, int plen) -{ - Channel *c; - int id, 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_done(); - debug("channel %d: rcvd adjust %d", id, adjust); - c->remote_window += adjust; -} - -/* - * Stops listening for channels, and removes any unix domain sockets that we - * might have. - */ - -void -channel_stop_listening() -{ - int i; - for (i = 0; i < channels_alloc; i++) { - switch (channels[i].type) { - case SSH_CHANNEL_AUTH_SOCKET: - close(channels[i].sock); - remove(channels[i].path); - channel_free(i); - break; - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_X11_LISTENER: - close(channels[i].sock); - channel_free(i); - break; - default: - break; - } - } -} - -/* - * Closes the sockets/fds of all channels. This is used to close extra file - * descriptors after a fork. - */ - -void -channel_close_all() -{ - int i; - for (i = 0; i < channels_alloc; i++) - if (channels[i].type != SSH_CHANNEL_FREE) - channel_close_fds(&channels[i]); -} - -/* Returns the maximum file descriptor number used by the channels. */ - -int -channel_max_fd() -{ - return channel_max_fd_value; -} - -/* Returns true if any channel is still open. */ - -int -channel_still_open() -{ - unsigned int i; - for (i = 0; i < channels_alloc; i++) - switch (channels[i].type) { - case SSH_CHANNEL_FREE: - case SSH_CHANNEL_X11_LISTENER: - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_CLOSED: - case SSH_CHANNEL_AUTH_SOCKET: - 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", channels[i].type); - /* NOTREACHED */ - } - return 0; -} - -/* - * 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() -{ - Buffer buffer; - int i; - char buf[512], *cp; - - 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++) { - Channel *c = &channels[i]; - switch (c->type) { - case SSH_CHANNEL_FREE: - case SSH_CHANNEL_X11_LISTENER: - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_CLOSED: - case SSH_CHANNEL_AUTH_SOCKET: - continue; - case SSH_CHANNEL_LARVAL: - case SSH_CHANNEL_OPENING: - 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; -} - -/* - * Initiate forwarding of connections to local port "port" through the secure - * channel to host:port from remote side. - */ - -void -channel_request_local_forwarding(u_short port, const char *host, - u_short host_port, int gateway_ports) -{ - int success, ch, sock, on = 1; - struct addrinfo hints, *ai, *aitop; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - struct linger linger; - - if (strlen(host) > sizeof(channels[0].path) - 1) - packet_disconnect("Forward host name too long."); - - /* - * 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 = gateway_ports ? AI_PASSIVE : 0; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%d", port); - if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) - packet_disconnect("getaddrinfo: fatal error"); - - success = 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_request_local_forwarding: getnameinfo failed"); - continue; - } - /* Create a port to listen for the host. */ - sock = socket(ai->ai_family, SOCK_STREAM, 0); - if (sock < 0) { - /* this is no error since kernel may not support ipv6 */ - verbose("socket: %.100s", strerror(errno)); - continue; - } - /* - * Set socket options. We would like the socket to disappear - * as soon as it has been closed for whatever reason. - */ - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); - linger.l_onoff = 1; - linger.l_linger = 5; - setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger)); - 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 */ - 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. */ - ch = channel_new( - "port listener", SSH_CHANNEL_PORT_LISTENER, - sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, - 0, xstrdup("port listener")); - strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); - channels[ch].host_port = host_port; - channels[ch].listening_port = port; - success = 1; - } - if (success == 0) - packet_disconnect("cannot listen port: %d", port); - freeaddrinfo(aitop); -} - -/* - * Initiate forwarding of connections to port "port" on remote host through - * the secure channel to host:port from local side. - */ - -void -channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect, - u_short port_to_connect) -{ - int payload_len; - /* 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"); - - 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++; - - /* Send the forward request to the remote side. */ - if (compat20) { - const char *address_to_bind = "0.0.0.0"; - packet_start(SSH2_MSG_GLOBAL_REQUEST); - packet_put_cstring("tcpip-forward"); - packet_put_char(0); /* boolean: want reply */ - packet_put_cstring(address_to_bind); - packet_put_int(listen_port); - } 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. It will send a disconnect - * message on failure, and we will never see it here. - */ - packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); - } -} - -/* - * 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(); - - /* - * 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); - /* - * Initiate forwarding, - */ - channel_request_local_forwarding(port, hostname, host_port, gateway_ports); - - /* Free the argument string. */ - xfree(hostname); -} - -/* XXX move to aux.c */ -int -channel_connect_to(const char *host, u_short host_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", host_port); - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { - error("%.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("channel_connect_to: getnameinfo failed"); - continue; - } - /* Create the socket. */ - sock = socket(ai->ai_family, SOCK_STREAM, 0); - if (sock < 0) { - error("socket: %.100s", strerror(errno)); - continue; - } - /* Connect to the host/port. */ - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - error("connect %.100s port %s: %.100s", ntop, strport, - strerror(errno)); - close(sock); - continue; /* fail -- try next */ - } - break; /* success */ - - } - freeaddrinfo(aitop); - if (!ai) { - error("connect %.100s port %d: failed.", host, host_port); - return -1; - } - /* success */ - return sock; -} -/* - * This is called after receiving PORT_OPEN message. This attempts to - * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION - * or CHANNEL_OPEN_FAILURE. - */ - -void -channel_input_port_open(int type, int plen) -{ - u_short host_port; - char *host, *originator_string; - int remote_channel, sock = -1, newch, i, denied; - unsigned int host_len, originator_len; - - /* Get remote channel number. */ - remote_channel = packet_get_int(); - - /* Get host name to connect to. */ - host = packet_get_string(&host_len); - - /* Get port to connect to. */ - host_port = packet_get_int(); - - /* Get remote originator name. */ - if (have_hostname_in_open) { - originator_string = packet_get_string(&originator_len); - originator_len += 4; /* size of packet_int */ - } else { - originator_string = xstrdup("unknown (remote did not supply name)"); - originator_len = 0; /* no originator supplied */ - } - - packet_integrity_check(plen, - 4 + 4 + host_len + 4 + originator_len, SSH_MSG_PORT_OPEN); - - /* Check if opening that port is permitted. */ - denied = 0; - if (!all_opens_permitted) { - /* Go trough all permitted ports. */ - for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].port_to_connect == host_port && - strcmp(permitted_opens[i].host_to_connect, host) == 0) - break; - - /* Check if we found the requested port among those permitted. */ - if (i >= num_permitted_opens) { - /* The port is not permitted. */ - log("Received request to connect to %.100s:%d, but the request was denied.", - host, host_port); - denied = 1; - } - } - sock = denied ? -1 : channel_connect_to(host, host_port); - if (sock > 0) { - /* Allocate a channel for this connection. */ - newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string); - channels[newch].remote_id = remote_channel; - - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remote_channel); - packet_put_int(newch); - packet_send(); - } else { - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_channel); - packet_send(); - } - xfree(host); -} - -/* - * Creates an internet domain socket for listening for X11 connections. - * Returns a suitable value for the DISPLAY variable, or NULL if an error - * occurs. - */ - -#define NUM_SOCKS 10 - -char * -x11_create_display_inet(int screen_number, int x11_display_offset) -{ - 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]; - char display[512]; - char hostname[MAXHOSTNAMELEN]; - - 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 = AI_PASSIVE; /* XXX loopback only ? */ - 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 NULL; - } - 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) { - error("socket: %.100s", strerror(errno)); - return NULL; - } - if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - debug("bind port %d: %.100s", port, strerror(errno)); - shutdown(sock, SHUT_RDWR); - close(sock); - for (n = 0; n < num_socks; n++) { - shutdown(socks[n], SHUT_RDWR); - close(socks[n]); - } - num_socks = 0; - break; - } - socks[num_socks++] = sock; - if (num_socks == NUM_SOCKS) - break; - } - if (num_socks > 0) - break; - } - if (display_number >= MAX_DISPLAYS) { - error("Failed to allocate internet-domain X11 display socket."); - return NULL; - } - /* Start listening for connections on the socket. */ - for (n = 0; n < num_socks; n++) { - sock = socks[n]; - if (listen(sock, 5) < 0) { - error("listen: %.100s", strerror(errno)); - shutdown(sock, SHUT_RDWR); - close(sock); - return NULL; - } - } - - /* Set up a suitable value for the DISPLAY variable. */ - if (gethostname(hostname, sizeof(hostname)) < 0) - fatal("gethostname: %.100s", strerror(errno)); - snprintf(display, sizeof display, "%.400s:%d.%d", hostname, - display_number, screen_number); - - /* Allocate a channel for each socket. */ - for (n = 0; n < num_socks; n++) { - sock = socks[n]; - (void) channel_new("x11 listener", - SSH_CHANNEL_X11_LISTENER, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, - 0, xstrdup("X11 inet listener")); - } - - /* Return a suitable value for the DISPLAY environment variable. */ - return xstrdup(display); -} - -#ifndef X_UNIX_PATH -#define X_UNIX_PATH "/tmp/.X11-unix/X" -#endif - -static -int -connect_local_xsocket(unsigned int dnr) -{ - static const char *const x_sockets[] = { - X_UNIX_PATH "%u", - "/var/X/.X11-unix/X" "%u", - "/usr/spool/sockets/X11/" "%u", - NULL - }; - int sock; - struct sockaddr_un addr; - const char *const * path; - - for (path = x_sockets; *path; ++path) { - 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, 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. - */ - strncpy(buf, display, sizeof(buf)); - buf[sizeof(buf) - 1] = 0; - 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; - } - 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, int plen) -{ - int remote_channel, sock = 0, newch; - char *remote_host; - unsigned int remote_len; - - /* Get remote channel number. */ - remote_channel = packet_get_int(); - - /* Get remote originator name. */ - if (have_hostname_in_open) { - remote_host = packet_get_string(&remote_len); - remote_len += 4; - } else { - remote_host = xstrdup("unknown (remote did not supply name)"); - remote_len = 0; - } - - debug("Received X11 open request."); - packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN); - - /* Obtain a connection to the real X display. */ - sock = x11_connect_display(); - if (sock == -1) { - /* Send refusal to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_channel); - packet_send(); - } else { - /* Allocate a channel for this connection. */ - newch = channel_allocate( - (x11_saved_proto == NULL) ? - SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN, - sock, remote_host); - channels[newch].remote_id = remote_channel; - - /* Send a confirmation to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remote_channel); - packet_put_int(newch); - packet_send(); - } -} - -/* - * Requests forwarding of X11 connections, generates fake authentication - * data, and enables authentication spoofing. - */ - -void -x11_request_forwarding_with_spoofing(int client_session_id, - const char *proto, const char *data) -{ - unsigned int data_len = (unsigned int) strlen(data) / 2; - unsigned int i, value; - char *new_data; - int screen_number; - const char *cp; - u_int32_t rand = 0; - - cp = getenv("DISPLAY"); - if (cp) - cp = strchr(cp, ':'); - 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 = xmalloc(2 * data_len + 1); - for (i = 0; i < data_len; i++) - sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]); - - /* 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); -} - -/* Sends a message to the server to request authentication fd forwarding. */ - -void -auth_request_forwarding() -{ - packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); - packet_send(); - packet_write_wait(); -} - -/* - * Returns the name of the forwarded authentication socket. Returns NULL if - * there is no forwarded authentication socket. The returned value points to - * a static buffer. - */ - -char * -auth_get_socket_name() -{ - return channel_forwarded_auth_socket_name; -} - -/* removes the agent forwarding socket */ - -void -cleanup_socket(void) -{ - remove(channel_forwarded_auth_socket_name); - rmdir(channel_forwarded_auth_socket_dir); -} - -/* - * This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. - * This starts forwarding authentication requests. - */ - -void -auth_input_request_forwarding(struct passwd * pw) -{ - int sock, newch; - struct sockaddr_un sunaddr; - - if (auth_get_socket_name() != NULL) - fatal("Protocol error: authentication forwarding requested twice."); - - /* Temporarily drop privileged uid for mkdir/bind. */ - temporarily_use_uid(pw->pw_uid); - - /* Allocate a buffer for the socket name, and format the name. */ - channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME); - channel_forwarded_auth_socket_dir = xmalloc(MAX_SOCKET_NAME); - strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME); - - /* Create private directory for socket */ - if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL) - packet_disconnect("mkdtemp: %.100s", strerror(errno)); - snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME, "%s/agent.%d", - channel_forwarded_auth_socket_dir, (int) getpid()); - - if (atexit(cleanup_socket) < 0) { - int saved = errno; - cleanup_socket(); - packet_disconnect("socket: %.100s", strerror(saved)); - } - /* 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; - strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_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. */ - newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock, - xstrdup("auth socket")); - strlcpy(channels[newch].path, channel_forwarded_auth_socket_name, - sizeof(channels[newch].path)); -} - -/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ - -void -auth_input_open_request(int type, int plen) -{ - int remch, sock, newch; - char *dummyname; - - packet_integrity_check(plen, 4, type); - - /* Read the remote channel number from the message. */ - remch = packet_get_int(); - - /* - * 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) { - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remch); - packet_send(); - return; - } - debug("Forwarding authentication connection."); - - /* - * Dummy host name. This will be freed when the channel is freed; it - * will still be valid in the packet_put_string below since the - * channel cannot yet be freed at that point. - */ - dummyname = xstrdup("authentication agent connection"); - - newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname); - channels[newch].remote_id = remch; - - /* Send a confirmation to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remch); - packet_put_int(newch); - packet_send(); -} - -void -channel_start_open(int id) -{ - Channel *c = channel_lookup(id); - if (c == NULL) { - log("channel_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); -} -void -channel_open(int id) -{ - /* XXX REMOVE ME */ - channel_start_open(id); - packet_send(); -} -void -channel_request(int id, char *service, int wantconfirm) -{ - channel_request_start(id, service, wantconfirm); - packet_send(); - debug("channel request %d: %s", id, service) ; -} -void -channel_request_start(int id, char *service, int wantconfirm) -{ - Channel *c = channel_lookup(id); - if (c == NULL) { - log("channel_request: %d: bad id", 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_callback(int id, int mtype, channel_callback_fn *fn, void *arg) -{ - Channel *c = channel_lookup(id); - if (c == NULL) { - log("channel_register_callback: %d: bad id", id); - return; - } - c->cb_event = mtype; - c->cb_fn = fn; - c->cb_arg = arg; -} -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->dettach_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->dettach_user = NULL; -} - -void -channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) -{ - 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); - c->type = SSH_CHANNEL_OPEN; - /* XXX window size? */ - c->local_window = c->local_window_max = c->local_maxpacket/2; - packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); - packet_put_int(c->remote_id); - packet_put_int(c->local_window); - packet_send(); -} diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h deleted file mode 100644 index 24ae2b8288f8..000000000000 --- a/crypto/openssh/channels.h +++ /dev/null @@ -1,237 +0,0 @@ -/* RCSID("$Id: channels.h,v 1.12 2000/05/03 18:03:06 markus Exp $"); */ - -#ifndef CHANNELS_H -#define CHANNELS_H - -/* Definitions for channel types. */ -#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */ -#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_MAX_TYPE 11 - -/* - * Data structure for channel data. This is iniailized in channel_allocate - * and cleared in channel_free. - */ -typedef void channel_callback_fn(int id, void *arg); - -typedef struct Channel { - int type; /* channel type/state */ - int self; /* my own channel identifier */ - int remote_id; /* channel identifier for remote peer */ - /* peer can be reached over encrypted connection, via packet-sent */ - int istate; /* input from channel (state of receive half) */ - int ostate; /* output to channel (state of transmit half) */ - int flags; /* close sent/rcvd */ - int rfd; /* read fd */ - int wfd; /* write fd */ - int efd; /* extended fd */ - int sock; /* sock fd */ - 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[200]; /* 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 */ - - int remote_window; - int remote_maxpacket; - int local_window; - int local_window_max; - int local_consumed; - int local_maxpacket; - int extended_usage; - - char *ctype; /* type */ - - /* callback */ - channel_callback_fn *cb_fn; - void *cb_arg; - int cb_event; - channel_callback_fn *dettach_user; -} Channel; - -#define CHAN_EXTENDED_IGNORE 0 -#define CHAN_EXTENDED_READ 1 -#define CHAN_EXTENDED_WRITE 2 - -void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage); -void channel_open(int id); -void channel_request(int id, char *service, int wantconfirm); -void channel_request_start(int id, char *service, int wantconfirm); -void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); -void channel_register_cleanup(int id, channel_callback_fn *fn); -void channel_cancel_cleanup(int id); -Channel *channel_lookup(int id); - -int -channel_new(char *ctype, int type, int rfd, int wfd, int efd, - int window, int maxpack, int extended_usage, char *remote_name); - -void channel_input_channel_request(int type, int plen); -void channel_input_close(int type, int plen); -void channel_input_close_confirmation(int type, int plen); -void channel_input_data(int type, int plen); -void channel_input_extended_data(int type, int plen); -void channel_input_ieof(int type, int plen); -void channel_input_oclose(int type, int plen); -void channel_input_open_confirmation(int type, int plen); -void channel_input_open_failure(int type, int plen); -void channel_input_port_open(int type, int plen); -void channel_input_window_adjust(int type, int plen); -void channel_input_open(int type, int plen); - -/* Sets specific protocol options. */ -void channel_set_options(int hostname_in_open); - -/* - * Allocate a new channel object and set its type and socket. Remote_name - * must have been allocated with xmalloc; this will free it when the channel - * is freed. - */ -int channel_allocate(int type, int sock, char *remote_name); - -/* Free the channel and close its socket. */ -void channel_free(int channel); - -/* Add any bits relevant to channels in select bitmasks. */ -void channel_prepare_select(fd_set * readset, fd_set * writeset); - -/* - * After select, perform any appropriate operations for channels which have - * events pending. - */ -void channel_after_select(fd_set * readset, fd_set * writeset); - -/* If there is data to send to the connection, send some of it now. */ -void channel_output_poll(void); - -/* Returns true if no channel has too much buffered data. */ -int channel_not_very_much_buffered_data(void); - -/* This closes any sockets that are listening for connections; this removes - any unix domain sockets. */ -void channel_stop_listening(void); - -/* - * Closes the sockets of all channels. This is used to close extra file - * descriptors after a fork. - */ -void channel_close_all(void); - -/* Returns the maximum file descriptor number used by the channels. */ -int channel_max_fd(void); - -/* Returns true if there is still an open channel over the connection. */ -int channel_still_open(void); - -/* - * Returns a string containing a list of all open channels. The list is - * suitable for displaying to the user. It uses crlf instead of newlines. - * The caller should free the string with xfree. - */ -char *channel_open_message(void); - -/* - * Initiate forwarding of connections to local port "port" through the secure - * channel to host:port from remote side. This never returns if there was an - * error. - */ -void -channel_request_local_forwarding(u_short port, const char *host, - u_short remote_port, int gateway_ports); - -/* - * Initiate forwarding of connections to port "port" on remote host through - * the secure channel to host:port from local side. This never returns if - * there was an error. This registers that open requests for that port are - * permitted. - */ -void -channel_request_remote_forwarding(u_short port, const char *host, - u_short remote_port); - -/* - * Permits opening to any host/port in SSH_MSG_PORT_OPEN. 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); - -/* - * 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); - -/* - * Creates a port for X11 connections, and starts listening for it. Returns - * the display name, or NULL if an error was encountered. - */ -char *x11_create_display(int screen); - -/* - * Creates an internet domain socket for listening for X11 connections. - * Returns a suitable value for the DISPLAY variable, or NULL if an error - * occurs. - */ -char *x11_create_display_inet(int screen, int x11_display_offset); - -/* - * 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, int plen); - -/* - * Requests forwarding of X11 connections. This should be called on the - * client only. - */ -void x11_request_forwarding(void); - -/* - * Requests forwarding for X11 connections, with authentication spoofing. - * This should be called in the client only. - */ -void -x11_request_forwarding_with_spoofing(int client_session_id, - const char *proto, const char *data); - -/* Sends a message to the server to request authentication fd forwarding. */ -void auth_request_forwarding(void); - -/* - * Returns the name of the forwarded authentication socket. Returns NULL if - * there is no forwarded authentication socket. The returned value points to - * a static buffer. - */ -char *auth_get_socket_name(void); - -/* - * This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. - * This starts forwarding authentication requests. - */ -void auth_input_request_forwarding(struct passwd * pw); - -/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ -void auth_input_open_request(int type, int plen); - -/* XXX */ -int channel_connect_to(const char *host, u_short host_port); -int x11_connect_display(void); - -#endif diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c deleted file mode 100644 index bcaff024db26..000000000000 --- a/crypto/openssh/cipher.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * - * cipher.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Apr 19 17:41:39 1995 ylo - * - */ - -#include "includes.h" -RCSID("$Id: cipher.c,v 1.26 2000/04/14 10:30:30 markus Exp $"); - -#include "ssh.h" -#include "cipher.h" -#include "xmalloc.h" - -#include <openssl/md5.h> - -/* - * 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. - */ -void -SSH_3CBC_ENCRYPT(des_key_schedule ks1, - des_key_schedule ks2, des_cblock * iv2, - des_key_schedule ks3, des_cblock * iv3, - unsigned char *dest, unsigned char *src, - unsigned int len) -{ - des_cblock iv1; - - memcpy(&iv1, iv2, 8); - - des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT); - memcpy(&iv1, dest + len - 8, 8); - - des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT); - memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ - - des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT); - memcpy(iv3, dest + len - 8, 8); -} - -void -SSH_3CBC_DECRYPT(des_key_schedule ks1, - des_key_schedule ks2, des_cblock * iv2, - des_key_schedule ks3, des_cblock * iv3, - unsigned char *dest, unsigned char *src, - unsigned int len) -{ - des_cblock iv1; - - memcpy(&iv1, iv2, 8); - - des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT); - memcpy(iv3, src + len - 8, 8); - - des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT); - memcpy(iv2, dest + len - 8, 8); - - des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT); - /* memcpy(&iv1, iv2, 8); */ - /* Note how iv1 == iv2 on entry and exit. */ -} - -/* - * 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 unsigned char *src, unsigned char *dst_, int n) -{ - /* dst must be properly aligned. */ - u_int32_t *dst = (u_int32_t *) dst_; - union { - u_int32_t i; - char c[4]; - } t; - - /* Process 8 bytes every lap. */ - for (n = n / 8; n > 0; n--) { - t.c[3] = *src++; - t.c[2] = *src++; - t.c[1] = *src++; - t.c[0] = *src++; - *dst++ = t.i; - - t.c[3] = *src++; - t.c[2] = *src++; - t.c[1] = *src++; - t.c[0] = *src++; - *dst++ = t.i; - } -} - -/* - * Names of all encryption algorithms. - * These must match the numbers defined in cipher.h. - */ -static char *cipher_names[] = -{ - "none", - "idea", - "des", - "3des", - "tss", - "rc4", - "blowfish", - "reserved", - "blowfish-cbc", - "3des-cbc", - "arcfour", - "cast128-cbc" -}; - -/* - * Returns a bit mask indicating which ciphers are supported by this - * implementation. The bit mask has the corresponding bit set of each - * supported cipher. - */ - -unsigned int -cipher_mask1() -{ - unsigned int mask = 0; - mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ - mask |= 1 << SSH_CIPHER_BLOWFISH; - return mask; -} -unsigned int -cipher_mask2() -{ - unsigned int mask = 0; - mask |= 1 << SSH_CIPHER_BLOWFISH_CBC; - mask |= 1 << SSH_CIPHER_3DES_CBC; - mask |= 1 << SSH_CIPHER_ARCFOUR; - mask |= 1 << SSH_CIPHER_CAST128_CBC; - return mask; -} -unsigned int -cipher_mask() -{ - return cipher_mask1() | cipher_mask2(); -} - -/* Returns the name of the cipher. */ - -const char * -cipher_name(int cipher) -{ - if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || - cipher_names[cipher] == NULL) - fatal("cipher_name: bad cipher name: %d", cipher); - return cipher_names[cipher]; -} - -/* Returns 1 if the name of the ciphers are valid. */ - -#define CIPHER_SEP "," -int -ciphers_valid(const char *names) -{ - char *ciphers; - char *p; - int i; - - if (strcmp(names, "") == 0) - return 0; - ciphers = xstrdup(names); - for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) { - i = cipher_number(p); - if (i == -1 || !(cipher_mask2() & (1 << i))) { - xfree(ciphers); - return 0; - } - } - 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) -{ - int i; - for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) - if (strcmp(cipher_names[i], name) == 0 && - (cipher_mask() & (1 << i))) - return i; - return -1; -} - -/* - * 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 *context, int cipher, const char *passphrase) -{ - MD5_CTX md; - unsigned char digest[16]; - - MD5_Init(&md); - MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase)); - MD5_Final(digest, &md); - - cipher_set_key(context, cipher, digest, 16); - - memset(digest, 0, sizeof(digest)); - memset(&md, 0, sizeof(md)); -} - -/* Selects the cipher to use and sets the key. */ - -void -cipher_set_key(CipherContext *context, int cipher, const unsigned char *key, - int keylen) -{ - unsigned char padded[32]; - - /* Set cipher type. */ - context->type = cipher; - - /* Get 32 bytes of key data. Pad if necessary. (So that code - below does not need to worry about key size). */ - memset(padded, 0, sizeof(padded)); - memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded)); - - /* Initialize the initialization vector. */ - switch (cipher) { - case SSH_CIPHER_NONE: - /* - * Has to stay for authfile saving of private key with no - * passphrase - */ - break; - - case SSH_CIPHER_3DES: - /* - * Note: the least significant bit of each byte of key is - * parity, and must be ignored by the implementation. 16 - * bytes of key are used (first and last keys are the same). - */ - if (keylen < 16) - error("Key length %d is insufficient for 3DES.", keylen); - des_set_key((void *) padded, context->u.des3.key1); - des_set_key((void *) (padded + 8), context->u.des3.key2); - if (keylen <= 16) - des_set_key((void *) padded, context->u.des3.key3); - else - des_set_key((void *) (padded + 16), context->u.des3.key3); - memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2)); - memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3)); - break; - - case SSH_CIPHER_BLOWFISH: - if (keylen < 16) - error("Key length %d is insufficient for blowfish.", keylen); - BF_set_key(&context->u.bf.key, keylen, padded); - memset(context->u.bf.iv, 0, 8); - break; - - case SSH_CIPHER_3DES_CBC: - case SSH_CIPHER_BLOWFISH_CBC: - case SSH_CIPHER_ARCFOUR: - case SSH_CIPHER_CAST128_CBC: - fatal("cipher_set_key: illegal cipher: %s", cipher_name(cipher)); - break; - - default: - fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); - } - memset(padded, 0, sizeof(padded)); -} - -void -cipher_set_key_iv(CipherContext * context, int cipher, - const unsigned char *key, int keylen, - const unsigned char *iv, int ivlen) -{ - /* Set cipher type. */ - context->type = cipher; - - /* Initialize the initialization vector. */ - switch (cipher) { - case SSH_CIPHER_NONE: - break; - - case SSH_CIPHER_3DES: - case SSH_CIPHER_BLOWFISH: - fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher)); - break; - - case SSH_CIPHER_3DES_CBC: - if (keylen < 24) - error("Key length %d is insufficient for 3des-cbc.", keylen); - des_set_key((void *) key, context->u.des3.key1); - des_set_key((void *) (key+8), context->u.des3.key2); - des_set_key((void *) (key+16), context->u.des3.key3); - if (ivlen < 8) - error("IV length %d is insufficient for 3des-cbc.", ivlen); - memcpy(context->u.des3.iv3, (char *)iv, 8); - break; - - case SSH_CIPHER_BLOWFISH_CBC: - if (keylen < 16) - error("Key length %d is insufficient for blowfish.", keylen); - if (ivlen < 8) - error("IV length %d is insufficient for blowfish.", ivlen); - BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key); - memcpy(context->u.bf.iv, (char *)iv, 8); - break; - - case SSH_CIPHER_ARCFOUR: - if (keylen < 16) - error("Key length %d is insufficient for arcfour.", keylen); - RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key); - break; - - case SSH_CIPHER_CAST128_CBC: - if (keylen < 16) - error("Key length %d is insufficient for cast128.", keylen); - if (ivlen < 8) - error("IV length %d is insufficient for cast128.", ivlen); - CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key); - memcpy(context->u.cast.iv, (char *)iv, 8); - break; - - default: - fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); - } -} - -/* Encrypts data using the cipher. */ - -void -cipher_encrypt(CipherContext *context, unsigned char *dest, - const unsigned char *src, unsigned int len) -{ - if ((len & 7) != 0) - fatal("cipher_encrypt: bad plaintext length %d", len); - - switch (context->type) { - case SSH_CIPHER_NONE: - memcpy(dest, src, len); - break; - - case SSH_CIPHER_3DES: - SSH_3CBC_ENCRYPT(context->u.des3.key1, - context->u.des3.key2, &context->u.des3.iv2, - context->u.des3.key3, &context->u.des3.iv3, - dest, (unsigned char *) src, len); - break; - - case SSH_CIPHER_BLOWFISH: - swap_bytes(src, dest, len); - BF_cbc_encrypt(dest, dest, len, - &context->u.bf.key, context->u.bf.iv, - BF_ENCRYPT); - swap_bytes(dest, dest, len); - break; - - case SSH_CIPHER_BLOWFISH_CBC: - BF_cbc_encrypt((void *)src, dest, len, - &context->u.bf.key, context->u.bf.iv, - BF_ENCRYPT); - break; - - case SSH_CIPHER_3DES_CBC: - des_ede3_cbc_encrypt(src, dest, len, - context->u.des3.key1, context->u.des3.key2, - context->u.des3.key3, &context->u.des3.iv3, DES_ENCRYPT); - break; - - case SSH_CIPHER_ARCFOUR: - RC4(&context->u.rc4, len, (unsigned char *)src, dest); - break; - - case SSH_CIPHER_CAST128_CBC: - CAST_cbc_encrypt(src, dest, len, - &context->u.cast.key, context->u.cast.iv, CAST_ENCRYPT); - break; - - default: - fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type)); - } -} - -/* Decrypts data using the cipher. */ - -void -cipher_decrypt(CipherContext *context, unsigned char *dest, - const unsigned char *src, unsigned int len) -{ - if ((len & 7) != 0) - fatal("cipher_decrypt: bad ciphertext length %d", len); - - switch (context->type) { - case SSH_CIPHER_NONE: - memcpy(dest, src, len); - break; - - case SSH_CIPHER_3DES: - SSH_3CBC_DECRYPT(context->u.des3.key1, - context->u.des3.key2, &context->u.des3.iv2, - context->u.des3.key3, &context->u.des3.iv3, - dest, (unsigned char *) src, len); - break; - - case SSH_CIPHER_BLOWFISH: - swap_bytes(src, dest, len); - BF_cbc_encrypt((void *) dest, dest, len, - &context->u.bf.key, context->u.bf.iv, - BF_DECRYPT); - swap_bytes(dest, dest, len); - break; - - case SSH_CIPHER_BLOWFISH_CBC: - BF_cbc_encrypt((void *) src, dest, len, - &context->u.bf.key, context->u.bf.iv, - BF_DECRYPT); - break; - - case SSH_CIPHER_3DES_CBC: - des_ede3_cbc_encrypt(src, dest, len, - context->u.des3.key1, context->u.des3.key2, - context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT); - break; - - case SSH_CIPHER_ARCFOUR: - RC4(&context->u.rc4, len, (unsigned char *)src, dest); - break; - - case SSH_CIPHER_CAST128_CBC: - CAST_cbc_encrypt(src, dest, len, - &context->u.cast.key, context->u.cast.iv, CAST_DECRYPT); - break; - - default: - fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type)); - } -} diff --git a/crypto/openssh/cipher.h b/crypto/openssh/cipher.h deleted file mode 100644 index 197d9541eaf2..000000000000 --- a/crypto/openssh/cipher.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * cipher.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Apr 19 16:50:42 1995 ylo - * - */ - -/* RCSID("$Id: cipher.h,v 1.17 2000/05/08 17:12:15 markus Exp $"); */ - -#ifndef CIPHER_H -#define CIPHER_H - -#include <openssl/des.h> -#include <openssl/blowfish.h> -#include <openssl/rc4.h> -#include <openssl/cast.h> - -/* Cipher types. New types can be added, but old types should not be removed - for compatibility. The maximum allowed value is 31. */ -#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 - -/* these ciphers are used in SSH2: */ -#define SSH_CIPHER_BLOWFISH_CBC 8 -#define SSH_CIPHER_3DES_CBC 9 -#define SSH_CIPHER_ARCFOUR 10 /* Alleged RC4 */ -#define SSH_CIPHER_CAST128_CBC 11 - -typedef struct { - unsigned int type; - union { - struct { - des_key_schedule key1; - des_key_schedule key2; - des_cblock iv2; - des_key_schedule key3; - des_cblock iv3; - } des3; - struct { - struct bf_key_st key; - unsigned char iv[8]; - } bf; - struct { - CAST_KEY key; - unsigned char iv[8]; - } cast; - RC4_KEY rc4; - } u; -} CipherContext; -/* - * Returns a bit mask indicating which ciphers are supported by this - * implementation. The bit mask has the corresponding bit set of each - * supported cipher. - */ -unsigned int cipher_mask(); -unsigned int cipher_mask1(); -unsigned int cipher_mask2(); - -/* Returns the name of the cipher. */ -const char *cipher_name(int cipher); - -/* - * Parses the name of the cipher. Returns the number of the corresponding - * cipher, or -1 on error. - */ -int cipher_number(const char *name); - -/* returns 1 if all ciphers are supported (ssh2 only) */ -int ciphers_valid(const char *names); - -/* - * Selects the cipher to use and sets the key. If for_encryption is true, - * the key is setup for encryption; otherwise it is setup for decryption. - */ -void -cipher_set_key(CipherContext * context, int cipher, - const unsigned char *key, int keylen); -void -cipher_set_key_iv(CipherContext * context, int cipher, - const unsigned char *key, int keylen, - const unsigned char *iv, int ivlen); - -/* - * Sets key for the cipher by computing the MD5 checksum of the passphrase, - * and using the resulting 16 bytes as the key. - */ -void -cipher_set_key_string(CipherContext * context, int cipher, - const char *passphrase); - -/* Encrypts data using the cipher. */ -void -cipher_encrypt(CipherContext * context, unsigned char *dest, - const unsigned char *src, unsigned int len); - -/* Decrypts data using the cipher. */ -void -cipher_decrypt(CipherContext * context, unsigned char *dest, - const unsigned char *src, unsigned int len); - -#endif /* CIPHER_H */ diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c deleted file mode 100644 index b4c7b287dfae..000000000000 --- a/crypto/openssh/clientloop.c +++ /dev/null @@ -1,1117 +0,0 @@ -/* - * - * clientloop.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * - * Created: Sat Sep 23 12:23:57 1995 ylo - * - * The main loop for the interactive session (client side). - * - * SSH2 support added by Markus Friedl. - */ - -#include "includes.h" -RCSID("$Id: clientloop.c,v 1.26 2000/05/08 17:42:24 markus Exp $"); - -#include "xmalloc.h" -#include "ssh.h" -#include "packet.h" -#include "buffer.h" -#include "authfd.h" -#include "readconf.h" - -#include "ssh2.h" -#include "compat.h" -#include "channels.h" -#include "dispatch.h" - - -/* 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 int received_window_change_signal = 0; - -/* Terminal modes, as saved by enter_raw_mode. */ -static struct termios saved_tio; - -/* - * Flag indicating whether we are in raw mode. This is used by - * enter_raw_mode and leave_raw_mode. - */ -static int in_raw_mode = 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 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 unsigned int buffer_high;/* Soft max buffer size. */ -static int max_fd; /* Maximum file descriptor number in select(). */ -static int connection_in; /* Connection to server (input). */ -static int connection_out; /* Connection to server (output). */ -static unsigned long stdin_bytes, stdout_bytes, stderr_bytes; -static int quit_pending; /* Set to non-zero to quit the client loop. */ -static int escape_char; /* Escape character. */ - - -void client_init_dispatch(void); -int session_ident = -1; - -/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ - -void -leave_raw_mode() -{ - if (!in_raw_mode) - return; - in_raw_mode = 0; - if (tcsetattr(fileno(stdin), TCSADRAIN, &saved_tio) < 0) - perror("tcsetattr"); - - fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL); -} - -/* Puts the user\'s terminal in raw mode. */ - -void -enter_raw_mode() -{ - struct termios tio; - - if (tcgetattr(fileno(stdin), &tio) < 0) - perror("tcgetattr"); - 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 /* IEXTEN */ - tio.c_oflag &= ~OPOST; - tio.c_cc[VMIN] = 1; - tio.c_cc[VTIME] = 0; - if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0) - perror("tcsetattr"); - in_raw_mode = 1; - - fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL); -} - -/* Restores stdin to blocking mode. */ - -void -leave_non_blocking() -{ - 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. */ - -void -enter_non_blocking() -{ - 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. - */ - -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. - */ - -void -signal_handler(int sig) -{ - if (in_raw_mode) - leave_raw_mode(); - if (in_non_blocking_mode) - leave_non_blocking(); - channel_stop_listening(); - packet_close(); - fatal("Killed by signal %d.", sig); -} - -/* - * Returns current time in seconds from Jan 1, 1970 with the maximum - * available resolution. - */ - -double -get_current_time() -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; -} - -/* - * 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. - */ - -void -client_check_initial_eof_on_stdin() -{ - 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 ((unsigned char) buf[0] == escape_char) - escape_pending = 1; - else { - buffer_append(&stdin_buffer, buf, 1); - stdin_bytes += 1; - } - } - leave_non_blocking(); - } -} - - -/* - * Make packets from buffered stdin data, and buffer them for sending to the - * connection. - */ - -void -client_make_packets_from_stdin_data() -{ - unsigned 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); - /* 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. - */ - -void -client_check_window_change() -{ - struct winsize ws; - - if (! received_window_change_signal) - return; - /** XXX race */ - received_window_change_signal = 0; - - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - return; - - debug("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(); - } -} - -/* - * Waits until the client can do something (some data becomes available on - * one of the file descriptors). - */ - -void -client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) -{ - /*debug("client_wait_until_can_do_something"); */ - - /* Initialize select masks. */ - FD_ZERO(readset); - FD_ZERO(writeset); - - 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, readset); - /* - * 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), readset); - - /* Select stdout/stderr if have data in buffer. */ - if (buffer_len(&stdout_buffer) > 0) - FD_SET(fileno(stdout), writeset); - if (buffer_len(&stderr_buffer) > 0) - FD_SET(fileno(stderr), writeset); - } else { - FD_SET(connection_in, readset); - } - - /* Add any selections by the channel mechanism. */ - channel_prepare_select(readset, writeset); - - /* Select server connection if have data to write to the server. */ - if (packet_have_data_to_write()) - FD_SET(connection_out, writeset); - -/* move UP XXX */ - /* Update maximum file descriptor number, if appropriate. */ - if (channel_max_fd() > max_fd) - max_fd = channel_max_fd(); - - /* - * Wait for something to happen. This will suspend the process until - * some selected descriptor can be read, written, or has some other - * event pending. Note: if you want to implement SSH_MSG_IGNORE - * messages to fool traffic analysis, this might be the place to do - * it: just have a random timeout for the select, and send a random - * SSH_MSG_IGNORE packet when the timeout expires. - */ - - if (select(max_fd + 1, readset, writeset, NULL, NULL) < 0) { - char buf[100]; - /* Some systems fail to clear these automatically. */ - FD_ZERO(readset); - FD_ZERO(writeset); - 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)); - stderr_bytes += strlen(buf); - quit_pending = 1; - } -} - -void -client_suspend_self() -{ - struct winsize oldws, newws; - - /* Flush stdout and stderr buffers. */ - if (buffer_len(&stdout_buffer) > 0) - atomicio(write, fileno(stdout), buffer_ptr(&stdout_buffer), - buffer_len(&stdout_buffer)); - if (buffer_len(&stderr_buffer) > 0) - atomicio(write, fileno(stderr), buffer_ptr(&stderr_buffer), - buffer_len(&stderr_buffer)); - - leave_raw_mode(); - - /* - * Free (and clear) the buffer to reduce the amount of data that gets - * written to swap. - */ - buffer_free(&stdin_buffer); - buffer_free(&stdout_buffer); - buffer_free(&stderr_buffer); - - /* 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(&stdin_buffer); - buffer_init(&stdout_buffer); - buffer_init(&stderr_buffer); - - enter_raw_mode(); -} - -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)); -/*debug("read connection_in len %d", len); XXX */ - if (len == 0) { - /* Received EOF. The remote host has closed the connection. */ - snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", - host); - buffer_append(&stderr_buffer, buf, strlen(buf)); - stderr_bytes += 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) - len = 0; - - if (len < 0) { - /* An error has encountered. Perhaps there is a network problem. */ - snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", - host, strerror(errno)); - buffer_append(&stderr_buffer, buf, strlen(buf)); - stderr_bytes += strlen(buf); - quit_pending = 1; - return; - } - packet_process_incoming(buf, len); - } -} - -void -client_process_input(fd_set * readset) -{ - int len; - pid_t pid; - char buf[8192], *s; - - /* 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) { - /* - * 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)); - stderr_bytes += 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 == -1) { - /* - * Normal successful read, and no escape character. - * Just append the data to buffer. - */ - buffer_append(&stdin_buffer, buf, len); - stdin_bytes += len; - } else { - /* - * Normal, successful read. But we have an escape character - * and have to process the characters one by one. - */ - unsigned int i; - for (i = 0; i < len; i++) { - unsigned char ch; - /* Get one character at a time. */ - ch = buf[i]; - - if (escape_pending) { - /* We have previously seen an escape character. */ - /* Clear the flag now. */ - escape_pending = 0; - /* Process the escaped character. */ - switch (ch) { - case '.': - /* Terminate the connection. */ - snprintf(buf, sizeof buf, "%c.\r\n", escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - stderr_bytes += strlen(buf); - quit_pending = 1; - return; - - case 'Z' - 64: - /* Suspend the program. */ - /* Print a message to that effect to the user. */ - snprintf(buf, sizeof buf, "%c^Z\r\n", escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - stderr_bytes += strlen(buf); - - /* Restore terminal modes and suspend. */ - client_suspend_self(); - - /* We have been continued. */ - continue; - - case '&': - /* - * Detach the program (continue to serve connections, - * but put in background and no more new connections). - */ - if (!stdin_eof) { - /* - * Sending SSH_CMSG_EOF alone does not always appear - * to be enough. So we try to send an EOF character - * first. - */ - packet_start(SSH_CMSG_STDIN_DATA); - packet_put_string("\004", 1); - packet_send(); - /* Close stdin. */ - stdin_eof = 1; - if (buffer_len(&stdin_buffer) == 0) { - packet_start(SSH_CMSG_EOF); - packet_send(); - } - } - /* Restore tty modes. */ - leave_raw_mode(); - - /* Stop listening for new connections. */ - channel_stop_listening(); - - printf("%c& [backgrounded]\n", escape_char); - - /* Fork into background. */ - pid = fork(); - if (pid < 0) { - error("fork: %.100s", strerror(errno)); - continue; - } - if (pid != 0) { /* This is the parent. */ - /* The parent just exits. */ - exit(0); - } - /* The child continues serving connections. */ - continue; - - case '?': - snprintf(buf, sizeof buf, -"%c?\r\n\ -Supported escape sequences:\r\n\ -~. - terminate connection\r\n\ -~^Z - suspend ssh\r\n\ -~# - list forwarded connections\r\n\ -~& - background ssh (when waiting for connections to terminate)\r\n\ -~? - this message\r\n\ -~~ - send the escape character by typing it twice\r\n\ -(Note that escapes are only recognized immediately after newline.)\r\n", - escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - continue; - - case '#': - snprintf(buf, sizeof buf, "%c#\r\n", escape_char); - buffer_append(&stderr_buffer, buf, strlen(buf)); - s = channel_open_message(); - buffer_append(&stderr_buffer, s, strlen(s)); - xfree(s); - continue; - - default: - if (ch != escape_char) { - /* - * Escape character followed by non-special character. - * Append both to the input buffer. - */ - buf[0] = escape_char; - buf[1] = ch; - buffer_append(&stdin_buffer, buf, 2); - stdin_bytes += 2; - continue; - } - /* - * Note that escape character typed twice - * falls through here; the latter gets processed - * as a normal character below. - */ - break; - } - } else { - /* - * The previous character was not an escape char. Check if this - * is an escape. - */ - if (last_was_cr && ch == escape_char) { - /* It is. Set the flag and continue to next character. */ - escape_pending = 1; - continue; - } - } - - /* - * Normal character. Record whether it was a newline, - * and append it to the buffer. - */ - last_was_cr = (ch == '\r' || ch == '\n'); - buf[0] = ch; - buffer_append(&stdin_buffer, buf, 1); - stdin_bytes += 1; - continue; - } - } - } -} - -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 == 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)); - stderr_bytes += strlen(buf); - quit_pending = 1; - return; - } - } - /* Consume printed data from the buffer. */ - buffer_consume(&stdout_buffer, 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 == 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); - } -} - -/* - * 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. - */ - -void -client_process_buffered_input_packets() -{ - dispatch_run(DISPATCH_NONBLOCK, &quit_pending); -} - -/* - * 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 != -1, 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) -{ - extern Options options; - double start_time, total_time; - int len; - 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 = connection_in; - if (connection_out > max_fd) - max_fd = connection_out; - 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. */ - signal(SIGINT, signal_handler); - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGPIPE, SIG_IGN); - if (have_pty) - signal(SIGWINCH, window_change_handler); - - if (have_pty) - enter_raw_mode(); - - /* Check if we should immediately send of on stdin. */ - if (!compat20) - client_check_initial_eof_on_stdin(); - - /* Main loop of the client for the interactive session mode. */ - while (!quit_pending) { - fd_set readset, writeset; - - /* Process buffered packets sent by the server. */ - client_process_buffered_input_packets(); - - if (compat20 && !channel_still_open()) { - debug("!channel_still_open."); - break; - } - - /* - * 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 buffer 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). - */ - client_wait_until_can_do_something(&readset, &writeset); - - if (quit_pending) - break; - - /* Do channel operations. */ - channel_after_select(&readset, &writeset); - - /* 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(); - } - - /* Terminate the session. */ - - /* Stop watching for window change. */ - if (have_pty) - signal(SIGWINCH, SIG_DFL); - - /* Stop listening for connections. */ - channel_stop_listening(); - - /* - * 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, "Connection to %.64s closed.\r\n", host); - buffer_append(&stderr_buffer, buf, strlen(buf)); - stderr_bytes += 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); - } - - /* 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); - } - - if (have_pty) - leave_raw_mode(); - - /* 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; -} - -/*********/ - -void -client_input_stdout_data(int type, int plen) -{ - unsigned int data_len; - char *data = packet_get_string(&data_len); - packet_integrity_check(plen, 4 + data_len, type); - buffer_append(&stdout_buffer, data, data_len); - stdout_bytes += data_len; - memset(data, 0, data_len); - xfree(data); -} -void -client_input_stderr_data(int type, int plen) -{ - unsigned int data_len; - char *data = packet_get_string(&data_len); - packet_integrity_check(plen, 4 + data_len, type); - buffer_append(&stderr_buffer, data, data_len); - stdout_bytes += data_len; - memset(data, 0, data_len); - xfree(data); -} -void -client_input_exit_status(int type, int plen) -{ - packet_integrity_check(plen, 4, type); - exit_status = packet_get_int(); - /* 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; -} - -/* XXXX move to generic input handler */ -void -client_input_channel_open(int type, int plen) -{ - Channel *c = NULL; - char *ctype; - int id; - unsigned int len; - int rchan; - int rmaxpack; - int rwindow; - - 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, "x11") == 0) { - int sock; - char *originator; - int originator_port; - originator = packet_get_string(NULL); - if (datafellows & SSH_BUG_X11FWD) { - debug("buggy server: x11 request w/o originator_port"); - originator_port = 0; - } else { - originator_port = packet_get_int(); - } - packet_done(); - /* XXX check permission */ - xfree(originator); - /* XXX move to channels.c */ - sock = x11_connect_display(); - if (sock >= 0) { - id = channel_new("x11", SSH_CHANNEL_X11_OPEN, - sock, sock, -1, 4*1024, 32*1024, 0, - xstrdup("x11")); - c = channel_lookup(id); - } - } -/* XXX duplicate : */ - if (c != NULL) { - debug("confirm %s", ctype); - c->remote_id = rchan; - c->remote_window = rwindow; - c->remote_maxpacket = rmaxpack; - - 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); - packet_put_cstring("bla bla"); - packet_put_cstring(""); - packet_send(); - } - xfree(ctype); -} - -void -client_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, &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, &channel_input_channel_request); - dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); -} -void -client_init_dispatch_13() -{ - 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_AGENT_OPEN, &auth_input_open_request); - 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_X11_OPEN, &x11_input_open); -} -void -client_init_dispatch_15() -{ - client_init_dispatch_13(); - dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); - dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); -} -void -client_init_dispatch() -{ - if (compat20) - client_init_dispatch_20(); - else if (compat13) - client_init_dispatch_13(); - else - client_init_dispatch_15(); -} - -void -client_input_channel_req(int id, void *arg) -{ - Channel *c = NULL; - unsigned int len; - int success = 0; - int reply; - char *rtype; - - rtype = packet_get_string(&len); - reply = packet_get_char(); - - debug("client_input_channel_req: rtype %s reply %d", rtype, reply); - - c = channel_lookup(id); - if (c == NULL) - fatal("session_input_channel_req: channel %d: bad channel", id); - - if (session_ident == -1) { - error("client_input_channel_req: no channel %d", id); - } else if (id != session_ident) { - error("client_input_channel_req: bad channel %d != %d", - id, session_ident); - } else if (strcmp(rtype, "exit-status") == 0) { - success = 1; - exit_status = packet_get_int(); - packet_done(); - } - if (reply) { - packet_start(success ? - SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); - packet_put_int(c->remote_id); - packet_send(); - } - xfree(rtype); -} - -void -client_set_session_ident(int id) -{ - debug("client_set_session_ident: id %d", id); - session_ident = id; - channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, - client_input_channel_req, (void *)0); -} diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c deleted file mode 100644 index 33e509cb89b2..000000000000 --- a/crypto/openssh/compat.c +++ /dev/null @@ -1,104 +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. - * 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. - */ - -#include "includes.h" -RCSID("$Id: compat.c,v 1.13 2000/05/08 17:42:24 markus Exp $"); - -#include "ssh.h" -#include "packet.h" -#include "xmalloc.h" -#include "compat.h" - -int compat13 = 0; -int compat20 = 0; -int datafellows = 0; - -void -enable_compat20(void) -{ - verbose("Enabling compatibility mode for protocol 2.0"); - compat20 = 1; -} -void -enable_compat13(void) -{ - verbose("Enabling compatibility mode for protocol 1.3"); - compat13 = 1; -} -/* datafellows bug compatibility */ -void -compat_datafellows(const char *version) -{ - int i; - size_t len; - struct { - char *version; - int bugs; - } check[] = { - {"2.1.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC}, - {"2.0.1", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD}, - {NULL, 0} - }; - for (i = 0; check[i].version; i++) { - len = strlen(check[i].version); - if (strlen(version) >= len && - (strncmp(version, check[i].version, len) == 0)) { - verbose("datafellows: %.200s", version); - datafellows = check[i].bugs; - return; - } - } -} - -#define SEP "," -int -proto_spec(const char *spec) -{ - char *s = xstrdup(spec); - char *p; - int ret = SSH_PROTO_UNKNOWN; - - for ((p = strtok(s, SEP)); p; (p = strtok(NULL, 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; -} diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h deleted file mode 100644 index 9308a6df3016..000000000000 --- a/crypto/openssh/compat.h +++ /dev/null @@ -1,51 +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. - * 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. - */ -/* RCSID("$Id: compat.h,v 1.7 2000/05/08 17:42:24 markus Exp $"); */ - -#ifndef COMPAT_H -#define COMPAT_H - -#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 0x01 -#define SSH_BUG_PUBKEYAUTH 0x02 -#define SSH_BUG_HMAC 0x04 -#define SSH_BUG_X11FWD 0x08 - -void enable_compat13(void); -void enable_compat20(void); -void compat_datafellows(const char *s); -int proto_spec(const char *spec); -extern int compat13; -extern int compat20; -extern int datafellows; -#endif diff --git a/crypto/openssh/compress.c b/crypto/openssh/compress.c deleted file mode 100644 index 86ccaa28ae21..000000000000 --- a/crypto/openssh/compress.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * - * compress.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Oct 25 22:12:46 1995 ylo - * - * Interface to packet compression for ssh. - * - */ - -#include "includes.h" -RCSID("$Id: compress.c,v 1.7 2000/04/14 10:30:31 markus Exp $"); - -#include "ssh.h" -#include "buffer.h" -#include "zlib.h" - -static z_stream incoming_stream; -static z_stream outgoing_stream; - -/* - * Initializes compression; level is compression level from 1 to 9 - * (as in gzip). - */ - -void -buffer_compress_init(int level) -{ - debug("Enabling compression at level %d.", level); - if (level < 1 || level > 9) - fatal("Bad compression level %d.", level); - inflateInit(&incoming_stream); - deflateInit(&outgoing_stream, level); -} - -/* Frees any data structures allocated for compression. */ - -void -buffer_compress_uninit() -{ - 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); - inflateEnd(&incoming_stream); - 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) -{ - 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 = (unsigned char *) 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 = (unsigned char *)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: - 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) -{ - char buf[4096]; - int status; - - incoming_stream.next_in = (unsigned char *) buffer_ptr(input_buffer); - incoming_stream.avail_in = buffer_len(input_buffer); - - for (;;) { - /* Set up fixed-size output buffer. */ - incoming_stream.next_out = (unsigned char *) 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: - fatal("buffer_uncompress: inflate returned %d", status); - /* NOTREACHED */ - } - } -} diff --git a/crypto/openssh/compress.h b/crypto/openssh/compress.h deleted file mode 100644 index f97561322590..000000000000 --- a/crypto/openssh/compress.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * compress.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Oct 25 22:12:46 1995 ylo - * - * Interface to packet compression for ssh. - * - */ - -/* RCSID("$Id: compress.h,v 1.4 2000/04/14 10:30:31 markus Exp $"); */ - -#ifndef COMPRESS_H -#define COMPRESS_H - -/* - * Initializes compression; level is compression level from 1 to 9 (as in - * gzip). - */ -void buffer_compress_init(int level); - -/* Frees any data structures allocated by buffer_compress_init. */ -void buffer_compress_uninit(); - -/* - * 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); - -/* - * 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); - -#endif /* COMPRESS_H */ diff --git a/crypto/openssh/crc32.c b/crypto/openssh/crc32.c deleted file mode 100644 index 42c99dad353e..000000000000 --- a/crypto/openssh/crc32.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * The implementation here was originally done by Gary S. Brown. - * I have borrowed the tables directly, and made some minor changes - * to the crc32-function (including changing the interface). - * //ylo - */ - -#include "includes.h" -RCSID("$Id: crc32.c,v 1.4 1999/11/24 00:26:01 deraadt Exp $"); - -#include "crc32.h" - - /* ============================================================= */ - /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ - /* code or tables extracted from it, as desired without restriction. */ - /* */ - /* First, the polynomial itself and its table of feedback terms. The */ - /* polynomial is */ - /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ - /* */ - /* Note that we take it "backwards" and put the highest-order term in */ - /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ - /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ - /* the MSB being 1. */ - /* */ - /* Note that the usual hardware shift register implementation, which */ - /* is what we're using (we're merely optimizing it by doing eight-bit */ - /* chunks at a time) shifts bits into the lowest-order term. In our */ - /* implementation, that means shifting towards the right. Why do we */ - /* do it this way? Because the calculated CRC must be transmitted in */ - /* order from highest-order term to lowest-order term. UARTs transmit */ - /* characters in order from LSB to MSB. By storing the CRC this way, */ - /* we hand it to the UART in the order low-byte to high-byte; the UART */ - /* sends each low-bit to hight-bit; and the result is transmission bit */ - /* by bit from highest- to lowest-order term without requiring any bit */ - /* shuffling on our part. Reception works similarly. */ - /* */ - /* The feedback terms table consists of 256, 32-bit entries. Notes: */ - /* */ - /* The table can be generated at runtime if desired; code to do so */ - /* is shown later. It might not be obvious, but the feedback */ - /* terms simply represent the results of eight shift/xor opera- */ - /* tions for all combinations of data and CRC register values. */ - /* */ - /* The values must be right-shifted by eight bits by the "updcrc" */ - /* logic; the shift must be unsigned (bring in zeroes). On some */ - /* hardware you could probably optimize the shift in assembler by */ - /* using byte-swap instructions. */ - /* polynomial $edb88320 */ - /* */ - /* -------------------------------------------------------------------- */ - -static unsigned int crc32_tab[] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -/* Return a 32-bit CRC of the contents of the buffer. */ - -unsigned int -crc32(const unsigned char *s, unsigned int len) -{ - unsigned int i; - unsigned int crc32val; - - crc32val = 0; - for (i = 0; i < len; i ++) { - crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); - } - return crc32val; -} diff --git a/crypto/openssh/crc32.h b/crypto/openssh/crc32.h deleted file mode 100644 index 4176e8a5f7c8..000000000000 --- a/crypto/openssh/crc32.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * crc32.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1992 Tatu Ylonen, Espoo, Finland - * All rights reserved - * - * Created: Tue Feb 11 14:37:27 1992 ylo - * - * Functions for computing 32-bit CRC. - * - */ - -/* RCSID("$Id: crc32.h,v 1.5 2000/04/14 10:30:31 markus Exp $"); */ - -#ifndef CRC32_H -#define CRC32_H - -/* - * This computes a 32 bit CRC of the data in the buffer, and returns the CRC. - * The polynomial used is 0xedb88320. - */ -unsigned int crc32(const unsigned char *buf, unsigned int len); - -#endif /* CRC32_H */ diff --git a/crypto/openssh/deattack.c b/crypto/openssh/deattack.c deleted file mode 100644 index 263e0396c868..000000000000 --- a/crypto/openssh/deattack.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * $Id: deattack.c,v 1.6 1999/11/24 00:26:01 deraadt Exp $ - * Cryptographic attack detector for ssh - source code - * - * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. - * - * 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" -#include "deattack.h" -#include "ssh.h" -#include "crc32.h" -#include "getput.h" -#include "xmalloc.h" - -/* 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)) - - -void -crc_update(u_int32_t *a, u_int32_t b) -{ - b ^= *a; - *a = crc32((unsigned char *) &b, sizeof(b)); -} - -/* detect if a block is used in a particular pattern */ -int -check_crc(unsigned char *S, unsigned char *buf, u_int32_t len, - unsigned char *IV) -{ - u_int32_t crc; - unsigned 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(unsigned char *buf, u_int32_t len, unsigned char *IV) -{ - static u_int16_t *h = (u_int16_t *) NULL; - static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE; - register u_int32_t i, j; - u_int32_t l; - register unsigned char *c; - unsigned 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, 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 (check_crc(c, buf, len, IV)) - return (DEATTACK_DETECTED); - else - break; - } - } - h[i] = j; - } - return (DEATTACK_OK); -} diff --git a/crypto/openssh/deattack.h b/crypto/openssh/deattack.h deleted file mode 100644 index 6ce54dedb178..000000000000 --- a/crypto/openssh/deattack.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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> - */ - -#ifndef _DEATTACK_H -#define _DEATTACK_H - -/* Return codes */ -#define DEATTACK_OK 0 -#define DEATTACK_DETECTED 1 - -int detect_attack(unsigned char *buf, u_int32_t len, unsigned char IV[8]); -#endif diff --git a/crypto/openssh/dispatch.c b/crypto/openssh/dispatch.c deleted file mode 100644 index 9b7def746854..000000000000 --- a/crypto/openssh/dispatch.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. - * 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. - */ -#include "includes.h" -RCSID("$Id: dispatch.c,v 1.2 2000/04/14 10:30:31 markus Exp $"); -#include "ssh.h" -#include "dispatch.h" -#include "packet.h" - -#define DISPATCH_MIN 0 -#define DISPATCH_MAX 255 - -dispatch_fn *dispatch[DISPATCH_MAX]; - -void -dispatch_protocol_error(int type, int plen) -{ - error("Hm, dispatch protocol error: type %d plen %d", type, plen); -} -void -dispatch_init(dispatch_fn *dflt) -{ - int i; - for (i = 0; i < DISPATCH_MAX; i++) - dispatch[i] = dflt; -} -void -dispatch_set(int type, dispatch_fn *fn) -{ - dispatch[type] = fn; -} -void -dispatch_run(int mode, int *done) -{ - for (;;) { - int plen; - int type; - - if (mode == DISPATCH_BLOCK) { - type = packet_read(&plen); - } else { - type = packet_read_poll(&plen); - if (type == SSH_MSG_NONE) - return; - } - if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) - (*dispatch[type])(type, plen); - else - packet_disconnect("protocol error: rcvd type %d", type); - if (done != NULL && *done) - return; - } -} diff --git a/crypto/openssh/dispatch.h b/crypto/openssh/dispatch.h deleted file mode 100644 index 12084aafe07a..000000000000 --- a/crypto/openssh/dispatch.h +++ /dev/null @@ -1,11 +0,0 @@ -enum { - DISPATCH_BLOCK, - DISPATCH_NONBLOCK -}; - -typedef void dispatch_fn(int type, int plen); - -void dispatch_init(dispatch_fn *dflt); -void dispatch_set(int type, dispatch_fn *fn); -void dispatch_run(int mode, int *done); -void dispatch_protocol_error(int type, int plen); diff --git a/crypto/openssh/dsa.c b/crypto/openssh/dsa.c deleted file mode 100644 index 51d7ff285242..000000000000 --- a/crypto/openssh/dsa.c +++ /dev/null @@ -1,300 +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. - * 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. - */ - -#include "includes.h" -RCSID("$Id: dsa.c,v 1.7 2000/05/08 17:42:24 markus Exp $"); - -#include "ssh.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "compat.h" - -#include <openssl/bn.h> -#include <openssl/dh.h> -#include <openssl/rsa.h> -#include <openssl/dsa.h> -#include <openssl/evp.h> -#include <openssl/bio.h> -#include <openssl/pem.h> - -#include <openssl/hmac.h> -#include "kex.h" -#include "key.h" -#include "uuencode.h" - -#define INTBLOB_LEN 20 -#define SIGBLOB_LEN (2*INTBLOB_LEN) - -Key * -dsa_key_from_blob( - char *blob, int blen) -{ - Buffer b; - char *ktype; - int rlen; - DSA *dsa; - Key *key; - -#ifdef DEBUG_DSS - dump_base64(stderr, blob, blen); -#endif - /* fetch & parse DSA/DSS pubkey */ - key = key_new(KEY_DSA); - dsa = key->dsa; - buffer_init(&b); - buffer_append(&b, blob, blen); - ktype = buffer_get_string(&b, NULL); - if (strcmp(KEX_DSS, ktype) != 0) { - error("dsa_key_from_blob: cannot handle type %s", ktype); - key_free(key); - return NULL; - } - buffer_get_bignum2(&b, dsa->p); - buffer_get_bignum2(&b, dsa->q); - buffer_get_bignum2(&b, dsa->g); - buffer_get_bignum2(&b, dsa->pub_key); - rlen = buffer_len(&b); - if(rlen != 0) - error("dsa_key_from_blob: remaining bytes in key blob %d", rlen); - buffer_free(&b); - - debug("keytype %s", ktype); -#ifdef DEBUG_DSS - DSA_print_fp(stderr, dsa, 8); -#endif - return key; -} -int -dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp) -{ - Buffer b; - int len; - unsigned char *buf; - - if (key == NULL || key->type != KEY_DSA) - return 0; - buffer_init(&b); - buffer_put_cstring(&b, KEX_DSS); - 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); - len = buffer_len(&b); - buf = xmalloc(len); - memcpy(buf, buffer_ptr(&b), len); - memset(buffer_ptr(&b), 0, len); - buffer_free(&b); - if (lenp != NULL) - *lenp = len; - if (blobp != NULL) - *blobp = buf; - return len; -} -int -dsa_sign( - Key *key, - unsigned char **sigp, int *lenp, - unsigned char *data, int datalen) -{ - unsigned char *digest; - unsigned char *ret; - DSA_SIG *sig; - EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - unsigned int rlen; - unsigned int slen; - unsigned int len; - unsigned char sigblob[SIGBLOB_LEN]; - Buffer b; - - if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { - error("dsa_sign: no DSA key"); - return -1; - } - digest = xmalloc(evp_md->md_size); - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, NULL); - - sig = DSA_do_sign(digest, evp_md->md_size, key->dsa); - if (sig == NULL) { - fatal("dsa_sign: cannot sign"); - } - - rlen = BN_num_bytes(sig->r); - slen = BN_num_bytes(sig->s); - if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { - error("bad sig size %d %d", rlen, slen); - DSA_SIG_free(sig); - return -1; - } - debug("sig size %d %d", rlen, slen); - - 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) { - debug("datafellows"); - ret = xmalloc(SIGBLOB_LEN); - memcpy(ret, sigblob, SIGBLOB_LEN); - if (lenp != NULL) - *lenp = SIGBLOB_LEN; - if (sigp != NULL) - *sigp = ret; - } else { - /* ietf-drafts */ - buffer_init(&b); - buffer_put_cstring(&b, KEX_DSS); - buffer_put_string(&b, sigblob, SIGBLOB_LEN); - len = buffer_len(&b); - ret = xmalloc(len); - memcpy(ret, buffer_ptr(&b), len); - buffer_free(&b); - if (lenp != NULL) - *lenp = len; - if (sigp != NULL) - *sigp = ret; - } - return 0; -} -int -dsa_verify( - Key *key, - unsigned char *signature, int signaturelen, - unsigned char *data, int datalen) -{ - Buffer b; - unsigned char *digest; - DSA_SIG *sig; - EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - char *ktype; - unsigned char *sigblob; - char *txt; - unsigned int len; - int rlen; - int ret; - - if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { - error("dsa_verify: no DSA key"); - return -1; - } - - if (!(datafellows & SSH_BUG_SIGBLOB) && - signaturelen == SIGBLOB_LEN) { - datafellows |= ~SSH_BUG_SIGBLOB; - log("autodetect SSH_BUG_SIGBLOB"); - } else if ((datafellows & SSH_BUG_SIGBLOB) && - signaturelen != SIGBLOB_LEN) { - log("autoremove SSH_BUG_SIGBLOB"); - datafellows &= ~SSH_BUG_SIGBLOB; - } - - debug("len %d datafellows %d", signaturelen, datafellows); - - /* fetch signature */ - if (datafellows & SSH_BUG_SIGBLOB) { - sigblob = signature; - len = signaturelen; - } else { - /* ietf-drafts */ - buffer_init(&b); - buffer_append(&b, (char *) signature, signaturelen); - ktype = buffer_get_string(&b, NULL); - sigblob = (unsigned char *)buffer_get_string(&b, &len); - rlen = buffer_len(&b); - if(rlen != 0) - error("remaining bytes in signature %d", rlen); - buffer_free(&b); - } - - if (len != SIGBLOB_LEN) { - fatal("bad sigbloblen %d != SIGBLOB_LEN", len); - } - - /* parse signature */ - sig = DSA_SIG_new(); - sig->r = BN_new(); - sig->s = BN_new(); - 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 */ - digest = xmalloc(evp_md->md_size); - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, data, datalen); - EVP_DigestFinal(&md, digest, NULL); - - ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa); - - memset(digest, 0, evp_md->md_size); - xfree(digest); - DSA_SIG_free(sig); - - switch (ret) { - case 1: - txt = "correct"; - break; - case 0: - txt = "incorrect"; - break; - case -1: - default: - txt = "error"; - break; - } - debug("dsa_verify: signature %s", txt); - return ret; -} - -Key * -dsa_generate_key(unsigned int bits) -{ - DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); - Key *k; - if (dsa == NULL) { - fatal("DSA_generate_parameters failed"); - } - if (!DSA_generate_key(dsa)) { - fatal("DSA_generate_keys failed"); - } - - k = key_new(KEY_EMPTY); - k->type = KEY_DSA; - k->dsa = dsa; - return k; -} diff --git a/crypto/openssh/dsa.h b/crypto/openssh/dsa.h deleted file mode 100644 index 3cece7c1f22b..000000000000 --- a/crypto/openssh/dsa.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef DSA_H -#define DSA_H - -Key *dsa_key_from_blob(char *blob, int blen); -int dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp); - -int -dsa_sign( - Key *key, - unsigned char **sigp, int *lenp, - unsigned char *data, int datalen); - -int -dsa_verify( - Key *key, - unsigned char *signature, int signaturelen, - unsigned char *data, int datalen); - -Key * -dsa_generate_key(unsigned int bits); - -#endif diff --git a/crypto/openssh/fingerprint.c b/crypto/openssh/fingerprint.c deleted file mode 100644 index 4b0966d91557..000000000000 --- a/crypto/openssh/fingerprint.c +++ /dev/null @@ -1,69 +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. - * 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. - */ - -#include "includes.h" -RCSID("$Id: fingerprint.c,v 1.6 2000/04/12 09:39:10 markus Exp $"); - -#include "ssh.h" -#include "xmalloc.h" -#include <openssl/md5.h> - -#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" - -/* - * Generate key fingerprint in ascii format. - * Based on ideas and code from Bjoern Groenvall <bg@sics.se> - */ -char * -fingerprint(BIGNUM *e, BIGNUM *n) -{ - static char retval[80]; - MD5_CTX md; - unsigned char d[16]; - unsigned char *buf; - int nlen, elen; - - nlen = BN_num_bytes(n); - elen = BN_num_bytes(e); - - buf = xmalloc(nlen + elen); - - BN_bn2bin(n, buf); - BN_bn2bin(e, buf + nlen); - - MD5_Init(&md); - MD5_Update(&md, buf, nlen + elen); - MD5_Final(d, &md); - snprintf(retval, sizeof(retval), FPRINT, - d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], - d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); - memset(buf, 0, nlen + elen); - xfree(buf); - return retval; -} diff --git a/crypto/openssh/fingerprint.h b/crypto/openssh/fingerprint.h deleted file mode 100644 index fbb0d4c46206..000000000000 --- a/crypto/openssh/fingerprint.h +++ /dev/null @@ -1,34 +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. - * 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. - */ -/* RCSID("$Id: fingerprint.h,v 1.3 1999/11/24 16:15:25 markus Exp $"); */ - -#ifndef FINGERPRINT_H -#define FINGERPRINT_H -char *fingerprint(BIGNUM * e, BIGNUM * n); -#endif diff --git a/crypto/openssh/getput.h b/crypto/openssh/getput.h deleted file mode 100644 index e1aa9bb64b1d..000000000000 --- a/crypto/openssh/getput.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * getput.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Wed Jun 28 22:36:30 1995 ylo - * - * Macros for storing and retrieving data in msb first and lsb first order. - * - */ - -/* RCSID("$Id: getput.h,v 1.3 2000/04/14 10:30:31 markus Exp $"); */ - -#ifndef GETPUT_H -#define GETPUT_H - -/*------------ macros for storing/extracting msb first words -------------*/ - -#define GET_32BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 24) | \ - ((unsigned long)(unsigned char)(cp)[1] << 16) | \ - ((unsigned long)(unsigned char)(cp)[2] << 8) | \ - ((unsigned long)(unsigned char)(cp)[3])) - -#define GET_16BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 8) | \ - ((unsigned long)(unsigned char)(cp)[1])) - -#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) - -/*------------ macros for storing/extracting lsb first words -------------*/ - -#define GET_32BIT_LSB_FIRST(cp) \ - (((unsigned long)(unsigned char)(cp)[0]) | \ - ((unsigned long)(unsigned char)(cp)[1] << 8) | \ - ((unsigned long)(unsigned char)(cp)[2] << 16) | \ - ((unsigned long)(unsigned char)(cp)[3] << 24)) - -#define GET_16BIT_LSB_FIRST(cp) \ - (((unsigned long)(unsigned char)(cp)[0]) | \ - ((unsigned long)(unsigned char)(cp)[1] << 8)) - -#define PUT_32BIT_LSB_FIRST(cp, value) do { \ - (cp)[0] = (value); \ - (cp)[1] = (value) >> 8; \ - (cp)[2] = (value) >> 16; \ - (cp)[3] = (value) >> 24; } while (0) - -#define PUT_16BIT_LSB_FIRST(cp, value) do { \ - (cp)[0] = (value); \ - (cp)[1] = (value) >> 8; } while (0) - -#endif /* GETPUT_H */ diff --git a/crypto/openssh/hmac.c b/crypto/openssh/hmac.c deleted file mode 100644 index fe53aa47e7c0..000000000000 --- a/crypto/openssh/hmac.c +++ /dev/null @@ -1,59 +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. - * 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. - */ - -#include "includes.h" -RCSID("$Id: hmac.c,v 1.2 2000/04/12 09:39:10 markus Exp $"); - -#include "xmalloc.h" -#include "ssh.h" -#include "getput.h" - -#include <openssl/hmac.h> - -unsigned char * -hmac( - EVP_MD *evp_md, - unsigned int seqno, - unsigned char *data, int datalen, - unsigned char *key, int keylen) -{ - HMAC_CTX c; - static unsigned char m[EVP_MAX_MD_SIZE]; - unsigned char b[4]; - - if (key == NULL) - fatal("hmac: no key"); - HMAC_Init(&c, key, keylen, evp_md); - PUT_32BIT(b, seqno); - HMAC_Update(&c, b, sizeof b); - HMAC_Update(&c, data, datalen); - HMAC_Final(&c, m, NULL); - HMAC_cleanup(&c); - return(m); -} diff --git a/crypto/openssh/hmac.h b/crypto/openssh/hmac.h deleted file mode 100644 index fb6802927392..000000000000 --- a/crypto/openssh/hmac.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef HMAC_H -#define HMAC_H - -unsigned char * -hmac( - EVP_MD *evp_md, - unsigned int seqno, - unsigned char *data, int datalen, - unsigned char *key, int len); - -#endif diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c deleted file mode 100644 index bac285da50f9..000000000000 --- a/crypto/openssh/hostfile.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * - * hostfile.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Thu Jun 29 07:10:56 1995 ylo - * - * Functions for manipulating the known hosts files. - * - */ - -#include "includes.h" -RCSID("$OpenBSD: hostfile.c,v 1.18 2000/04/29 18:11:52 markus Exp $"); - -#include "packet.h" -#include "match.h" -#include "ssh.h" -#include <openssl/rsa.h> -#include <openssl/dsa.h> -#include "key.h" -#include "hostfile.h" - -/* - * 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, unsigned int *bitsp, Key *ret) -{ - unsigned int bits; - char *cp; - - /* Skip leading whitespace. */ - for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) - ; - - bits = key_read(ret, &cp); - if (bits == 0) - return 0; - - /* Skip trailing whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - - /* Return results. */ - *cpp = cp; - *bitsp = bits; - return 1; -} - -int -auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) -{ - Key *k = key_new(KEY_RSA); - int ret = hostfile_read_key(cpp, bitsp, k); - BN_copy(e, k->rsa->e); - BN_copy(n, k->rsa->n); - key_free(k); - return ret; -} - -int -hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum) -{ - if (key == NULL || key->type != KEY_RSA || 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. - */ - -HostStatus -check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found) -{ - FILE *f; - char line[8192]; - int linenum = 0; - unsigned int kbits, hostlen; - char *cp, *cp2; - HostStatus end_return; - - if (key == NULL) - fatal("no key to look up"); - /* Open the file containing the list of known hosts. */ - f = fopen(filename, "r"); - if (!f) - return HOST_NEW; - - /* Cache the length of the host name. */ - hostlen = strlen(host); - - /* - * 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 trough 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, (unsigned int) (cp2 - cp))) - 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 (!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. */ - 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; -} - -/* - * 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, Key *key) -{ - FILE *f; - int success = 0; - if (key == NULL) - return 1; /* XXX ? */ - f = fopen(filename, "a"); - if (!f) - return 0; - fprintf(f, "%s ", 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/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h deleted file mode 100644 index c9bdd7f2e495..000000000000 --- a/crypto/openssh/hostfile.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef HOSTFILE_H -#define HOSTFILE_H - -/* - * Checks whether the given host 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. The host must be in all lowercase. - */ -typedef enum { - HOST_OK, HOST_NEW, HOST_CHANGED -} HostStatus; -HostStatus -check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *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, Key *key); - -#endif diff --git a/crypto/openssh/includes.h b/crypto/openssh/includes.h deleted file mode 100644 index ef374dfe808f..000000000000 --- a/crypto/openssh/includes.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * includes.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Thu Mar 23 16:29:37 1995 ylo - * - * This file includes most of the needed system headers. - * - */ - -#ifndef INCLUDES_H -#define INCLUDES_H - -#define RCSID(msg) \ -static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/param.h> -#include <sys/ioctl.h> -#include <sys/endian.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/un.h> -#include <sys/resource.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/tcp.h> -#include <netinet/ip.h> -#include <arpa/inet.h> -#include <netdb.h> - -#include <netgroup.h> -#include <stdio.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <termios.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <pwd.h> -#include <grp.h> -#include <unistd.h> -#include <time.h> -#include <paths.h> -#include <dirent.h> - -#include "version.h" - -/* Define this to be the path of the xauth program. */ -#define XAUTH_PATH "/usr/X11R6/bin/xauth" - -/* - * Define this to use pipes instead of socketpairs for communicating with the - * client program. Socketpairs do not seem to work on all systems. - */ -#define USE_PIPES 1 - -#endif /* INCLUDES_H */ diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c deleted file mode 100644 index c10c77ead605..000000000000 --- a/crypto/openssh/kex.c +++ /dev/null @@ -1,424 +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. - * 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. - */ - -#include "includes.h" -RCSID("$Id: kex.c,v 1.6 2000/05/08 17:42:25 markus Exp $"); - -#include "ssh.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "cipher.h" -#include "compat.h" - -#include <openssl/bn.h> -#include <openssl/dh.h> - -#include <openssl/crypto.h> -#include <openssl/bio.h> -#include <openssl/bn.h> -#include <openssl/dh.h> -#include <openssl/pem.h> - -#include "kex.h" - -Buffer * -kex_init(char *myproposal[PROPOSAL_MAX]) -{ - char c = 0; - unsigned char cookie[16]; - u_int32_t rand = 0; - int i; - Buffer *ki = xmalloc(sizeof(*ki)); - for (i = 0; i < 16; i++) { - if (i % 4 == 0) - rand = arc4random(); - cookie[i] = rand & 0xff; - rand >>= 8; - } - buffer_init(ki); - buffer_append(ki, (char *)cookie, sizeof cookie); - for (i = 0; i < PROPOSAL_MAX; i++) - buffer_put_cstring(ki, myproposal[i]); - buffer_append(ki, &c, 1); /* boolean first_kex_packet_follows */ - buffer_put_int(ki, 0); /* uint32 0 (reserved for future extension) */ - return ki; -} - -/* 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; - - /* we only accept g==2 */ - if (!BN_is_word(dh->g, 2)) { - log("invalid DH base != 2"); - return 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; -} - -DH * -dh_new_group1() -{ - static char *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"; - DH *dh; - int ret, tries = 0; - dh = DH_new(); - if(dh == NULL) - fatal("DH_new"); - ret = BN_hex2bn(&dh->p, group1); - if(ret<0) - fatal("BN_hex2bn"); - dh->g = BN_new(); - if(dh->g == NULL) - fatal("DH_new g"); - BN_set_word(dh->g, 2); - do { - if (DH_generate_key(dh) == 0) - fatal("DH_generate_key"); - if (tries++ > 10) - fatal("dh_new_group1: too many bad keys: giving up"); - } while (!dh_pub_is_valid(dh, dh->pub_key)); - return dh; -} - -void -bignum_print(BIGNUM *b) -{ - BN_print_fp(stderr,b); -} - -void -dump_digest(unsigned char *digest, int len) -{ - int i; - for (i = 0; i< len; i++){ - fprintf(stderr, "%02x", digest[i]); - if(i%2!=0) - fprintf(stderr, " "); - } - fprintf(stderr, "\n"); -} - -unsigned char * -kex_hash( - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - char *serverhostkeyblob, int sbloblen, - BIGNUM *client_dh_pub, - BIGNUM *server_dh_pub, - BIGNUM *shared_secret) -{ - Buffer b; - static unsigned char digest[EVP_MAX_MD_SIZE]; - EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - - buffer_init(&b); - buffer_put_string(&b, client_version_string, strlen(client_version_string)); - buffer_put_string(&b, server_version_string, strlen(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(digest, evp_md->md_size); -#endif - return digest; -} - -unsigned char * -derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret) -{ - Buffer b; - EVP_MD *evp_md = EVP_sha1(); - EVP_MD_CTX md; - char c = id; - int have; - int mdsz = evp_md->md_size; - unsigned char *digest = xmalloc(((need+mdsz-1)/mdsz)*mdsz); - - buffer_init(&b); - buffer_put_bignum2(&b, shared_secret); - - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */ - EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */ - EVP_DigestUpdate(&md, &c, 1); /* key id */ - EVP_DigestUpdate(&md, hash, mdsz); /* session id */ - EVP_DigestFinal(&md, digest, NULL); - - /* expand */ - for (have = mdsz; need > have; have += mdsz) { - EVP_DigestInit(&md, evp_md); - 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, "Digest '%c'== ", c); - dump_digest(digest, need); -#endif - return digest; -} - -#define NKEYS 6 - -#define MAX_PROP 20 -#define SEP "," - -char * -get_match(char *client, char *server) -{ - char *sproposals[MAX_PROP]; - char *p; - int i, j, nproposals; - - for ((p = strtok(server, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { - if (i < MAX_PROP) - sproposals[i] = p; - else - break; - } - nproposals = i; - - for ((p = strtok(client, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { - for (j = 0; j < nproposals; j++) - if (strcmp(p, sproposals[j]) == 0) - return xstrdup(p); - } - return NULL; -} -void -choose_enc(Enc *enc, char *client, char *server) -{ - char *name = get_match(client, server); - if (name == NULL) - fatal("no matching cipher found: client %s server %s", client, server); - enc->type = cipher_number(name); - - switch (enc->type) { - case SSH_CIPHER_3DES_CBC: - enc->key_len = 24; - enc->iv_len = 8; - enc->block_size = 8; - break; - case SSH_CIPHER_BLOWFISH_CBC: - case SSH_CIPHER_CAST128_CBC: - enc->key_len = 16; - enc->iv_len = 8; - enc->block_size = 8; - break; - case SSH_CIPHER_ARCFOUR: - enc->key_len = 16; - enc->iv_len = 0; - enc->block_size = 8; - break; - default: - fatal("unsupported cipher %s", name); - } - enc->name = name; - enc->enabled = 0; - enc->iv = NULL; - enc->key = NULL; -} -void -choose_mac(Mac *mac, char *client, char *server) -{ - char *name = get_match(client, server); - if (name == NULL) - fatal("no matching mac found: client %s server %s", client, server); - if (strcmp(name, "hmac-md5") == 0) { - mac->md = EVP_md5(); - } else if (strcmp(name, "hmac-sha1") == 0) { - mac->md = EVP_sha1(); - } else if (strcmp(name, "hmac-ripemd160@openssh.com") == 0) { - mac->md = EVP_ripemd160(); - } else { - fatal("unsupported mac %s", name); - } - mac->name = name; - mac->mac_len = mac->md->md_size; - mac->key_len = (datafellows & SSH_BUG_HMAC) ? 16 : mac->mac_len; - mac->key = NULL; - mac->enabled = 0; -} -void -choose_comp(Comp *comp, char *client, char *server) -{ - char *name = get_match(client, server); - 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; -} -void -choose_kex(Kex *k, char *client, char *server) -{ - k->name = get_match(client, server); - if (k->name == NULL) - fatal("no kex alg"); - if (strcmp(k->name, KEX_DH1) != 0) - fatal("bad kex alg %s", k->name); -} -void -choose_hostkeyalg(Kex *k, char *client, char *server) -{ - k->hostkeyalg = get_match(client, server); - if (k->hostkeyalg == NULL) - fatal("no hostkey alg"); - if (strcmp(k->hostkeyalg, KEX_DSS) != 0) - fatal("bad hostkey alg %s", k->hostkeyalg); -} - -Kex * -kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) -{ - int i; - int mode; - int ctos; /* direction: if true client-to-server */ - int need; - Kex *k; - - k = xmalloc(sizeof(*k)); - memset(k, 0, sizeof(*k)); - k->server = server; - - for (mode = 0; mode < MODE_MAX; mode++) { - int nenc, nmac, ncomp; - ctos = (!k->server && mode == MODE_OUT) || (k->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 (&k->enc [mode], cprop[nenc], sprop[nenc]); - choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]); - choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]); - debug("kex: %s %s %s %s", - ctos ? "client->server" : "server->client", - k->enc[mode].name, - k->mac[mode].name, - k->comp[mode].name); - } - choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); - choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], - sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); - for (i = 0; i < PROPOSAL_MAX; i++) { - xfree(cprop[i]); - xfree(sprop[i]); - } - need = 0; - for (mode = 0; mode < MODE_MAX; mode++) { - if (need < k->enc[mode].key_len) - need = k->enc[mode].key_len; - if (need < k->enc[mode].iv_len) - need = k->enc[mode].iv_len; - if (need < k->mac[mode].key_len) - need = k->mac[mode].key_len; - } - /* need runden? */ -#define WE_NEED 32 - k->we_need = WE_NEED; - k->we_need = need; - return k; -} - -int -kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret) -{ - int i; - int mode; - int ctos; - unsigned char *keys[NKEYS]; - - for (i = 0; i < NKEYS; i++) - keys[i] = derive_key('A'+i, k->we_need, hash, shared_secret); - - for (mode = 0; mode < MODE_MAX; mode++) { - ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); - k->enc[mode].iv = keys[ctos ? 0 : 1]; - k->enc[mode].key = keys[ctos ? 2 : 3]; - k->mac[mode].key = keys[ctos ? 4 : 5]; - } - return 0; -} diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h deleted file mode 100644 index 5395ebc3f085..000000000000 --- a/crypto/openssh/kex.h +++ /dev/null @@ -1,112 +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. - * 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. - */ -#ifndef KEX_H -#define KEX_H - -#define KEX_DH1 "diffie-hellman-group1-sha1" -#define KEX_DSS "ssh-dss" - -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 -}; - -typedef struct Kex Kex; -typedef struct Mac Mac; -typedef struct Comp Comp; -typedef struct Enc Enc; - -struct Enc { - int type; - int enabled; - int block_size; - unsigned char *key; - unsigned char *iv; - int key_len; - int iv_len; - char *name; -}; -struct Mac { - EVP_MD *md; - int enabled; - int mac_len; - unsigned char *key; - int key_len; - char *name; -}; -struct Comp { - int type; - int enabled; - char *name; -}; -struct Kex { - Enc enc [MODE_MAX]; - Mac mac [MODE_MAX]; - Comp comp[MODE_MAX]; - int we_need; - int server; - char *name; - char *hostkeyalg; -}; - -Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); -int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); -DH *dh_new_group1(); -Kex *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server); -int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); -void bignum_print(BIGNUM *b); -void packet_set_kex(Kex *k); - -unsigned char * -kex_hash( - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - char *serverhostkeyblob, int sbloblen, - BIGNUM *client_dh_pub, - BIGNUM *server_dh_pub, - BIGNUM *shared_secret); - -#endif diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h deleted file mode 100644 index ed3f770b8be9..000000000000 --- a/crypto/openssh/key.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef KEY_H -#define KEY_H - -typedef struct Key Key; -enum types { - KEY_RSA, - KEY_DSA, - KEY_EMPTY -}; -struct Key { - int type; - RSA *rsa; - DSA *dsa; -}; - -Key *key_new(int type); -void key_free(Key *k); -int key_equal(Key *a, Key *b); -char *key_fingerprint(Key *k); -char *key_type(Key *k); -int key_write(Key *key, FILE *f); -unsigned int -key_read(Key *key, char **cpp); - -#endif diff --git a/crypto/openssh/lib/Makefile b/crypto/openssh/lib/Makefile deleted file mode 100644 index 35de105b496d..000000000000 --- a/crypto/openssh/lib/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -.PATH: ${.CURDIR}/.. - -LIB= ssh -SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \ - cipher.c compat.c compress.c crc32.c deattack.c fingerprint.c \ - hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \ - rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c atomicio.c \ - key.c dispatch.c dsa.c kex.c hmac.c uuencode.c - -NOPROFILE= yes -NOPIC= yes - -install: - @echo -n - -.include <bsd.own.mk> - -.if (${KERBEROS} == "yes") -CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV -.if (${AFS} == "yes") -CFLAGS+= -DAFS -SRCS+= radix.c -.endif # AFS -.endif # KERBEROS - -.include <bsd.lib.mk> diff --git a/crypto/openssh/log-client.c b/crypto/openssh/log-client.c deleted file mode 100644 index 1e3c162cb37e..000000000000 --- a/crypto/openssh/log-client.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * log-client.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Mon Mar 20 21:13:40 1995 ylo - * - * Client-side versions of debug(), log(), etc. These print to stderr. - * This is a stripped down version of log-server.c. - * - */ - -#include "includes.h" -RCSID("$Id: log-client.c,v 1.8 2000/04/14 10:30:31 markus Exp $"); - -#include "xmalloc.h" -#include "ssh.h" - -static LogLevel log_level = SYSLOG_LEVEL_INFO; - -/* Initialize the log. - * av0 program name (should be argv[0]) - * level logging level - */ - -void -log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2) -{ - switch (level) { - case SYSLOG_LEVEL_QUIET: - case SYSLOG_LEVEL_ERROR: - case SYSLOG_LEVEL_FATAL: - case SYSLOG_LEVEL_INFO: - case SYSLOG_LEVEL_VERBOSE: - case SYSLOG_LEVEL_DEBUG: - log_level = level; - break; - default: - /* unchanged */ - break; - } -} - -#define MSGBUFSIZ 1024 - -void -do_log(LogLevel level, const char *fmt, va_list args) -{ - char msgbuf[MSGBUFSIZ]; - - if (level > log_level) - return; - if (level == SYSLOG_LEVEL_DEBUG) - fprintf(stderr, "debug: "); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); - fprintf(stderr, "%s", msgbuf); - fprintf(stderr, "\r\n"); -} diff --git a/crypto/openssh/log-server.c b/crypto/openssh/log-server.c deleted file mode 100644 index 81ba67371f07..000000000000 --- a/crypto/openssh/log-server.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * - * log-server.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Mon Mar 20 21:19:30 1995 ylo - * - * Server-side versions of debug(), log(), etc. These normally send the output - * to the system log. - * - */ - -#include "includes.h" -RCSID("$Id: log-server.c,v 1.14 2000/04/14 10:30:31 markus Exp $"); - -#include <syslog.h> -#include "packet.h" -#include "xmalloc.h" -#include "ssh.h" - -static LogLevel log_level = SYSLOG_LEVEL_INFO; -static int log_on_stderr = 0; -static int log_facility = LOG_AUTH; - -/* Initialize the log. - * av0 program name (should be argv[0]) - * on_stderr print also on stderr - * level logging level - */ - -void -log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) -{ - switch (level) { - case SYSLOG_LEVEL_QUIET: - case SYSLOG_LEVEL_ERROR: - case SYSLOG_LEVEL_FATAL: - case SYSLOG_LEVEL_INFO: - case SYSLOG_LEVEL_VERBOSE: - case SYSLOG_LEVEL_DEBUG: - log_level = level; - break; - default: - fprintf(stderr, "Unrecognized internal syslog level code %d\n", - (int) level); - exit(1); - } - 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; - 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); - } - log_on_stderr = on_stderr; -} - -#define MSGBUFSIZ 1024 - -void -do_log(LogLevel level, const char *fmt, va_list args) -{ - char msgbuf[MSGBUFSIZ]; - char fmtbuf[MSGBUFSIZ]; - char *txt = NULL; - int pri = LOG_INFO; - extern char *__progname; - - if (level > log_level) - return; - switch (level) { - case SYSLOG_LEVEL_ERROR: - txt = "error"; - pri = LOG_ERR; - break; - case SYSLOG_LEVEL_FATAL: - txt = "fatal"; - pri = LOG_ERR; - break; - case SYSLOG_LEVEL_INFO: - case SYSLOG_LEVEL_VERBOSE: - pri = LOG_INFO; - break; - case SYSLOG_LEVEL_DEBUG: - txt = "debug"; - pri = LOG_DEBUG; - break; - default: - txt = "internal error"; - pri = LOG_ERR; - break; - } - if (txt != NULL) { - snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); - } else { - vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); - } - if (log_on_stderr) { - fprintf(stderr, "%s\n", msgbuf); - } else { - openlog(__progname, LOG_PID, log_facility); - syslog(pri, "%.500s", msgbuf); - closelog(); - } -} diff --git a/crypto/openssh/log.c b/crypto/openssh/log.c deleted file mode 100644 index 03038b2fbe41..000000000000 --- a/crypto/openssh/log.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Shared versions of debug(), log(), etc. - */ - -#include "includes.h" -RCSID("$OpenBSD: log.c,v 1.7 2000/01/04 00:07:59 markus Exp $"); - -#include "ssh.h" -#include "xmalloc.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(); -} - -/* 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); -} - -/* 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_DEBUG, 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 frunction 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; - } - } - fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", - (unsigned long) proc, (unsigned long) context); -} - -/* Cleanup and exit */ -void -fatal_cleanup(void) -{ - struct fatal_cleanup *cu, *next_cu; - static int called = 0; - - if (called) - exit(255); - called = 1; - /* Call cleanup functions. */ - for (cu = fatal_cleanups; cu; cu = next_cu) { - next_cu = cu->next; - debug("Calling cleanup 0x%lx(0x%lx)", - (unsigned long) cu->proc, (unsigned long) cu->context); - (*cu->proc) (cu->context); - } - exit(255); -} - -/* 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 }, - { "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, 0 } -}; - -static struct { - const char *name; - LogLevel val; -} log_levels[] = -{ - { "QUIET", SYSLOG_LEVEL_QUIET }, - { "FATAL", SYSLOG_LEVEL_FATAL }, - { "ERROR", SYSLOG_LEVEL_ERROR }, - { "INFO", SYSLOG_LEVEL_INFO }, - { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, - { "DEBUG", SYSLOG_LEVEL_DEBUG }, - { NULL, 0 } -}; - -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 (SyslogFacility) - 1; -} - -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 (LogLevel) - 1; -} diff --git a/crypto/openssh/login.c b/crypto/openssh/login.c deleted file mode 100644 index 8e40784e2cb0..000000000000 --- a/crypto/openssh/login.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * - * login.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 24 14:51:08 1995 ylo - * - * This file performs some of the things login(1) normally does. We cannot - * easily use something like login -p -h host -f user, because there are - * several different logins around, and it is hard to determined what kind of - * login the current system has. Also, we want to be able to execute commands - * on a tty. - * - */ - -#include "includes.h" -RCSID("$Id: login.c,v 1.13 2000/04/19 07:05:49 deraadt Exp $"); - -#include <util.h> -#include <utmp.h> -#include "ssh.h" - -/* - * 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. - */ - -/* - * Returns the time when the user last logged in (or 0 if no previous login - * is found). The name of the host used last time is returned in buf. - */ - -unsigned long -get_last_login_time(uid_t uid, const char *logname, - char *buf, unsigned int bufsize) -{ - struct lastlog ll; - char *lastlog; - int fd; - - lastlog = _PATH_LASTLOG; - buf[0] = '\0'; - - fd = open(lastlog, O_RDONLY); - if (fd < 0) - return 0; - lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); - if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { - close(fd); - return 0; - } - close(fd); - if (bufsize > sizeof(ll.ll_host) + 1) - bufsize = sizeof(ll.ll_host) + 1; - strncpy(buf, ll.ll_host, bufsize - 1); - buf[bufsize - 1] = 0; - return ll.ll_time; -} - -/* - * Records that the user has logged in. I these parts of operating systems - * were more standardized. - */ - -void -record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, - const char *host, struct sockaddr * addr) -{ - int fd; - struct lastlog ll; - char *lastlog; - struct utmp u; - const char *utmp, *wtmp; - - /* Construct an utmp/wtmp entry. */ - memset(&u, 0, sizeof(u)); - strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); - u.ut_time = time(NULL); - strncpy(u.ut_name, user, sizeof(u.ut_name)); - strncpy(u.ut_host, host, sizeof(u.ut_host)); - - /* Figure out the file names. */ - utmp = _PATH_UTMP; - wtmp = _PATH_WTMP; - - login(&u); - lastlog = _PATH_LASTLOG; - - /* Update lastlog unless actually recording a logout. */ - if (strcmp(user, "") != 0) { - /* - * It is safer to bzero the lastlog structure first because - * some systems might have some extra fields in it (e.g. SGI) - */ - memset(&ll, 0, sizeof(ll)); - - /* Update lastlog. */ - ll.ll_time = time(NULL); - strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); - strncpy(ll.ll_host, host, sizeof(ll.ll_host)); - fd = open(lastlog, O_RDWR); - if (fd >= 0) { - lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); - if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) - log("Could not write %.100s: %.100s", lastlog, strerror(errno)); - close(fd); - } - } -} - -/* Records that the user has logged out. */ - -void -record_logout(pid_t pid, const char *ttyname) -{ - const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */ - if (logout(line)) - logwtmp(line, "", ""); -} diff --git a/crypto/openssh/match.c b/crypto/openssh/match.c deleted file mode 100644 index 00dff8a86130..000000000000 --- a/crypto/openssh/match.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * match.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Thu Jun 22 01:17:50 1995 ylo - * - * Simple pattern matching, with '*' and '?' as wildcards. - * - */ - -#include "includes.h" -RCSID("$Id: match.c,v 1.6 2000/04/14 10:30:31 markus Exp $"); - -#include "ssh.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 host name (which must be in all lowercase) against the - * comma-separated sequence of subpatterns (each possibly preceded by ! to - * indicate negation). Returns true if there is a positive match; zero - * otherwise. - */ - -int -match_hostname(const char *host, const char *pattern, unsigned int len) -{ - char sub[1024]; - int negated; - int got_positive; - unsigned 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] = 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 host name. */ - if (match_pattern(host, sub)) { - if (negated) - return 0; /* Fail */ - else - got_positive = 1; - } - } - - /* - * Return success if got a positive match. If there was a negative - * match, we have already returned zero and never get here. - */ - return got_positive; -} diff --git a/crypto/openssh/match.h b/crypto/openssh/match.h deleted file mode 100644 index 4625d97691fb..000000000000 --- a/crypto/openssh/match.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MATCH_H -#define MATCH_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); - -/* - * Tries to match the host name (which must be in all lowercase) against the - * comma-separated sequence of subpatterns (each possibly preceded by ! to - * indicate negation). Returns true if there is a positive match; zero - * otherwise. - */ -int match_hostname(const char *host, const char *pattern, unsigned int len); - -#endif diff --git a/crypto/openssh/mpaux.c b/crypto/openssh/mpaux.c deleted file mode 100644 index 3442070e41b2..000000000000 --- a/crypto/openssh/mpaux.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * mpaux.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sun Jul 16 04:29:30 1995 ylo - * - * This file contains various auxiliary functions related to multiple - * precision integers. - * -*/ - -#include "includes.h" -RCSID("$Id: mpaux.c,v 1.12 2000/04/14 10:30:32 markus Exp $"); - -#include <openssl/bn.h> -#include "getput.h" -#include "xmalloc.h" - -#include <openssl/md5.h> - -void -compute_session_id(unsigned char session_id[16], - unsigned char cookie[8], - BIGNUM* host_key_n, - BIGNUM* session_key_n) -{ - unsigned int host_key_bytes = BN_num_bytes(host_key_n); - unsigned int session_key_bytes = BN_num_bytes(session_key_n); - unsigned int bytes = host_key_bytes + session_key_bytes; - unsigned 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/crypto/openssh/mpaux.h b/crypto/openssh/mpaux.h deleted file mode 100644 index 671fc511a929..000000000000 --- a/crypto/openssh/mpaux.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * mpaux.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sun Jul 16 04:29:30 1995 ylo - * - * This file contains various auxiliary functions related to multiple - * precision integers. - */ - -/* RCSID("$Id: mpaux.h,v 1.6 2000/04/14 10:30:32 markus Exp $"); */ - -#ifndef MPAUX_H -#define MPAUX_H - -/* - * Computes a 16-byte session id in the global variable session_id. The - * session id is computed by concatenating the linearized, msb first - * representations of host_key_n, session_key_n, and the cookie. - */ -void -compute_session_id(unsigned char session_id[16], - unsigned char cookie[8], - BIGNUM * host_key_n, - BIGNUM * session_key_n); - -#endif /* MPAUX_H */ diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h deleted file mode 100644 index 8b24179724f3..000000000000 --- a/crypto/openssh/myproposal.h +++ /dev/null @@ -1,20 +0,0 @@ -#define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1" -#define KEX_DEFAULT_PK_ALG "ssh-dss" -#define KEX_DEFAULT_ENCRYPT "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" -#define KEX_DEFAULT_MAC "hmac-sha1,hmac-md5,hmac-ripemd160@openssh.com" -#define KEX_DEFAULT_COMP "zlib,none" -#define KEX_DEFAULT_LANG "" - - -static const char *myproposal[PROPOSAL_MAX] = { - KEX_DEFAULT_KEX, - KEX_DEFAULT_PK_ALG, - KEX_DEFAULT_ENCRYPT, - KEX_DEFAULT_ENCRYPT, - KEX_DEFAULT_MAC, - KEX_DEFAULT_MAC, - KEX_DEFAULT_COMP, - KEX_DEFAULT_COMP, - KEX_DEFAULT_LANG, - KEX_DEFAULT_LANG -}; diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c deleted file mode 100644 index fd92fe8f653f..000000000000 --- a/crypto/openssh/nchan.c +++ /dev/null @@ -1,495 +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. - * 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. - */ - -#include "includes.h" -RCSID("$Id: nchan.c,v 1.17 2000/05/08 17:44:54 markus Exp $"); - -#include "ssh.h" - -#include "buffer.h" -#include "packet.h" -#include "channels.h" -#include "nchan.h" - -#include "ssh2.h" -#include "compat.h" - -/* functions manipulating channel states */ -/* - * EVENTS update channel input/output states execute ACTIONS - */ -/* events concerning the INPUT from socket for channel (istate) */ -chan_event_fn *chan_rcvd_oclose = NULL; -chan_event_fn *chan_read_failed = NULL; -chan_event_fn *chan_ibuf_empty = NULL; -/* events concerning the OUTPUT from channel for socket (ostate) */ -chan_event_fn *chan_rcvd_ieof = NULL; -chan_event_fn *chan_write_failed = NULL; -chan_event_fn *chan_obuf_empty = NULL; -/* - * ACTIONS: should never update the channel states - */ -static void chan_send_ieof1(Channel *c); -static void chan_send_oclose1(Channel *c); -static void chan_send_close2(Channel *c); -static void chan_send_eof2(Channel *c); - -/* channel cleanup */ -chan_event_fn *chan_delete_if_full_closed = NULL; - -/* helper */ -static void chan_shutdown_write(Channel *c); -static void chan_shutdown_read(Channel *c); - -/* - * 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: - debug("channel %d: input wait_oclose -> closed", c->self); - c->istate = CHAN_INPUT_CLOSED; - break; - case CHAN_INPUT_OPEN: - debug("channel %d: input open -> closed", c->self); - chan_shutdown_read(c); - chan_send_ieof1(c); - c->istate = CHAN_INPUT_CLOSED; - break; - case CHAN_INPUT_WAIT_DRAIN: - /* both local read_failed and remote write_failed */ - log("channel %d: input drain -> closed", c->self); - chan_send_ieof1(c); - c->istate = CHAN_INPUT_CLOSED; - break; - default: - error("channel %d: protocol error: chan_rcvd_oclose for istate %d", - c->self, c->istate); - return; - } -} -static void -chan_read_failed_12(Channel *c) -{ - debug("channel %d: read failed", c->self); - switch (c->istate) { - case CHAN_INPUT_OPEN: - debug("channel %d: input open -> drain", c->self); - chan_shutdown_read(c); - c->istate = CHAN_INPUT_WAIT_DRAIN; - if (buffer_len(&c->input) == 0) { - debug("channel %d: input: no drain shortcut", c->self); - chan_ibuf_empty(c); - } - break; - default: - error("channel %d: internal error: we do not read, but chan_read_failed for istate %d", - c->self, c->istate); - break; - } -} -static void -chan_ibuf_empty1(Channel *c) -{ - debug("channel %d: ibuf empty", c->self); - if (buffer_len(&c->input)) { - error("channel %d: internal error: chan_ibuf_empty for non empty buffer", - c->self); - return; - } - switch (c->istate) { - case CHAN_INPUT_WAIT_DRAIN: - debug("channel %d: input drain -> wait_oclose", c->self); - chan_send_ieof1(c); - c->istate = CHAN_INPUT_WAIT_OCLOSE; - break; - default: - error("channel %d: internal error: 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); - if (c->type != SSH_CHANNEL_OPEN) { - debug("channel %d: non-open", c->self); - if (c->istate == CHAN_INPUT_OPEN) { - debug("channel %d: non-open: input open -> wait_oclose", c->self); - chan_shutdown_read(c); - chan_send_ieof1(c); - c->istate = CHAN_INPUT_WAIT_OCLOSE; - } else { - error("channel %d: istate %d != open", c->self, c->istate); - } - if (c->ostate == CHAN_OUTPUT_OPEN) { - debug("channel %d: non-open: output open -> closed", c->self); - chan_send_oclose1(c); - c->ostate = CHAN_OUTPUT_CLOSED; - } else { - error("channel %d: ostate %d != open", c->self, c->ostate); - } - return; - } - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - debug("channel %d: output open -> drain", c->self); - c->ostate = CHAN_OUTPUT_WAIT_DRAIN; - break; - case CHAN_OUTPUT_WAIT_IEOF: - debug("channel %d: output wait_ieof -> closed", c->self); - c->ostate = CHAN_OUTPUT_CLOSED; - break; - default: - error("channel %d: protocol error: chan_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: - debug("channel %d: output open -> wait_ieof", c->self); - chan_send_oclose1(c); - c->ostate = CHAN_OUTPUT_WAIT_IEOF; - break; - case CHAN_OUTPUT_WAIT_DRAIN: - debug("channel %d: output wait_drain -> closed", c->self); - chan_send_oclose1(c); - c->ostate = CHAN_OUTPUT_CLOSED; - break; - default: - error("channel %d: internal error: chan_write_failed for ostate %d", - c->self, c->ostate); - break; - } -} -static void -chan_obuf_empty1(Channel *c) -{ - debug("channel %d: obuf empty", c->self); - if (buffer_len(&c->output)) { - error("channel %d: internal error: chan_obuf_empty for non empty buffer", - c->self); - return; - } - switch (c->ostate) { - case CHAN_OUTPUT_WAIT_DRAIN: - debug("channel %d: output drain -> closed", c->self); - chan_send_oclose1(c); - c->ostate = CHAN_OUTPUT_CLOSED; - break; - default: - error("channel %d: internal error: chan_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: internal error: 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: - chan_shutdown_write(c); - buffer_consume(&c->output, buffer_len(&c->output)); - packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); - packet_put_int(c->remote_id); - packet_send(); - break; - default: - error("channel %d: internal error: cannot send oclose for ostate %d", - c->self, c->ostate); - break; - } -} -static void -chan_delete_if_full_closed1(Channel *c) -{ - if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { - debug("channel %d: full closed", c->self); - channel_free(c->self); - } -} - -/* - * the same for SSH2 - */ -static void -chan_rcvd_oclose2(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 */ - c->ostate = CHAN_OUTPUT_CLOSED; - c->istate = 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 */ - debug("channel %d: output open -> drain", c->self); - c->ostate = CHAN_OUTPUT_WAIT_DRAIN; - break; - } - switch (c->istate) { - case CHAN_INPUT_OPEN: - debug("channel %d: input open -> closed", c->self); - chan_shutdown_read(c); - break; - case CHAN_INPUT_WAIT_DRAIN: - debug("channel %d: input drain -> closed", c->self); - chan_send_eof2(c); - break; - } - c->istate = CHAN_INPUT_CLOSED; -} -static void -chan_ibuf_empty2(Channel *c) -{ - debug("channel %d: ibuf empty", c->self); - if (buffer_len(&c->input)) { - error("channel %d: internal error: chan_ibuf_empty for non empty buffer", - c->self); - return; - } - switch (c->istate) { - case CHAN_INPUT_WAIT_DRAIN: - debug("channel %d: input drain -> closed", c->self); - if (!(c->flags & CHAN_CLOSE_SENT)) - chan_send_eof2(c); - c->istate = CHAN_INPUT_CLOSED; - break; - default: - error("channel %d: internal error: chan_ibuf_empty for istate %d", - c->self, c->istate); - break; - } -} -static void -chan_rcvd_ieof2(Channel *c) -{ - debug("channel %d: rcvd eof", c->self); - if (c->ostate == CHAN_OUTPUT_OPEN) { - debug("channel %d: output open -> drain", c->self); - c->ostate = 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: - debug("channel %d: output open -> closed", c->self); - chan_shutdown_write(c); /* ?? */ - c->ostate = CHAN_OUTPUT_CLOSED; - break; - case CHAN_OUTPUT_WAIT_DRAIN: - debug("channel %d: output drain -> closed", c->self); - chan_shutdown_write(c); - c->ostate = CHAN_OUTPUT_CLOSED; - break; - default: - error("channel %d: internal error: chan_write_failed for ostate %d", - c->self, c->ostate); - break; - } -} -static void -chan_obuf_empty2(Channel *c) -{ - debug("channel %d: obuf empty", c->self); - if (buffer_len(&c->output)) { - error("internal error: chan_obuf_empty %d for non empty buffer", - c->self); - return; - } - switch (c->ostate) { - case CHAN_OUTPUT_WAIT_DRAIN: - debug("channel %d: output drain -> closed", c->self); - chan_shutdown_write(c); - c->ostate = CHAN_OUTPUT_CLOSED; - break; - default: - error("channel %d: internal error: chan_obuf_empty 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(); - break; - default: - error("channel %d: internal error: 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: internal error: cannot send close for istate/ostate %d/%d", - c->self, c->istate, c->ostate); - } else if (c->flags & CHAN_CLOSE_SENT) { - error("channel %d: internal error: 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_delete_if_full_closed2(Channel *c) -{ - if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { - if (!(c->flags & CHAN_CLOSE_SENT)) { - chan_send_close2(c); - } - if ((c->flags & CHAN_CLOSE_SENT) && - (c->flags & CHAN_CLOSE_RCVD)) { - debug("channel %d: full closed2", c->self); - channel_free(c->self); - } - } -} - -/* shared */ -void -chan_init_iostates(Channel *c) -{ - c->ostate = CHAN_OUTPUT_OPEN; - c->istate = CHAN_INPUT_OPEN; - c->flags = 0; -} - -/* init */ -void -chan_init(void) -{ - if (compat20) { - chan_rcvd_oclose = chan_rcvd_oclose2; - chan_read_failed = chan_read_failed_12; - chan_ibuf_empty = chan_ibuf_empty2; - - chan_rcvd_ieof = chan_rcvd_ieof2; - chan_write_failed = chan_write_failed2; - chan_obuf_empty = chan_obuf_empty2; - - chan_delete_if_full_closed = chan_delete_if_full_closed2; - } else { - chan_rcvd_oclose = chan_rcvd_oclose1; - chan_read_failed = chan_read_failed_12; - chan_ibuf_empty = chan_ibuf_empty1; - - chan_rcvd_ieof = chan_rcvd_ieof1; - chan_write_failed = chan_write_failed1; - chan_obuf_empty = chan_obuf_empty1; - - chan_delete_if_full_closed = chan_delete_if_full_closed1; - } -} - -/* helper */ -static void -chan_shutdown_write(Channel *c) -{ - buffer_consume(&c->output, buffer_len(&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 (close(c->wfd) < 0) - log("channel %d: chan_shutdown_write: close() failed for fd%d: %.100s", - c->self, c->wfd, strerror(errno)); - c->wfd = -1; - } -} -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) { - if (shutdown(c->sock, SHUT_RD) < 0) - 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 (close(c->rfd) < 0) - log("channel %d: chan_shutdown_read: close() failed for fd%d: %.100s", - c->self, c->rfd, strerror(errno)); - c->rfd = -1; - } -} diff --git a/crypto/openssh/nchan.h b/crypto/openssh/nchan.h deleted file mode 100644 index 0a2cf35f781f..000000000000 --- a/crypto/openssh/nchan.h +++ /dev/null @@ -1,96 +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. - * 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. - */ - -/* RCSID("$Id: nchan.h,v 1.7 2000/04/03 07:07:15 markus Exp $"); */ - -#ifndef NCHAN_H -#define NCHAN_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 - * - * See the debugging output from 'ssh -v' and 'sshd -d' of - * ssh-1.2.27 as an example. - * - */ - -/* ssh-proto-1.5 overloads prot-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 - -/* possible input states */ -#define CHAN_INPUT_OPEN 0x01 -#define CHAN_INPUT_WAIT_DRAIN 0x02 -#define CHAN_INPUT_WAIT_OCLOSE 0x04 -#define CHAN_INPUT_CLOSED 0x08 - -/* possible output states */ -#define CHAN_OUTPUT_OPEN 0x10 -#define CHAN_OUTPUT_WAIT_DRAIN 0x20 -#define CHAN_OUTPUT_WAIT_IEOF 0x40 -#define CHAN_OUTPUT_CLOSED 0x80 - -#define CHAN_CLOSE_SENT 0x01 -#define CHAN_CLOSE_RCVD 0x02 - - -/* Channel EVENTS */ -typedef void chan_event_fn(Channel * c); - -/* for the input state */ -extern chan_event_fn *chan_rcvd_oclose; -extern chan_event_fn *chan_read_failed; -extern chan_event_fn *chan_ibuf_empty; - -/* for the output state */ -extern chan_event_fn *chan_rcvd_ieof; -extern chan_event_fn *chan_write_failed; -extern chan_event_fn *chan_obuf_empty; - -extern chan_event_fn *chan_delete_if_full_closed; - -void chan_init_iostates(Channel * c); -void chan_init(void); -#endif diff --git a/crypto/openssh/nchan.ms b/crypto/openssh/nchan.ms deleted file mode 100644 index eb49cd3b4fad..000000000000 --- a/crypto/openssh/nchan.ms +++ /dev/null @@ -1,102 +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. -.\" 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. -.\" -.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/crypto/openssh/nchan2.ms b/crypto/openssh/nchan2.ms deleted file mode 100644 index 1b119d1353bf..000000000000 --- a/crypto/openssh/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/crypto/openssh/packet.c b/crypto/openssh/packet.c deleted file mode 100644 index 5fa76a315b5e..000000000000 --- a/crypto/openssh/packet.c +++ /dev/null @@ -1,1283 +0,0 @@ -/* - * - * packet.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sat Mar 18 02:40:40 1995 ylo - * - * This file contains code implementing the packet protocol and communication - * with the other side. This same code is used both on client and server side. - * - * SSH2 packet format added by Markus Friedl. - * - */ - -#include "includes.h" -RCSID("$Id: packet.c,v 1.32 2000/05/04 22:22:43 markus Exp $"); - -#include "xmalloc.h" -#include "buffer.h" -#include "packet.h" -#include "bufaux.h" -#include "ssh.h" -#include "crc32.h" -#include "cipher.h" -#include "getput.h" - -#include "compress.h" -#include "deattack.h" -#include "channels.h" - -#include "compat.h" -#include "ssh2.h" - -#include <openssl/bn.h> -#include <openssl/dh.h> -#include <openssl/hmac.h> -#include "buffer.h" -#include "kex.h" -#include "hmac.h" - -#ifdef PACKET_DEBUG -#define DBG(x) x -#else -#define DBG(x) -#endif - -/* - * 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; - -/* - * Cipher type. This value is only used to determine whether to pad the - * packets with zeroes or random data. - */ -static int cipher_type = SSH_CIPHER_NONE; - -/* Protocol flags for the remote side. */ -static unsigned 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. */ -static Buffer input; - -/* Buffer for raw output data going to the socket. */ -static 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; - -/* 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; - -/* True if SSH2 packet format is used */ -int use_ssh2_packet_format = 0; - -/* Session key information for Encryption and MAC */ -Kex *kex = NULL; - -void -packet_set_kex(Kex *k) -{ - if( k->mac[MODE_IN ].key == NULL || - k->enc[MODE_IN ].key == NULL || - k->enc[MODE_IN ].iv == NULL || - k->mac[MODE_OUT].key == NULL || - k->enc[MODE_OUT].key == NULL || - k->enc[MODE_OUT].iv == NULL) - fatal("bad KEX"); - kex = k; -} -void -clear_enc_keys(Enc *enc, int len) -{ - memset(enc->iv, 0, len); - memset(enc->key, 0, len); - xfree(enc->iv); - xfree(enc->key); - enc->iv = NULL; - enc->key = NULL; -} -void -packet_set_ssh2_format(void) -{ - DBG(debug("use_ssh2_packet_format")); - use_ssh2_packet_format = 1; -} - -/* - * 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) -{ - connection_in = fd_in; - connection_out = fd_out; - cipher_type = SSH_CIPHER_NONE; - cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); - cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); - if (!initialized) { - initialized = 1; - buffer_init(&input); - buffer_init(&output); - buffer_init(&outgoing_packet); - buffer_init(&incoming_packet); - } - /* 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() -{ - struct sockaddr_storage from, to; - socklen_t fromlen, tolen; - - /* filedescriptors in and out are the same, so it's a socket */ - if (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() -{ - 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 0; - return 1; -} - -/* Sets the connection into non-blocking mode. */ - -void -packet_set_nonblocking() -{ - /* 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() -{ - return connection_in; -} - -/* Returns the descriptor used for writing. */ - -int -packet_get_connection_out() -{ - return connection_out; -} - -/* Closes the connection and clears and frees internal data structures. */ - -void -packet_close() -{ - 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 (packet_compression) { - buffer_free(&compression_buffer); - buffer_compress_uninit(); - } -} - -/* Sets remote side protocol flags. */ - -void -packet_set_protocol_flags(unsigned int protocol_flags) -{ - remote_protocol_flags = protocol_flags; - channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0); -} - -/* Returns the remote protocol flags set earlier by the above function. */ - -unsigned int -packet_get_protocol_flags() -{ - 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. - */ - -/*** XXXXX todo: kex means re-init */ -void -packet_start_compression(int level) -{ - if (packet_compression) - fatal("Compression already enabled."); - packet_compression = 1; - buffer_init(&compression_buffer); - buffer_compress_init(level); -} - -/* - * Encrypts the given number of bytes, copying from src to dest. bytes is - * known to be a multiple of 8. - */ - -void -packet_encrypt(CipherContext * cc, void *dest, void *src, - unsigned int bytes) -{ - cipher_encrypt(cc, dest, src, bytes); -} - -/* - * Decrypts the given number of bytes, copying from src to dest. bytes is - * known to be a multiple of 8. - */ - -void -packet_decrypt(CipherContext * cc, void *dest, void *src, - unsigned int bytes) -{ - int i; - - if ((bytes % 8) != 0) - fatal("packet_decrypt: bad ciphertext length %d", bytes); - - /* - * Cryptographic attack detector for ssh - Modifications for packet.c - * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) - */ - - if (cc->type == SSH_CIPHER_NONE || compat20) { - i = DEATTACK_OK; - } else { - i = detect_attack(src, bytes, NULL); - } - if (i == DEATTACK_DETECTED) - packet_disconnect("crc32 compensation attack: network attack detected"); - - cipher_decrypt(cc, dest, src, bytes); -} - -/* - * 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 unsigned char *key, unsigned int keylen, - int cipher) -{ - if (keylen < 20) - fatal("keylen too small: %d", keylen); - - /* All other ciphers use the same key in both directions for now. */ - cipher_set_key(&receive_context, cipher, key, keylen); - cipher_set_key(&send_context, cipher, key, keylen); -} - -/* Starts constructing a packet to send. */ - -void -packet_start1(int type) -{ - char buf[9]; - - buffer_clear(&outgoing_packet); - memset(buf, 0, 8); - buf[8] = type; - buffer_append(&outgoing_packet, buf, 9); -} - -void -packet_start2(int type) -{ - char buf[4+1+1]; - - buffer_clear(&outgoing_packet); - memset(buf, 0, sizeof buf); - /* buf[0..3] = payload_len; */ - /* buf[4] = pad_len; */ - buf[5] = type & 0xff; - buffer_append(&outgoing_packet, buf, sizeof buf); -} - -void -packet_start(int type) -{ - DBG(debug("packet_start[%d]",type)); - if (use_ssh2_packet_format) - packet_start2(type); - else - packet_start1(type); -} - -/* Appends a character to the packet data. */ - -void -packet_put_char(int value) -{ - char ch = value; - buffer_append(&outgoing_packet, &ch, 1); -} - -/* Appends an integer to the packet data. */ - -void -packet_put_int(unsigned int value) -{ - buffer_put_int(&outgoing_packet, value); -} - -/* Appends a string to packet data. */ - -void -packet_put_string(const char *buf, unsigned int len) -{ - buffer_put_string(&outgoing_packet, buf, len); -} -void -packet_put_cstring(const char *str) -{ - buffer_put_string(&outgoing_packet, str, strlen(str)); -} - -void -packet_put_raw(const char *buf, unsigned int len) -{ - buffer_append(&outgoing_packet, buf, len); -} - - -/* Appends an arbitrary precision integer to packet data. */ - -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. - */ - -void -packet_send1() -{ - char buf[8], *cp; - int i, padding, len; - unsigned int checksum; - u_int32_t rand = 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 (cipher_type != SSH_CIPHER_NONE) { - cp = buffer_ptr(&outgoing_packet); - for (i = 0; i < padding; i++) { - if (i % 4 == 0) - rand = arc4random(); - cp[7 - i] = rand & 0xff; - rand >>= 8; - } - } - buffer_consume(&outgoing_packet, 8 - padding); - - /* Add check bytes. */ - checksum = crc32((unsigned char *) 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); - buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); - packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), - buffer_len(&outgoing_packet)); - -#ifdef PACKET_DEBUG - fprintf(stderr, "encrypted: "); - 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. - */ -} - -/* - * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) - */ -void -packet_send2() -{ - unsigned char *macbuf = NULL; - char *cp; - unsigned int packet_length = 0; - unsigned int i, padlen, len; - u_int32_t rand = 0; - static unsigned int seqnr = 0; - int type; - Enc *enc = NULL; - Mac *mac = NULL; - Comp *comp = NULL; - int block_size; - - if (kex != NULL) { - enc = &kex->enc[MODE_OUT]; - mac = &kex->mac[MODE_OUT]; - comp = &kex->comp[MODE_OUT]; - } - block_size = enc ? enc->block_size : 8; - - cp = buffer_ptr(&outgoing_packet); - type = cp[5] & 0xff; - -#ifdef PACKET_DEBUG - fprintf(stderr, "plain: "); - 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; - buffer_append_space(&outgoing_packet, &cp, padlen); - if (enc && enc->type != SSH_CIPHER_NONE) { - /* random padding */ - for (i = 0; i < padlen; i++) { - if (i % 4 == 0) - rand = arc4random(); - cp[i] = rand & 0xff; - rand <<= 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 & 0xff; - DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); - - /* compute MAC over seqnr and packet(length fields, payload, padding) */ - if (mac && mac->enabled) { - macbuf = hmac( mac->md, seqnr, - (unsigned char *) buffer_ptr(&outgoing_packet), - buffer_len(&outgoing_packet), - mac->key, mac->key_len - ); - DBG(debug("done calc HMAC out #%d", seqnr)); - } - /* encrypt packet and append to output buffer. */ - buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); - packet_encrypt(&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 - fprintf(stderr, "encrypted: "); - buffer_dump(&output); -#endif - /* increment sequence number for outgoing packets */ - if (++seqnr == 0) - log("outgoing seqnr wraps around"); - buffer_clear(&outgoing_packet); - - if (type == SSH2_MSG_NEWKEYS) { - if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) - fatal("packet_send2: no KEX"); - if (mac->md != NULL) - mac->enabled = 1; - DBG(debug("cipher_set_key_iv send_context")); - cipher_set_key_iv(&send_context, enc->type, - enc->key, enc->key_len, - enc->iv, enc->iv_len); - clear_enc_keys(enc, kex->we_need); - if (comp->type != 0 && comp->enabled == 0) { - comp->enabled = 1; - if (! packet_compression) - packet_start_compression(6); - } - } -} - -void -packet_send() -{ - if (use_ssh2_packet_format) - 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. - */ - -int -packet_read(int *payload_len_ptr) -{ - int type, len; - fd_set set; - char buf[8192]; - DBG(debug("packet_read()")); - - /* 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(payload_len_ptr); - if (!use_ssh2_packet_format && ( - type == SSH_SMSG_SUCCESS - || type == SSH_SMSG_FAILURE - || type == SSH_CMSG_EOF - || type == SSH_CMSG_EXIT_CONFIRMATION)) - packet_integrity_check(*payload_len_ptr, 0, type); - /* If we got a packet, return it. */ - if (type != SSH_MSG_NONE) - return type; - /* - * Otherwise, wait for some data to arrive, add it to the - * buffer, and try again. - */ - FD_ZERO(&set); - FD_SET(connection_in, &set); - - /* Wait for some data to arrive. */ - select(connection_in + 1, &set, NULL, NULL, NULL); - - /* Read data from the socket. */ - len = read(connection_in, buf, sizeof(buf)); - if (len == 0) { - log("Connection closed by %.200s", get_remote_ipaddr()); - fatal_cleanup(); - } - if (len < 0) - fatal("Read from socket failed: %.100s", strerror(errno)); - /* Append it to the buffer. */ - packet_process_incoming(buf, len); - } - /* NOTREACHED */ -} - -/* - * 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 *payload_len_ptr, int expected_type) -{ - int type; - - type = packet_read(payload_len_ptr); - 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. - * - * The returned payload_len does include space consumed by: - * Packet length - * Padding - * Packet type - * Check bytes - */ - -int -packet_read_poll1(int *payload_len_ptr) -{ - unsigned int len, padded_len; - unsigned char *ucp; - char buf[8], *cp; - unsigned 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. */ - ucp = (unsigned char *) buffer_ptr(&input); - len = GET_32BIT(ucp); - 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); - - /* Copy data to incoming_packet. */ - buffer_clear(&incoming_packet); - buffer_append_space(&incoming_packet, &cp, padded_len); - packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len); - buffer_consume(&input, padded_len); - -#ifdef PACKET_DEBUG - fprintf(stderr, "read_poll plain: "); - buffer_dump(&incoming_packet); -#endif - - /* Compute packet checksum. */ - checksum = crc32((unsigned char *) 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_poll: len %d != buffer_len %d.", - len, buffer_len(&incoming_packet)); - - ucp = (unsigned char *) buffer_ptr(&incoming_packet) + len - 4; - stored_checksum = GET_32BIT(ucp); - if (checksum != stored_checksum) - packet_disconnect("Corrupted check bytes on input."); - buffer_consume_end(&incoming_packet, 4); - - /* If using packet compression, decompress the packet. */ - 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)); - } - /* Get packet type. */ - buffer_get(&incoming_packet, &buf[0], 1); - - /* Return length of payload (without type field). */ - *payload_len_ptr = buffer_len(&incoming_packet); - - /* Return type. */ - return (unsigned char) buf[0]; -} - -int -packet_read_poll2(int *payload_len_ptr) -{ - unsigned int padlen, need; - unsigned char buf[8], *macbuf; - unsigned char *ucp; - char *cp; - static unsigned int packet_length = 0; - static unsigned int seqnr = 0; - int type; - int maclen, block_size; - Enc *enc = NULL; - Mac *mac = NULL; - Comp *comp = NULL; - - if (kex != NULL) { - enc = &kex->enc[MODE_IN]; - mac = &kex->mac[MODE_IN]; - comp = &kex->comp[MODE_IN]; - } - 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; - buffer_clear(&incoming_packet); - buffer_append_space(&incoming_packet, &cp, block_size); - packet_decrypt(&receive_context, cp, buffer_ptr(&input), - block_size); - ucp = (unsigned char *) buffer_ptr(&incoming_packet); - packet_length = GET_32BIT(ucp); - if (packet_length < 1 + 4 || packet_length > 256 * 1024) { - buffer_dump(&incoming_packet); - packet_disconnect("Bad packet length %d.", packet_length); - } - DBG(debug("input: packet len %d", 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, need %d, maclen %d", block_size, - need, maclen)); - if (need % block_size != 0) - fatal("padding error: need %d block %d mod %d", - need, block_size, need % block_size); - /* - * 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 - fprintf(stderr, "read_poll enc/full: "); - buffer_dump(&input); -#endif - buffer_append_space(&incoming_packet, &cp, need); - packet_decrypt(&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 = hmac( mac->md, seqnr, - (unsigned char *) buffer_ptr(&incoming_packet), - buffer_len(&incoming_packet), - mac->key, mac->key_len - ); - if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) - packet_disconnect("Corrupted HMAC on input."); - DBG(debug("HMAC #%d ok", seqnr)); - buffer_consume(&input, mac->mac_len); - } - if (++seqnr == 0) - log("incoming seqnr wraps around"); - - /* get padlen */ - cp = buffer_ptr(&incoming_packet) + 4; - padlen = *cp & 0xff; - 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) - */ - buffer_get(&incoming_packet, (char *)&buf[0], 1); - *payload_len_ptr = buffer_len(&incoming_packet); - - /* reset for next packet */ - packet_length = 0; - - /* extract packet type */ - type = (unsigned char)buf[0]; - - if (type == SSH2_MSG_NEWKEYS) { - if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) - fatal("packet_read_poll2: no KEX"); - if (mac->md != NULL) - mac->enabled = 1; - DBG(debug("cipher_set_key_iv receive_context")); - cipher_set_key_iv(&receive_context, enc->type, - enc->key, enc->key_len, - enc->iv, enc->iv_len); - clear_enc_keys(enc, kex->we_need); - if (comp->type != 0 && comp->enabled == 0) { - comp->enabled = 1; - if (! packet_compression) - packet_start_compression(6); - } - } - -#ifdef PACKET_DEBUG - fprintf(stderr, "read/plain[%d]:\r\n",type); - buffer_dump(&incoming_packet); -#endif - return (unsigned char)type; -} - -int -packet_read_poll(int *payload_len_ptr) -{ - char *msg; - for (;;) { - int type = use_ssh2_packet_format ? - packet_read_poll2(payload_len_ptr): - packet_read_poll1(payload_len_ptr); - - if(compat20) { - int reason; - if (type != 0) - DBG(debug("received packet type %d", type)); - switch(type) { - case SSH2_MSG_IGNORE: - break; - case SSH2_MSG_DEBUG: - packet_get_char(); - msg = packet_get_string(NULL); - 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_string(NULL); - log("Received disconnect: %d: %.900s", reason, msg); - xfree(msg); - fatal_cleanup(); - break; - default: - return type; - break; - } - } else { - 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: %.900s", msg); - fatal_cleanup(); - xfree(msg); - break; - default: - if (type != 0) - DBG(debug("received packet type %d", type)); - return type; - break; - } - } - } -} - -/* - * 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, unsigned int len) -{ - buffer_append(&input, buf, len); -} - -/* Returns a character from the packet. */ - -unsigned int -packet_get_char() -{ - char ch; - buffer_get(&incoming_packet, &ch, 1); - return (unsigned char) ch; -} - -/* Returns an integer from the packet data. */ - -unsigned int -packet_get_int() -{ - 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, int *length_ptr) -{ - *length_ptr = buffer_get_bignum(&incoming_packet, value); -} - -void -packet_get_bignum2(BIGNUM * value, int *length_ptr) -{ - *length_ptr = buffer_get_bignum2(&incoming_packet, value); -} - -char * -packet_get_raw(int *length_ptr) -{ - 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. - */ - -char * -packet_get_string(unsigned int *length_ptr) -{ - return buffer_get_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; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - - if (compat20) { - packet_start(SSH2_MSG_DEBUG); - packet_put_char(0); /* bool: always display */ - packet_put_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); - - /* 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_cstring(buf); - packet_put_cstring(""); - } else { - packet_start(SSH_MSG_DISCONNECT); - packet_put_string(buf, strlen(buf)); - } - packet_send(); - packet_write_wait(); - - /* Stop listening for connections. */ - channel_stop_listening(); - - /* 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() -{ - 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)); - } - buffer_consume(&output, len); - } -} - -/* - * Calls packet_write_poll repeatedly until all pending output data has been - * written. - */ - -void -packet_write_wait() -{ - packet_write_poll(); - while (packet_have_data_to_write()) { - fd_set set; - FD_ZERO(&set); - FD_SET(connection_out, &set); - select(connection_out + 1, NULL, &set, NULL, NULL); - packet_write_poll(); - } -} - -/* Returns true if there is buffered data to write to the connection. */ - -int -packet_have_data_to_write() -{ - 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() -{ - 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, int keepalives) -{ - int on = 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; - if (keepalives) { - /* Set keepalives if requested. */ - if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *) &on, - sizeof(on)) < 0) - error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); - } - /* - * IPTOS_LOWDELAY, TCP_NODELAY and IPTOS_THROUGHPUT are IPv4 only - */ - if (!packet_connection_is_ipv4()) - return; - if (interactive) { - /* - * Set IP options for an interactive connection. Use - * IPTOS_LOWDELAY and TCP_NODELAY. - */ - int lowdelay = IPTOS_LOWDELAY; - if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay, - sizeof(lowdelay)) < 0) - error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno)); - if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on, - sizeof(on)) < 0) - error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); - } else { - /* - * Set IP options for a non-interactive connection. Use - * IPTOS_THROUGHPUT. - */ - int throughput = IPTOS_THROUGHPUT; - if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput, - sizeof(throughput)) < 0) - error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno)); - } -} - -/* Returns true if the current connection is interactive. */ - -int -packet_is_interactive() -{ - 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; - } - log("packet_set_maxsize: setting to %d", s); - max_packet_size = s; - return s; -} diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h deleted file mode 100644 index ac96c505af4b..000000000000 --- a/crypto/openssh/packet.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * - * packet.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sat Mar 18 02:02:14 1995 ylo - * - * Interface for the packet protocol functions. - * - */ - -/* RCSID("$Id: packet.h,v 1.15 2000/04/14 10:30:32 markus Exp $"); */ - -#ifndef PACKET_H -#define PACKET_H - -#include <openssl/bn.h> - -/* - * Sets the socket used for communication. Disables encryption until - * packet_set_encryption_key is called. It is permissible that fd_in and - * fd_out are the same descriptor; in that case it is assumed to be a socket. - */ -void packet_set_connection(int fd_in, int fd_out); - -/* Puts the connection file descriptors into non-blocking mode. */ -void packet_set_nonblocking(void); - -/* Returns the file descriptor used for input. */ -int packet_get_connection_in(void); - -/* Returns the file descriptor used for output. */ -int packet_get_connection_out(void); - -/* - * Closes the connection (both descriptors) and clears and frees internal - * data structures. - */ -void packet_close(void); - -/* - * 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. Cipher types are defined in ssh.h. - */ -void -packet_set_encryption_key(const unsigned char *key, unsigned int keylen, - int cipher_type); - -/* - * Sets remote side protocol flags for the current connection. This can be - * called at any time. - */ -void packet_set_protocol_flags(unsigned int flags); - -/* Returns the remote protocol flags set earlier by the above function. */ -unsigned int packet_get_protocol_flags(void); - -/* Enables compression in both directions starting from the next packet. */ -void packet_start_compression(int level); - -/* - * Informs that the current session is interactive. Sets IP flags for - * optimal performance in interactive use. - */ -void packet_set_interactive(int interactive, int keepalives); - -/* Returns true if the current connection is interactive. */ -int packet_is_interactive(void); - -/* Starts constructing a packet to send. */ -void packet_start(int type); - -/* Appends a character to the packet data. */ -void packet_put_char(int ch); - -/* Appends an integer to the packet data. */ -void packet_put_int(unsigned int value); - -/* Appends an arbitrary precision integer to packet data. */ -void packet_put_bignum(BIGNUM * value); -void packet_put_bignum2(BIGNUM * value); - -/* Appends a string to packet data. */ -void packet_put_string(const char *buf, unsigned int len); -void packet_put_cstring(const char *str); -void packet_put_raw(const char *buf, unsigned int len); - -/* - * Finalizes and sends the packet. If the encryption key has been set, - * encrypts the packet before sending. - */ -void packet_send(void); - -/* Waits until a packet has been received, and returns its type. */ -int packet_read(int *payload_len_ptr); - -/* - * 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 *payload_len_ptr, int 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. - */ -int packet_read_poll(int *packet_len_ptr); - -/* - * 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, unsigned int len); - -/* Returns a character (0-255) from the packet data. */ -unsigned int packet_get_char(void); - -/* Returns an integer from the packet data. */ -unsigned int packet_get_int(void); - -/* - * Returns an arbitrary precision integer from the packet data. The integer - * must have been initialized before this call. - */ -void packet_get_bignum(BIGNUM * value, int *length_ptr); -void packet_get_bignum2(BIGNUM * value, int *length_ptr); -char *packet_get_raw(int *length_ptr); - -/* - * 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. - */ -char *packet_get_string(unsigned int *length_ptr); - -/* - * Logs the error in syslog using LOG_INFO, constructs and sends a disconnect - * packet, closes the connection, and exits. This function never returns. - * The error message should not contain a newline. The total length of the - * message must not exceed 1024 bytes. - */ -void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); - -/* - * Sends a diagnostic message to the other side. 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 total length of the message must not exceed - * 1024 bytes. This will automatically call packet_write_wait. If the - * remote side protocol flags do not indicate that it supports SSH_MSG_DEBUG, - * this will do nothing. - */ -void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); - -/* Checks if there is any buffered output, and tries to write some of the output. */ -void packet_write_poll(void); - -/* Waits until all pending output data has been written. */ -void packet_write_wait(void); - -/* Returns true if there is buffered data to write to the connection. */ -int packet_have_data_to_write(void); - -/* Returns true if there is not too much data to write to the connection. */ -int packet_not_very_much_data_to_write(void); - -/* maximum packet size, requested by client with SSH_CMSG_MAX_PACKET_SIZE */ -extern int max_packet_size; -int packet_set_maxsize(int s); -#define packet_get_maxsize() max_packet_size - -/* Stores tty modes from the fd into current packet. */ -void tty_make_modes(int fd); - -/* Parses tty modes for the fd from the current packet. */ -void tty_parse_modes(int fd, int *n_bytes_ptr); - -#define packet_integrity_check(payload_len, expected_len, type) \ -do { \ - int _p = (payload_len), _e = (expected_len); \ - if (_p != _e) { \ - log("Packet integrity error (%d != %d) at %s:%d", \ - _p, _e, __FILE__, __LINE__); \ - packet_disconnect("Packet integrity error. (%d)", (type)); \ - } \ -} while (0) - -#define packet_done() \ -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) - -/* remote host is connected via a socket/ipv4 */ -int packet_connection_is_on_socket(void); -int packet_connection_is_ipv4(void); - -/* enable SSH2 packet format */ -void packet_set_ssh2_format(void); - -/* returns remaining payload bytes */ -int packet_remaining(void); - -#endif /* PACKET_H */ diff --git a/crypto/openssh/pty.c b/crypto/openssh/pty.c deleted file mode 100644 index 430f9e529501..000000000000 --- a/crypto/openssh/pty.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * - * pty.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 17 04:37:25 1995 ylo - * - * Allocating a pseudo-terminal, and making it the controlling tty. - * - */ - -#include "includes.h" -RCSID("$Id: pty.c,v 1.13 2000/04/14 10:30:32 markus Exp $"); - -#include <util.h> -#include "pty.h" -#include "ssh.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 - -#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 buf[64]; - int i; - - i = openpty(ptyfd, ttyfd, buf, NULL, NULL); - if (i < 0) { - error("openpty: %.100s", strerror(errno)); - return 0; - } - strlcpy(namebuf, buf, 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 */ -#ifdef 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; - - ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); - if (ptm < 0) { - error("/dev/ptmx: %.100s", strerror(errno)); - return 0; - } - if (grantpt(ptm) < 0) { - error("grantpt: %.100s", strerror(errno)); - return 0; - } - 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; - } - /* Push the appropriate streams modules, as described in Solaris pts(7). */ - 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)); - if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) - error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); - 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 */ - /* 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; - - for (i = 0; i < num_ptys; i++) { - snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], - ptyminors[i % num_minors]); - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) - continue; - snprintf(namebuf, namebuflen, "/dev/tty%c%c", - ptymajors[i / num_minors], ptyminors[i % num_minors]); - - /* 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; -#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; - - /* First disconnect from the old controlling tty. */ -#ifdef TIOCNOTTY - fd = open("/dev/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("/dev/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."); - /* - * We ignore errors from this, because HPSUX defines TIOCSCTTY, but - * returns EINVAL with these arguments, and there is absolutely no - * documentation. - */ - ioctl(*ttyfd, TIOCSCTTY, NULL); -#endif /* TIOCSCTTY */ - fd = open(ttyname, O_RDWR); - if (fd < 0) - error("%.100s: %.100s", ttyname, strerror(errno)); - else - close(fd); - - /* Verify that we now have a controlling tty. */ - fd = open("/dev/tty", O_WRONLY); - if (fd < 0) - error("open /dev/tty failed - could not set controlling tty: %.100s", - strerror(errno)); - else { - close(fd); - } -} - -/* 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; - - /* 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 ownership of the tty. */ - if (chown(ttyname, pw->pw_uid, gid) < 0) - fatal("chown(%.100s, %d, %d) failed: %.100s", - ttyname, pw->pw_uid, gid, strerror(errno)); - if (chmod(ttyname, mode) < 0) - fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); -} diff --git a/crypto/openssh/pty.h b/crypto/openssh/pty.h deleted file mode 100644 index a5f9cb22dcc1..000000000000 --- a/crypto/openssh/pty.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * pty.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 17 05:03:28 1995 ylo - * - * Functions for allocating a pseudo-terminal and making it the controlling - * tty. - */ - -/* RCSID("$Id: pty.h,v 1.6 2000/04/14 10:30:32 markus Exp $"); */ - -#ifndef PTY_H -#define PTY_H - -/* - * 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 *ttyname, int ttynamelen); - -/* - * Releases the tty. Its ownership is returned to root, and permissions to - * 0666. - */ -void pty_release(const char *ttyname); - -/* - * Makes the tty the processes controlling tty and sets it to sane modes. - * This may need to reopen the tty to get rid of possible eavesdroppers. - */ -void pty_make_controlling_tty(int *ttyfd, const char *ttyname); - -/* Changes the window size associated with the pty. */ -void -pty_change_window_size(int ptyfd, int row, int col, - int xpixel, int ypixel); - -void pty_setowner(struct passwd *pw, const char *ttyname); - -#endif /* PTY_H */ diff --git a/crypto/openssh/radix.c b/crypto/openssh/radix.c deleted file mode 100644 index 033773344152..000000000000 --- a/crypto/openssh/radix.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * radix.c - * - * Dug Song <dugsong@UMICH.EDU> - */ - -#include "includes.h" -#include "uuencode.h" - -#ifdef AFS -#include <krb.h> - -typedef unsigned char my_u_char; -typedef unsigned int my_u_int32_t; -typedef unsigned short my_u_short; - -/* Nasty macros from BIND-4.9.2 */ - -#define GETSHORT(s, cp) { \ - register my_u_char *t_cp = (my_u_char*)(cp); \ - (s) = (((my_u_short)t_cp[0]) << 8) \ - | (((my_u_short)t_cp[1])) \ - ; \ - (cp) += 2; \ -} - -#define GETLONG(l, cp) { \ - register my_u_char *t_cp = (my_u_char*)(cp); \ - (l) = (((my_u_int32_t)t_cp[0]) << 24) \ - | (((my_u_int32_t)t_cp[1]) << 16) \ - | (((my_u_int32_t)t_cp[2]) << 8) \ - | (((my_u_int32_t)t_cp[3])) \ - ; \ - (cp) += 4; \ -} - -#define PUTSHORT(s, cp) { \ - register my_u_short t_s = (my_u_short)(s); \ - register my_u_char *t_cp = (my_u_char*)(cp); \ - *t_cp++ = t_s >> 8; \ - *t_cp = t_s; \ - (cp) += 2; \ -} - -#define PUTLONG(l, cp) { \ - register my_u_int32_t t_l = (my_u_int32_t)(l); \ - register my_u_char *t_cp = (my_u_char*)(cp); \ - *t_cp++ = t_l >> 24; \ - *t_cp++ = t_l >> 16; \ - *t_cp++ = t_l >> 8; \ - *t_cp = t_l; \ - (cp) += 4; \ -} - -#define GETSTRING(s, p, p_l) { \ - register char* p_targ = (p) + p_l; \ - register char* s_c = (s); \ - register char* p_c = (p); \ - while (*p_c && (p_c < p_targ)) { \ - *s_c++ = *p_c++; \ - } \ - if (p_c == p_targ) { \ - return 1; \ - } \ - *s_c = *p_c++; \ - (p_l) = (p_l) - (p_c - (p)); \ - (p) = p_c; \ -} - - -int -creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen) -{ - char *p, *s; - int len; - char temp[2048]; - - p = temp; - *p++ = 1; /* version */ - s = creds->service; - while (*s) - *p++ = *s++; - *p++ = *s; - s = creds->instance; - while (*s) - *p++ = *s++; - *p++ = *s; - s = creds->realm; - while (*s) - *p++ = *s++; - *p++ = *s; - - s = creds->pname; - while (*s) - *p++ = *s++; - *p++ = *s; - s = creds->pinst; - while (*s) - *p++ = *s++; - *p++ = *s; - /* Null string to repeat the realm. */ - *p++ = '\0'; - - PUTLONG(creds->issue_date, p); - { - unsigned int endTime; - endTime = (unsigned int) krb_life_to_time(creds->issue_date, - creds->lifetime); - PUTLONG(endTime, p); - } - - memcpy(p, &creds->session, sizeof(creds->session)); - p += sizeof(creds->session); - - PUTSHORT(creds->kvno, p); - PUTLONG(creds->ticket_st.length, p); - - memcpy(p, creds->ticket_st.dat, creds->ticket_st.length); - p += creds->ticket_st.length; - len = p - temp; - - return (uuencode((unsigned char *)temp, len, (char *)buf, buflen)); -} - -int -radix_to_creds(const char *buf, CREDENTIALS *creds) -{ - - char *p; - int len, tl; - char version; - char temp[2048]; - - len = uudecode(buf, (unsigned char *)temp, sizeof(temp)); - if (len < 0) - return 0; - - p = temp; - - /* check version and length! */ - if (len < 1) - return 0; - version = *p; - p++; - len--; - - GETSTRING(creds->service, p, len); - GETSTRING(creds->instance, p, len); - GETSTRING(creds->realm, p, len); - - GETSTRING(creds->pname, p, len); - GETSTRING(creds->pinst, p, len); - /* Ignore possibly different realm. */ - while (*p && len) - p++, len--; - if (len == 0) - return 0; - p++, len--; - - /* Enough space for remaining fixed-length parts? */ - if (len < (4 + 4 + sizeof(creds->session) + 2 + 4)) - return 0; - - GETLONG(creds->issue_date, p); - len -= 4; - { - unsigned int endTime; - GETLONG(endTime, p); - len -= 4; - creds->lifetime = krb_time_to_life(creds->issue_date, endTime); - } - - memcpy(&creds->session, p, sizeof(creds->session)); - p += sizeof(creds->session); - len -= sizeof(creds->session); - - GETSHORT(creds->kvno, p); - len -= 2; - GETLONG(creds->ticket_st.length, p); - len -= 4; - - tl = creds->ticket_st.length; - if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat)) - return 0; - - memcpy(creds->ticket_st.dat, p, tl); - p += tl; - len -= tl; - - return 1; -} -#endif /* AFS */ diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c deleted file mode 100644 index 2053c67aa2bc..000000000000 --- a/crypto/openssh/readconf.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - * - * readconf.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sat Apr 22 00:03:10 1995 ylo - * - * Functions for reading the configuration files. - * - */ - -#include "includes.h" -RCSID("$Id: readconf.c,v 1.31 2000/05/08 17:12:15 markus Exp $"); - -#include "ssh.h" -#include "cipher.h" -#include "readconf.h" -#include "match.h" -#include "xmalloc.h" -#include "compat.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 - FallBackToRsh no - - 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 - UseRsh yes - - Host *.su - Cipher none - PasswordAuthentication no - - # Defaults for various options - Host * - ForwardAgent no - ForwardX11 yes - RhostsAuthentication yes - PasswordAuthentication yes - RSAAuthentication yes - RhostsRSAAuthentication yes - FallBackToRsh no - UseRsh no - StrictHostKeyChecking yes - KeepAlives no - IdentityFile ~/.ssh/identity - Port 22 - EscapeChar ~ - -*/ - -/* Keyword tokens. */ - -typedef enum { - oBadOption, - oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, - oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, - oSkeyAuthentication, -#ifdef KRB4 - oKerberosAuthentication, -#endif /* KRB4 */ -#ifdef AFS - oKerberosTgtPassing, oAFSTokenPassing, -#endif - oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, - oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, - oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, - oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, - oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, - oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2, - oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication -} OpCodes; - -/* Textual representations of the tokens. */ - -static struct { - const char *name; - OpCodes opcode; -} keywords[] = { - { "forwardagent", oForwardAgent }, - { "forwardx11", oForwardX11 }, - { "gatewayports", oGatewayPorts }, - { "useprivilegedport", oUsePrivilegedPort }, - { "rhostsauthentication", oRhostsAuthentication }, - { "passwordauthentication", oPasswordAuthentication }, - { "rsaauthentication", oRSAAuthentication }, - { "dsaauthentication", oDSAAuthentication }, - { "skeyauthentication", oSkeyAuthentication }, -#ifdef KRB4 - { "kerberosauthentication", oKerberosAuthentication }, -#endif /* KRB4 */ -#ifdef AFS - { "kerberostgtpassing", oKerberosTgtPassing }, - { "afstokenpassing", oAFSTokenPassing }, -#endif - { "fallbacktorsh", oFallBackToRsh }, - { "usersh", oUseRsh }, - { "identityfile", oIdentityFile }, - { "identityfile2", oIdentityFile2 }, - { "hostname", oHostName }, - { "proxycommand", oProxyCommand }, - { "port", oPort }, - { "cipher", oCipher }, - { "ciphers", oCiphers }, - { "protocol", oProtocol }, - { "remoteforward", oRemoteForward }, - { "localforward", oLocalForward }, - { "user", oUser }, - { "host", oHost }, - { "escapechar", oEscapeChar }, - { "rhostsrsaauthentication", oRhostsRSAAuthentication }, - { "globalknownhostsfile", oGlobalKnownHostsFile }, - { "userknownhostsfile", oUserKnownHostsFile }, - { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, - { "userknownhostsfile2", oUserKnownHostsFile2 }, - { "connectionattempts", oConnectionAttempts }, - { "batchmode", oBatchMode }, - { "checkhostip", oCheckHostIP }, - { "stricthostkeychecking", oStrictHostKeyChecking }, - { "compression", oCompression }, - { "compressionlevel", oCompressionLevel }, - { "keepalive", oKeepAlives }, - { "numberofpasswordprompts", oNumberOfPasswordPrompts }, - { "tisauthentication", oTISAuthentication }, - { "loglevel", oLogLevel }, - { NULL, 0 } -}; - -/* Characters considered whitespace in strtok calls. */ -#define WHITESPACE " \t\r\n" - - -/* - * Adds a local TCP/IP port forward to options. Never returns if there is an - * error. - */ - -void -add_local_forward(Options *options, u_short port, const char *host, - u_short host_port) -{ - Forward *fwd; - extern uid_t original_real_uid; - if (port < IPPORT_RESERVED && original_real_uid != 0) - fatal("Privileged ports can only be forwarded by root.\n"); - 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->port = port; - fwd->host = xstrdup(host); - fwd->host_port = host_port; -} - -/* - * Adds a remote TCP/IP port forward to options. Never returns if there is - * an error. - */ - -void -add_remote_forward(Options *options, u_short port, const char *host, - u_short host_port) -{ - 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->port = port; - fwd->host = xstrdup(host); - fwd->host_port = host_port; -} - -/* - * Returns the number of the token pointed to by cp of length len. Never - * returns if the token is not known. - */ - -static OpCodes -parse_token(const char *cp, const char *filename, int linenum) -{ - unsigned int i; - - for (i = 0; keywords[i].name; i++) - if (strcasecmp(cp, keywords[i].name) == 0) - return keywords[i].opcode; - - fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", - 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 buf[256], *cp, *string, **charptr, *cp2; - int opcode, *intptr, value; - u_short fwd_port, fwd_host_port; - - /* Skip leading whitespace. */ - cp = line + strspn(line, WHITESPACE); - if (!*cp || *cp == '\n' || *cp == '#') - return 0; - - /* Get the keyword. (Each line is supposed to begin with a keyword). */ - cp = strtok(cp, WHITESPACE); - opcode = parse_token(cp, filename, linenum); - - switch (opcode) { - case oBadOption: - /* don't panic, but count bad options */ - return -1; - /* NOTREACHED */ - case oForwardAgent: - intptr = &options->forward_agent; -parse_flag: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); - value = 0; /* To avoid compiler warning... */ - if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) - value = 1; - else if (strcmp(cp, "no") == 0 || strcmp(cp, "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 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 oDSAAuthentication: - intptr = &options->dsa_authentication; - goto parse_flag; - - case oRSAAuthentication: - intptr = &options->rsa_authentication; - goto parse_flag; - - case oRhostsRSAAuthentication: - intptr = &options->rhosts_rsa_authentication; - goto parse_flag; - - case oTISAuthentication: - /* fallthrough, there is no difference on the client side */ - case oSkeyAuthentication: - intptr = &options->skey_authentication; - goto parse_flag; - -#ifdef KRB4 - case oKerberosAuthentication: - intptr = &options->kerberos_authentication; - goto parse_flag; -#endif /* KRB4 */ - -#ifdef AFS - case oKerberosTgtPassing: - intptr = &options->kerberos_tgt_passing; - goto parse_flag; - - 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; - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing yes/no argument.", - filename, linenum); - value = 0; /* To avoid compiler warning... */ - if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) - value = 1; - else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) - value = 0; - else if (strcmp(cp, "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 oNumberOfPasswordPrompts: - intptr = &options->number_of_password_prompts; - goto parse_int; - - case oCompressionLevel: - intptr = &options->compression_level; - goto parse_int; - - case oIdentityFile: - case oIdentityFile2: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (*activep) { - intptr = (opcode == oIdentityFile) ? - &options->num_identity_files : - &options->num_identity_files2; - if (*intptr >= SSH_MAX_IDENTITY_FILES) - fatal("%.200s line %d: Too many identity files specified (max %d).", - filename, linenum, SSH_MAX_IDENTITY_FILES); - charptr = (opcode == oIdentityFile) ? - &options->identity_files[*intptr] : - &options->identity_files2[*intptr]; - *charptr = xstrdup(cp); - *intptr = *intptr + 1; - } - break; - - case oUser: - charptr = &options->user; -parse_string: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (*activep && *charptr == NULL) - *charptr = xstrdup(cp); - 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 oProxyCommand: - charptr = &options->proxy_command; - string = xstrdup(""); - while ((cp = strtok(NULL, WHITESPACE)) != NULL) { - string = xrealloc(string, strlen(string) + strlen(cp) + 2); - strcat(string, " "); - strcat(string, cp); - } - if (*activep && *charptr == NULL) - *charptr = string; - else - xfree(string); - return 0; - - case oPort: - intptr = &options->port; -parse_int: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] < '0' || cp[0] > '9') - fatal("%.200s line %d: Bad number.", filename, linenum); - - /* Octal, decimal, or hex format? */ - value = strtol(cp, &cp2, 0); - if (cp == cp2) - 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; - cp = strtok(NULL, WHITESPACE); - value = cipher_number(cp); - if (value == -1) - fatal("%.200s line %d: Bad cipher '%s'.", - filename, linenum, cp ? cp : "<NONE>"); - if (*activep && *intptr == -1) - *intptr = value; - break; - - case oCiphers: - cp = strtok(NULL, WHITESPACE); - if (!ciphers_valid(cp)) - fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); - if (*activep && options->ciphers == NULL) - options->ciphers = xstrdup(cp); - break; - - case oProtocol: - intptr = &options->protocol; - cp = strtok(NULL, WHITESPACE); - value = proto_spec(cp); - if (value == SSH_PROTO_UNKNOWN) - fatal("%.200s line %d: Bad protocol spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); - if (*activep && *intptr == SSH_PROTO_UNKNOWN) - *intptr = value; - break; - - case oLogLevel: - intptr = (int *) &options->log_level; - cp = strtok(NULL, WHITESPACE); - value = log_level_number(cp); - if (value == (LogLevel) - 1) - fatal("%.200s line %d: unsupported log level '%s'\n", - filename, linenum, cp ? cp : "<NONE>"); - if (*activep && (LogLevel) * intptr == -1) - *intptr = (LogLevel) value; - break; - - case oRemoteForward: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] < '0' || cp[0] > '9') - fatal("%.200s line %d: Badly formatted port number.", - filename, linenum); - fwd_port = atoi(cp); - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing second argument.", - filename, linenum); - if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) - fatal("%.200s line %d: Badly formatted host:port.", - filename, linenum); - if (*activep) - add_remote_forward(options, fwd_port, buf, fwd_host_port); - break; - - case oLocalForward: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] < '0' || cp[0] > '9') - fatal("%.200s line %d: Badly formatted port number.", - filename, linenum); - fwd_port = atoi(cp); - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing second argument.", - filename, linenum); - if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2) - fatal("%.200s line %d: Badly formatted host:port.", - filename, linenum); - if (*activep) - add_local_forward(options, fwd_port, buf, fwd_host_port); - break; - - case oHost: - *activep = 0; - while ((cp = strtok(NULL, WHITESPACE)) != NULL) - if (match_pattern(host, cp)) { - debug("Applying options for %.100s", cp); - *activep = 1; - break; - } - /* Avoid garbage check below, as strtok already returned NULL. */ - return 0; - - case oEscapeChar: - intptr = &options->escape_char; - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (cp[0] == '^' && cp[2] == 0 && - (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128) - value = (unsigned char) cp[1] & 31; - else if (strlen(cp) == 1) - value = (unsigned char) cp[0]; - else if (strcmp(cp, "none") == 0) - value = -2; - else { - fatal("%.200s line %d: Bad escape character.", - filename, linenum); - /* NOTREACHED */ - value = 0; /* Avoid compiler warning. */ - } - if (*activep && *intptr == -1) - *intptr = value; - break; - - default: - fatal("process_config_line: Unimplemented opcode %d", opcode); - } - - /* Check that there is no garbage at end of line. */ - if (strtok(NULL, WHITESPACE) != NULL) - fatal("%.200s line %d: garbage at end of line.", - filename, linenum); - 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 immediately. - */ - -void -read_config_file(const char *filename, const char *host, Options *options) -{ - FILE *f; - char line[1024]; - int active, linenum; - int bad_options = 0; - - /* Open the file. */ - f = fopen(filename, "r"); - if (!f) - return; - - 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++; - if (process_config_line(options, host, line, filename, linenum, &active) != 0) - bad_options++; - } - fclose(f); - if (bad_options > 0) - fatal("%s: terminating, %d bad configuration options\n", - filename, bad_options); -} - -/* - * 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->gateway_ports = -1; - options->use_privileged_port = -1; - options->rhosts_authentication = -1; - options->rsa_authentication = -1; - options->dsa_authentication = -1; - options->skey_authentication = -1; -#ifdef KRB4 - options->kerberos_authentication = -1; -#endif -#ifdef AFS - options->kerberos_tgt_passing = -1; - options->afs_token_passing = -1; -#endif - options->password_authentication = -1; - options->rhosts_rsa_authentication = -1; - options->fallback_to_rsh = -1; - options->use_rsh = -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->number_of_password_prompts = -1; - options->cipher = -1; - options->ciphers = NULL; - options->protocol = SSH_PROTO_UNKNOWN; - options->num_identity_files = 0; - options->num_identity_files2 = 0; - options->hostname = 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->log_level = (LogLevel) - 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) -{ - if (options->forward_agent == -1) - options->forward_agent = 1; - if (options->forward_x11 == -1) - options->forward_x11 = 0; - if (options->gateway_ports == -1) - options->gateway_ports = 0; - if (options->use_privileged_port == -1) - options->use_privileged_port = 1; - if (options->rhosts_authentication == -1) - options->rhosts_authentication = 1; - if (options->rsa_authentication == -1) - options->rsa_authentication = 1; - if (options->dsa_authentication == -1) - options->dsa_authentication = 1; - if (options->skey_authentication == -1) - options->skey_authentication = 0; -#ifdef KRB4 - if (options->kerberos_authentication == -1) - options->kerberos_authentication = 1; -#endif /* KRB4 */ -#ifdef AFS - if (options->kerberos_tgt_passing == -1) - options->kerberos_tgt_passing = 1; - if (options->afs_token_passing == -1) - options->afs_token_passing = 1; -#endif /* AFS */ - if (options->password_authentication == -1) - options->password_authentication = 1; - if (options->rhosts_rsa_authentication == -1) - options->rhosts_rsa_authentication = 1; - if (options->fallback_to_rsh == -1) - options->fallback_to_rsh = 1; - if (options->use_rsh == -1) - options->use_rsh = 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 = 4; - 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 */ - if (options->protocol == SSH_PROTO_UNKNOWN) - options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED; - if (options->num_identity_files == 0) { - options->identity_files[0] = - xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); - sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); - options->num_identity_files = 1; - } - if (options->num_identity_files2 == 0) { - options->identity_files2[0] = - xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1); - sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA); - options->num_identity_files2 = 1; - } - if (options->escape_char == -1) - options->escape_char = '~'; - if (options->system_hostfile == NULL) - options->system_hostfile = SSH_SYSTEM_HOSTFILE; - if (options->user_hostfile == NULL) - options->user_hostfile = SSH_USER_HOSTFILE; - if (options->system_hostfile2 == NULL) - options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2; - if (options->user_hostfile2 == NULL) - options->user_hostfile2 = SSH_USER_HOSTFILE2; - if (options->log_level == (LogLevel) - 1) - options->log_level = SYSLOG_LEVEL_INFO; - /* 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 */ -} diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h deleted file mode 100644 index 7ee91571186c..000000000000 --- a/crypto/openssh/readconf.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * - * readconf.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sat Apr 22 00:25:29 1995 ylo - * - * Functions for reading the configuration file. - * - */ - -/* RCSID("$Id: readconf.h,v 1.18 2000/05/08 17:12:15 markus Exp $"); */ - -#ifndef READCONF_H -#define READCONF_H - -/* Data structure for representing a forwarding request. */ - -typedef struct { - u_short port; /* Port to forward. */ - char *host; /* Host to connect. */ - u_short host_port; /* Port to connect on host. */ -} Forward; -/* Data structure for representing option data. */ - -typedef struct { - int forward_agent; /* Forward authentication agent. */ - int forward_x11; /* Forward X11 display. */ - 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 dsa_authentication; /* Try DSA authentication. */ - int skey_authentication; /* Try S/Key or TIS authentication. */ -#ifdef KRB4 - int kerberos_authentication; /* Try Kerberos - * authentication. */ -#endif -#ifdef AFS - int kerberos_tgt_passing; /* Try Kerberos tgt passing. */ - int afs_token_passing; /* Try AFS token passing. */ -#endif - int password_authentication; /* Try password - * authentication. */ - int fallback_to_rsh;/* Use rsh if cannot connect with ssh. */ - int use_rsh; /* Always use rsh (don\'t try ssh). */ - 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 number_of_password_prompts; /* Max number of password - * prompts. */ - int cipher; /* Cipher to use. */ - char *ciphers; /* SSH2 ciphers in order of preference. */ - int protocol; /* Protocol in order of preference. */ - char *hostname; /* Real host to connect. */ - 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_known_hosts. */ - char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */ - char *system_hostfile2; - char *user_hostfile2; - - int num_identity_files; /* Number of files for RSA identities. */ - int num_identity_files2; /* DSA identities. */ - char *identity_files[SSH_MAX_IDENTITY_FILES]; - char *identity_files2[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]; -} Options; - - -/* - * 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); - -/* - * 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); - -/* - * Processes a single option line as used in the configuration files. This - * only sets those values that have not already been set. Returns 0 for legal - * options - */ -int -process_config_line(Options * options, const char *host, - char *line, const char *filename, int linenum, - int *activep); - -/* - * 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 immediately. - */ -void -read_config_file(const char *filename, const char *host, - Options * options); - -/* - * Adds a local TCP/IP port forward to options. Never returns if there is an - * error. - */ -void -add_local_forward(Options * options, u_short port, const char *host, - u_short host_port); - -/* - * Adds a remote TCP/IP port forward to options. Never returns if there is - * an error. - */ -void -add_remote_forward(Options * options, u_short port, const char *host, - u_short host_port); - -#endif /* READCONF_H */ diff --git a/crypto/openssh/readpass.c b/crypto/openssh/readpass.c deleted file mode 100644 index 85d88f804610..000000000000 --- a/crypto/openssh/readpass.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 1988, 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" -RCSID("$Id: readpass.c,v 1.10 2000/04/14 10:30:32 markus Exp $"); - -#include "xmalloc.h" -#include "ssh.h" - -volatile int intr; - -void -intcatch() -{ - intr = 1; -} - -/* - * Reads a passphrase from /dev/tty with echo turned off. Returns the - * passphrase (allocated with xmalloc), being very careful to ensure that - * no other userland buffer is storing the password. - */ -char * -read_passphrase(const char *prompt, int from_stdin) -{ - char buf[1024], *p, ch; - struct termios tio, saved_tio; - sigset_t oset, nset; - struct sigaction sa, osa; - int input, output, echo = 0; - - if (from_stdin) { - input = STDIN_FILENO; - output = STDERR_FILENO; - } else - input = output = open("/dev/tty", O_RDWR); - - if (input == -1) - fatal("You have no controlling tty. Cannot read passphrase.\n"); - - /* block signals, get terminal modes and turn off echo */ - sigemptyset(&nset); - sigaddset(&nset, SIGTSTP); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = intcatch; - (void) sigaction(SIGINT, &sa, &osa); - - intr = 0; - - if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) { - echo = 1; - tio = saved_tio; - tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); - (void) tcsetattr(input, TCSANOW, &tio); - } - - fflush(stdout); - - (void)write(output, prompt, strlen(prompt)); - for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) { - if (intr) - break; - if (p < buf + sizeof(buf) - 1) - *p++ = ch; - } - *p = '\0'; - if (!intr) - (void)write(output, "\n", 1); - - /* restore terminal modes and allow signals */ - if (echo) - tcsetattr(input, TCSANOW, &saved_tio); - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - (void) sigaction(SIGINT, &osa, NULL); - - if (intr) { - kill(getpid(), SIGINT); - sigemptyset(&nset); - /* XXX tty has not neccessarily drained by now? */ - sigsuspend(&nset); - } - - if (!from_stdin) - (void)close(input); - p = xstrdup(buf); - memset(buf, 0, sizeof(buf)); - return (p); -} diff --git a/crypto/openssh/rsa.c b/crypto/openssh/rsa.c deleted file mode 100644 index 002c1cc4f8f0..000000000000 --- a/crypto/openssh/rsa.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * rsa.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 3 22:07:06 1995 ylo - * - * 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("$Id: rsa.c,v 1.14 2000/04/14 10:30:32 markus Exp $"); - -#include "rsa.h" -#include "ssh.h" -#include "xmalloc.h" - -int rsa_verbose = 1; - -int -rsa_alive() -{ - RSA *key; - - key = RSA_generate_key(32, 3, NULL, NULL); - if (key == NULL) - return (0); - RSA_free(key); - return (1); -} - -/* - * Generates RSA public and private keys. This initializes the data - * structures; they should be freed with rsa_clear_private_key and - * rsa_clear_public_key. - */ - -void -rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits) -{ - RSA *key; - - if (rsa_verbose) { - printf("Generating RSA keys: "); - fflush(stdout); - } - key = RSA_generate_key(bits, 35, NULL, NULL); - if (key == NULL) - fatal("rsa_generate_key: key generation failed."); - - /* Copy public key parameters */ - pub->n = BN_new(); - BN_copy(pub->n, key->n); - pub->e = BN_new(); - BN_copy(pub->e, key->e); - - /* Copy private key parameters */ - prv->n = BN_new(); - BN_copy(prv->n, key->n); - prv->e = BN_new(); - BN_copy(prv->e, key->e); - prv->d = BN_new(); - BN_copy(prv->d, key->d); - prv->p = BN_new(); - BN_copy(prv->p, key->p); - prv->q = BN_new(); - BN_copy(prv->q, key->q); - - prv->dmp1 = BN_new(); - BN_copy(prv->dmp1, key->dmp1); - - prv->dmq1 = BN_new(); - BN_copy(prv->dmq1, key->dmq1); - - prv->iqmp = BN_new(); - BN_copy(prv->iqmp, key->iqmp); - - RSA_free(key); - - if (rsa_verbose) - printf("Key generation complete.\n"); -} - -void -rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) -{ - unsigned 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); -} - -void -rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) -{ - unsigned 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) - fatal("rsa_private_decrypt() failed"); - - BN_bin2bn(outbuf, len, out); - - memset(outbuf, 0, olen); - memset(inbuf, 0, ilen); - xfree(outbuf); - xfree(inbuf); -} - -/* Set whether to output verbose messages during key generation. */ - -void -rsa_set_verbose(int verbose) -{ - rsa_verbose = verbose; -} diff --git a/crypto/openssh/rsa.h b/crypto/openssh/rsa.h deleted file mode 100644 index 16e319d43129..000000000000 --- a/crypto/openssh/rsa.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * rsa.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 3 22:01:06 1995 ylo - * - * RSA key generation, encryption and decryption. - * -*/ - -/* RCSID("$Id: rsa.h,v 1.6 2000/04/14 10:30:32 markus Exp $"); */ - -#ifndef RSA_H -#define RSA_H - -#include <openssl/bn.h> -#include <openssl/rsa.h> - -/* Calls SSL RSA_generate_key, only copies to prv and pub */ -void rsa_generate_key(RSA * prv, RSA * pub, unsigned int bits); - -/* - * Indicates whether the rsa module is permitted to show messages on the - * terminal. - */ -void rsa_set_verbose __P((int verbose)); - -int rsa_alive __P((void)); - -void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); -void rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); - -#endif /* RSA_H */ diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1 deleted file mode 100644 index 51de6c5e8175..000000000000 --- a/crypto/openssh/scp.1 +++ /dev/null @@ -1,123 +0,0 @@ -.\" -*- nroff -*- -.\" -.\" scp.1 -.\" -.\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" -.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland -.\" All rights reserved -.\" -.\" Created: Sun May 7 00:14:37 1995 ylo -.\" -.\" $Id: scp.1,v 1.7 2000/04/12 21:47:50 aaron Exp $ -.\" -.Dd September 25, 1999 -.Dt SCP 1 -.Os -.Sh NAME -.Nm scp -.Nd secure copy (remote file copy program) -.Sh SYNOPSIS -.Nm scp -.Op Fl pqrvC46 -.Op Fl P Ar port -.Op Fl c Ar cipher -.Op Fl i Ar identity_file -.Sm off -.Oo -.Op Ar user@ -.Ar host1 No : -.Oc Ns Ar file1 -.Sm on -.Op Ar ... -.Sm off -.Oo -.Op Ar user@ -.Ar host2 No : -.Oc Ar file2 -.Sm on -.Sh DESCRIPTION -.Nm -copies files between hosts on a network. -It uses -.Xr ssh 1 -for data transfer, and uses the same authentication and provides the -same security as -.Xr ssh 1 . -Unlike -.Xr rcp 1 , -.Nm -will ask for passwords or passphrases if they are needed for -authentication. -.Pp -Any file name may contain a host and user specification to indicate -that the file is to be copied to/from that host. -Copies between two remote hosts are permitted. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl c Ar cipher -Selects the cipher to use for encrypting the data transfer. -This option is directly passed to -.Xr ssh 1 . -.It Fl i Ar identity_file -Selects the file from which the identity (private key) for RSA -authentication is read. -This option is directly passed to -.Xr ssh 1 . -.It Fl p -Preserves modification times, access times, and modes from the -original file. -.It Fl r -Recursively copy entire directories. -.It Fl v -Verbose mode. -Causes -.Nm -and -.Xr ssh 1 -to print debugging messages about their progress. -This is helpful in -debugging connection, authentication, and configuration problems. -.It Fl B -Selects batch mode (prevents asking for passwords or passphrases). -.It Fl q -Disables the progress meter. -.It Fl C -Compression enable. -Passes the -.Fl C -flag to -.Xr ssh 1 -to enable compression. -.It Fl P Ar port -Specifies the port to connect to on the remote host. -Note that this option is written with a capital -.Sq P , -because -.Fl p -is already reserved for preserving the times and modes of the file in -.Xr rcp 1 . -.It Fl 4 -Forces -.Nm -to use IPv4 addresses only. -.It Fl 6 -Forces -.Nm -to use IPv6 addresses only. -.Sh AUTHORS -Timo Rinne <tri@iki.fi> and Tatu Ylonen <ylo@cs.hut.fi> -.Sh HISTORY -.Nm -is based on the -.Xr rcp 1 -program in BSD source code from the Regents of the University of -California. -.Sh SEE ALSO -.Xr rcp 1 , -.Xr ssh 1 , -.Xr ssh-add 1 , -.Xr ssh-agent 1 , -.Xr ssh-keygen 1 , -.Xr sshd 8 diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c deleted file mode 100644 index 491a78907fca..000000000000 --- a/crypto/openssh/scp.c +++ /dev/null @@ -1,1251 +0,0 @@ -/* - * - * 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> - * -*/ - -/* - * 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("$Id: scp.c,v 1.30 2000/05/02 18:21:48 deraadt Exp $"); - -#include "ssh.h" -#include "xmalloc.h" -#include <utime.h> - -#define _PATH_CP "cp" - -/* For progressmeter() -- number of seconds before xfer considered "stalled" */ -#define STALLTIME 5 - -/* Visual statistics about files as they are transferred. */ -void progressmeter(int); - -/* Returns width of the terminal (for progress meter calculations). */ -int getttywidth(void); - -/* Time a transfer started. */ -static struct timeval start; - -/* Number of bytes of current file transferred so far. */ -volatile unsigned long statbytes; - -/* Total size of current file. */ -off_t totalbytes = 0; - -/* Name of current file being transferred. */ -char *curfile; - -/* This is set to non-zero if IPv4 is desired. */ -int IPv4 = 0; - -/* This is set to non-zero if IPv6 is desired. */ -int IPv6 = 0; - -/* This is set to non-zero to enable verbose mode. */ -int verbose_mode = 0; - -/* This is set to non-zero if compression is desired. */ -int compress = 0; - -/* This is set to zero if the progressmeter is not desired. */ -int showprogress = 1; - -/* This is set to non-zero if running in batch mode (that is, password - and passphrase queries are not allowed). */ -int batchmode = 0; - -/* This is set to the cipher type string if given on the command line. */ -char *cipher = NULL; - -/* This is set to the RSA authentication identity file name if given on - the command line. */ -char *identity = NULL; - -/* This is the port to use in contacting the remote site (is non-NULL). */ -char *port = NULL; - -/* - * 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 pin[2], pout[2], reserved[2]; - - if (verbose_mode) - fprintf(stderr, "Executing: host %s, user %s, command %s\n", - host, remuser ? remuser : "(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 (fork() == 0) { - char *args[100]; - unsigned int i; - - /* Child. */ - close(pin[1]); - close(pout[0]); - dup2(pin[0], 0); - dup2(pout[1], 1); - close(pin[0]); - close(pout[1]); - - i = 0; - args[i++] = SSH_PROGRAM; - args[i++] = "-x"; - args[i++] = "-oFallBackToRsh no"; - if (IPv4) - args[i++] = "-4"; - if (IPv6) - args[i++] = "-6"; - args[i++] = "-oFallBackToRsh no"; - if (verbose_mode) - args[i++] = "-v"; - if (compress) - args[i++] = "-C"; - if (batchmode) - args[i++] = "-oBatchMode yes"; - if (cipher != NULL) { - args[i++] = "-c"; - args[i++] = cipher; - } - if (identity != NULL) { - args[i++] = "-i"; - args[i++] = identity; - } - if (port != NULL) { - args[i++] = "-p"; - args[i++] = port; - } - if (remuser != NULL) { - args[i++] = "-l"; - args[i++] = remuser; - } - args[i++] = host; - args[i++] = cmd; - args[i++] = NULL; - - execvp(SSH_PROGRAM, args); - perror(SSH_PROGRAM); - exit(1); - } - /* Parent. Close the other side, and return the local side. */ - close(pin[0]); - *fdout = pin[1]; - close(pout[1]); - *fdin = pout[0]; - return 0; -} - -void -fatal(const char *fmt,...) -{ - va_list ap; - char buf[1024]; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - fprintf(stderr, "%s\n", buf); - exit(255); -} - -/* This stuff used to be in BSD rcp extern.h. */ - -typedef struct { - int cnt; - char *buf; -} BUF; - -extern int iamremote; - -BUF *allocbuf(BUF *, int, int); -char *colon(char *); -void lostconn(int); -void nospace(void); -int okname(char *); -void run_err(const char *,...); -void verifydir(char *); - -/* Stuff from BSD rcp.c continues. */ - -struct passwd *pwd; -uid_t userid; -int errs, remin, remout; -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; - char *targ; - extern char *optarg; - extern int optind; - - fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF) - switch (ch) { - /* User-visible flags. */ - case '4': - IPv4 = 1; - break; - case '6': - IPv6 = 1; - break; - case 'p': - pflag = 1; - break; - case 'P': - port = optarg; - break; - case 'r': - iamrecursive = 1; - break; - /* Server options. */ - case 'd': - targetshouldbedirectory = 1; - break; - case 'f': /* "from" */ - iamremote = 1; - fflag = 1; - break; - case 't': /* "to" */ - iamremote = 1; - tflag = 1; - break; - case 'c': - cipher = optarg; - break; - case 'i': - identity = optarg; - break; - case 'v': - verbose_mode = 1; - break; - case 'B': - batchmode = 1; - break; - case 'C': - compress = 1; - break; - case 'q': - showprogress = 0; - break; - case '?': - 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; - /* Command to be executed on remote system using "ssh". */ - (void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", - iamrecursive ? " -r" : "", pflag ? " -p" : "", - targetshouldbedirectory ? " -d" : ""); - - (void) signal(SIGPIPE, lostconn); - - if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ - toremote(targ, argc, argv); - else { - tolocal(argc, argv); /* Dest is local host. */ - if (targetshouldbedirectory) - verifydir(argv[argc - 1]); - } - exit(errs != 0); -} - -char * -cleanhostname(host) - char *host; -{ - if (*host == '[' && host[strlen(host) - 1] == ']') { - host[strlen(host) - 1] = '\0'; - return (host + 1); - } else - return host; -} - -void -toremote(targ, argc, argv) - char *targ, *argv[]; - int argc; -{ - int i, len; - char *bp, *host, *src, *suser, *thost, *tuser; - - *targ++ = 0; - if (*targ == 0) - targ = "."; - - if ((thost = strchr(argv[argc - 1], '@'))) { - /* user@host */ - *thost++ = 0; - tuser = argv[argc - 1]; - if (*tuser == '\0') - tuser = NULL; - else if (!okname(tuser)) - exit(1); - } else { - thost = argv[argc - 1]; - tuser = NULL; - } - - for (i = 0; i < argc - 1; i++) { - src = colon(argv[i]); - if (src) { /* remote to remote */ - *src++ = 0; - if (*src == 0) - src = "."; - host = strchr(argv[i], '@'); - len = strlen(SSH_PROGRAM) + strlen(argv[i]) + - strlen(src) + (tuser ? strlen(tuser) : 0) + - strlen(thost) + strlen(targ) + CMDNEEDS + 32; - bp = xmalloc(len); - if (host) { - *host++ = 0; - host = cleanhostname(host); - suser = argv[i]; - if (*suser == '\0') - suser = pwd->pw_name; - else if (!okname(suser)) - continue; - (void) sprintf(bp, - "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", - SSH_PROGRAM, verbose_mode ? " -v" : "", - suser, host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); - } else { - host = cleanhostname(argv[i]); - (void) sprintf(bp, - "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", - SSH_PROGRAM, verbose_mode ? " -v" : "", - host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); - } - if (verbose_mode) - fprintf(stderr, "Executing: %s\n", bp); - (void) system(bp); - (void) xfree(bp); - } else { /* local to remote */ - if (remin == -1) { - len = strlen(targ) + CMDNEEDS + 20; - bp = xmalloc(len); - (void) sprintf(bp, "%s -t %s", cmd, targ); - host = cleanhostname(thost); - if (do_cmd(host, tuser, - bp, &remin, &remout) < 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; - - for (i = 0; i < argc - 1; i++) { - if (!(src = colon(argv[i]))) { /* Local to local. */ - len = strlen(_PATH_CP) + strlen(argv[i]) + - strlen(argv[argc - 1]) + 20; - bp = xmalloc(len); - (void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP, - iamrecursive ? " -r" : "", pflag ? " -p" : "", - argv[i], argv[argc - 1]); - if (verbose_mode) - fprintf(stderr, "Executing: %s\n", bp); - if (system(bp)) - ++errs; - (void) xfree(bp); - 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) sprintf(bp, "%s -f %s", cmd, src); - if (do_cmd(host, suser, bp, &remin, &remout) < 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; - int amt, fd, haderr, indx, result; - char *last, *name, buf[2048]; - - for (indx = 0; indx < argc; ++indx) { - name = argv[indx]; - statbytes = 0; - 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) sprintf(buf, "T%lu 0 %lu 0\n", - (unsigned long) stb.st_mtime, - (unsigned long) 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) - (void) sprintf(buf, "C%04o %lu %s\n", - (unsigned int) (stb.st_mode & FILEMODEMASK), - (unsigned long) stb.st_size, - last); - if (verbose_mode) { - fprintf(stderr, "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) sprintf(path, "T%lu 0 %lu 0\n", - (unsigned long) statp->st_mtime, - (unsigned long) statp->st_atime); - (void) atomicio(write, remout, path, strlen(path)); - if (response() < 0) { - closedir(dirp); - return; - } - } - (void) sprintf(path, "D%04o %d %.1024s\n", - (unsigned int) (statp->st_mode & FILEMODEMASK), - 0, last); - if (verbose_mode) - fprintf(stderr, "Entering directory: %s", path); - (void) atomicio(write, remout, path, strlen(path)); - if (response() < 0) { - closedir(dirp); - return; - } - while ((dp = readdir(dirp))) { - if (dp->d_ino == 0) - continue; - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - 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) sprintf(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; - int setimes, size, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; - struct utimbuf ut; - int dummy_usec; - -#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; - -#define getnum(t) (t) = 0; \ - while (*cp >= '0' && *cp <= '9') (t) = (t) * 10 + (*cp++ - '0'); - cp = buf; - if (*cp == 'T') { - setimes++; - cp++; - getnum(ut.modtime); - if (*cp++ != ' ') - SCREWUP("mtime.sec not delimited"); - getnum(dummy_usec); - if (*cp++ != ' ') - SCREWUP("mtime.usec not delimited"); - getnum(ut.actime); - if (*cp++ != ' ') - SCREWUP("atime.sec not delimited"); - getnum(dummy_usec); - if (*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; *cp >= '0' && *cp <= '9';) - size = size * 10 + (*cp++ - '0'); - if (*cp++ != ' ') - SCREWUP("size not delimited"); - if (targisdir) { - static char *namebuf; - static int cursize; - size_t need; - - need = strlen(targ) + strlen(cp) + 250; - if (need > cursize) - namebuf = xmalloc(need); - (void) sprintf(namebuf, "%s%s%s", targ, - *targ ? "/" : "", cp); - np = namebuf; - } else - np = targ; - curfile = cp; - exists = stat(np, &stb) == 0; - if (buf[0] == 'D') { - int mod_flag = pflag; - 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] = np; - sink(1, vect); - if (setimes) { - setimes = 0; - if (utime(np, &ut) < 0) - run_err("%s: set times: %s", - np, strerror(errno)); - } - if (mod_flag) - (void) chmod(np, mode); - continue; - } - omode = mode; - mode |= S_IWRITE; - if ((ofd = open(np, O_WRONLY | O_CREAT | O_TRUNC, 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; - } - cp = bp->buf; - wrerr = NO; - - if (showprogress) { - totalbytes = size; - progressmeter(-1); - } - statbytes = 0; - for (count = i = 0; i < size; i += 4096) { - amt = 4096; - if (i + amt > size) - amt = size - i; - count += amt; - do { - j = atomicio(read, remin, cp, amt); - if (j <= 0) { - run_err("%s", j ? strerror(errno) : - "dropped connection"); - exit(1); - } - amt -= j; - cp += j; - statbytes += j; - } while (amt > 0); - if (count == bp->cnt) { - /* 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; - } - } - count = 0; - cp = bp->buf; - } - } - if (showprogress) - progressmeter(1); - if (count != 0 && wrerr == NO && - (j = atomicio(write, ofd, bp->buf, count)) != count) { - wrerr = YES; - wrerrno = j >= 0 ? EIO : errno; - } -#if 0 - if (ftruncate(ofd, size)) { - run_err("%s: truncate: %s", np, strerror(errno)); - wrerr = DISPLAYED; - } -#endif - if (pflag) { - if (exists || omode != mode) - if (fchmod(ofd, omode)) - run_err("%s: set mode: %s", - np, strerror(errno)); - } else { - if (!exists && omode != mode) - if (fchmod(ofd, omode & ~mask)) - run_err("%s: set mode: %s", - np, strerror(errno)); - } - (void) close(ofd); - (void) response(); - if (setimes && wrerr == NO) { - setimes = 0; - if (utime(np, &ut) < 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() -{ - 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) fprintf(stderr, - "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n"); - exit(1); -} - -void -run_err(const char *fmt,...) -{ - static FILE *fp; - va_list ap; - va_start(ap, fmt); - - ++errs; - if (fp == NULL && !(fp = fdopen(remout, "w"))) - return; - (void) fprintf(fp, "%c", 0x01); - (void) fprintf(fp, "scp: "); - (void) vfprintf(fp, fmt, ap); - (void) fprintf(fp, "\n"); - (void) fflush(fp); - - if (!iamremote) { - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } - va_end(ap); -} - -/* Stuff below is from BSD rcp util.c. */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: scp.c,v 1.30 2000/05/02 18:21:48 deraadt Exp $ - */ - -char * -colon(cp) - char *cp; -{ - 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); -} - -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 = *cp; - if (c & 0200) - goto bad; - if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-' && c != '.') - goto bad; - } while (*++cp); - return (1); - -bad: fprintf(stderr, "%s: invalid user name\n", cp0); - return (0); -} - -BUF * -allocbuf(bp, fd, blksize) - BUF *bp; - int fd, blksize; -{ - size_t size; - 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; - if (bp->cnt >= size) - return (bp); - if (bp->buf == NULL) - bp->buf = xmalloc(size); - else - bp->buf = xrealloc(bp->buf, size); - bp->cnt = size; - return (bp); -} - -void -lostconn(signo) - int signo; -{ - if (!iamremote) - fprintf(stderr, "lost connection\n"); - exit(1); -} - - -void -alarmtimer(int wait) -{ - struct itimerval itv; - - itv.it_value.tv_sec = wait; - itv.it_value.tv_usec = 0; - itv.it_interval = itv.it_value; - setitimer(ITIMER_REAL, &itv, NULL); -} - -void -updateprogressmeter(int ignore) -{ - int save_errno = errno; - - progressmeter(0); - errno = save_errno; -} - -int -foregroundproc() -{ - static pid_t pgrp = -1; - int ctty_pgrp; - - if (pgrp == -1) - pgrp = getpgrp(); - - return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && - ctty_pgrp == pgrp)); -} - -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[256]; - - 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 = 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 < sizeof(prefixes)) { - i++; - abbrevsize >>= 10; - } - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5qd %c%c ", - (quad_t) 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 (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 = 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) { - signal(SIGALRM, updateprogressmeter); - alarmtimer(1); - } else if (flag == 1) { - alarmtimer(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/crypto/openssh/scp/Makefile b/crypto/openssh/scp/Makefile deleted file mode 100644 index 3f59a9fd153e..000000000000 --- a/crypto/openssh/scp/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -.PATH: ${.CURDIR}/.. - -PROG= scp -BINOWN= root - -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else -BINMODE?=555 -.endif - -BINDIR= /usr/bin -MAN= scp.1 - -SRCS= scp.c - -.include <bsd.prog.mk> diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c deleted file mode 100644 index 57f7050dbb42..000000000000 --- a/crypto/openssh/servconf.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * - * servconf.c - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Mon Aug 21 15:48:58 1995 ylo - * - */ - -#include "includes.h" -RCSID("$Id: servconf.c,v 1.40 2000/05/08 17:12:15 markus Exp $"); - -#include "ssh.h" -#include "servconf.h" -#include "xmalloc.h" -#include "compat.h" - -/* add listen address */ -void add_listen_addr(ServerOptions *options, char *addr); - -/* Initializes the server options to their default values. */ - -void -initialize_server_options(ServerOptions *options) -{ - memset(options, 0, sizeof(*options)); - options->num_ports = 0; - options->ports_from_cmdline = 0; - options->listen_addrs = NULL; - options->host_key_file = NULL; - options->host_dsa_key_file = NULL; - options->pid_file = NULL; - options->server_key_bits = -1; - options->login_grace_time = -1; - options->key_regeneration_time = -1; - options->permit_root_login = -1; - options->ignore_rhosts = -1; - options->ignore_user_known_hosts = -1; - options->print_motd = -1; - options->check_mail = -1; - options->x11_forwarding = -1; - options->x11_display_offset = -1; - options->strict_modes = -1; - options->keepalives = -1; - options->log_facility = (SyslogFacility) - 1; - options->log_level = (LogLevel) - 1; - options->rhosts_authentication = -1; - options->rhosts_rsa_authentication = -1; - options->rsa_authentication = -1; - options->dsa_authentication = -1; -#ifdef KRB4 - options->kerberos_authentication = -1; - options->kerberos_or_local_passwd = -1; - options->kerberos_ticket_cleanup = -1; -#endif -#ifdef AFS - options->kerberos_tgt_passing = -1; - options->afs_token_passing = -1; -#endif - options->password_authentication = -1; -#ifdef SKEY - options->skey_authentication = -1; -#endif - options->permit_empty_passwd = -1; - options->use_login = -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->protocol = SSH_PROTO_UNKNOWN; - options->gateway_ports = -1; -} - -void -fill_default_server_options(ServerOptions *options) -{ - if (options->num_ports == 0) - options->ports[options->num_ports++] = SSH_DEFAULT_PORT; - if (options->listen_addrs == NULL) - add_listen_addr(options, NULL); - if (options->host_key_file == NULL) - options->host_key_file = HOST_KEY_FILE; - if (options->host_dsa_key_file == NULL) - options->host_dsa_key_file = HOST_DSA_KEY_FILE; - if (options->pid_file == NULL) - options->pid_file = 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 = 600; - if (options->key_regeneration_time == -1) - options->key_regeneration_time = 3600; - if (options->permit_root_login == -1) - options->permit_root_login = 1; /* 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->check_mail == -1) - options->check_mail = 0; - if (options->print_motd == -1) - options->print_motd = 1; - if (options->x11_forwarding == -1) - options->x11_forwarding = 0; - if (options->x11_display_offset == -1) - options->x11_display_offset = 10; - if (options->strict_modes == -1) - options->strict_modes = 1; - if (options->keepalives == -1) - options->keepalives = 1; - if (options->log_facility == (SyslogFacility) (-1)) - options->log_facility = SYSLOG_FACILITY_AUTH; - if (options->log_level == (LogLevel) (-1)) - 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->rsa_authentication == -1) - options->rsa_authentication = 1; - if (options->dsa_authentication == -1) - options->dsa_authentication = 1; -#ifdef KRB4 - if (options->kerberos_authentication == -1) - options->kerberos_authentication = (access(KEYFILE, R_OK) == 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 /* KRB4 */ -#ifdef AFS - if (options->kerberos_tgt_passing == -1) - options->kerberos_tgt_passing = 0; - if (options->afs_token_passing == -1) - options->afs_token_passing = k_hasafs(); -#endif /* AFS */ - if (options->password_authentication == -1) - options->password_authentication = 1; -#ifdef SKEY - if (options->skey_authentication == -1) - options->skey_authentication = 1; -#endif - if (options->permit_empty_passwd == -1) - options->permit_empty_passwd = 0; - if (options->use_login == -1) - options->use_login = 0; - if (options->protocol == SSH_PROTO_UNKNOWN) - options->protocol = SSH_PROTO_1|SSH_PROTO_2; - if (options->gateway_ports == -1) - options->gateway_ports = 0; -} - -#define WHITESPACE " \t\r\n" - -/* Keyword tokens. */ -typedef enum { - sBadOption, /* == unknown option */ - sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, -#ifdef KRB4 - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -#endif -#ifdef AFS - sKerberosTgtPassing, sAFSTokenPassing, -#endif -#ifdef SKEY - sSkeyAuthentication, -#endif - sPasswordAuthentication, sListenAddress, - sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, - sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, - sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, - sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, - sGatewayPorts, sDSAAuthentication -} ServerOpCodes; - -/* Textual representation of the tokens. */ -static struct { - const char *name; - ServerOpCodes opcode; -} keywords[] = { - { "port", sPort }, - { "hostkey", sHostKeyFile }, - { "hostdsakey", sHostDSAKeyFile }, - { "pidfile", sPidFile }, - { "serverkeybits", sServerKeyBits }, - { "logingracetime", sLoginGraceTime }, - { "keyregenerationinterval", sKeyRegenerationTime }, - { "permitrootlogin", sPermitRootLogin }, - { "syslogfacility", sLogFacility }, - { "loglevel", sLogLevel }, - { "rhostsauthentication", sRhostsAuthentication }, - { "rhostsrsaauthentication", sRhostsRSAAuthentication }, - { "rsaauthentication", sRSAAuthentication }, - { "dsaauthentication", sDSAAuthentication }, -#ifdef KRB4 - { "kerberosauthentication", sKerberosAuthentication }, - { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, - { "kerberosticketcleanup", sKerberosTicketCleanup }, -#endif -#ifdef AFS - { "kerberostgtpassing", sKerberosTgtPassing }, - { "afstokenpassing", sAFSTokenPassing }, -#endif - { "passwordauthentication", sPasswordAuthentication }, -#ifdef SKEY - { "skeyauthentication", sSkeyAuthentication }, -#endif - { "checkmail", sCheckMail }, - { "listenaddress", sListenAddress }, - { "printmotd", sPrintMotd }, - { "ignorerhosts", sIgnoreRhosts }, - { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, - { "x11forwarding", sX11Forwarding }, - { "x11displayoffset", sX11DisplayOffset }, - { "strictmodes", sStrictModes }, - { "permitemptypasswords", sEmptyPasswd }, - { "uselogin", sUseLogin }, - { "randomseed", sRandomSeedFile }, - { "keepalive", sKeepAlives }, - { "allowusers", sAllowUsers }, - { "denyusers", sDenyUsers }, - { "allowgroups", sAllowGroups }, - { "denygroups", sDenyGroups }, - { "ciphers", sCiphers }, - { "protocol", sProtocol }, - { "gatewayports", sGatewayPorts }, - { NULL, 0 } -}; - -/* - * Returns the number of the token pointed to by cp of length len. Never - * returns if the token is not known. - */ - -static ServerOpCodes -parse_token(const char *cp, const char *filename, - int linenum) -{ - unsigned int i; - - for (i = 0; keywords[i].name; i++) - if (strcasecmp(cp, keywords[i].name) == 0) - return keywords[i].opcode; - - fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", - filename, linenum, cp); - return sBadOption; -} - -/* - * add listen address - */ -void -add_listen_addr(ServerOptions *options, char *addr) -{ - extern int IPv4or6; - struct addrinfo hints, *ai, *aitop; - char strport[NI_MAXSERV]; - int gaierr; - int i; - - if (options->num_ports == 0) - options->ports[options->num_ports++] = SSH_DEFAULT_PORT; - for (i = 0; i < options->num_ports; i++) { - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; - snprintf(strport, sizeof strport, "%d", options->ports[i]); - if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) - fatal("bad addr or host: %s (%s)\n", - 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; - } -} - -/* Reads the server configuration file. */ - -void -read_server_config(ServerOptions *options, const char *filename) -{ - FILE *f; - char line[1024]; - char *cp, **charptr; - int linenum, *intptr, value; - int bad_options = 0; - ServerOpCodes opcode; - - f = fopen(filename, "r"); - if (!f) { - perror(filename); - exit(1); - } - linenum = 0; - while (fgets(line, sizeof(line), f)) { - linenum++; - cp = line + strspn(line, WHITESPACE); - if (!*cp || *cp == '#') - continue; - cp = strtok(cp, WHITESPACE); - opcode = parse_token(cp, filename, linenum); - switch (opcode) { - case sBadOption: - bad_options++; - continue; - case sPort: - /* ignore ports from configfile if cmdline specifies ports */ - if (options->ports_from_cmdline) - continue; - if (options->listen_addrs != NULL) - fatal("%s line %d: ports must be specified before " - "ListenAdress.\n", filename, linenum); - if (options->num_ports >= MAX_PORTS) - fatal("%s line %d: too many ports.\n", - filename, linenum); - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%s line %d: missing port number.\n", - filename, linenum); - options->ports[options->num_ports++] = atoi(cp); - break; - - case sServerKeyBits: - intptr = &options->server_key_bits; -parse_int: - cp = strtok(NULL, WHITESPACE); - if (!cp) { - fprintf(stderr, "%s line %d: missing integer value.\n", - filename, linenum); - exit(1); - } - value = atoi(cp); - if (*intptr == -1) - *intptr = value; - break; - - case sLoginGraceTime: - intptr = &options->login_grace_time; - goto parse_int; - - case sKeyRegenerationTime: - intptr = &options->key_regeneration_time; - goto parse_int; - - case sListenAddress: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%s line %d: missing inet addr.\n", - filename, linenum); - add_listen_addr(options, cp); - break; - - case sHostKeyFile: - case sHostDSAKeyFile: - charptr = (opcode == sHostKeyFile ) ? - &options->host_key_file : &options->host_dsa_key_file; - cp = strtok(NULL, WHITESPACE); - if (!cp) { - fprintf(stderr, "%s line %d: missing file name.\n", - filename, linenum); - exit(1); - } - if (*charptr == NULL) - *charptr = tilde_expand_filename(cp, getuid()); - break; - - case sPidFile: - charptr = &options->pid_file; - cp = strtok(NULL, WHITESPACE); - if (!cp) { - fprintf(stderr, "%s line %d: missing file name.\n", - filename, linenum); - exit(1); - } - if (*charptr == NULL) - *charptr = tilde_expand_filename(cp, getuid()); - break; - - case sRandomSeedFile: - fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", - filename, linenum); - cp = strtok(NULL, WHITESPACE); - break; - - case sPermitRootLogin: - intptr = &options->permit_root_login; - cp = strtok(NULL, WHITESPACE); - if (!cp) { - fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", - filename, linenum); - exit(1); - } - if (strcmp(cp, "without-password") == 0) - value = 2; - else if (strcmp(cp, "yes") == 0) - value = 1; - else if (strcmp(cp, "no") == 0) - value = 0; - else { - fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", - filename, linenum, cp); - exit(1); - } - if (*intptr == -1) - *intptr = value; - break; - - case sIgnoreRhosts: - intptr = &options->ignore_rhosts; -parse_flag: - cp = strtok(NULL, WHITESPACE); - if (!cp) { - fprintf(stderr, "%s line %d: missing yes/no argument.\n", - filename, linenum); - exit(1); - } - if (strcmp(cp, "yes") == 0) - value = 1; - else if (strcmp(cp, "no") == 0) - value = 0; - else { - fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", - filename, linenum, cp); - exit(1); - } - if (*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 sRSAAuthentication: - intptr = &options->rsa_authentication; - goto parse_flag; - - case sDSAAuthentication: - intptr = &options->dsa_authentication; - goto parse_flag; - -#ifdef KRB4 - 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 - -#ifdef AFS - case sKerberosTgtPassing: - intptr = &options->kerberos_tgt_passing; - goto parse_flag; - - case sAFSTokenPassing: - intptr = &options->afs_token_passing; - goto parse_flag; -#endif - - case sPasswordAuthentication: - intptr = &options->password_authentication; - goto parse_flag; - - case sCheckMail: - intptr = &options->check_mail; - goto parse_flag; - -#ifdef SKEY - case sSkeyAuthentication: - intptr = &options->skey_authentication; - goto parse_flag; -#endif - - case sPrintMotd: - intptr = &options->print_motd; - goto parse_flag; - - case sX11Forwarding: - intptr = &options->x11_forwarding; - goto parse_flag; - - case sX11DisplayOffset: - intptr = &options->x11_display_offset; - goto parse_int; - - 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 sUseLogin: - intptr = &options->use_login; - goto parse_flag; - - case sGatewayPorts: - intptr = &options->gateway_ports; - goto parse_flag; - - case sLogFacility: - intptr = (int *) &options->log_facility; - cp = strtok(NULL, WHITESPACE); - value = log_facility_number(cp); - if (value == (SyslogFacility) - 1) - fatal("%.200s line %d: unsupported log facility '%s'\n", - filename, linenum, cp ? cp : "<NONE>"); - if (*intptr == -1) - *intptr = (SyslogFacility) value; - break; - - case sLogLevel: - intptr = (int *) &options->log_level; - cp = strtok(NULL, WHITESPACE); - value = log_level_number(cp); - if (value == (LogLevel) - 1) - fatal("%.200s line %d: unsupported log level '%s'\n", - filename, linenum, cp ? cp : "<NONE>"); - if (*intptr == -1) - *intptr = (LogLevel) value; - break; - - case sAllowUsers: - while ((cp = strtok(NULL, WHITESPACE))) { - if (options->num_allow_users >= MAX_ALLOW_USERS) - fatal("%s line %d: too many allow users.\n", - filename, linenum); - options->allow_users[options->num_allow_users++] = xstrdup(cp); - } - break; - - case sDenyUsers: - while ((cp = strtok(NULL, WHITESPACE))) { - if (options->num_deny_users >= MAX_DENY_USERS) - fatal( "%s line %d: too many deny users.\n", - filename, linenum); - options->deny_users[options->num_deny_users++] = xstrdup(cp); - } - break; - - case sAllowGroups: - while ((cp = strtok(NULL, WHITESPACE))) { - if (options->num_allow_groups >= MAX_ALLOW_GROUPS) - fatal("%s line %d: too many allow groups.\n", - filename, linenum); - options->allow_groups[options->num_allow_groups++] = xstrdup(cp); - } - break; - - case sDenyGroups: - while ((cp = strtok(NULL, WHITESPACE))) { - if (options->num_deny_groups >= MAX_DENY_GROUPS) - fatal("%s line %d: too many deny groups.\n", - filename, linenum); - options->deny_groups[options->num_deny_groups++] = xstrdup(cp); - } - break; - - case sCiphers: - cp = strtok(NULL, WHITESPACE); - if (!ciphers_valid(cp)) - fatal("%s line %d: Bad SSH2 cipher spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); - if (options->ciphers == NULL) - options->ciphers = xstrdup(cp); - break; - - case sProtocol: - intptr = &options->protocol; - cp = strtok(NULL, WHITESPACE); - value = proto_spec(cp); - if (value == SSH_PROTO_UNKNOWN) - fatal("%s line %d: Bad protocol spec '%s'.", - filename, linenum, cp ? cp : "<NONE>"); - if (*intptr == SSH_PROTO_UNKNOWN) - *intptr = value; - break; - - default: - fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", - filename, linenum, cp, opcode); - exit(1); - } - if (strtok(NULL, WHITESPACE) != NULL) { - fprintf(stderr, "%s line %d: garbage at end of line.\n", - filename, linenum); - exit(1); - } - } - fclose(f); - if (bad_options > 0) { - fprintf(stderr, "%s: terminating, %d bad configuration options\n", - filename, bad_options); - exit(1); - } -} diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h deleted file mode 100644 index 4fa6deea6f55..000000000000 --- a/crypto/openssh/servconf.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * - * servconf.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Mon Aug 21 15:35:03 1995 ylo - * - * Definitions for server configuration data and for the functions reading it. - * - */ - -/* RCSID("$Id: servconf.h,v 1.22 2000/05/06 17:45:37 markus Exp $"); */ - -#ifndef SERVCONF_H -#define SERVCONF_H - -#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. */ - -typedef struct { - unsigned int num_ports; - unsigned 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_file; /* File containing host key. */ - char *host_dsa_key_file; /* File containing dsa host key. */ - 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; /* If true, permit root login. */ - 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 check_mail; /* If true, check for new mail. */ - int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ - int x11_display_offset; /* What DISPLAY number to start - * searching at */ - int strict_modes; /* If true, require string home dir modes. */ - int keepalives; /* If true, set SO_KEEPALIVE. */ - char *ciphers; /* Ciphers in order of preference. */ - int protocol; /* Protocol in order of preference. */ - 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 rsa_authentication; /* If true, permit RSA authentication. */ - int dsa_authentication; /* If true, permit DSA authentication. */ -#ifdef KRB4 - 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 -#ifdef AFS - int kerberos_tgt_passing; /* If true, permit Kerberos tgt - * passing. */ - int afs_token_passing; /* If true, permit AFS token passing. */ -#endif - int password_authentication; /* If true, permit password - * authentication. */ -#ifdef SKEY - int skey_authentication; /* If true, permit s/key - * authentication. */ -#endif - int permit_empty_passwd; /* If false, do not permit empty - * passwords. */ - int use_login; /* If true, login(1) is used */ - unsigned int num_allow_users; - char *allow_users[MAX_ALLOW_USERS]; - unsigned int num_deny_users; - char *deny_users[MAX_DENY_USERS]; - unsigned int num_allow_groups; - char *allow_groups[MAX_ALLOW_GROUPS]; - unsigned int num_deny_groups; - char *deny_groups[MAX_DENY_GROUPS]; -} ServerOptions; -/* - * Initializes the server options to special values that indicate that they - * have not yet been set. - */ -void initialize_server_options(ServerOptions * options); - -/* - * Reads the server configuration file. This only sets the values for those - * options that have the special value indicating they have not been set. - */ -void read_server_config(ServerOptions * options, const char *filename); - -/* Sets values for those values that have not yet been set. */ -void fill_default_server_options(ServerOptions * options); - -#endif /* SERVCONF_H */ diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c deleted file mode 100644 index 9bf31275beaf..000000000000 --- a/crypto/openssh/serverloop.c +++ /dev/null @@ -1,824 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Sun Sep 10 00:30:37 1995 ylo - * Server main loop for handling the interactive session. - */ -/* - * SSH2 support by Markus Friedl. - * Copyright (c) 2000 Markus Friedl. All rights reserved. - */ - -#include "includes.h" -#include "xmalloc.h" -#include "ssh.h" -#include "packet.h" -#include "buffer.h" -#include "servconf.h" -#include "pty.h" -#include "channels.h" - -#include "compat.h" -#include "ssh2.h" -#include "session.h" -#include "dispatch.h" - -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 connection_in; /* Connection to client (input). */ -static int connection_out; /* Connection to client (output). */ -static unsigned int buffer_high;/* "Soft" max buffer size. */ -static int max_fd; /* Max file descriptor number for select(). */ - -/* - * 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 pid_t child_pid; /* Pid of the child. */ -static volatile int child_terminated; /* The child has terminated. */ -static volatile int child_wait_status; /* Status from wait(). */ - -void server_init_dispatch(void); - -void -sigchld_handler(int sig) -{ - int save_errno = errno; - pid_t wait_pid; - - debug("Received SIGCHLD."); - wait_pid = wait((int *) &child_wait_status); - if (wait_pid != -1) { - if (wait_pid != child_pid) - error("Strange, got SIGCHLD and wait returned pid %d but child is %d", - wait_pid, child_pid); - if (WIFEXITED(child_wait_status) || - WIFSIGNALED(child_wait_status)) - child_terminated = 1; - } - signal(SIGCHLD, sigchld_handler); - errno = save_errno; -} -void -sigchld_handler2(int sig) -{ - int save_errno = errno; - debug("Received SIGCHLD."); - child_terminated = 1; - signal(SIGCHLD, sigchld_handler2); - errno = save_errno; -} - -/* - * Make packets from buffered stderr data, and buffer it for sending - * to the client. - */ -void -make_packets_from_stderr_data() -{ - 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. - */ -void -make_packets_from_stdout_data() -{ - 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; - } -} - -/* - * 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). - */ -void -wait_until_can_do_something(fd_set * readset, fd_set * writeset, - unsigned int max_time_milliseconds) -{ - struct timeval tv, *tvp; - int ret; - - /* When select fails we restart from here. */ -retry_select: - - /* Initialize select() masks. */ - FD_ZERO(readset); - - /* - * Read packets from the client unless we have too much buffered - * stdin or channel data. - */ - if (compat20) { - /* wrong: bad condition XXX */ - if (channel_not_very_much_buffered_data()) - FD_SET(connection_in, readset); - } else { - if (buffer_len(&stdin_buffer) < 4096 && - channel_not_very_much_buffered_data()) - FD_SET(connection_in, readset); - } - - /* - * If there is not too much data already buffered going to the - * client, try to get some more data from the program. - */ - if (!compat20 && packet_not_very_much_data_to_write()) { - if (!fdout_eof) - FD_SET(fdout, readset); - if (!fderr_eof) - FD_SET(fderr, readset); - } - FD_ZERO(writeset); - - /* Set masks for channel descriptors. */ - channel_prepare_select(readset, writeset); - - /* - * If we have buffered packet data going to the client, mark that - * descriptor. - */ - if (packet_have_data_to_write()) - FD_SET(connection_out, writeset); - - /* If we have buffered data, try to write some of that data to the - program. */ - if (!compat20 && fdin != -1 && buffer_len(&stdin_buffer) > 0) - FD_SET(fdin, writeset); - - /* Update the maximum descriptor number if appropriate. */ - if (channel_max_fd() > max_fd) - max_fd = channel_max_fd(); - - /* - * 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) - 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; - } - if (tvp!=NULL) - debug("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); - - /* Wait for something to happen, or the timeout to expire. */ - ret = select(max_fd + 1, readset, writeset, NULL, tvp); - - if (ret < 0) { - if (errno != EINTR) - error("select: %.100s", strerror(errno)); - else - goto retry_select; - } -} - -/* - * Processes input from the client and the program. Input data is stored - * in buffers and processed later. - */ -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) { - verbose("Connection closed by remote host."); - fatal_cleanup(); - } - /* - * 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) - len = 0; - - if (len < 0) { - verbose("Read error from remote host: %.100s", strerror(errno)); - fatal_cleanup(); - } - /* 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) - 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) - fderr_eof = 1; - else - buffer_append(&stderr_buffer, buf, len); - } -} - -/* - * Sends data from internal buffers to client program stdin. - */ -void -process_output(fd_set * writeset) -{ - int len; - - /* Write buffered data to program stdin. */ - if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { - len = write(fdin, buffer_ptr(&stdin_buffer), - buffer_len(&stdin_buffer)); - if (len <= 0) { -#ifdef USE_PIPES - close(fdin); -#else - if (fdin != fdout) - close(fdin); - else - shutdown(fdin, SHUT_WR); /* We will no longer send. */ -#endif - fdin = -1; - } else { - /* Successful write. 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. - */ -void -drain_output() -{ - /* 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(); -} - -void -process_buffered_input_packets() -{ - dispatch_run(DISPATCH_NONBLOCK, 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) -{ - int wait_status; /* Status returned by wait(). */ - pid_t wait_pid; /* pid returned by wait(). */ - int waiting_termination = 0; /* Have displayed waiting close message. */ - unsigned int max_time_milliseconds; - unsigned int previous_stdout_buffer_bytes; - unsigned int stdout_buffer_bytes; - int type; - - debug("Entering interactive session."); - - /* Initialize the SIGCHLD kludge. */ - child_pid = pid; - child_terminated = 0; - signal(SIGCHLD, sigchld_handler); - - /* Initialize our global variables. */ - fdin = fdin_arg; - fdout = fdout_arg; - fderr = fderr_arg; - connection_in = packet_get_connection_in(); - connection_out = packet_get_connection_out(); - - previous_stdout_buffer_bytes = 0; - - /* Set approximate I/O buffer size. */ - if (packet_is_interactive()) - buffer_high = 4096; - else - buffer_high = 64 * 1024; - - /* Initialize max_fd to the maximum of the known file descriptors. */ - max_fd = fdin; - if (fdout > max_fd) - max_fd = fdout; - if (fderr != -1 && fderr > max_fd) - max_fd = fderr; - if (connection_in > max_fd) - max_fd = connection_in; - if (connection_out > max_fd) - max_fd = connection_out; - - /* 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 (;;) { - fd_set readset, writeset; - - /* 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) { -#ifdef USE_PIPES - close(fdin); -#else - if (fdin != fdout) - close(fdin); - else - shutdown(fdin, SHUT_WR); /* We will no longer send. */ -#endif - 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); - } - } - /* Sleep in select() until we can do something. */ - wait_until_can_do_something(&readset, &writeset, - 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); - } - - /* 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) - close(fdout); - fdout = -1; - fdout_eof = 1; - if (fderr != -1) - close(fderr); - fderr = -1; - fderr_eof = 1; - if (fdin != -1) - close(fdin); - fdin = -1; - - /* Stop listening for channels; this removes unix domain sockets. */ - channel_stop_listening(); - - /* Wait for the child to exit. Get its exit status. */ - wait_pid = wait(&wait_status); - if (wait_pid < 0) { - /* - * It is possible that the wait was handled by SIGCHLD - * handler. This may result in either: this call - * returning with EINTR, or: this call returning ECHILD. - */ - if (child_terminated) - wait_status = child_wait_status; - else - packet_disconnect("wait: %.100s", strerror(errno)); - } else { - /* Check if it matches the process we forked. */ - if (wait_pid != pid) - error("Strange, wait returned pid %d, expected %d", - wait_pid, pid); - } - - /* We no longer want our SIGCHLD handler to be called. */ - signal(SIGCHLD, SIG_DFL); - - /* 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 { - int plen; - type = packet_read(&plen); - } - 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 */ -} - -void -server_loop2(void) -{ - fd_set readset, writeset; - int had_channel = 0; - int status; - pid_t pid; - - debug("Entering interactive session for SSH2."); - - signal(SIGCHLD, sigchld_handler2); - child_terminated = 0; - connection_in = packet_get_connection_in(); - connection_out = packet_get_connection_out(); - max_fd = connection_in; - if (connection_out > max_fd) - max_fd = connection_out; - server_init_dispatch(); - - for (;;) { - process_buffered_input_packets(); - if (!had_channel && channel_still_open()) - had_channel = 1; - if (had_channel && !channel_still_open()) { - debug("!channel_still_open."); - break; - } - if (packet_not_very_much_data_to_write()) - channel_output_poll(); - wait_until_can_do_something(&readset, &writeset, 0); - if (child_terminated) { - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) - session_close_by_pid(pid, status); - child_terminated = 0; - } - channel_after_select(&readset, &writeset); - process_input(&readset); - process_output(&writeset); - } - signal(SIGCHLD, SIG_DFL); - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) - session_close_by_pid(pid, status); - channel_stop_listening(); -} - -void -server_input_stdin_data(int type, int plen) -{ - char *data; - unsigned 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_integrity_check(plen, (4 + data_len), type); - buffer_append(&stdin_buffer, data, data_len); - memset(data, 0, data_len); - xfree(data); -} - -void -server_input_eof(int type, int plen) -{ - /* - * 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_integrity_check(plen, 0, type); - stdin_eof = 1; -} - -void -server_input_window_size(int type, int plen) -{ - 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_integrity_check(plen, 4 * 4, type); - if (fdin != -1) - pty_change_window_size(fdin, row, col, xpixel, ypixel); -} - -int -input_direct_tcpip(void) -{ - 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_done(); - /* XXX check permission */ - sock = channel_connect_to(target, target_port); - xfree(target); - xfree(originator); - if (sock < 0) - return -1; - return channel_new("direct-tcpip", SSH_CHANNEL_OPEN, - sock, sock, -1, 4*1024, 32*1024, 0, xstrdup("direct-tcpip")); -} - -void -server_input_channel_open(int type, int plen) -{ - Channel *c = NULL; - char *ctype; - int id; - unsigned int len; - int rchan; - int rmaxpack; - int rwindow; - - ctype = packet_get_string(&len); - rchan = packet_get_int(); - rwindow = packet_get_int(); - rmaxpack = packet_get_int(); - - debug("channel_input_open: ctype %s rchan %d win %d max %d", - ctype, rchan, rwindow, rmaxpack); - - if (strcmp(ctype, "session") == 0) { - debug("open session"); - packet_done(); - /* - * 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. - */ - id = channel_new(ctype, SSH_CHANNEL_LARVAL, - -1, -1, -1, 0, 32*1024, 0, xstrdup("server-session")); - if (session_open(id) == 1) { - channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, - session_input_channel_req, (void *)0); - channel_register_cleanup(id, session_close_by_channel); - c = channel_lookup(id); - } else { - debug("session open failed, free channel %d", id); - channel_free(id); - } - } else if (strcmp(ctype, "direct-tcpip") == 0) { - debug("open direct-tcpip"); - id = input_direct_tcpip(); - if (id >= 0) - c = channel_lookup(id); - } - if (c != NULL) { - debug("confirm %s", ctype); - c->remote_id = rchan; - c->remote_window = rwindow; - c->remote_maxpacket = rmaxpack; - - 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); - packet_put_cstring("bla bla"); - packet_put_cstring(""); - packet_send(); - } - xfree(ctype); -} - -void -server_init_dispatch_20() -{ - 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, &channel_input_channel_request); - dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); -} -void -server_init_dispatch_13() -{ - 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); -} -void -server_init_dispatch_15() -{ - 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); -} -void -server_init_dispatch() -{ - if (compat20) - server_init_dispatch_20(); - else if (compat13) - server_init_dispatch_13(); - else - server_init_dispatch_15(); -} diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c deleted file mode 100644 index 53d20c59cf25..000000000000 --- a/crypto/openssh/session.c +++ /dev/null @@ -1,1516 +0,0 @@ -/* - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - */ -/* - * SSH2 support by Markus Friedl. - * Copyright (c) 2000 Markus Friedl. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $"); - -#include "xmalloc.h" -#include "ssh.h" -#include "pty.h" -#include "packet.h" -#include "buffer.h" -#include "cipher.h" -#include "mpaux.h" -#include "servconf.h" -#include "uidswap.h" -#include "compat.h" -#include "channels.h" -#include "nchan.h" - -#include "bufaux.h" -#include "ssh2.h" -#include "auth.h" - -/* types */ - -#define TTYSZ 64 -typedef struct Session Session; -struct Session { - int used; - int self; - int extended; - struct passwd *pw; - pid_t pid; - /* tty */ - char *term; - int ptyfd, ttyfd, ptymaster; - int row, col, xpixel, ypixel; - char tty[TTYSZ]; - /* X11 */ - char *display; - int screen; - char *auth_proto; - char *auth_data; - int single_connection; - /* proto 2 */ - int chanid; -}; - -/* func */ - -Session *session_new(void); -void session_set_fds(Session *s, int fdin, int fdout, int fderr); -void session_pty_cleanup(Session *s); -void session_proctitle(Session *s); -void do_exec_pty(Session *s, const char *command, struct passwd * pw); -void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); - -void -do_child(const char *command, struct passwd * pw, const char *term, - const char *display, const char *auth_proto, - const char *auth_data, const char *ttyname); - -/* import */ -extern ServerOptions options; -extern char *__progname; -extern int log_stderr; -extern int debug_flag; - -/* Local Xauthority file. */ -static char *xauthfile; - -/* data */ -#define MAX_SESSIONS 10 -Session sessions[MAX_SESSIONS]; - -/* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */ -int no_port_forwarding_flag = 0; -int no_agent_forwarding_flag = 0; -int no_x11_forwarding_flag = 0; -int no_pty_flag = 0; - -/* RSA authentication "command=" option. */ -char *forced_command = NULL; - -/* RSA authentication "environment=" options. */ -struct envstring *custom_environment = NULL; - -/* - * Remove local Xauthority file. - */ -void -xauthfile_cleanup_proc(void *ignore) -{ - debug("xauthfile_cleanup_proc called"); - - if (xauthfile != NULL) { - char *p; - unlink(xauthfile); - p = strrchr(xauthfile, '/'); - if (p != NULL) { - *p = '\0'; - rmdir(xauthfile); - } - xfree(xauthfile); - xauthfile = NULL; - } -} - -/* - * Function to perform cleanup if we get aborted abnormally (e.g., due to a - * dropped connection). - */ -void -pty_cleanup_proc(void *session) -{ - Session *s=session; - if (s == NULL) - fatal("pty_cleanup_proc: no session"); - debug("pty_cleanup_proc: %s", s->tty); - - if (s->pid != 0) { - /* Record that the user has logged out. */ - record_logout(s->pid, s->tty); - } - - /* Release the pseudo-tty. */ - pty_release(s->tty); -} - -/* - * 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. - */ -void -do_authenticated(struct passwd * pw) -{ - Session *s; - int type; - int compression_level = 0, enable_compression_after_reply = 0; - int have_pty = 0; - char *command; - int n_bytes; - int plen; - unsigned int proto_len, data_len, dlen; - - /* - * Cancel the alarm we set to limit the time taken for - * authentication. - */ - alarm(0); - - /* - * Inform the channel mechanism that we are the server side and that - * the client may request to connect to any port at all. (The user - * could do it anyway, and we wouldn\'t know what is permitted except - * by the client telling us, so we can equally well trust the client - * not to request anything bogus.) - */ - if (!no_port_forwarding_flag) - channel_permit_all_opens(); - - s = session_new(); - s->pw = pw; - - /* - * We stay in this loop until the client requests to execute a shell - * or a command. - */ - for (;;) { - int success = 0; - - /* Get a packet from the client. */ - type = packet_read(&plen); - - /* Process the packet. */ - switch (type) { - case SSH_CMSG_REQUEST_COMPRESSION: - packet_integrity_check(plen, 4, type); - compression_level = packet_get_int(); - if (compression_level < 1 || compression_level > 9) { - packet_send_debug("Received illegal compression level %d.", - compression_level); - break; - } - /* Enable compression after we have responded with SUCCESS. */ - enable_compression_after_reply = 1; - success = 1; - break; - - case SSH_CMSG_REQUEST_PTY: - if (no_pty_flag) { - debug("Allocating a pty not permitted for this authentication."); - break; - } - if (have_pty) - packet_disconnect("Protocol error: you already have a pty."); - - debug("Allocating pty."); - - /* Allocate a pty and open it. */ - if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, - sizeof(s->tty))) { - error("Failed to allocate pty."); - break; - } - fatal_add_cleanup(pty_cleanup_proc, (void *)s); - pty_setowner(pw, s->tty); - - /* Get TERM from the packet. Note that the value may be of arbitrary length. */ - s->term = packet_get_string(&dlen); - packet_integrity_check(dlen, strlen(s->term), type); - /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */ - /* Remaining bytes */ - n_bytes = plen - (4 + dlen + 4 * 4); - - if (strcmp(s->term, "") == 0) { - xfree(s->term); - s->term = NULL; - } - /* Get window size from the packet. */ - s->row = packet_get_int(); - s->col = packet_get_int(); - s->xpixel = packet_get_int(); - s->ypixel = packet_get_int(); - pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); - - /* Get tty modes from the packet. */ - tty_parse_modes(s->ttyfd, &n_bytes); - packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type); - - session_proctitle(s); - - /* Indicate that we now have a pty. */ - success = 1; - have_pty = 1; - break; - - case SSH_CMSG_X11_REQUEST_FORWARDING: - if (!options.x11_forwarding) { - packet_send_debug("X11 forwarding disabled in server configuration file."); - break; - } -#ifdef XAUTH_PATH - if (no_x11_forwarding_flag) { - packet_send_debug("X11 forwarding not permitted for this authentication."); - break; - } - debug("Received request for X11 forwarding with auth spoofing."); - if (s->display != NULL) - packet_disconnect("Protocol error: X11 display already set."); - - s->auth_proto = packet_get_string(&proto_len); - s->auth_data = packet_get_string(&data_len); - packet_integrity_check(plen, 4 + proto_len + 4 + data_len + 4, type); - - if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER) - s->screen = packet_get_int(); - else - s->screen = 0; - s->display = x11_create_display_inet(s->screen, options.x11_display_offset); - - if (s->display == NULL) - break; - - /* Setup to always have a local .Xauthority. */ - xauthfile = xmalloc(MAXPATHLEN); - strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); - temporarily_use_uid(pw->pw_uid); - if (mkdtemp(xauthfile) == NULL) { - restore_uid(); - error("private X11 dir: mkdtemp %s failed: %s", - xauthfile, strerror(errno)); - xfree(xauthfile); - xauthfile = NULL; - /* XXXX remove listening channels */ - break; - } - strlcat(xauthfile, "/cookies", MAXPATHLEN); - open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); - restore_uid(); - fatal_add_cleanup(xauthfile_cleanup_proc, NULL); - success = 1; - break; -#else /* XAUTH_PATH */ - packet_send_debug("No xauth program; cannot forward with spoofing."); - break; -#endif /* XAUTH_PATH */ - - case SSH_CMSG_AGENT_REQUEST_FORWARDING: - if (no_agent_forwarding_flag || compat13) { - debug("Authentication agent forwarding not permitted for this authentication."); - break; - } - debug("Received authentication agent forwarding request."); - auth_input_request_forwarding(pw); - success = 1; - break; - - case SSH_CMSG_PORT_FORWARD_REQUEST: - if (no_port_forwarding_flag) { - debug("Port forwarding not permitted for this authentication."); - break; - } - debug("Received TCP/IP port forwarding request."); - channel_input_port_forward_request(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; - - case SSH_CMSG_EXEC_SHELL: - case SSH_CMSG_EXEC_CMD: - /* Set interactive/non-interactive mode. */ - packet_set_interactive(have_pty || s->display != NULL, - options.keepalives); - - if (type == SSH_CMSG_EXEC_CMD) { - command = packet_get_string(&dlen); - debug("Exec command '%.500s'", command); - packet_integrity_check(plen, 4 + dlen, type); - } else { - command = NULL; - packet_integrity_check(plen, 0, type); - } - if (forced_command != NULL) { - command = forced_command; - debug("Forced command '%.500s'", forced_command); - } - if (have_pty) - do_exec_pty(s, command, pw); - else - do_exec_no_pty(s, command, pw); - - if (command != NULL) - xfree(command); - /* Cleanup user's local Xauthority file. */ - if (xauthfile) - xauthfile_cleanup_proc(NULL); - 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, struct passwd * pw) -{ - int pid; - -#ifdef USE_PIPES - int pin[2], pout[2], perr[2]; - /* Allocate pipes for communicating with the program. */ - if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) - packet_disconnect("Could not create pipes: %.100s", - strerror(errno)); -#else /* USE_PIPES */ - 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)); -#endif /* USE_PIPES */ - if (s == NULL) - fatal("do_exec_no_pty: no session"); - - session_proctitle(s); - - /* Fork the child. */ - if ((pid = fork()) == 0) { - /* 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)); - -#ifdef USE_PIPES - /* - * Redirect stdin. We close the parent side of the socket - * pair, and make the child side the standard input. - */ - close(pin[1]); - if (dup2(pin[0], 0) < 0) - perror("dup2 stdin"); - close(pin[0]); - - /* Redirect stdout. */ - close(pout[0]); - if (dup2(pout[1], 1) < 0) - perror("dup2 stdout"); - close(pout[1]); - - /* Redirect stderr. */ - close(perr[0]); - if (dup2(perr[1], 2) < 0) - perror("dup2 stderr"); - close(perr[1]); -#else /* USE_PIPES */ - /* - * 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 (dup2(err[0], 2) < 0) /* stderr */ - perror("dup2 stderr"); -#endif /* USE_PIPES */ - - /* Do processing for the child (exec command etc). */ - do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL); - /* NOTREACHED */ - } - if (pid < 0) - packet_disconnect("fork failed: %.100s", strerror(errno)); - s->pid = pid; -#ifdef USE_PIPES - /* We are the parent. Close the child sides of the pipes. */ - close(pin[0]); - close(pout[1]); - close(perr[1]); - - if (compat20) { - session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1); - } else { - /* Enter the interactive session. */ - server_loop(pid, pin[1], pout[0], perr[0]); - /* server_loop has closed pin[1], pout[1], and perr[1]. */ - } -#else /* USE_PIPES */ - /* 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->extended ? err[1] : -1); - } else { - server_loop(pid, inout[1], inout[1], err[1]); - /* server_loop has closed inout[1] and err[1]. */ - } -#endif /* USE_PIPES */ -} - -/* - * 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, struct passwd * pw) -{ - FILE *f; - char buf[100], *time_string; - char line[256]; - const char *hostname; - int fdout, ptyfd, ttyfd, ptymaster; - int quiet_login; - pid_t pid; - socklen_t fromlen; - struct sockaddr_storage from; - struct stat st; - time_t last_login_time; - - if (s == NULL) - fatal("do_exec_pty: no session"); - ptyfd = s->ptyfd; - ttyfd = s->ttyfd; - - /* Get remote host name. */ - hostname = get_canonical_hostname(); - - /* - * Get the time when the user last logged in. Buf will be set to - * contain the hostname the last login was from. - */ - if (!options.use_login) { - last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, - buf, sizeof(buf)); - } - - /* Fork the child. */ - if ((pid = fork()) == 0) { - pid = getpid(); - - /* Child. Reinitialize the log because the pid has - changed. */ - 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 from the pseudo tty. */ - if (dup2(ttyfd, fileno(stdin)) < 0) - error("dup2 stdin failed: %.100s", strerror(errno)); - - /* Redirect stdout to the pseudo tty. */ - if (dup2(ttyfd, fileno(stdout)) < 0) - error("dup2 stdin failed: %.100s", strerror(errno)); - - /* Redirect stderr to the pseudo tty. */ - if (dup2(ttyfd, fileno(stderr)) < 0) - error("dup2 stdin failed: %.100s", strerror(errno)); - - /* Close the extra descriptor for the pseudo tty. */ - close(ttyfd); - -/* XXXX ? move to do_child() ??*/ - /* - * Get IP address of client. This is needed because we want - * to record where the user logged in from. If the - * connection is not a socket, let the ip address be 0.0.0.0. - */ - memset(&from, 0, sizeof(from)); - if (packet_connection_is_on_socket()) { - fromlen = sizeof(from); - if (getpeername(packet_get_connection_in(), - (struct sockaddr *) & from, &fromlen) < 0) { - debug("getpeername: %.100s", strerror(errno)); - fatal_cleanup(); - } - } - /* Record that there was a login on that terminal. */ - record_login(pid, s->tty, pw->pw_name, pw->pw_uid, hostname, - (struct sockaddr *)&from); - - /* Check if .hushlogin exists. */ - snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); - quiet_login = stat(line, &st) >= 0; - - /* - * If the user has logged in before, display the time of last - * login. However, don't display anything extra if a command - * has been specified (so that ssh can be used to execute - * commands on a remote machine without users knowing they - * are going to another machine). Login(1) will do this for - * us as well, so check if login(1) is used - */ - if (command == NULL && last_login_time != 0 && !quiet_login && - !options.use_login) { - /* Convert the date to a string. */ - time_string = ctime(&last_login_time); - /* Remove the trailing newline. */ - if (strchr(time_string, '\n')) - *strchr(time_string, '\n') = 0; - /* Display the last login time. Host if displayed - if known. */ - if (strcmp(buf, "") == 0) - printf("Last login: %s\r\n", time_string); - else - printf("Last login: %s from %s\r\n", time_string, buf); - } - /* - * Print /etc/motd unless a command was specified or printing - * it was disabled in server options or login(1) will be - * used. Note that some machines appear to print it in - * /etc/profile or similar. - */ - if (command == NULL && options.print_motd && !quiet_login && - !options.use_login) { - /* Print /etc/motd if it exists. */ - f = fopen("/etc/motd", "r"); - if (f) { - while (fgets(line, sizeof(line), f)) - fputs(line, stdout); - fclose(f); - } - } - /* Do common processing for the child, such as execing the command. */ - do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty); - /* NOTREACHED */ - } - 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. */ - if (compat20) { - session_set_fds(s, ptyfd, fdout, -1); - } else { - server_loop(pid, ptyfd, fdout, -1); - /* server_loop _has_ closed ptyfd and fdout. */ - session_pty_cleanup(s); - } -} - -/* - * 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, unsigned int *envsizep, const char *name, - const char *value) -{ - unsigned 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) { - (*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. - */ -void -read_environment_file(char ***env, unsigned int *envsize, - const char *filename) -{ - FILE *f; - char buf[4096]; - char *cp, *value; - - f = fopen(filename, "r"); - if (!f) - return; - - while (fgets(buf, sizeof(buf), f)) { - 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, "Bad line in %.100s: %.200s\n", filename, buf); - 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); -} - -/* - * 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. - */ -void -do_child(const char *command, struct passwd * pw, const char *term, - const char *display, const char *auth_proto, - const char *auth_data, const char *ttyname) -{ - const char *shell, *cp = NULL; - char buf[256]; - FILE *f; - unsigned int envsize, i; - char **env; - extern char **environ; - struct stat st; - char *argv[10]; - - f = fopen("/etc/nologin", "r"); - if (f) { - /* /etc/nologin exists. Print its contents and exit. */ - while (fgets(buf, sizeof(buf), f)) - fputs(buf, stderr); - fclose(f); - if (pw->pw_uid != 0) - exit(254); - } - /* Set login name in the kernel. */ - if (setlogin(pw->pw_name) < 0) - error("setlogin failed: %s", strerror(errno)); - - /* Set uid, gid, and groups. */ - /* Login(1) does this as well, and it needs uid 0 for the "-h" - switch, so we let login(1) to this for us. */ - if (!options.use_login) { - if (getuid() == 0 || geteuid() == 0) { - if (setgid(pw->pw_gid) < 0) { - perror("setgid"); - exit(1); - } - /* Initialize the group list. */ - if (initgroups(pw->pw_name, pw->pw_gid) < 0) { - perror("initgroups"); - exit(1); - } - endgrent(); - - /* Permanently switch to the desired uid. */ - permanently_set_uid(pw->pw_uid); - } - if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) - fatal("Failed to set uids to %d.", (int) pw->pw_uid); - } - /* - * Get the shell from the password data. An empty shell field is - * legal, and means /bin/sh. - */ - shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; - -#ifdef 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 */ - - /* Initialize the environment. */ - envsize = 100; - env = xmalloc(envsize * sizeof(char *)); - env[0] = NULL; - - if (!options.use_login) { - /* 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); - child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); - - 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); - } - if (getenv("TZ")) - child_set_env(&env, &envsize, "TZ", getenv("TZ")); - - /* Set custom environment options from RSA authentication. */ - while (custom_environment) { - struct envstring *ce = custom_environment; - char *s = ce->s; - int i; - for (i = 0; s[i] != '=' && s[i]; i++); - if (s[i] == '=') { - s[i] = 0; - child_set_env(&env, &envsize, s, s + i + 1); - } - custom_environment = ce->next; - xfree(ce->s); - xfree(ce); - } - - snprintf(buf, sizeof buf, "%.50s %d %d", - get_remote_ipaddr(), get_remote_port(), get_local_port()); - child_set_env(&env, &envsize, "SSH_CLIENT", buf); - - if (ttyname) - child_set_env(&env, &envsize, "SSH_TTY", ttyname); - if (term) - child_set_env(&env, &envsize, "TERM", term); - if (display) - child_set_env(&env, &envsize, "DISPLAY", display); - -#ifdef KRB4 - { - extern char *ticket; - - if (ticket) - child_set_env(&env, &envsize, "KRBTKFILE", ticket); - } -#endif /* KRB4 */ - - if (xauthfile) - child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); - if (auth_get_socket_name() != NULL) - child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, - auth_get_socket_name()); - - /* read $HOME/.ssh/environment. */ - if (!options.use_login) { - snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); - read_environment_file(&env, &envsize, buf); - } - if (debug_flag) { - /* dump the environment */ - fprintf(stderr, "Environment:\n"); - for (i = 0; env[i]; i++) - fprintf(stderr, " %.200s\n", env[i]); - } - /* - * 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(); - - /* - * 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. - */ - for (i = 3; i < 64; i++) - close(i); - - /* Change current directory to the user\'s home directory. */ - if (chdir(pw->pw_dir) < 0) - fprintf(stderr, "Could not chdir to home directory %s: %s\n", - pw->pw_dir, strerror(errno)); - - /* - * Must take new environment into use so that .ssh/rc, /etc/sshrc and - * xauth are run in the proper environment. - */ - environ = env; - - /* - * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first - * in this order). - */ - if (!options.use_login) { - if (stat(SSH_USER_RC, &st) >= 0) { - if (debug_flag) - fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC); - - f = popen("/bin/sh " SSH_USER_RC, "w"); - if (f) { - if (auth_proto != NULL && auth_data != NULL) - fprintf(f, "%s %s\n", auth_proto, auth_data); - pclose(f); - } else - fprintf(stderr, "Could not run %s\n", SSH_USER_RC); - } else if (stat(SSH_SYSTEM_RC, &st) >= 0) { - if (debug_flag) - fprintf(stderr, "Running /bin/sh %s\n", SSH_SYSTEM_RC); - - f = popen("/bin/sh " SSH_SYSTEM_RC, "w"); - if (f) { - if (auth_proto != NULL && auth_data != NULL) - fprintf(f, "%s %s\n", auth_proto, auth_data); - pclose(f); - } else - fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC); - } -#ifdef XAUTH_PATH - else { - /* Add authority data to .Xauthority if appropriate. */ - if (auth_proto != NULL && auth_data != NULL) { - if (debug_flag) - fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n", - XAUTH_PATH, display, auth_proto, auth_data); - - f = popen(XAUTH_PATH " -q -", "w"); - if (f) { - fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data); - pclose(f); - } else - fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH); - } - } -#endif /* XAUTH_PATH */ - - /* Get the last component of the shell name. */ - cp = strrchr(shell, '/'); - if (cp) - cp++; - else - cp = 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) { - if (!options.use_login) { - char buf[256]; - - /* - * Check for mail if we have a tty and it was enabled - * in server options. - */ - if (ttyname && options.check_mail) { - char *mailbox; - struct stat mailstat; - mailbox = getenv("MAIL"); - if (mailbox != NULL) { - if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0) - printf("No mail.\n"); - else if (mailstat.st_mtime < mailstat.st_atime) - printf("You have mail.\n"); - else - printf("You have new mail.\n"); - } - } - /* Start the shell. Set initial character to '-'. */ - buf[0] = '-'; - strncpy(buf + 1, cp, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = 0; - - /* Execute the shell. */ - argv[0] = buf; - argv[1] = NULL; - execve(shell, argv, env); - - /* Executing the shell failed. */ - perror(shell); - exit(1); - - } else { - /* Launch login(1). */ - - execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(), - "-p", "-f", "--", pw->pw_name, NULL); - - /* Login couldn't be executed, die. */ - - perror("login"); - exit(1); - } - } - /* - * Execute the command using the user's shell. This uses the -c - * option to execute the command. - */ - argv[0] = (char *) cp; - 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; - sessions[i].self = i; - } - did_init = 1; - } - for(i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (! s->used) { - s->pid = 0; - s->extended = 0; - s->chanid = -1; - s->ptyfd = -1; - s->ttyfd = -1; - s->term = NULL; - s->pw = NULL; - s->display = NULL; - s->screen = 0; - s->auth_data = NULL; - s->auth_proto = NULL; - s->used = 1; - s->pw = NULL; - debug("session_new: session %d", i); - return s; - } - } - return NULL; -} - -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 %d", - s->used, - s->self, - s, - s->chanid, - s->pid); - } -} - -int -session_open(int chanid) -{ - Session *s = session_new(); - debug("session_open: channel %d", chanid); - if (s == NULL) { - error("no more sessions"); - return 0; - } - s->pw = auth_get_user(); - if (s->pw == NULL) - fatal("no user for session %i", s->self); - debug("session_open: session %d: link with channel %d", s->self, chanid); - s->chanid = chanid; - return 1; -} - -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; -} - -Session * -session_by_pid(pid_t pid) -{ - int i; - debug("session_by_pid: pid %d", 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 %d", pid); - session_dump(); - return NULL; -} - -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_done(); - pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); - return 1; -} - -int -session_pty_req(Session *s) -{ - unsigned int len; - char *term_modes; /* encoded terminal modes */ - - if (s->ttyfd != -1) - return 0; - s->term = packet_get_string(&len); - s->col = packet_get_int(); - s->row = packet_get_int(); - s->xpixel = packet_get_int(); - s->ypixel = packet_get_int(); - term_modes = packet_get_string(&len); - packet_done(); - - if (strcmp(s->term, "") == 0) { - xfree(s->term); - s->term = NULL; - } - /* Allocate a pty and open it. */ - if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { - xfree(s->term); - s->term = NULL; - s->ptyfd = -1; - s->ttyfd = -1; - error("session_pty_req: session %d alloc failed", s->self); - xfree(term_modes); - return 0; - } - debug("session_pty_req: session %d alloc %s", s->self, s->tty); - /* - * 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(pty_cleanup_proc, (void *)s); - pty_setowner(s->pw, s->tty); - /* Get window size from the packet. */ - pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); - - session_proctitle(s); - - /* XXX parse and set terminal modes */ - xfree(term_modes); - return 1; -} - -int -session_subsystem_req(Session *s) -{ - unsigned int len; - int success = 0; - char *subsys = packet_get_string(&len); - - packet_done(); - log("subsystem request for %s", subsys); - - xfree(subsys); - return success; -} - -int -session_x11_req(Session *s) -{ - if (!options.x11_forwarding) { - debug("X11 forwarding disabled in server configuration file."); - return 0; - } - if (xauthfile != NULL) { - debug("X11 fwd already started."); - return 0; - } - - debug("Received request for X11 forwarding with auth spoofing."); - if (s->display != NULL) - packet_disconnect("Protocol error: X11 display already set."); - - 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_done(); - - s->display = x11_create_display_inet(s->screen, options.x11_display_offset); - if (s->display == NULL) { - xfree(s->auth_proto); - xfree(s->auth_data); - return 0; - } - xauthfile = xmalloc(MAXPATHLEN); - strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); - temporarily_use_uid(s->pw->pw_uid); - if (mkdtemp(xauthfile) == NULL) { - restore_uid(); - error("private X11 dir: mkdtemp %s failed: %s", - xauthfile, strerror(errno)); - xfree(xauthfile); - xauthfile = NULL; - xfree(s->auth_proto); - xfree(s->auth_data); - /* XXXX remove listening channels */ - return 0; - } - strlcat(xauthfile, "/cookies", MAXPATHLEN); - open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); - restore_uid(); - fatal_add_cleanup(xauthfile_cleanup_proc, s); - return 1; -} - -void -session_input_channel_req(int id, void *arg) -{ - unsigned int len; - int reply; - int success = 0; - char *rtype; - Session *s; - Channel *c; - - rtype = packet_get_string(&len); - reply = packet_get_char(); - - s = session_by_channel(id); - if (s == NULL) - fatal("session_input_channel_req: channel %d: no session", id); - c = channel_lookup(id); - if (c == NULL) - fatal("session_input_channel_req: channel %d: bad channel", id); - - debug("session_input_channel_req: session %d channel %d request %s reply %d", - s->self, id, rtype, reply); - - /* - * a session is in LARVAL state until a shell - * or programm is executed - */ - if (c->type == SSH_CHANNEL_LARVAL) { - if (strcmp(rtype, "shell") == 0) { - packet_done(); - s->extended = 1; - if (s->ttyfd == -1) - do_exec_no_pty(s, NULL, s->pw); - else - do_exec_pty(s, NULL, s->pw); - success = 1; - } else if (strcmp(rtype, "exec") == 0) { - char *command = packet_get_string(&len); - packet_done(); - s->extended = 1; - if (s->ttyfd == -1) - do_exec_no_pty(s, command, s->pw); - else - do_exec_pty(s, command, s->pw); - xfree(command); - success = 1; - } 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, "subsystem") == 0) { - success = session_subsystem_req(s); - } - } - if (strcmp(rtype, "window-change") == 0) { - success = session_window_change_req(s); - } - - if (reply) { - packet_start(success ? - SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); - packet_put_int(c->remote_id); - packet_send(); - } - xfree(rtype); -} - -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); -} - -void -session_pty_cleanup(Session *s) -{ - if (s == NULL || s->ttyfd == -1) - return; - - debug("session_pty_cleanup: session %i release %s", s->self, s->tty); - - /* Cancel the cleanup function. */ - fatal_remove_cleanup(pty_cleanup_proc, (void *)s); - - /* Record that the user has logged out. */ - record_logout(s->pid, s->tty); - - /* Release the pseudo-tty. */ - 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): %s", strerror(errno)); -} - -void -session_exit_message(Session *s, int status) -{ - Channel *c; - if (s == NULL) - fatal("session_close: no session"); - c = channel_lookup(s->chanid); - if (c == NULL) - fatal("session_close: session %d: no channel %d", - s->self, s->chanid); - debug("session_exit_message: session %d channel %d pid %d", - s->self, s->chanid, 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_int(WTERMSIG(status)); - packet_put_char(WCOREDUMP(status)); - packet_put_cstring(""); - packet_put_cstring(""); - packet_send(); - } else { - /* Some weird exit cause. Just exit. */ - packet_disconnect("wait returned status %04x.", status); - } - - /* 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_free(Session *s) -{ - debug("session_free: session %d pid %d", s->self, s->pid); - if (s->term) - xfree(s->term); - if (s->display) - xfree(s->display); - if (s->auth_data) - xfree(s->auth_data); - if (s->auth_proto) - xfree(s->auth_proto); - s->used = 0; -} - -void -session_close(Session *s) -{ - session_pty_cleanup(s); - session_free(s); - 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 %d", s->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 - */ -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 channel %d", id); - return; - } - /* disconnect channel */ - channel_cancel_cleanup(s->chanid); - s->chanid = -1; - - debug("session_close_by_channel: channel %d kill %d", id, s->pid); - if (s->pid == 0) { - /* close session immediately */ - session_close(s); - } else { - /* notify child, delay session cleanup */ - if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0) - error("session_close_by_channel: kill %d: %s", - s->pid, strerror(errno)); - } -} - -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()); -} - -void -do_authenticated2(void) -{ - /* - * Cancel the alarm we set to limit the time taken for - * authentication. - */ - alarm(0); - server_loop2(); - if (xauthfile) - xauthfile_cleanup_proc(NULL); -} diff --git a/crypto/openssh/session.h b/crypto/openssh/session.h deleted file mode 100644 index a3427bcb0888..000000000000 --- a/crypto/openssh/session.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SESSION_H -#define SESSION_H - -/* SSH1 */ -void do_authenticated(struct passwd * pw); - -/* SSH2 */ -void do_authenticated2(void); -int session_open(int id); -void session_input_channel_req(int id, void *arg); -void session_close_by_pid(pid_t pid, int status); -void session_close_by_channel(int id, void *arg); - -#endif diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1 deleted file mode 100644 index 10363956f8b9..000000000000 --- a/crypto/openssh/ssh-add.1 +++ /dev/null @@ -1,127 +0,0 @@ -.\" -*- nroff -*- -.\" -.\" ssh-add.1 -.\" -.\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" -.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland -.\" All rights reserved -.\" -.\" Created: Sat Apr 22 23:55:14 1995 ylo -.\" -.\" $Id: ssh-add.1,v 1.13 2000/05/03 18:04:38 markus Exp $ -.\" -.Dd September 25, 1999 -.Dt SSH-ADD 1 -.Os -.Sh NAME -.Nm ssh-add -.Nd adds RSA identities for the authentication agent -.Sh SYNOPSIS -.Nm ssh-add -.Op Fl lLdD -.Op Ar -.Sh DESCRIPTION -.Nm -adds RSA identities to the authentication agent, -.Xr ssh-agent 1 . -When run without arguments, it adds the file -.Pa $HOME/.ssh/identity . -Alternative file names can be given on the command line. -If any file requires a passphrase, -.Nm -asks for the passphrase from the user. -The Passphrase it is read from the user's tty. -.Pp -The authentication agent must be running and must be an ancestor of -the current process for -.Nm -to work. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl l -Lists fingerprints of all identities currently represented by the agent. -.It Fl L -Lists public key parameters of all identities currently represented by the agent. -.It Fl d -Instead of adding the identity, removes the identity from the agent. -.It Fl D -Deletes all identities from the agent. -.El -.Sh FILES -.Bl -tag -width Ds -.It Pa $HOME/.ssh/identity -Contains the RSA authentication identity of the user. -This file should not be readable by anyone but the user. -Note that -.Nm -ignores this file if it is accessible by others. -It is possible to -specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file. -This is the default file added by -.Nm -when no other files have been specified. -.Pp -.Sh ENVIRONMENT -.Bl -tag -width Ds -.It Ev "DISPLAY" and "SSH_ASKPASS" -If -.Nm -needs a passphrase, it will read the passphrase from the current -terminal if it was run from a terminal. -If -.Nm -does not have a terminal associated with it but -.Ev DISPLAY -and -.Ev SSH_ASKPASS -are set, it will execute the program specified by -.Ev SSH_ASKPASS -and open an X11 window to read the passphrase. -This is particularly useful when calling -.Nm -from a -.Pa .Xsession -or related script. -(Note that on some machines it -may be necessary to redirect the input from -.Pa /dev/null -to make this work.) -.Sh AUTHOR -Tatu Ylonen <ylo@cs.hut.fi> -.Pp -OpenSSH -is a derivative of the original (free) ssh 1.2.12 release, but with bugs -removed and newer features re-added. -Rapidly after the 1.2.12 release, -newer versions bore successively more restrictive licenses. -This version of OpenSSH -.Bl -bullet -.It -has all components of a restrictive nature (i.e., patents, see -.Xr ssl 8 ) -directly removed from the source code; any licensed or patented components -are chosen from -external libraries. -.It -has been updated to support ssh protocol 1.5. -.It -contains added support for -.Xr kerberos 8 -authentication and ticket passing. -.It -supports one-time password authentication with -.Xr skey 1 . -.El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. -.Sh SEE ALSO -.Xr ssh 1 , -.Xr ssh-agent 1 , -.Xr ssh-keygen 1 , -.Xr sshd 8 , -.Xr ssl 8 diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c deleted file mode 100644 index b7a385c171d4..000000000000 --- a/crypto/openssh/ssh-add.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Thu Apr 6 00:52:24 1995 ylo - * Adds an identity to the authentication server, or removes an identity. - */ - -#include "includes.h" -RCSID("$Id: ssh-add.c,v 1.16 2000/04/26 20:56:29 markus Exp $"); - -#include <openssl/rsa.h> -#include <openssl/dsa.h> - -#include "rsa.h" -#include "ssh.h" -#include "xmalloc.h" -#include "authfd.h" -#include "fingerprint.h" -#include "key.h" -#include "authfile.h" - -void -delete_file(AuthenticationConnection *ac, const char *filename) -{ - Key *public; - char *comment; - - public = key_new(KEY_RSA); - if (!load_public_key(filename, public, &comment)) { - printf("Bad key file %s: %s\n", filename, strerror(errno)); - return; - } - if (ssh_remove_identity(ac, public->rsa)) - fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); - else - fprintf(stderr, "Could not remove identity: %s\n", filename); - key_free(public); - xfree(comment); -} - -void -delete_all(AuthenticationConnection *ac) -{ - /* Send a request to remove all identities. */ - if (ssh_remove_all_identities(ac)) - fprintf(stderr, "All identities removed.\n"); - else - fprintf(stderr, "Failed to remove all identitities.\n"); -} - -char * -ssh_askpass(char *askpass, char *msg) -{ - pid_t pid; - size_t len; - char *nl, *pass; - int p[2], status; - char buf[1024]; - - if (askpass == NULL) - fatal("internal error: askpass undefined"); - if (pipe(p) < 0) - fatal("ssh_askpass: pipe: %s", strerror(errno)); - if ((pid = fork()) < 0) - fatal("ssh_askpass: fork: %s", strerror(errno)); - if (pid == 0) { - 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 = read(p[0], buf, sizeof buf); - close(p[0]); - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - break; - if (len <= 1) - return xstrdup(""); - nl = strchr(buf, '\n'); - if (nl) - *nl = '\0'; - pass = xstrdup(buf); - memset(buf, 0, sizeof(buf)); - return pass; -} - -void -add_file(AuthenticationConnection *ac, const char *filename) -{ - Key *public; - Key *private; - char *saved_comment, *comment, *askpass = NULL; - char buf[1024], msg[1024]; - int success; - int interactive = isatty(STDIN_FILENO); - - public = key_new(KEY_RSA); - if (!load_public_key(filename, public, &saved_comment)) { - printf("Bad key file %s: %s\n", filename, strerror(errno)); - return; - } - key_free(public); - - if (!interactive && getenv("DISPLAY")) { - if (getenv(SSH_ASKPASS_ENV)) - askpass = getenv(SSH_ASKPASS_ENV); - else - askpass = SSH_ASKPASS_DEFAULT; - } - - /* At first, try empty passphrase */ - private = key_new(KEY_RSA); - success = load_private_key(filename, "", private, &comment); - if (!success) { - printf("Need passphrase for %.200s\n", filename); - if (!interactive && askpass == NULL) { - xfree(saved_comment); - return; - } - snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment); - for (;;) { - char *pass; - if (interactive) { - snprintf(buf, sizeof buf, "%s: ", msg); - pass = read_passphrase(buf, 1); - } else { - pass = ssh_askpass(askpass, msg); - } - if (strcmp(pass, "") == 0) { - xfree(pass); - xfree(saved_comment); - return; - } - success = load_private_key(filename, pass, private, &comment); - memset(pass, 0, strlen(pass)); - xfree(pass); - if (success) - break; - strlcpy(msg, "Bad passphrase, try again", sizeof msg); - } - } - xfree(saved_comment); - - if (ssh_add_identity(ac, private->rsa, comment)) - fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); - else - fprintf(stderr, "Could not add identity: %s\n", filename); - key_free(private); - xfree(comment); -} - -void -list_identities(AuthenticationConnection *ac, int fp) -{ - BIGNUM *e, *n; - int status; - char *comment; - int had_identities; - - e = BN_new(); - n = BN_new(); - had_identities = 0; - for (status = ssh_get_first_identity(ac, e, n, &comment); - status; - status = ssh_get_next_identity(ac, e, n, &comment)) { - unsigned int bits = BN_num_bits(n); - had_identities = 1; - if (fp) { - printf("%d %s %s\n", bits, fingerprint(e, n), comment); - } else { - char *ebuf, *nbuf; - ebuf = BN_bn2dec(e); - if (ebuf == NULL) { - error("list_identities: BN_bn2dec(e) failed."); - } else { - nbuf = BN_bn2dec(n); - if (nbuf == NULL) { - error("list_identities: BN_bn2dec(n) failed."); - } else { - printf("%d %s %s %s\n", bits, ebuf, nbuf, comment); - free(nbuf); - } - free(ebuf); - } - } - xfree(comment); - } - BN_clear_free(e); - BN_clear_free(n); - if (!had_identities) - printf("The agent has no identities.\n"); -} - -int -main(int argc, char **argv) -{ - AuthenticationConnection *ac = NULL; - struct passwd *pw; - char buf[1024]; - int no_files = 1; - int i; - int deleting = 0; - - /* check if RSA support exists */ - if (rsa_alive() == 0) { - extern char *__progname; - - fprintf(stderr, - "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", - __progname); - exit(1); - } - /* At first, get a connection to the authentication agent. */ - ac = ssh_get_authentication_connection(); - if (ac == NULL) { - fprintf(stderr, "Could not open a connection to your authentication agent.\n"); - exit(1); - } - for (i = 1; i < argc; i++) { - if ((strcmp(argv[i], "-l") == 0) || - (strcmp(argv[i], "-L") == 0)) { - list_identities(ac, argv[i][1] == 'l' ? 1 : 0); - /* Don't default-add/delete if -l. */ - no_files = 0; - continue; - } - if (strcmp(argv[i], "-d") == 0) { - deleting = 1; - continue; - } - if (strcmp(argv[i], "-D") == 0) { - delete_all(ac); - no_files = 0; - continue; - } - no_files = 0; - if (deleting) - delete_file(ac, argv[i]); - else - add_file(ac, argv[i]); - } - if (no_files) { - pw = getpwuid(getuid()); - if (!pw) { - fprintf(stderr, "No user found with uid %d\n", (int) getuid()); - ssh_close_authentication_connection(ac); - exit(1); - } - snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY); - if (deleting) - delete_file(ac, buf); - else - add_file(ac, buf); - } - ssh_close_authentication_connection(ac); - exit(0); -} diff --git a/crypto/openssh/ssh-add/Makefile b/crypto/openssh/ssh-add/Makefile deleted file mode 100644 index 5451e7d31b97..000000000000 --- a/crypto/openssh/ssh-add/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -.PATH: ${.CURDIR}/.. - -PROG= ssh-add -BINOWN= root - -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else -BINMODE?=555 -.endif - -BINDIR= /usr/bin -MAN= ssh-add.1 - -SRCS= ssh-add.c log-client.c - -.include <bsd.prog.mk> - -LDADD+= -lcrypto -lutil -lz -DPADD+= ${LIBCRYPTO} ${LIBDES} ${LIBUTIL} ${LIBZ} diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1 deleted file mode 100644 index 9f7299d3719e..000000000000 --- a/crypto/openssh/ssh-agent.1 +++ /dev/null @@ -1,171 +0,0 @@ -.\" $OpenBSD: ssh-agent.1,v 1.12 2000/05/03 18:04:39 markus Exp $ -.\" -.\" -*- nroff -*- -.\" -.\" ssh-agent.1 -.\" -.\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" -.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland -.\" All rights reserved -.\" -.\" Created: Sat Apr 23 20:10:43 1995 ylo -.\" -.Dd September 25, 1999 -.Dt SSH-AGENT 1 -.Os -.Sh NAME -.Nm ssh-agent -.Nd authentication agent -.Sh SYNOPSIS -.Nm ssh-agent -.Op Fl c Li | Fl s -.Op Fl k -.Oo -.Ar command -.Op Ar args ... -.Oc -.Sh DESCRIPTION -.Nm -is a program to hold private keys used for RSA authentication. -The idea is that -.Nm -is started in the beginning of an X-session or a login session, and -all other windows or programs are started as clients to the ssh-agent -program. -Through use of environment variables the agent can be located -and automatically used for RSA authentication when logging in to other -machines using -.Xr ssh 1 . -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl c -Generate C-shell commands on -.Dv stdout . -This is the default if -.Ev SHELL -looks like it's a csh style of shell. -.It Fl s -Generate Bourne shell commands on -.Dv stdout . -This is the default if -.Ev SHELL -does not look like it's a csh style of shell. -.It Fl k -Kill the current agent (given by the -.Ev SSH_AGENT_PID -environment variable). -.El -.Pp -If a commandline is given, this is executed as a subprocess of the agent. -When the command dies, so does the agent. -.Pp -The agent initially does not have any private keys. -Keys are added using -.Xr ssh-add 1 . -When executed without arguments, -.Xr ssh-add 1 -adds the -.Pa $HOME/.ssh/identity -file. -If the identity has a passphrase, -.Xr ssh-add 1 -asks for the passphrase (using a small X11 application if running -under X11, or from the terminal if running without X). -It then sends the identity to the agent. -Several identities can be stored in the -agent; the agent can automatically use any of these identities. -.Ic ssh-add -l -displays the identities currently held by the agent. -.Pp -The idea is that the agent is run in the user's local PC, laptop, or -terminal. -Authentication data need not be stored on any other -machine, and authentication passphrases never go over the network. -However, the connection to the agent is forwarded over SSH -remote logins, and the user can thus use the privileges given by the -identities anywhere in the network in a secure way. -.Pp -There are two main ways to get an agent setup: -Either you let the agent -start a new subcommand into which some environment variables are exported, or -you let the agent print the needed shell commands (either -.Xr sh 1 -or -.Xr csh 1 -syntax can be generated) which can be evalled in the calling shell. -Later -.Xr ssh 1 -look at these variables and use them to establish a connection to the agent. -.Pp -A unix-domain socket is created -.Pq Pa /tmp/ssh-XXXXXXXX/agent.<pid> , -and the name of this socket is stored in the -.Ev SSH_AUTH_SOCK -environment -variable. -The socket is made accessible only to the current user. -This method is easily abused by root or another instance of the same -user. -.Pp -The -.Ev SSH_AGENT_PID -environment variable holds the agent's PID. -.Pp -The agent exits automatically when the command given on the command -line terminates. -.Sh FILES -.Bl -tag -width Ds -.It Pa $HOME/.ssh/identity -Contains the RSA authentication identity of the user. -This file should not be readable by anyone but the user. -It is possible to -specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file. -This file is not used by -.Nm -but is normally added to the agent using -.Xr ssh-add 1 -at login time. -.It Pa /tmp/ssh-XXXX/agent.<pid> , -Unix-domain sockets used to contain the connection to the -authentication agent. -These sockets should only be readable by the owner. -The sockets should get automatically removed when the agent exits. -.Sh AUTHOR -Tatu Ylonen <ylo@cs.hut.fi> -.Pp -OpenSSH -is a derivative of the original (free) ssh 1.2.12 release, but with bugs -removed and newer features re-added. -Rapidly after the 1.2.12 release, -newer versions bore successively more restrictive licenses. -This version of OpenSSH -.Bl -bullet -.It -has all components of a restrictive nature (i.e., patents, see -.Xr ssl 8 ) -directly removed from the source code; any licensed or patented components -are chosen from -external libraries. -.It -has been updated to support ssh protocol 1.5. -.It -contains added support for -.Xr kerberos 8 -authentication and ticket passing. -.It -supports one-time password authentication with -.Xr skey 1 . -.El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. -.Sh SEE ALSO -.Xr ssh 1 , -.Xr ssh-add 1 , -.Xr ssh-keygen 1 , -.Xr sshd 8 , -.Xr ssl 8 diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c deleted file mode 100644 index 18f1315fc4dd..000000000000 --- a/crypto/openssh/ssh-agent.c +++ /dev/null @@ -1,659 +0,0 @@ -/* $OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $ */ - -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Wed Mar 29 03:46:59 1995 ylo - * The authentication agent program. - */ - -#include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $"); - -#include "ssh.h" -#include "rsa.h" -#include "authfd.h" -#include "buffer.h" -#include "bufaux.h" -#include "xmalloc.h" -#include "packet.h" -#include "getput.h" -#include "mpaux.h" - -#include <openssl/md5.h> - -typedef struct { - int fd; - enum { - AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION - } type; - Buffer input; - Buffer output; -} SocketEntry; - -unsigned int sockets_alloc = 0; -SocketEntry *sockets = NULL; - -typedef struct { - RSA *key; - char *comment; -} Identity; - -unsigned int num_identities = 0; -Identity *identities = NULL; - -int max_fd = 0; - -/* pid of shell == parent of agent */ -pid_t parent_pid = -1; - -/* pathname and directory for AUTH_SOCKET */ -char socket_name[1024]; -char socket_dir[1024]; - -extern char *__progname; - -void -process_request_identity(SocketEntry *e) -{ - Buffer msg; - int i; - - buffer_init(&msg); - buffer_put_char(&msg, SSH_AGENT_RSA_IDENTITIES_ANSWER); - buffer_put_int(&msg, num_identities); - for (i = 0; i < num_identities; i++) { - buffer_put_int(&msg, BN_num_bits(identities[i].key->n)); - buffer_put_bignum(&msg, identities[i].key->e); - buffer_put_bignum(&msg, identities[i].key->n); - buffer_put_string(&msg, identities[i].comment, - strlen(identities[i].comment)); - } - buffer_put_int(&e->output, buffer_len(&msg)); - buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); - buffer_free(&msg); -} - -void -process_authentication_challenge(SocketEntry *e) -{ - int i, pub_bits, len; - BIGNUM *pub_e, *pub_n, *challenge; - Buffer msg; - MD5_CTX md; - unsigned char buf[32], mdbuf[16], session_id[16]; - unsigned int response_type; - - buffer_init(&msg); - pub_e = BN_new(); - pub_n = BN_new(); - challenge = BN_new(); - pub_bits = buffer_get_int(&e->input); - buffer_get_bignum(&e->input, pub_e); - buffer_get_bignum(&e->input, pub_n); - buffer_get_bignum(&e->input, challenge); - if (buffer_len(&e->input) == 0) { - /* Compatibility code for old servers. */ - memset(session_id, 0, 16); - response_type = 0; - } else { - /* New code. */ - buffer_get(&e->input, (char *) session_id, 16); - response_type = buffer_get_int(&e->input); - } - for (i = 0; i < num_identities; i++) - if (pub_bits == BN_num_bits(identities[i].key->n) && - BN_cmp(pub_e, identities[i].key->e) == 0 && - BN_cmp(pub_n, identities[i].key->n) == 0) { - /* Decrypt the challenge using the private key. */ - rsa_private_decrypt(challenge, challenge, identities[i].key); - - /* Compute the desired response. */ - switch (response_type) { - case 0:/* As of protocol 1.0 */ - /* This response type is no longer supported. */ - log("Compatibility with ssh protocol 1.0 no longer supported."); - buffer_put_char(&msg, SSH_AGENT_FAILURE); - goto send; - - case 1:/* As of protocol 1.1 */ - /* The response is MD5 of decrypted challenge plus session id. */ - len = BN_num_bytes(challenge); - - if (len <= 0 || len > 32) { - fatal("process_authentication_challenge: " - "bad challenge length %d", len); - } - memset(buf, 0, 32); - BN_bn2bin(challenge, buf + 32 - len); - MD5_Init(&md); - MD5_Update(&md, buf, 32); - MD5_Update(&md, session_id, 16); - MD5_Final(mdbuf, &md); - break; - - default: - fatal("process_authentication_challenge: bad response_type %d", - response_type); - break; - } - - /* Send the response. */ - buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); - for (i = 0; i < 16; i++) - buffer_put_char(&msg, mdbuf[i]); - - goto send; - } - /* Unknown identity. 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)); - buffer_free(&msg); - BN_clear_free(pub_e); - BN_clear_free(pub_n); - BN_clear_free(challenge); -} - -void -process_remove_identity(SocketEntry *e) -{ - unsigned int bits; - unsigned int i; - BIGNUM *dummy, *n; - - dummy = BN_new(); - n = BN_new(); - - /* Get the key from the packet. */ - bits = buffer_get_int(&e->input); - buffer_get_bignum(&e->input, dummy); - buffer_get_bignum(&e->input, n); - - if (bits != BN_num_bits(n)) - log("Warning: identity keysize mismatch: actual %d, announced %d", - BN_num_bits(n), bits); - - /* Check if we have the key. */ - for (i = 0; i < num_identities; i++) - if (BN_cmp(identities[i].key->n, n) == 0) { - /* - * We have this key. Free the old key. Since we - * don\'t want to leave empty slots in the middle of - * the array, we actually free the key there and copy - * data from the last entry. - */ - RSA_free(identities[i].key); - xfree(identities[i].comment); - if (i < num_identities - 1) - identities[i] = identities[num_identities - 1]; - num_identities--; - BN_clear_free(dummy); - BN_clear_free(n); - - /* Send success. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); - return; - } - /* We did not have the key. */ - BN_clear(dummy); - BN_clear(n); - - /* Send failure. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_FAILURE); -} - -/* - * Removes all identities from the agent. - */ -void -process_remove_all_identities(SocketEntry *e) -{ - unsigned int i; - - /* Loop over all identities and clear the keys. */ - for (i = 0; i < num_identities; i++) { - RSA_free(identities[i].key); - xfree(identities[i].comment); - } - - /* Mark that there are no identities. */ - num_identities = 0; - - /* Send success. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); - return; -} - -/* - * Adds an identity to the agent. - */ -void -process_add_identity(SocketEntry *e) -{ - RSA *k; - int i; - BIGNUM *aux; - BN_CTX *ctx; - - if (num_identities == 0) - identities = xmalloc(sizeof(Identity)); - else - identities = xrealloc(identities, (num_identities + 1) * sizeof(Identity)); - - identities[num_identities].key = RSA_new(); - k = identities[num_identities].key; - buffer_get_int(&e->input); /* bits */ - k->n = BN_new(); - buffer_get_bignum(&e->input, k->n); - k->e = BN_new(); - buffer_get_bignum(&e->input, k->e); - k->d = BN_new(); - buffer_get_bignum(&e->input, k->d); - k->iqmp = BN_new(); - buffer_get_bignum(&e->input, k->iqmp); - /* SSH and SSL have p and q swapped */ - k->q = BN_new(); - buffer_get_bignum(&e->input, k->q); /* p */ - k->p = BN_new(); - buffer_get_bignum(&e->input, k->p); /* q */ - - /* Generate additional parameters */ - aux = BN_new(); - ctx = BN_CTX_new(); - - BN_sub(aux, k->q, BN_value_one()); - k->dmq1 = BN_new(); - BN_mod(k->dmq1, k->d, aux, ctx); - - BN_sub(aux, k->p, BN_value_one()); - k->dmp1 = BN_new(); - BN_mod(k->dmp1, k->d, aux, ctx); - - BN_clear_free(aux); - BN_CTX_free(ctx); - - identities[num_identities].comment = buffer_get_string(&e->input, NULL); - - /* Check if we already have the key. */ - for (i = 0; i < num_identities; i++) - if (BN_cmp(identities[i].key->n, k->n) == 0) { - /* - * We already have this key. Clear and free the new - * data and return success. - */ - RSA_free(k); - xfree(identities[num_identities].comment); - - /* Send success. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); - return; - } - /* Increment the number of identities. */ - num_identities++; - - /* Send a success message. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); -} - -void -process_message(SocketEntry *e) -{ - unsigned int msg_len; - unsigned int type; - unsigned char *cp; - if (buffer_len(&e->input) < 5) - return; /* Incomplete message. */ - cp = (unsigned char *) buffer_ptr(&e->input); - msg_len = GET_32BIT(cp); - if (msg_len > 256 * 1024) { - shutdown(e->fd, SHUT_RDWR); - close(e->fd); - e->type = AUTH_UNUSED; - return; - } - if (buffer_len(&e->input) < msg_len + 4) - return; - buffer_consume(&e->input, 4); - type = buffer_get_char(&e->input); - - switch (type) { - case SSH_AGENTC_REQUEST_RSA_IDENTITIES: - process_request_identity(e); - break; - case SSH_AGENTC_RSA_CHALLENGE: - process_authentication_challenge(e); - break; - case SSH_AGENTC_ADD_RSA_IDENTITY: - process_add_identity(e); - break; - case SSH_AGENTC_REMOVE_RSA_IDENTITY: - process_remove_identity(e); - break; - case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: - process_remove_all_identities(e); - break; - default: - /* Unknown message. Respond with failure. */ - error("Unknown message %d", type); - buffer_clear(&e->input); - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_FAILURE); - break; - } -} - -void -new_socket(int type, int fd) -{ - unsigned int i, old_alloc; - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) - error("fcntl O_NONBLOCK: %s", strerror(errno)); - - if (fd > max_fd) - max_fd = fd; - - for (i = 0; i < sockets_alloc; i++) - if (sockets[i].type == AUTH_UNUSED) { - sockets[i].fd = fd; - sockets[i].type = type; - buffer_init(&sockets[i].input); - buffer_init(&sockets[i].output); - return; - } - old_alloc = sockets_alloc; - sockets_alloc += 10; - if (sockets) - sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0])); - else - sockets = xmalloc(sockets_alloc * sizeof(sockets[0])); - for (i = old_alloc; i < sockets_alloc; i++) - sockets[i].type = AUTH_UNUSED; - sockets[old_alloc].type = type; - sockets[old_alloc].fd = fd; - buffer_init(&sockets[old_alloc].input); - buffer_init(&sockets[old_alloc].output); -} - -void -prepare_select(fd_set *readset, fd_set *writeset) -{ - unsigned int i; - for (i = 0; i < sockets_alloc; i++) - switch (sockets[i].type) { - case AUTH_SOCKET: - case AUTH_CONNECTION: - FD_SET(sockets[i].fd, readset); - if (buffer_len(&sockets[i].output) > 0) - FD_SET(sockets[i].fd, writeset); - break; - case AUTH_UNUSED: - break; - default: - fatal("Unknown socket type %d", sockets[i].type); - break; - } -} - -void -after_select(fd_set *readset, fd_set *writeset) -{ - unsigned int i; - int len, sock; - socklen_t slen; - char buf[1024]; - struct sockaddr_un sunaddr; - - 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) { - perror("accept from AUTH_SOCKET"); - break; - } - new_socket(AUTH_CONNECTION, sock); - } - break; - case AUTH_CONNECTION: - if (buffer_len(&sockets[i].output) > 0 && - FD_ISSET(sockets[i].fd, writeset)) { - len = write(sockets[i].fd, buffer_ptr(&sockets[i].output), - buffer_len(&sockets[i].output)); - if (len <= 0) { - shutdown(sockets[i].fd, SHUT_RDWR); - close(sockets[i].fd); - sockets[i].type = AUTH_UNUSED; - buffer_free(&sockets[i].input); - buffer_free(&sockets[i].output); - break; - } - buffer_consume(&sockets[i].output, len); - } - if (FD_ISSET(sockets[i].fd, readset)) { - len = read(sockets[i].fd, buf, sizeof(buf)); - if (len <= 0) { - shutdown(sockets[i].fd, SHUT_RDWR); - close(sockets[i].fd); - sockets[i].type = AUTH_UNUSED; - buffer_free(&sockets[i].input); - buffer_free(&sockets[i].output); - break; - } - buffer_append(&sockets[i].input, buf, len); - process_message(&sockets[i]); - } - break; - default: - fatal("Unknown type %d", sockets[i].type); - } -} - -void -check_parent_exists(int sig) -{ - if (parent_pid != -1 && kill(parent_pid, 0) < 0) { - /* printf("Parent has died - Authentication agent exiting.\n"); */ - exit(1); - } - signal(SIGALRM, check_parent_exists); - alarm(10); -} - -void -cleanup_socket(void) -{ - remove(socket_name); - rmdir(socket_dir); -} - -void -cleanup_exit(int i) -{ - cleanup_socket(); - exit(i); -} - -void -usage() -{ - fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION); - fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n", - __progname); - exit(1); -} - -int -main(int ac, char **av) -{ - fd_set readset, writeset; - int sock, c_flag = 0, k_flag = 0, s_flag = 0, ch; - struct sockaddr_un sunaddr; - pid_t pid; - char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid]; - - /* check if RSA support exists */ - if (rsa_alive() == 0) { - fprintf(stderr, - "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", - __progname); - exit(1); - } - while ((ch = getopt(ac, av, "cks")) != -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; - default: - usage(); - } - } - ac -= optind; - av += optind; - - if (ac > 0 && (c_flag || k_flag || s_flag)) - usage(); - - if (ac == 0 && !c_flag && !k_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, "%s not set, cannot kill agent\n", - SSH_AGENTPID_ENV_NAME); - exit(1); - } - pid = atoi(pidstr); - if (pid < 1) { /* XXX PID_MAX check too */ - /* Yes, PID_MAX check please */ - fprintf(stderr, "%s=\"%s\", which is not a good PID\n", - SSH_AGENTPID_ENV_NAME, pidstr); - 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 Agent pid %d killed;\n", pid); - exit(0); - } - parent_pid = getpid(); - - /* Create private directory for agent socket */ - strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir); - if (mkdtemp(socket_dir) == NULL) { - perror("mkdtemp: private socket dir"); - exit(1); - } - snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir, - parent_pid); - - /* - * 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"); - cleanup_exit(1); - } - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); - if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { - perror("bind"); - cleanup_exit(1); - } - if (listen(sock, 5) < 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. - */ - pid = fork(); - if (pid == -1) { - perror("fork"); - exit(1); - } - if (pid != 0) { /* Parent - execute the given command. */ - close(sock); - snprintf(pidstrbuf, sizeof pidstrbuf, "%d", 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 Agent pid %d;\n", pid); - exit(0); - } - setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1); - setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1); - execvp(av[0], av); - perror(av[0]); - exit(1); - } - close(0); - close(1); - close(2); - - if (setsid() == -1) { - perror("setsid"); - cleanup_exit(1); - } - if (atexit(cleanup_socket) < 0) { - perror("atexit"); - cleanup_exit(1); - } - new_socket(AUTH_SOCKET, sock); - if (ac > 0) { - signal(SIGALRM, check_parent_exists); - alarm(10); - } - signal(SIGINT, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, cleanup_exit); - signal(SIGTERM, cleanup_exit); - while (1) { - FD_ZERO(&readset); - FD_ZERO(&writeset); - prepare_select(&readset, &writeset); - if (select(max_fd + 1, &readset, &writeset, NULL, NULL) < 0) { - if (errno == EINTR) - continue; - exit(1); - } - after_select(&readset, &writeset); - } - /* NOTREACHED */ -} diff --git a/crypto/openssh/ssh-agent/Makefile b/crypto/openssh/ssh-agent/Makefile deleted file mode 100644 index ba78521f5cdc..000000000000 --- a/crypto/openssh/ssh-agent/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -.PATH: ${.CURDIR}/.. - -PROG= ssh-agent -BINOWN= root - -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else -BINMODE?=555 -.endif - -BINDIR= /usr/bin -MAN= ssh-agent.1 - -SRCS= ssh-agent.c log-client.c - -.include <bsd.prog.mk> - -LDADD+= -lcrypto -lutil -lz -DPADD+= ${LIBCRYPTO} ${LIBDES} ${LIBUTIL} ${LIBZ} diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1 deleted file mode 100644 index ea81532e9879..000000000000 --- a/crypto/openssh/ssh-keygen.1 +++ /dev/null @@ -1,226 +0,0 @@ -.\" -*- nroff -*- -.\" -.\" ssh-keygen.1 -.\" -.\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" -.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland -.\" All rights reserved -.\" -.\" Created: Sat Apr 22 23:55:14 1995 ylo -.\" -.\" $Id: ssh-keygen.1,v 1.18 2000/05/08 17:26:04 hugh Exp $ -.\" -.Dd September 25, 1999 -.Dt SSH-KEYGEN 1 -.Os -.Sh NAME -.Nm ssh-keygen -.Nd authentication key generation -.Sh SYNOPSIS -.Nm ssh-keygen -.Op Fl dq -.Op Fl b Ar bits -.Op Fl N Ar new_passphrase -.Op Fl C Ar comment -.Op Fl f Ar keyfile -.Nm ssh-keygen -.Fl p -.Op Fl P Ar old_passphrase -.Op Fl N Ar new_passphrase -.Op Fl f Ar keyfile -.Nm ssh-keygen -.Fl x -.Op Fl f Ar keyfile -.Nm ssh-keygen -.Fl X -.Op Fl f Ar keyfile -.Nm ssh-keygen -.Fl y -.Op Fl f Ar keyfile -.Nm ssh-keygen -.Fl c -.Op Fl P Ar passphrase -.Op Fl C Ar comment -.Op Fl f Ar keyfile -.Nm ssh-keygen -.Fl l -.Op Fl f Ar keyfile -.Nm ssh-keygen -.Fl R -.Sh DESCRIPTION -.Nm -generates and manages authentication keys for -.Xr ssh 1 . -.Nm -defaults to generating an RSA key for use by protocols 1.3 and 1.5; -specifying the -.Fl d -flag will create a DSA key instead for use by protocol 2.0. -.Pp -Normally each user wishing to use SSH -with RSA or DSA authentication runs this once to create the authentication -key in -.Pa $HOME/.ssh/identity -or -.Pa $HOME/.ssh/id_dsa . -Additionally, the system administrator may use this to generate host keys, -as seen in -.Pa /etc/rc . -.Pp -Normally this program generates the key and asks for a file in which -to store the private key. -The public key is stored in a file with the same name but -.Dq .pub -appended. -The program also asks for a passphrase. -The passphrase may be empty to indicate no passphrase -(host keys must have empty passphrase), or it may be a string of -arbitrary length. -Good passphrases are 10-30 characters long and are -not simple sentences or otherwise easily guessable (English -prose has only 1-2 bits of entropy per word, and provides very bad -passphrases). -The passphrase can be changed later by using the -.Fl p -option. -.Pp -There is no way to recover a lost passphrase. -If the passphrase is -lost or forgotten, you will have to generate a new key and copy the -corresponding public key to other machines. -.Pp -For RSA, there is also a comment field in the key file that is only for -convenience to the user to help identify the key. -The comment can tell what the key is for, or whatever is useful. -The comment is initialized to -.Dq user@host -when the key is created, but can be changed using the -.Fl c -option. -.Pp -After a key is generated, instructions below detail where the keys -should be placed to be activated. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl b Ar bits -Specifies the number of bits in the key to create. -Minimum is 512 bits. -Generally 1024 bits is considered sufficient, and key sizes -above that no longer improve security but make things slower. -The default is 1024 bits. -.It Fl c -Requests changing the comment in the private and public key files. -The program will prompt for the file containing the private keys, for -passphrase if the key has one, and for the new comment. -.It Fl f -Specifies the filename of the key file. -.It Fl l -Show fingerprint of specified private or public key file. -.It Fl p -Requests changing the passphrase of a private key file instead of -creating a new private key. -The program will prompt for the file -containing the private key, for the old passphrase, and twice for the -new passphrase. -.It Fl q -Silence -.Nm ssh-keygen . -Used by -.Pa /etc/rc -when creating a new key. -.It Fl C Ar comment -Provides the new comment. -.It Fl N Ar new_passphrase -Provides the new passphrase. -.It Fl P Ar passphrase -Provides the (old) passphrase. -.It Fl R -If RSA support is functional, immediately exits with code 0. If RSA -support is not functional, exits with code 1. This flag will be -removed once the RSA patent expires. -.It Fl x -This option will read a private -OpenSSH DSA format file and print a SSH2-compatible public key to stdout. -.It Fl X -This option will read a -SSH2-compatible public key file and print an OpenSSH DSA compatible public key to stdout. -.It Fl y -This option will read a private -OpenSSH DSA format file and print an OpenSSH DSA public key to stdout. -.El -.Sh FILES -.Bl -tag -width Ds -.It Pa $HOME/.ssh/identity -Contains the RSA authentication identity of the user. -This file should not be readable by anyone but the user. -It is possible to -specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file using 3DES. -This file is not automatically accessed by -.Nm -but it is offered as the default file for the private key. -.Xr sshd 8 -will read this file when a login attempt is made. -.It Pa $HOME/.ssh/identity.pub -Contains the public key for authentication. -The contents of this file should be added to -.Pa $HOME/.ssh/authorized_keys -on all machines -where you wish to log in using RSA authentication. -There is no need to keep the contents of this file secret. -.It Pa $HOME/.ssh/id_dsa -Contains the DSA authentication identity of the user. -This file should not be readable by anyone but the user. -It is possible to -specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file using 3DES. -This file is not automatically accessed by -.Nm -but it is offered as the default file for the private key. -.Xr sshd 8 -will read this file when a login attempt is made. -.It Pa $HOME/.ssh/id_dsa.pub -Contains the public key for authentication. -The contents of this file should be added to -.Pa $HOME/.ssh/authorized_keys2 -on all machines -where you wish to log in using DSA authentication. -There is no need to keep the contents of this file secret. -.Sh AUTHOR -Tatu Ylonen <ylo@cs.hut.fi> -.Pp -OpenSSH -is a derivative of the original (free) ssh 1.2.12 release, but with bugs -removed and newer features re-added. -Rapidly after the 1.2.12 release, -newer versions bore successively more restrictive licenses. -This version of OpenSSH -.Bl -bullet -.It -has all components of a restrictive nature (i.e., patents, see -.Xr ssl 8 ) -directly removed from the source code; any licensed or patented components -are chosen from -external libraries. -.It -has been updated to support ssh protocol 1.5. -.It -contains added support for -.Xr kerberos 8 -authentication and ticket passing. -.It -supports one-time password authentication with -.Xr skey 1 . -.El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. -.Sh SEE ALSO -.Xr ssh 1 , -.Xr ssh-add 1 , -.Xr ssh-agent 1 , -.Xr sshd 8 , -.Xr ssl 8 diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c deleted file mode 100644 index 9129c70a8ec8..000000000000 --- a/crypto/openssh/ssh-keygen.c +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Mon Mar 27 02:26:40 1995 ylo - * Identity and host key generation and maintenance. - */ - -#include "includes.h" -RCSID("$Id: ssh-keygen.c,v 1.25 2000/05/08 18:23:07 markus Exp $"); - -#include <openssl/evp.h> -#include <openssl/pem.h> -#include <openssl/rsa.h> -#include <openssl/dsa.h> - -#include "ssh.h" -#include "xmalloc.h" -#include "fingerprint.h" -#include "key.h" -#include "rsa.h" -#include "dsa.h" -#include "authfile.h" -#include "uuencode.h" - -/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ -int bits = 1024; - -/* - * 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 just want to see the key fingerprint */ -int print_fingerprint = 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; - -/* Dump public key file in format used by real and the original SSH 2 */ -int convert_to_ssh2 = 0; -int convert_from_ssh2 = 0; -int print_public = 0; -int dsa_mode = 0; - -/* argv0 */ -extern char *__progname; - -char hostname[MAXHOSTNAMELEN]; - -void -ask_filename(struct passwd *pw, const char *prompt) -{ - char buf[1024]; - snprintf(identity_file, sizeof(identity_file), "%s/%s", - pw->pw_dir, - dsa_mode ? SSH_CLIENT_ID_DSA: SSH_CLIENT_IDENTITY); - printf("%s (%s): ", prompt, identity_file); - fflush(stdout); - 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; -} - -int -try_load_key(char *filename, Key *k) -{ - int success = 1; - if (!load_private_key(filename, "", k, NULL)) { - char *pass = read_passphrase("Enter passphrase: ", 1); - if (!load_private_key(filename, pass, k, NULL)) { - success = 0; - } - memset(pass, 0, strlen(pass)); - xfree(pass); - } - return success; -} - -#define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" -#define SSH_COM_MAGIC_END "---- END SSH2 PUBLIC KEY ----" - -void -do_convert_to_ssh2(struct passwd *pw) -{ - Key *k; - int len; - unsigned char *blob; - struct stat st; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - k = key_new(KEY_DSA); - if (!try_load_key(identity_file, k)) { - fprintf(stderr, "load failed\n"); - exit(1); - } - dsa_make_key_blob(k, &blob, &len); - fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n"); - fprintf(stdout, - "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", - BN_num_bits(k->dsa->p), - pw->pw_name, hostname); - dump_base64(stdout, blob, len); - fprintf(stdout, SSH_COM_MAGIC_END "\n"); - key_free(k); - xfree(blob); - exit(0); -} - -void -do_convert_from_ssh2(struct passwd *pw) -{ - Key *k; - int blen; - char line[1024], *p; - char blob[8096]; - char encoded[8096]; - struct stat st; - int escaped = 0; - FILE *fp; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - fp = fopen(identity_file, "r"); - if (fp == NULL) { - perror(identity_file); - exit(1); - } - encoded[0] = '\0'; - while (fgets(line, sizeof(line), fp)) { - if (!(p = strchr(line, '\n'))) { - fprintf(stderr, "input line too long.\n"); - exit(1); - } - if (p > line && p[-1] == '\\') - escaped++; - if (strncmp(line, "----", 4) == 0 || - strstr(line, ": ") != NULL) { - fprintf(stderr, "ignore: %s", line); - continue; - } - if (escaped) { - escaped--; - fprintf(stderr, "escaped: %s", line); - continue; - } - *p = '\0'; - strlcat(encoded, line, sizeof(encoded)); - } - blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob)); - if (blen < 0) { - fprintf(stderr, "uudecode failed.\n"); - exit(1); - } - k = dsa_key_from_blob(blob, blen); - if (!key_write(k, stdout)) - fprintf(stderr, "key_write failed"); - key_free(k); - fprintf(stdout, "\n"); - fclose(fp); - exit(0); -} - -void -do_print_public(struct passwd *pw) -{ - Key *k; - int len; - unsigned char *blob; - struct stat st; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - k = key_new(KEY_DSA); - if (!try_load_key(identity_file, k)) { - fprintf(stderr, "load failed\n"); - exit(1); - } - dsa_make_key_blob(k, &blob, &len); - if (!key_write(k, stdout)) - fprintf(stderr, "key_write failed"); - key_free(k); - xfree(blob); - fprintf(stdout, "\n"); - exit(0); -} - -void -do_fingerprint(struct passwd *pw) -{ - FILE *f; - BIGNUM *e, *n; - Key *public; - char *comment = NULL, *cp, *ep, line[16*1024]; - int i, skip = 0, num = 1, invalid = 1; - unsigned int ignore; - struct stat st; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - public = key_new(KEY_RSA); - if (load_public_key(identity_file, public, &comment)) { - printf("%d %s %s\n", BN_num_bits(public->rsa->n), - key_fingerprint(public), comment); - key_free(public); - exit(0); - } - key_free(public); - - /* XXX */ - f = fopen(identity_file, "r"); - if (f != NULL) { - n = BN_new(); - e = BN_new(); - while (fgets(line, sizeof(line), f)) { - i = strlen(line) - 1; - if (line[i] != '\n') { - 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; - if (auth_rsa_read_key(&cp, &ignore, e, n)) { - invalid = 0; - comment = *cp ? cp : comment; - printf("%d %s %s\n", BN_num_bits(n), - fingerprint(e, n), - comment ? comment : "no comment"); - } - } - BN_free(e); - BN_free(n); - fclose(f); - } - if (invalid) { - printf("%s is not a valid key file.\n", identity_file); - exit(1); - } - exit(0); -} - -/* - * Perform changing a passphrase. The argument is the passwd structure - * for the current user. - */ -void -do_change_passphrase(struct passwd *pw) -{ - char *comment; - char *old_passphrase, *passphrase1, *passphrase2; - struct stat st; - Key *private; - Key *public; - int type = dsa_mode ? KEY_DSA : KEY_RSA; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - - if (type == KEY_RSA) { - /* XXX this works currently only for RSA */ - public = key_new(type); - if (!load_public_key(identity_file, public, NULL)) { - printf("%s is not a valid key file.\n", identity_file); - exit(1); - } - /* Clear the public key since we are just about to load the whole file. */ - key_free(public); - } - - /* Try to load the file with empty passphrase. */ - private = key_new(type); - if (!load_private_key(identity_file, "", private, &comment)) { - if (identity_passphrase) - old_passphrase = xstrdup(identity_passphrase); - else - old_passphrase = read_passphrase("Enter old passphrase: ", 1); - if (!load_private_key(identity_file, old_passphrase, private, &comment)) { - memset(old_passphrase, 0, strlen(old_passphrase)); - xfree(old_passphrase); - printf("Bad passphrase.\n"); - exit(1); - } - memset(old_passphrase, 0, strlen(old_passphrase)); - xfree(old_passphrase); - } - printf("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("Enter new passphrase (empty for no passphrase): ", 1); - passphrase2 = read_passphrase("Enter same passphrase again: ", 1); - - /* 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("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 (!save_private_key(identity_file, passphrase1, private, comment)) { - printf("Saving the key failed: %s: %s.\n", - identity_file, strerror(errno)); - 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("Your identification has been saved with the new passphrase.\n"); - exit(0); -} - -/* - * Change the comment of a private key file. - */ -void -do_change_comment(struct passwd *pw) -{ - char new_comment[1024], *comment; - Key *private; - Key *public; - char *passphrase; - struct stat st; - FILE *f; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - /* - * Try to load the public key from the file the verify that it is - * readable and of the proper format. - */ - public = key_new(KEY_RSA); - if (!load_public_key(identity_file, public, NULL)) { - printf("%s is not a valid key file.\n", identity_file); - exit(1); - } - - private = key_new(KEY_RSA); - if (load_private_key(identity_file, "", private, &comment)) - passphrase = xstrdup(""); - else { - if (identity_passphrase) - passphrase = xstrdup(identity_passphrase); - else if (identity_new_passphrase) - passphrase = xstrdup(identity_new_passphrase); - else - passphrase = read_passphrase("Enter passphrase: ", 1); - /* Try to load using the passphrase. */ - if (!load_private_key(identity_file, passphrase, private, &comment)) { - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - printf("Bad passphrase.\n"); - exit(1); - } - } - printf("Key now has comment '%s'\n", comment); - - if (identity_comment) { - strlcpy(new_comment, identity_comment, sizeof(new_comment)); - } else { - printf("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 (!save_private_key(identity_file, passphrase, private, new_comment)) { - printf("Saving the key failed: %s: %s.\n", - identity_file, strerror(errno)); - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - key_free(private); - xfree(comment); - exit(1); - } - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - key_free(private); - - strlcat(identity_file, ".pub", sizeof(identity_file)); - f = fopen(identity_file, "w"); - if (!f) { - printf("Could not save your public key in %s\n", identity_file); - exit(1); - } - if (!key_write(public, f)) - fprintf(stderr, "write key failed"); - key_free(public); - fprintf(f, " %s\n", new_comment); - fclose(f); - - xfree(comment); - - printf("The comment in your key file has been changed.\n"); - exit(0); -} - -void -usage(void) -{ - printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname); - exit(1); -} - -/* - * Main program for key management. - */ -int -main(int ac, char **av) -{ - char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2; - struct passwd *pw; - int opt; - struct stat st; - FILE *f; - Key *private; - Key *public; - extern int optind; - extern char *optarg; - - OpenSSL_add_all_algorithms(); - - /* we need this for the home * directory. */ - pw = getpwuid(getuid()); - if (!pw) { - printf("You don't exist, go away!\n"); - exit(1); - } - if (gethostname(hostname, sizeof(hostname)) < 0) { - perror("gethostname"); - exit(1); - } - - while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) { - switch (opt) { - case 'b': - bits = atoi(optarg); - if (bits < 512 || bits > 32768) { - printf("Bits has bad value.\n"); - exit(1); - } - break; - - case 'l': - print_fingerprint = 1; - break; - - 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 'R': - if (rsa_alive() == 0) - exit(1); - else - exit(0); - break; - - case 'x': - convert_to_ssh2 = 1; - break; - - case 'X': - convert_from_ssh2 = 1; - break; - - case 'y': - print_public = 1; - break; - - case 'd': - dsa_mode = 1; - break; - - case '?': - default: - usage(); - } - } - if (optind < ac) { - printf("Too many arguments.\n"); - usage(); - } - if (change_passphrase && change_comment) { - printf("Can only have one of -p and -c.\n"); - usage(); - } - /* check if RSA support is needed and exists */ - if (dsa_mode == 0 && rsa_alive() == 0) { - fprintf(stderr, - "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", - __progname); - exit(1); - } - if (print_fingerprint) - do_fingerprint(pw); - if (change_passphrase) - do_change_passphrase(pw); - if (change_comment) - do_change_comment(pw); - if (convert_to_ssh2) - do_convert_to_ssh2(pw); - if (convert_from_ssh2) - do_convert_from_ssh2(pw); - if (print_public) - do_print_public(pw); - - arc4random_stir(); - - if (dsa_mode != 0) { - if (!quiet) - printf("Generating DSA parameter and key.\n"); - public = private = dsa_generate_key(bits); - if (private == NULL) { - fprintf(stderr, "dsa_generate_keys failed"); - exit(1); - } - } else { - if (quiet) - rsa_set_verbose(0); - /* Generate the rsa key pair. */ - public = key_new(KEY_RSA); - private = key_new(KEY_RSA); - rsa_generate_key(private->rsa, public->rsa, bits); - } - - if (!have_identity) - ask_filename(pw, "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, SSH_USER_DIR); - if (strstr(identity_file, dotsshdir) != NULL && - stat(dotsshdir, &st) < 0) { - if (mkdir(dotsshdir, 0755) < 0) - error("Could not create directory '%s'.", dotsshdir); - else if (!quiet) - printf("Created directory '%s'.\n", dotsshdir); - } - /* If the file already exists, ask the user to confirm. */ - if (stat(identity_file, &st) >= 0) { - char yesno[3]; - printf("%s already exists.\n", identity_file); - printf("Overwrite (y/n)? "); - fflush(stdout); - if (fgets(yesno, sizeof(yesno), stdin) == NULL) - exit(1); - if (yesno[0] != 'y' && yesno[0] != 'Y') - 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("Enter passphrase (empty for no passphrase): ", 1); - passphrase2 = read_passphrase("Enter same passphrase again: ", 1); - 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("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 (!save_private_key(identity_file, passphrase1, private, comment)) { - printf("Saving the key failed: %s: %s.\n", - identity_file, strerror(errno)); - 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. */ - if (private != public) { - key_free(private); - } - arc4random_stir(); - - if (!quiet) - printf("Your identification has been saved in %s.\n", identity_file); - - strlcat(identity_file, ".pub", sizeof(identity_file)); - f = fopen(identity_file, "w"); - if (!f) { - printf("Could not save your public key in %s\n", identity_file); - exit(1); - } - if (!key_write(public, f)) - fprintf(stderr, "write key failed"); - fprintf(f, " %s\n", comment); - fclose(f); - - if (!quiet) { - printf("Your public key has been saved in %s.\n", - identity_file); - printf("The key fingerprint is:\n"); - printf("%s %s\n", key_fingerprint(public), comment); - } - - key_free(public); - exit(0); -} diff --git a/crypto/openssh/ssh-keygen/Makefile b/crypto/openssh/ssh-keygen/Makefile deleted file mode 100644 index 1f9205919b51..000000000000 --- a/crypto/openssh/ssh-keygen/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -.PATH: ${.CURDIR}/.. - -PROG= ssh-keygen -BINOWN= root - -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else -BINMODE?=555 -.endif - -BINDIR= /usr/bin -MAN= ssh-keygen.1 - -SRCS= ssh-keygen.c log-client.c - -.include <bsd.prog.mk> - -LDADD+= -lcrypto -lutil -lz -DPADD+= ${LIBCRYPTO} ${LIBDES} ${LIBUTIL} ${LIBZ} diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1 deleted file mode 100644 index 77c39806071c..000000000000 --- a/crypto/openssh/ssh.1 +++ /dev/null @@ -1,1221 +0,0 @@ -.\" -*- nroff -*- -.\" -.\" ssh.1.in -.\" -.\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" -.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland -.\" All rights reserved -.\" -.\" Created: Sat Apr 22 21:55:14 1995 ylo -.\" -.\" $Id: ssh.1,v 1.52 2000/05/08 17:21:32 hugh Exp $ -.\" -.Dd September 25, 1999 -.Dt SSH 1 -.Os -.Sh NAME -.Nm ssh -.Nd OpenSSH secure shell client (remote login program) -.Sh SYNOPSIS -.Nm ssh -.Op Fl l Ar login_name -.Op Ar hostname | user@hostname -.Op Ar command -.Pp -.Nm ssh -.Op Fl afgknqtvxCPX246 -.Op Fl c Ar cipher_spec -.Op Fl e Ar escape_char -.Op Fl i Ar identity_file -.Op Fl l Ar login_name -.Op Fl o Ar option -.Op Fl p Ar port -.Oo Fl L Xo -.Sm off -.Ar port : -.Ar host : -.Ar hostport -.Sm on -.Xc -.Oc -.Oo Fl R Xo -.Sm off -.Ar port : -.Ar host : -.Ar hostport -.Sm on -.Xc -.Oc -.Op Ar hostname | user@hostname -.Op Ar command -.Sh DESCRIPTION -.Nm -(Secure Shell) is a program for logging into a remote machine and for -executing commands on a remote machine. -It is intended to replace -rlogin and rsh, and provide secure encrypted communications between -two untrusted hosts over an insecure network. -X11 connections and -arbitrary TCP/IP ports can also be forwarded over the secure channel. -.Pp -.Nm -connects and logs into the specified -.Ar hostname . -The user must prove -his/her identity to the remote machine using one of several methods -depending on the protocol version used: -.Pp -.Ss SSH protocol version 1 -.Pp -First, if the machine the user logs in from is listed in -.Pa /etc/hosts.equiv -or -.Pa /etc/shosts.equiv -on the remote machine, and the user names are -the same on both sides, the user is immediately permitted to log in. -Second, if -.Pa \&.rhosts -or -.Pa \&.shosts -exists in the user's home directory on the -remote machine and contains a line containing the name of the client -machine and the name of the user on that machine, the user is -permitted to log in. -This form of authentication alone is normally not -allowed by the server because it is not secure. -.Pp -The second (and primary) authentication method is the -.Pa rhosts -or -.Pa hosts.equiv -method combined with RSA-based host authentication. -It means that if the login would be permitted by -.Pa $HOME/.rhosts , -.Pa $HOME/.shosts , -.Pa /etc/hosts.equiv , -or -.Pa /etc/shosts.equiv , -and if additionally the server can verify the client's -host key (see -.Pa /etc/ssh_known_hosts -and -.Pa $HOME/.ssh/known_hosts -in the -.Sx FILES -section), only then login is permitted. -This authentication method closes security holes due to IP -spoofing, DNS spoofing and routing spoofing. -[Note to the administrator: -.Pa /etc/hosts.equiv , -.Pa $HOME/.rhosts , -and the rlogin/rsh protocol in general, are inherently insecure and should be -disabled if security is desired.] -.Pp -As a third authentication method, -.Nm -supports RSA based authentication. -The scheme is based on public-key cryptography: there are cryptosystems -where encryption and decryption are done using separate keys, and it -is not possible to derive the decryption key from the encryption key. -RSA is one such system. -The idea is that each user creates a public/private -key pair for authentication purposes. -The server knows the public key, and only the user knows the private key. -The file -.Pa $HOME/.ssh/authorized_keys -lists the public keys that are permitted for logging -in. -When the user logs in, the -.Nm -program tells the server which key pair it would like to use for -authentication. -The server checks if this key is permitted, and if -so, sends the user (actually the -.Nm -program running on behalf of the user) a challenge, a random number, -encrypted by the user's public key. -The challenge can only be -decrypted using the proper private key. -The user's client then decrypts the -challenge using the private key, proving that he/she knows the private -key but without disclosing it to the server. -.Pp -.Nm -implements the RSA authentication protocol automatically. -The user creates his/her RSA key pair by running -.Xr ssh-keygen 1 . -This stores the private key in -.Pa $HOME/.ssh/identity -and the public key in -.Pa $HOME/.ssh/identity.pub -in the user's home directory. -The user should then copy the -.Pa identity.pub -to -.Pa $HOME/.ssh/authorized_keys -in his/her home directory on the remote machine (the -.Pa authorized_keys -file corresponds to the conventional -.Pa $HOME/.rhosts -file, and has one key -per line, though the lines can be very long). -After this, the user can log in without giving the password. -RSA authentication is much -more secure than rhosts authentication. -.Pp -The most convenient way to use RSA authentication may be with an -authentication agent. -See -.Xr ssh-agent 1 -for more information. -.Pp -If other authentication methods fail, -.Nm -prompts the user for a password. -The password is sent to the remote -host for checking; however, since all communications are encrypted, -the password cannot be seen by someone listening on the network. -.Pp -.Ss SSH protocol version 2 -.Pp -When a user connects using the protocol version 2 -different authentication methods are available: -At first, the client attempts to authenticate using the public key method. -If this method fails password authentication is tried. -.Pp -The public key method is similar to RSA authentication described -in the previous section except that the DSA algorithm is used -instead of the patented RSA algorithm. -The client uses his private DSA key -.Pa $HOME/.ssh/id_dsa -to sign the session identifier and sends the result to the server. -The server checks whether the matching public key is listed in -.Pa $HOME/.ssh/authorized_keys2 -and grants access if both the key is found and the signature is correct. -The session identifier is derived from a shared Diffie-Hellman value -and is only known to the client and the server. -.Pp -If public key authentication fails or is not available a password -can be sent encrypted to the remote host for proving the user's identity. -This protocol 2 implementation does not yet support Kerberos or -S/Key authentication. -.Pp -Protocol 2 provides additional mechanisms for confidentiality -(the traffic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) -and integrity (hmac-sha1, hmac-md5). -Note that protocol 1 lacks a strong mechanism for ensuring the -integrity of the connection. -.Pp -.Ss Login session and remote execution -.Pp -When the user's identity has been accepted by the server, the server -either executes the given command, or logs into the machine and gives -the user a normal shell on the remote machine. -All communication with -the remote command or shell will be automatically encrypted. -.Pp -If a pseudo-terminal has been allocated (normal login session), the -user can disconnect with -.Ic ~. , -and suspend -.Nm -with -.Ic ~^Z . -All forwarded connections can be listed with -.Ic ~# -and if -the session blocks waiting for forwarded X11 or TCP/IP -connections to terminate, it can be backgrounded with -.Ic ~& -(this should not be used while the user shell is active, as it can cause the -shell to hang). -All available escapes can be listed with -.Ic ~? . -.Pp -A single tilde character can be sent as -.Ic ~~ -(or by following the tilde by a character other than those described above). -The escape character must always follow a newline to be interpreted as -special. -The escape character can be changed in configuration files -or on the command line. -.Pp -If no pseudo tty has been allocated, the -session is transparent and can be used to reliably transfer binary -data. -On most systems, setting the escape character to -.Dq none -will also make the session transparent even if a tty is used. -.Pp -The session terminates when the command or shell in on the remote -machine exists and all X11 and TCP/IP connections have been closed. -The exit status of the remote program is returned as the exit status -of -.Nm ssh . -.Pp -.Ss X11 and TCP forwarding -.Pp -If the user is using X11 (the -.Ev DISPLAY -environment variable is set), the connection to the X11 display is -automatically forwarded to the remote side in such a way that any X11 -programs started from the shell (or command) will go through the -encrypted channel, and the connection to the real X server will be made -from the local machine. -The user should not manually set -.Ev DISPLAY . -Forwarding of X11 connections can be -configured on the command line or in configuration files. -.Pp -The -.Ev DISPLAY -value set by -.Nm -will point to the server machine, but with a display number greater -than zero. -This is normal, and happens because -.Nm -creates a -.Dq proxy -X server on the server machine for forwarding the -connections over the encrypted channel. -.Pp -.Nm -will also automatically set up Xauthority data on the server machine. -For this purpose, it will generate a random authorization cookie, -store it in Xauthority on the server, and verify that any forwarded -connections carry this cookie and replace it by the real cookie when -the connection is opened. -The real authentication cookie is never -sent to the server machine (and no cookies are sent in the plain). -.Pp -If the user is using an authentication agent, the connection to the agent -is automatically forwarded to the remote side unless disabled on -command line or in a configuration file. -.Pp -Forwarding of arbitrary TCP/IP connections over the secure channel can -be specified either on command line or in a configuration file. -One possible application of TCP/IP forwarding is a secure connection to an -electronic purse; another is going trough firewalls. -.Pp -.Ss Server authentication -.Pp -.Nm -automatically maintains and checks a database containing -identifications for all hosts it has ever been used with. -RSA host keys are stored in -.Pa $HOME/.ssh/known_hosts -and -DSA host keys are stored in -.Pa $HOME/.ssh/known_hosts2 -in the user's home directory. -Additionally, the files -.Pa /etc/ssh_known_hosts -and -.Pa /etc/ssh_known_hosts2 -are automatically checked for known hosts. -Any new hosts are automatically added to the user's file. -If a host's identification -ever changes, -.Nm -warns about this and disables password authentication to prevent a -trojan horse from getting the user's password. -Another purpose of -this mechanism is to prevent man-in-the-middle attacks which could -otherwise be used to circumvent the encryption. -The -.Cm StrictHostKeyChecking -option (see below) can be used to prevent logins to machines whose -host key is not known or has changed. -.Sh OPTIONS -.Bl -tag -width Ds -.It Fl a -Disables forwarding of the authentication agent connection. -This may also be specified on a per-host basis in the configuration file. -.It Fl c Ar blowfish|3des -Selects the cipher to use for encrypting the session. -.Ar 3des -is used by default. -It is believed to be secure. -.Ar 3des -(triple-des) is an encrypt-decrypt-encrypt triple with three different keys. -It is presumably more secure than the -.Ar des -cipher which is no longer supported in -.Nm ssh . -.Ar blowfish -is a fast block cipher, it appears very secure and is much faster than -.Ar 3des . -.It Fl c Ar "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" -Additionally, for protocol version 2 a comma-separated list of ciphers can -be specified in order of preference. Protocol version 2 supports -3DES, Blowfish and CAST128 in CBC mode and Arcfour. -.It Fl e Ar ch|^ch|none -Sets the escape character for sessions with a pty (default: -.Ql ~ ) . -The escape character is only recognized at the beginning of a line. -The escape character followed by a dot -.Pq Ql \&. -closes the connection, followed -by control-Z suspends the connection, and followed by itself sends the -escape character once. -Setting the character to -.Dq none -disables any escapes and makes the session fully transparent. -.It Fl f -Requests -.Nm -to go to background just before command execution. -This is useful if -.Nm -is going to ask for passwords or passphrases, but the user -wants it in the background. -This implies -.Fl n . -The recommended way to start X11 programs at a remote site is with -something like -.Ic ssh -f host xterm . -.It Fl g -Allows remote hosts to connect to local forwarded ports. -.It Fl i Ar identity_file -Selects the file from which the identity (private key) for -RSA authentication is read. -Default is -.Pa $HOME/.ssh/identity -in the user's home directory. -Identity files may also be specified on -a per-host basis in the configuration file. -It is possible to have multiple -.Fl i -options (and multiple identities specified in -configuration files). -.It Fl k -Disables forwarding of Kerberos tickets and AFS tokens. -This may also be specified on a per-host basis in the configuration file. -.It Fl l Ar login_name -Specifies the user to log in as on the remote machine. -This also may be specified on a per-host basis in the configuration file. -.It Fl n -Redirects stdin from -.Pa /dev/null -(actually, prevents reading from stdin). -This must be used when -.Nm -is run in the background. -A common trick is to use this to run X11 programs on a remote machine. -For example, -.Ic ssh -n shadows.cs.hut.fi emacs & -will start an emacs on shadows.cs.hut.fi, and the X11 -connection will be automatically forwarded over an encrypted channel. -The -.Nm -program will be put in the background. -(This does not work if -.Nm -needs to ask for a password or passphrase; see also the -.Fl f -option.) -.It Fl o Ar option -Can be used to give options in the format used in the config file. -This is useful for specifying options for which there is no separate -command-line flag. -The option has the same format as a line in the configuration file. -.It Fl p Ar port -Port to connect to on the remote host. -This can be specified on a -per-host basis in the configuration file. -.It Fl P -Use a non-privileged port for outgoing connections. -This can be used if your firewall does -not permit connections from privileged ports. -Note that this option turns off -.Cm RhostsAuthentication -and -.Cm RhostsRSAAuthentication . -.It Fl q -Quiet mode. -Causes all warning and diagnostic messages to be suppressed. -Only fatal errors are displayed. -.It Fl t -Force pseudo-tty allocation. -This can be used to execute arbitrary -screen-based programs on a remote machine, which can be very useful, -e.g., when implementing menu services. -.It Fl v -Verbose mode. -Causes -.Nm -to print debugging messages about its progress. -This is helpful in -debugging connection, authentication, and configuration problems. -The verbose mode is also used to display -.Xr skey 1 -challenges, if the user entered "s/key" as password. -.It Fl x -Disables X11 forwarding. -This can also be specified on a per-host basis in a configuration file. -.It Fl X -Enables X11 forwarding. -.It Fl C -Requests compression of all data (including stdin, stdout, stderr, and -data for forwarded X11 and TCP/IP connections). -The compression algorithm is the same used by -.Xr gzip 1 , -and the -.Dq level -can be controlled by the -.Cm CompressionLevel -option (see below). -Compression is desirable on modem lines and other -slow connections, but will only slow down things on fast networks. -The default value can be set on a host-by-host basis in the -configuration files; see the -.Cm Compress -option below. -.It Fl L Ar port:host:hostport -Specifies that the given port on the local (client) host is to be -forwarded to the given host and port on the remote side. -This works by allocating a socket to listen to -.Ar port -on the local side, and whenever a connection is made to this port, the -connection is forwarded over the secure channel, and a connection is -made to -.Ar host -port -.Ar hostport -from the remote machine. -Port forwardings can also be specified in the configuration file. -Only root can forward privileged ports. -IPv6 addresses can be specified with an alternative syntax: -.Ar port/host/hostport -.It Fl R Ar port:host:hostport -Specifies that the given port on the remote (server) host is to be -forwarded to the given host and port on the local side. -This works by allocating a socket to listen to -.Ar port -on the remote side, and whenever a connection is made to this port, the -connection is forwarded over the secure channel, and a connection is -made to -.Ar host -port -.Ar hostport -from the local machine. -Port forwardings can also be specified in the configuration file. -Privileged ports can be forwarded only when -logging in as root on the remote machine. -.It Fl 2 -Forces -.Nm -to try protocol version 2 only. -.It Fl 4 -Forces -.Nm -to use IPv4 addresses only. -.It Fl 6 -Forces -.Nm -to use IPv6 addresses only. -.El -.Sh CONFIGURATION FILES -.Nm -obtains configuration data from the following sources (in this order): -command line options, user's configuration file -.Pq Pa $HOME/.ssh/config , -and system-wide configuration file -.Pq Pa /etc/ssh_config . -For each parameter, the first obtained value -will be used. -The configuration files contain sections bracketed by -.Dq Host -specifications, and that section is only applied for hosts that -match one of the patterns given in the specification. -The matched host name is the one given on the command line. -.Pp -Since the first obtained value for each parameter is used, more -host-specific declarations should be given near the beginning of the -file, and general defaults at the end. -.Pp -The configuration file has the following format: -.Pp -Empty lines and lines starting with -.Ql # -are comments. -.Pp -Otherwise a line is of the format -.Dq keyword arguments . -The possible -keywords and their meanings are as follows (note that the -configuration files are case-sensitive): -.Bl -tag -width Ds -.It Cm Host -Restricts the following declarations (up to the next -.Cm Host -keyword) to be only for those hosts that match one of the patterns -given after the keyword. -.Ql \&* -and -.Ql ? -can be used as wildcards in the -patterns. -A single -.Ql \&* -as a pattern can be used to provide global -defaults for all hosts. -The host is the -.Ar hostname -argument given on the command line (i.e., the name is not converted to -a canonicalized host name before matching). -.It Cm AFSTokenPassing -Specifies whether to pass AFS tokens to remote host. -The argument to this keyword must be -.Dq yes -or -.Dq no . -.It Cm BatchMode -If set to -.Dq yes , -passphrase/password querying will be disabled. -This option is useful in scripts and other batch jobs where you have no -user to supply the password. -The argument must be -.Dq yes -or -.Dq no . -.It Cm CheckHostIP -If this flag is set to -.Dq yes , -ssh will additionally check the host ip address in the -.Pa known_hosts -file. -This allows ssh to detect if a host key changed due to DNS spoofing. -If the option is set to -.Dq no , -the check will not be executed. -.It Cm Cipher -Specifies the cipher to use for encrypting the session. -Currently, -.Dq blowfish , -and -.Dq 3des -are supported. -The default is -.Dq 3des . -.It Cm Ciphers -Specifies the ciphers allowed for protocol version 2 -in order of preference. -Multiple ciphers must be comma-separated. -The default is -.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc . -.It Cm Compression -Specifies whether to use compression. -The argument must be -.Dq yes -or -.Dq no . -.It Cm CompressionLevel -Specifies the compression level to use if compression is enable. -The argument must be an integer from 1 (fast) to 9 (slow, best). -The default level is 6, which is good for most applications. -The meaning of the values is the same as in -.Xr gzip 1 . -.It Cm ConnectionAttempts -Specifies the number of tries (one per second) to make before falling -back to rsh or exiting. -The argument must be an integer. -This may be useful in scripts if the connection sometimes fails. -.It Cm DSAAuthentication -Specifies whether to try DSA authentication. -The argument to this keyword must be -.Dq yes -or -.Dq no . -DSA authentication will only be -attempted if a DSA identity file exists. -Note that this option applies to protocol version 2 only. -.It Cm EscapeChar -Sets the escape character (default: -.Ql ~ ) . -The escape character can also -be set on the command line. -The argument should be a single character, -.Ql ^ -followed by a letter, or -.Dq none -to disable the escape -character entirely (making the connection transparent for binary -data). -.It Cm FallBackToRsh -Specifies that if connecting via -.Nm -fails due to a connection refused error (there is no -.Xr sshd 8 -listening on the remote host), -.Xr rsh 1 -should automatically be used instead (after a suitable warning about -the session being unencrypted). -The argument must be -.Dq yes -or -.Dq no . -.It Cm ForwardAgent -Specifies whether the connection to the authentication agent (if any) -will be forwarded to the remote machine. -The argument must be -.Dq yes -or -.Dq no . -.It Cm ForwardX11 -Specifies whether X11 connections will be automatically redirected -over the secure channel and -.Ev DISPLAY -set. -The argument must be -.Dq yes -or -.Dq no . -The default is -.Dq no . -.It Cm GatewayPorts -Specifies whether remote hosts are allowed to connect to local -forwarded ports. -The argument must be -.Dq yes -or -.Dq no . -The default is -.Dq no . -.It Cm GlobalKnownHostsFile -Specifies a file to use instead of -.Pa /etc/ssh_known_hosts . -.It Cm HostName -Specifies the real host name to log into. -This can be used to specify nicknames or abbreviations for hosts. -Default is the name given on the command line. -Numeric IP addresses are also permitted (both on the command line and in -.Cm HostName -specifications). -.It Cm IdentityFile -Specifies the file from which the user's RSA authentication identity -is read (default -.Pa $HOME/.ssh/identity -in the user's home directory). -Additionally, any identities represented by the authentication agent -will be used for authentication. -The file name may use the tilde -syntax to refer to a user's home directory. -It is possible to have -multiple identity files specified in configuration files; all these -identities will be tried in sequence. -.It Cm IdentityFile2 -Specifies the file from which the user's DSA authentication identity -is read (default -.Pa $HOME/.ssh/id_dsa -in the user's home directory). -The file name may use the tilde -syntax to refer to a user's home directory. -It is possible to have -multiple identity files specified in configuration files; all these -identities will be tried in sequence. -.It Cm KeepAlive -Specifies whether the system should send keepalive messages to the -other side. -If they are sent, death of the connection or crash of one -of the machines will be properly noticed. -However, this means that -connections will die if the route is down temporarily, and some people -find it annoying. -.Pp -The default is -.Dq yes -(to send keepalives), and the client will notice -if the network goes down or the remote host dies. -This is important in scripts, and many users want it too. -.Pp -To disable keepalives, the value should be set to -.Dq no -in both the server and the client configuration files. -.It Cm KerberosAuthentication -Specifies whether Kerberos authentication will be used. -The argument to this keyword must be -.Dq yes -or -.Dq no . -.It Cm KerberosTgtPassing -Specifies whether a Kerberos TGT will be forwarded to the server. -This will only work if the Kerberos server is actually an AFS kaserver. -The argument to this keyword must be -.Dq yes -or -.Dq no . -.It Cm LocalForward -Specifies that a TCP/IP port on the local machine be forwarded over -the secure channel to given host:port from the remote machine. -The first argument must be a port number, and the second must be -host:port. -Multiple forwardings may be specified, and additional -forwardings can be given on the command line. -Only the superuser can forward privileged ports. -.It Cm LogLevel -Gives the verbosity level that is used when logging messages from -.Nm ssh . -The possible values are: -QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. -The default is INFO. -.It Cm NumberOfPasswordPrompts -Specifies the number of password prompts before giving up. -The argument to this keyword must be an integer. -Default is 3. -.It Cm PasswordAuthentication -Specifies whether to use password authentication. -The argument to this keyword must be -.Dq yes -or -.Dq no . -Note that this option applies to both protocol version 1 and 2. -.It Cm Port -Specifies the port number to connect on the remote host. -Default is 22. -.It Cm Protocol -Specifies the protocol versions -.Nm -should support in order of preference. -The possible values are -.Dq 1 -and -.Dq 2 . -Multiple versions must be comma-separated. -The default is -.Dq 1,2 . -This means that -.Nm -tries version 1 and falls back to version 2 -if version 1 is not available. -.It Cm ProxyCommand -Specifies the command to use to connect to the server. -The command -string extends to the end of the line, and is executed with -.Pa /bin/sh . -In the command string, -.Ql %h -will be substituted by the host name to -connect and -.Ql %p -by the port. -The command can be basically anything, -and should read from its standard input and write to its standard output. -It should eventually connect an -.Xr sshd 8 -server running on some machine, or execute -.Ic sshd -i -somewhere. -Host key management will be done using the -HostName of the host being connected (defaulting to the name typed by -the user). -Note that -.Cm CheckHostIP -is not available for connects with a proxy command. -.Pp -.It Cm RemoteForward -Specifies that a TCP/IP port on the remote machine be forwarded over -the secure channel to given host:port from the local machine. -The first argument must be a port number, and the second must be -host:port. -Multiple forwardings may be specified, and additional -forwardings can be given on the command line. -Only the superuser can forward privileged ports. -.It Cm RhostsAuthentication -Specifies whether to try rhosts based authentication. -Note that this -declaration only affects the client side and has no effect whatsoever -on security. -Disabling rhosts authentication may reduce -authentication time on slow connections when rhosts authentication is -not used. -Most servers do not permit RhostsAuthentication because it -is not secure (see RhostsRSAAuthentication). -The argument to this keyword must be -.Dq yes -or -.Dq no . -.It Cm RhostsRSAAuthentication -Specifies whether to try rhosts based authentication with RSA host -authentication. -This is the primary authentication method for most sites. -The argument must be -.Dq yes -or -.Dq no . -.It Cm RSAAuthentication -Specifies whether to try RSA authentication. -The argument to this keyword must be -.Dq yes -or -.Dq no . -RSA authentication will only be -attempted if the identity file exists, or an authentication agent is -running. -Note that this option applies to protocol version 1 only. -.It Cm SkeyAuthentication -Specifies whether to use -.Xr skey 1 -authentication. -The argument to this keyword must be -.Dq yes -or -.Dq no . -The default is -.Dq no . -.It Cm StrictHostKeyChecking -If this flag is set to -.Dq yes , -.Nm -ssh will never automatically add host keys to the -.Pa $HOME/.ssh/known_hosts -and -.Pa $HOME/.ssh/known_hosts2 -files, and refuses to connect hosts whose host key has changed. -This provides maximum protection against trojan horse attacks. -However, it can be somewhat annoying if you don't have good -.Pa /etc/ssh_known_hosts -and -.Pa /etc/ssh_known_hosts2 -files installed and frequently -connect new hosts. -Basically this option forces the user to manually -add any new hosts. -Normally this option is disabled, and new hosts -will automatically be added to the known host files. -The host keys of -known hosts will be verified automatically in either case. -The argument must be -.Dq yes -or -.Dq no . -.It Cm UsePrivilegedPort -Specifies whether to use a privileged port for outgoing connections. -The argument must be -.Dq yes -or -.Dq no . -The default is -.Dq yes . -Note that setting this option to -.Dq no -turns off -.Cm RhostsAuthentication -and -.Cm RhostsRSAAuthentication . -.It Cm User -Specifies the user to log in as. -This can be useful if you have a different user name on different machines. -This saves the trouble of -having to remember to give the user name on the command line. -.It Cm UserKnownHostsFile -Specifies a file to use instead of -.Pa $HOME/.ssh/known_hosts . -.It Cm UseRsh -Specifies that rlogin/rsh should be used for this host. -It is possible that the host does not at all support the -.Nm -protocol. -This causes -.Nm -to immediately execute -.Xr rsh 1 . -All other options (except -.Cm HostName ) -are ignored if this has been specified. -The argument must be -.Dq yes -or -.Dq no . -.Sh ENVIRONMENT -.Nm -will normally set the following environment variables: -.Bl -tag -width Ds -.It Ev DISPLAY -The -.Ev DISPLAY -variable indicates the location of the X11 server. -It is automatically set by -.Nm -to point to a value of the form -.Dq hostname:n -where hostname indicates -the host where the shell runs, and n is an integer >= 1. -.Nm -uses this special value to forward X11 connections over the secure -channel. -The user should normally not set DISPLAY explicitly, as that -will render the X11 connection insecure (and will require the user to -manually copy any required authorization cookies). -.It Ev HOME -Set to the path of the user's home directory. -.It Ev LOGNAME -Synonym for -.Ev USER ; -set for compatibility with systems that use this variable. -.It Ev MAIL -Set to point the user's mailbox. -.It Ev PATH -Set to the default -.Ev PATH , -as specified when compiling -.Nm ssh . -.It Ev SSH_AUTH_SOCK -indicates the path of a unix-domain socket used to communicate with the -agent. -.It Ev SSH_CLIENT -Identifies the client end of the connection. -The variable contains -three space-separated values: client ip-address, client port number, -and server port number. -.It Ev SSH_TTY -This is set to the name of the tty (path to the device) associated -with the current shell or command. -If the current session has no tty, -this variable is not set. -.It Ev TZ -The timezone variable is set to indicate the present timezone if it -was set when the daemon was started (e.i., the daemon passes the value -on to new connections). -.It Ev USER -Set to the name of the user logging in. -.El -.Pp -Additionally, -.Nm -reads -.Pa $HOME/.ssh/environment , -and adds lines of the format -.Dq VARNAME=value -to the environment. -.Sh FILES -.Bl -tag -width Ds -.It Pa $HOME/.ssh/known_hosts -Records host keys for all hosts the user has logged into (that are not -in -.Pa /etc/ssh_known_hosts ) . -See -.Xr sshd 8 . -.It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa -Contains the RSA and the DSA authentication identity of the user. -These files -contain sensitive data and should be readable by the user but not -accessible by others (read/write/execute). -Note that -.Nm -ignores a private key file if it is accessible by others. -It is possible to specify a passphrase when -generating the key; the passphrase will be used to encrypt the -sensitive part of this file using 3DES. -.It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub -Contains the public key for authentication (public part of the -identity file in human-readable form). -The contents of the -.Pa $HOME/.ssh/identity.pub -file should be added to -.Pa $HOME/.ssh/authorized_keys -on all machines -where you wish to log in using RSA authentication. -The contents of the -.Pa $HOME/.ssh/id_dsa.pub -file should be added to -.Pa $HOME/.ssh/authorized_keys2 -on all machines -where you wish to log in using DSA authentication. -These files are not -sensitive and can (but need not) be readable by anyone. -These files are -never used automatically and are not necessary; they is only provided for -the convenience of the user. -.It Pa $HOME/.ssh/config -This is the per-user configuration file. -The format of this file is described above. -This file is used by the -.Nm -client. -This file does not usually contain any sensitive information, -but the recommended permissions are read/write for the user, and not -accessible by others. -.It Pa $HOME/.ssh/authorized_keys -Lists the RSA keys that can be used for logging in as this user. -The format of this file is described in the -.Xr sshd 8 -manual page. -In the simplest form the format is the same as the .pub -identity files (that is, each line contains the number of bits in -modulus, public exponent, modulus, and comment fields, separated by -spaces). -This file is not highly sensitive, but the recommended -permissions are read/write for the user, and not accessible by others. -.It Pa $HOME/.ssh/authorized_keys2 -Lists the DSA keys that can be used for logging in as this user. -This file is not highly sensitive, but the recommended -permissions are read/write for the user, and not accessible by others. -.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2 -Systemwide list of known host keys. -.Pa /etc/ssh_known_hosts -contains RSA and -.Pa /etc/ssh_known_hosts2 -contains DSA keys. -These files should be prepared by the -system administrator to contain the public host keys of all machines in the -organization. -This file should be world-readable. -This file contains -public keys, one per line, in the following format (fields separated -by spaces): system name, number of bits in modulus, public exponent, -modulus, and optional comment field. -When different names are used -for the same machine, all such names should be listed, separated by -commas. -The format is described on the -.Xr sshd 8 -manual page. -.Pp -The canonical system name (as returned by name servers) is used by -.Xr sshd 8 -to verify the client host when logging in; other names are needed because -.Nm -does not convert the user-supplied name to a canonical name before -checking the key, because someone with access to the name servers -would then be able to fool host authentication. -.It Pa /etc/ssh_config -Systemwide configuration file. -This file provides defaults for those -values that are not specified in the user's configuration file, and -for those users who do not have a configuration file. -This file must be world-readable. -.It Pa $HOME/.rhosts -This file is used in -.Pa \&.rhosts -authentication to list the -host/user pairs that are permitted to log in. -(Note that this file is -also used by rlogin and rsh, which makes using this file insecure.) -Each line of the file contains a host name (in the canonical form -returned by name servers), and then a user name on that host, -separated by a space. -One some machines this file may need to be -world-readable if the user's home directory is on a NFS partition, -because -.Xr sshd 8 -reads it as root. -Additionally, this file must be owned by the user, -and must not have write permissions for anyone else. -The recommended -permission for most machines is read/write for the user, and not -accessible by others. -.Pp -Note that by default -.Xr sshd 8 -will be installed so that it requires successful RSA host -authentication before permitting \s+2.\s0rhosts authentication. -If your server machine does not have the client's host key in -.Pa /etc/ssh_known_hosts , -you can store it in -.Pa $HOME/.ssh/known_hosts . -The easiest way to do this is to -connect back to the client from the server machine using ssh; this -will automatically add the host key to -.Pa $HOME/.ssh/known_hosts . -.It Pa $HOME/.shosts -This file is used exactly the same way as -.Pa \&.rhosts . -The purpose for -having this file is to be able to use rhosts authentication with -.Nm -without permitting login with -.Xr rlogin 1 -or -.Xr rsh 1 . -.It Pa /etc/hosts.equiv -This file is used during -.Pa \&.rhosts authentication. -It contains -canonical hosts names, one per line (the full format is described on -the -.Xr sshd 8 -manual page). -If the client host is found in this file, login is -automatically permitted provided client and server user names are the -same. -Additionally, successful RSA host authentication is normally -required. -This file should only be writable by root. -.It Pa /etc/shosts.equiv -This file is processed exactly as -.Pa /etc/hosts.equiv . -This file may be useful to permit logins using -.Nm -but not using rsh/rlogin. -.It Pa /etc/sshrc -Commands in this file are executed by -.Nm -when the user logs in just before the user's shell (or command) is started. -See the -.Xr sshd 8 -manual page for more information. -.It Pa $HOME/.ssh/rc -Commands in this file are executed by -.Nm -when the user logs in just before the user's shell (or command) is -started. -See the -.Xr sshd 8 -manual page for more information. -.It Pa $HOME/.ssh/environment -Contains additional definitions for environment variables, see section -.Sx ENVIRONMENT -above. -.It Pa libcrypto.so.X.1 -A version of this library which includes support for the RSA algorithm -is required for proper operation. -.Sh AUTHOR -OpenSSH -is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, -but with bugs removed and newer features re-added. -Rapidly after the -1.2.12 release, newer versions of the original ssh bore successively -more restrictive licenses, and thus demand for a free version was born. -.Pp -This version of OpenSSH -.Bl -bullet -.It -has all components of a restrictive nature (i.e., patents, see -.Xr ssl 8 ) -directly removed from the source code; any licensed or patented components -are chosen from -external libraries. -.It -has been updated to support SSH protocol 1.5 and 2, making it compatible with -all other SSH clients and servers. -.It -contains added support for -.Xr kerberos 8 -authentication and ticket passing. -.It -supports one-time password authentication with -.Xr skey 1 . -.El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. -.Pp -OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, -Niels Provos, Theo de Raadt, and Dug Song. -.Pp -The support for SSH protocol 2 was written by Markus Friedl. -.Sh SEE ALSO -.Xr rlogin 1 , -.Xr rsh 1 , -.Xr scp 1 , -.Xr ssh-add 1 , -.Xr ssh-agent 1 , -.Xr ssh-keygen 1 , -.Xr telnet 1 , -.Xr sshd 8 , -.Xr ssl 8 diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c deleted file mode 100644 index 0ab3f9fb058a..000000000000 --- a/crypto/openssh/ssh.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Sat Mar 18 16:36:11 1995 ylo - * Ssh client program. This program can be used to log into a remote machine. - * The software supports strong authentication, encryption, and forwarding - * of X11, TCP/IP, and authentication connections. - * - * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> in Canada. - */ - -#include "includes.h" -RCSID("$Id: ssh.c,v 1.51 2000/05/08 17:12:15 markus Exp $"); - -#include <openssl/evp.h> -#include <openssl/dsa.h> -#include <openssl/rsa.h> - -#include "xmalloc.h" -#include "ssh.h" -#include "packet.h" -#include "buffer.h" -#include "authfd.h" -#include "readconf.h" -#include "uidswap.h" - -#include "ssh2.h" -#include "compat.h" -#include "channels.h" -#include "key.h" -#include "authfile.h" - -extern char *__progname; - -/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. - Default value is AF_UNSPEC means both IPv4 and IPv6. */ -int IPv4or6 = AF_UNSPEC; - -/* 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; - -/* don't exec a shell */ -int no_shell_flag = 0; -int no_tty_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 pasphrase 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; - -/* - * 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; - -/* - * 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. - */ -volatile int received_window_change_signal = 0; - -/* Value of argv[0] (set in the main program). */ -char *av0; - -/* Flag indicating whether we have a valid host private key loaded. */ -int host_private_key_loaded = 0; - -/* Host private key. */ -RSA *host_private_key = NULL; - -/* Original real UID. */ -uid_t original_real_uid; - -/* command to be executed */ -Buffer command; - -/* Prints a help message to the user. This function never returns. */ - -void -usage() -{ - fprintf(stderr, "Usage: %s [options] host [command]\n", av0); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -l user Log in using this user name.\n"); - fprintf(stderr, " -n Redirect input from /dev/null.\n"); - fprintf(stderr, " -a Disable authentication agent forwarding.\n"); -#ifdef AFS - fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); -#endif /* AFS */ - fprintf(stderr, " -x Disable X11 connection forwarding.\n"); - fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); - fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); - fprintf(stderr, " -T Do not allocate a tty.\n"); - fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); - fprintf(stderr, " -V Display version number only.\n"); - fprintf(stderr, " -P Don't allocate a privileged port.\n"); - fprintf(stderr, " -q Quiet; don't display any warning messages.\n"); - fprintf(stderr, " -f Fork into background after authentication.\n"); - fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n"); - - fprintf(stderr, " -c cipher Select encryption algorithm: " - "``3des'', " - "``blowfish''\n"); - fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n"); - fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n"); - fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); - fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0); - fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); - fprintf(stderr, " -C Enable compression.\n"); - fprintf(stderr, " -N Do not execute a shell or command.\n"); - fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); - fprintf(stderr, " -4 Use IPv4 only.\n"); - fprintf(stderr, " -6 Use IPv6 only.\n"); - fprintf(stderr, " -2 Force protocol version 2.\n"); - fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); - exit(1); -} - -/* - * Connects to the given host using rsh (or prints an error message and exits - * if rsh is not available). This function never returns. - */ -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) - fprintf(stderr, " "); - fprintf(stderr, "%s", args[i]); - } - fprintf(stderr, "\n"); - } - execv(_PATH_RSH, args); - perror(_PATH_RSH); - exit(1); -} - -int ssh_session(void); -int ssh_session2(void); - -/* - * Main program for the ssh client. - */ -int -main(int ac, char **av) -{ - int i, opt, optind, exit_status, ok; - u_short fwd_port, fwd_host_port; - char *optarg, *cp, buf[256]; - struct stat st; - struct passwd *pw, pwcopy; - int dummy; - uid_t original_effective_uid; - - /* - * 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(); - - /* 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)); - } - /* - * 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). - */ - temporarily_use_uid(original_real_uid); - - /* - * 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); - - /* Save our own name. */ - av0 = av[0]; - - /* Initialize option structure to indicate that no values have been set. */ - initialize_options(&options); - - /* Parse command-line arguments. */ - host = NULL; - - /* If program name is not one of the standard names, use it as host name. */ - if (strchr(av0, '/')) - cp = strrchr(av0, '/') + 1; - else - cp = av0; - if (strcmp(cp, "rsh") != 0 && strcmp(cp, "ssh") != 0 && - strcmp(cp, "rlogin") != 0 && strcmp(cp, "slogin") != 0) - host = cp; - - for (optind = 1; optind < ac; optind++) { - if (av[optind][0] != '-') { - if (host) - break; - if ((cp = strchr(av[optind], '@'))) { - if(cp == av[optind]) - usage(); - options.user = av[optind]; - *cp = '\0'; - host = ++cp; - } else - host = av[optind]; - continue; - } - opt = av[optind][1]; - if (!opt) - usage(); - if (strchr("eilcpLRo", opt)) { /* options with arguments */ - optarg = av[optind] + 2; - if (strcmp(optarg, "") == 0) { - if (optind >= ac - 1) - usage(); - optarg = av[++optind]; - } - } else { - if (av[optind][2]) - usage(); - optarg = NULL; - } - switch (opt) { - 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': - options.use_privileged_port = 0; - break; - case 'a': - options.forward_agent = 0; - 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, "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 't': - tty_flag = 1; - break; - case 'v': - case 'V': - fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n", - SSH_VERSION, - PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2); - fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay()); - if (opt == 'V') - exit(0); - debug_flag = 1; - options.log_level = SYSLOG_LEVEL_DEBUG; - break; - case 'q': - options.log_level = SYSLOG_LEVEL_QUIET; - break; - case 'e': - if (optarg[0] == '^' && optarg[2] == 0 && - (unsigned char) optarg[1] >= 64 && (unsigned char) optarg[1] < 128) - options.escape_char = (unsigned char) optarg[1] & 31; - else if (strlen(optarg) == 1) - options.escape_char = (unsigned char) optarg[0]; - else if (strcmp(optarg, "none") == 0) - options.escape_char = -2; - else { - fprintf(stderr, "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, "Unknown cipher type '%s'\n", optarg); - exit(1); - } - } - break; - case 'p': - options.port = atoi(optarg); - break; - case 'l': - options.user = optarg; - break; - case 'R': - if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, - &fwd_host_port) != 3 && - sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, - &fwd_host_port) != 3) { - fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); - usage(); - /* NOTREACHED */ - } - add_remote_forward(&options, fwd_port, buf, fwd_host_port); - break; - case 'L': - if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, - &fwd_host_port) != 3 && - sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, - &fwd_host_port) != 3) { - fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); - usage(); - /* NOTREACHED */ - } - add_local_forward(&options, fwd_port, buf, fwd_host_port); - 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; - default: - usage(); - } - } - - /* Check that we got a host name. */ - if (!host) - usage(); - - OpenSSL_add_all_algorithms(); - - /* 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 (optind == ac) { - /* No command specified - execute shell on a tty. */ - tty_flag = 1; - } else { - /* A command has been specified. Store it into the - buffer. */ - for (i = optind; i < ac; i++) { - if (i > optind) - 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) - 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; - - /* Do not allocate a tty if stdin is not a tty. */ - if (!isatty(fileno(stdin))) { - if (tty_flag) - fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); - tty_flag = 0; - } - /* force */ - if (no_tty_flag) - tty_flag = 0; - - /* Get user data. */ - pw = getpwuid(original_real_uid); - if (!pw) { - fprintf(stderr, "You don't exist, go away!\n"); - exit(1); - } - /* Take a copy of the returned structure. */ - memset(&pwcopy, 0, sizeof(pwcopy)); - pwcopy.pw_name = xstrdup(pw->pw_name); - pwcopy.pw_passwd = xstrdup(pw->pw_passwd); - pwcopy.pw_uid = pw->pw_uid; - pwcopy.pw_gid = pw->pw_gid; - pwcopy.pw_dir = xstrdup(pw->pw_dir); - pwcopy.pw_shell = xstrdup(pw->pw_shell); - pw = &pwcopy; - - /* Initialize "log" output. Since we are the client all output - actually goes to the terminal. */ - log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); - - /* Read per-user configuration file. */ - snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_CONFFILE); - read_config_file(buf, host, &options); - - /* Read systemwide configuration file. */ - read_config_file(HOST_CONFIG_FILE, host, &options); - - /* Fill configuration defaults. */ - fill_default_options(&options); - - /* reinit */ - log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); - - /* check if RSA support exists */ - if ((options.protocol & SSH_PROTO_1) && - rsa_alive() == 0) { - log("%s: no RSA support in libssl and libcrypto. See ssl(8).", - __progname); - log("Disabling protocol version 1"); - options.protocol &= ~ (SSH_PROTO_1|SSH_PROTO_1_PREFERRED); - } - if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { - fprintf(stderr, "%s: No protocol version available.\n", - __progname); - exit(1); - } - - if (options.user == NULL) - options.user = xstrdup(pw->pw_name); - - if (options.hostname != NULL) - host = options.hostname; - - /* Find canonic host name. */ - if (strchr(host, '.') == 0) { - struct addrinfo hints; - struct addrinfo *ai = NULL; - int errgai; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_flags = AI_CANONNAME; - hints.ai_socktype = SOCK_STREAM; - errgai = getaddrinfo(host, NULL, &hints, &ai); - if (errgai == 0) { - if (ai->ai_canonname != NULL) - host = xstrdup(ai->ai_canonname); - freeaddrinfo(ai); - } - } - /* Disable rhosts authentication if not running as root. */ - if (original_effective_uid != 0 || !options.use_privileged_port) { - options.rhosts_authentication = 0; - options.rhosts_rsa_authentication = 0; - } - /* - * If using rsh has been selected, exec it now (without trying - * anything else). Note that we must release privileges first. - */ - if (options.use_rsh) { - /* - * Restore our superuser privileges. This must be done - * before permanently setting the uid. - */ - restore_uid(); - - /* Switch to the original uid permanently. */ - permanently_set_uid(original_real_uid); - - /* Execute rsh. */ - rsh_connect(host, options.user, &command); - fatal("rsh_connect returned"); - } - /* Restore our superuser privileges. */ - restore_uid(); - - /* - * Open a connection to the remote host. This needs root privileges - * if rhosts_{rsa_}authentication is enabled. - */ - - ok = ssh_connect(host, &hostaddr, options.port, - options.connection_attempts, - !options.rhosts_authentication && - !options.rhosts_rsa_authentication, - original_real_uid, - options.proxy_command); - - /* - * 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 (ok && (options.protocol & SSH_PROTO_1)) { - Key k; - host_private_key = RSA_new(); - k.type = KEY_RSA; - k.rsa = host_private_key; - if (load_private_key(HOST_KEY_FILE, "", &k, NULL)) - host_private_key_loaded = 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. - */ - - /* - * Note that some legacy systems need to postpone the following call - * to permanently_set_uid() until the private hostkey is destroyed - * with RSA_free(). Otherwise the calling user could ptrace() the - * process, read the private hostkey and impersonate the host. - * OpenBSD does not allow ptracing of setuid processes. - */ - permanently_set_uid(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/%.100s", pw->pw_dir, SSH_USER_DIR); - if (stat(buf, &st) < 0) - if (mkdir(buf, 0755) < 0) - error("Could not create directory '%.200s'.", buf); - - /* Check if the connection failed, and try "rsh" if appropriate. */ - if (!ok) { - if (options.port != 0) - log("Secure connection to %.100s on port %hu refused%.100s.", - host, options.port, - options.fallback_to_rsh ? "; reverting to insecure method" : ""); - else - log("Secure connection to %.100s refused%.100s.", host, - options.fallback_to_rsh ? "; reverting to insecure method" : ""); - - if (options.fallback_to_rsh) { - rsh_connect(host, options.user, &command); - fatal("rsh_connect returned"); - } - exit(1); - } - /* Expand ~ in options.identity_files. */ - /* XXX mem-leaks */ - for (i = 0; i < options.num_identity_files; i++) - options.identity_files[i] = - tilde_expand_filename(options.identity_files[i], original_real_uid); - for (i = 0; i < options.num_identity_files2; i++) - options.identity_files2[i] = - tilde_expand_filename(options.identity_files2[i], original_real_uid); - /* Expand ~ in known host file names. */ - 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); - - /* Log into the remote system. This never returns if the login fails. */ - ssh_login(host_private_key_loaded, host_private_key, - host, (struct sockaddr *)&hostaddr, original_real_uid); - - /* We no longer need the host private key. Clear it now. */ - if (host_private_key_loaded) - RSA_free(host_private_key); /* Destroys contents safely */ - - exit_status = compat20 ? ssh_session2() : ssh_session(); - packet_close(); - return exit_status; -} - -void -x11_get_proto(char *proto, int proto_len, char *data, int data_len) -{ - char line[512]; - FILE *f; - int got_data = 0, i; - -#ifdef XAUTH_PATH - /* Try to get Xauthority information for the display. */ - snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null", - XAUTH_PATH, getenv("DISPLAY")); - f = popen(line, "r"); - if (f && fgets(line, sizeof(line), f) && - sscanf(line, "%*s %s %s", proto, data) == 2) - got_data = 1; - if (f) - pclose(f); -#endif /* XAUTH_PATH */ - /* - * If 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 rand = 0; - - strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len); - for (i = 0; i < 16; i++) { - if (i % 4 == 0) - rand = arc4random(); - snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff); - rand >>= 8; - } - } -} - -int -ssh_session(void) -{ - int type; - int i; - int plen; - int interactive = 0; - int have_tty = 0; - struct winsize ws; - int authfd; - char *cp; - - /* 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(&plen); - 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_string(cp, strlen(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)); - - /* Send the packet, and wait for it to leave. */ - packet_send(); - packet_write_wait(); - - /* Read response from the server. */ - type = packet_read(&plen); - 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. */ - if (options.forward_x11 && getenv("DISPLAY") != NULL) { - char proto[512], data[512]; - /* Get reasonable local authentication information. */ - x11_get_proto(proto, sizeof proto, data, sizeof data); - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(0, proto, data); - - /* Read response from the server. */ - type = packet_read(&plen); - 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, options.keepalives); - - /* Clear agent forwarding if we don\'t have an agent. */ - authfd = ssh_get_authentication_socket(); - if (authfd < 0) - options.forward_agent = 0; - else - ssh_close_authentication_socket(authfd); - - /* Request authentication agent forwarding if appropriate. */ - if (options.forward_agent) { - debug("Requesting authentication agent forwarding."); - auth_request_forwarding(); - - /* Read response from the server. */ - type = packet_read(&plen); - packet_integrity_check(plen, 0, type); - if (type != SSH_SMSG_SUCCESS) - log("Warning: Remote host denied authentication agent forwarding."); - } - /* Initiate local TCP/IP port forwardings. */ - for (i = 0; i < options.num_local_forwards; i++) { - debug("Connections to local port %d forwarded to remote address %.200s:%d", - options.local_forwards[i].port, - options.local_forwards[i].host, - options.local_forwards[i].host_port); - channel_request_local_forwarding(options.local_forwards[i].port, - options.local_forwards[i].host, - options.local_forwards[i].host_port, - options.gateway_ports); - } - - /* Initiate remote TCP/IP port forwardings. */ - for (i = 0; i < options.num_remote_forwards; i++) { - debug("Connections to remote port %d forwarded to local address %.200s:%d", - options.remote_forwards[i].port, - options.remote_forwards[i].host, - options.remote_forwards[i].host_port); - channel_request_remote_forwarding(options.remote_forwards[i].port, - options.remote_forwards[i].host, - options.remote_forwards[i].host_port); - } - - /* 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, 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 : -1); -} - -void -init_local_fwd(void) -{ - int i; - /* Initiate local TCP/IP port forwardings. */ - for (i = 0; i < options.num_local_forwards; i++) { - debug("Connections to local port %d forwarded to remote address %.200s:%d", - options.local_forwards[i].port, - options.local_forwards[i].host, - options.local_forwards[i].host_port); - channel_request_local_forwarding(options.local_forwards[i].port, - options.local_forwards[i].host, - options.local_forwards[i].host_port, - options.gateway_ports); - } -} - -extern void client_set_session_ident(int id); - -void -client_init(int id, void *arg) -{ - int len; - debug("client_init id %d arg %d", id, (int)arg); - - if (no_shell_flag) - goto done; - - 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); - packet_put_cstring(""); /* XXX: encode terminal modes */ - packet_send(); - /* XXX wait for reply */ - } - if (options.forward_x11 && - getenv("DISPLAY") != NULL) { - char proto[512], data[512]; - /* Get reasonable local authentication information. */ - x11_get_proto(proto, sizeof proto, data, sizeof data); - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(id, proto, data); - /* XXX wait for reply */ - } - - len = buffer_len(&command); - if (len > 0) { - if (len > 900) - len = 900; - debug("Sending command: %.*s", len, buffer_ptr(&command)); - channel_request_start(id, "exec", 0); - packet_put_string(buffer_ptr(&command), len); - packet_send(); - } else { - channel_request(id, "shell", 0); - } - /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */ -done: - /* register different callback, etc. XXX */ - client_set_session_ident(id); -} - -int -ssh_session2(void) -{ - int window, packetmax, id; - int in = dup(STDIN_FILENO); - int out = dup(STDOUT_FILENO); - int err = dup(STDERR_FILENO); - - if (in < 0 || out < 0 || err < 0) - fatal("dump in/out/err failed"); - - /* should be pre-session */ - init_local_fwd(); - - window = 32*1024; - if (tty_flag) { - packetmax = window/8; - } else { - window *= 2; - packetmax = window/2; - } - - id = channel_new( - "session", SSH_CHANNEL_OPENING, in, out, err, - window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session")); - - - channel_open(id); - channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); - - return client_loop(tty_flag, tty_flag ? options.escape_char : -1); -} diff --git a/crypto/openssh/ssh.h b/crypto/openssh/ssh.h deleted file mode 100644 index 0762c964ca26..000000000000 --- a/crypto/openssh/ssh.h +++ /dev/null @@ -1,508 +0,0 @@ -/* - * - * ssh.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Fri Mar 17 17:09:37 1995 ylo - * - * Generic header file for ssh. - * - */ - -/* RCSID("$Id: ssh.h,v 1.45 2000/05/08 17:12:16 markus Exp $"); */ - -#ifndef SSH_H -#define SSH_H - -#include "rsa.h" -#include "cipher.h" - -/* - * XXX - * The default cipher used if IDEA is not supported by the remote host. It is - * recommended that this be one of the mandatory ciphers (DES, 3DES), though - * that is not required. - */ -#define SSH_FALLBACK_CIPHER SSH_CIPHER_3DES - -/* 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 incompatiblity - * 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" - -#define ETCDIR "/etc" -#define PIDDIR "/var/run" - -/* - * System-wide file containing host keys of known hosts. This file should be - * world-readable. - */ -#define SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts" -#define SSH_SYSTEM_HOSTFILE2 ETCDIR "/ssh_known_hosts2" - -/* - * Of these, ssh_host_key must be readable only by root, whereas ssh_config - * should be world-readable. - */ -#define HOST_KEY_FILE ETCDIR "/ssh_host_key" -#define SERVER_CONFIG_FILE ETCDIR "/sshd_config" -#define HOST_CONFIG_FILE ETCDIR "/ssh_config" -#define HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key" - -#define SSH_PROGRAM "/usr/bin/ssh" - -/* - * The process id of the daemon listening for connections is saved here to - * make it easier to kill the correct daemon when necessary. - */ -#define SSH_DAEMON_PID_FILE 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 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 SSH_USER_HOSTFILE "~/.ssh/known_hosts" -#define 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 SSH_CLIENT_IDENTITY ".ssh/identity" -#define SSH_CLIENT_ID_DSA ".ssh/id_dsa" - -/* - * 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 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 SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" -#define 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 SSH_USER_RC ".ssh/rc" -#define SSH_SYSTEM_RC ETCDIR "/sshrc" - -/* - * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use - * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled. - */ -#define SSH_HOSTS_EQUIV ETCDIR "/shosts.equiv" - -/* - * Name of the environment variable containing the pathname of the - * authentication socket. - */ -#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" - -/* - * Name of the environment variable containing the pathname of the - * authentication socket. - */ -#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" - -/* - * Default path to ssh-askpass used by ssh-add, - * environment variable for overwriting the default location - */ -#define SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-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" - -/* - * 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 */ - -/* - * 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) */ - -/*------------ definitions for login.c -------------*/ - -/* - * 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 from which the user logged in is stored in buf. - */ -unsigned long -get_last_login_time(uid_t uid, const char *logname, - char *buf, unsigned int bufsize); - -/* - * Records that the user has logged in. This does many things normally done - * by login(1). - */ -void -record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, - const char *host, struct sockaddr *addr); - -/* - * Records that the user has logged out. This does many thigs normally done - * by login(1) or init. - */ -void record_logout(pid_t pid, const char *ttyname); - -/*------------ definitions for sshconnect.c ----------*/ - -/* - * Opens a TCP/IP connection to the remote server on the given host. If port - * is 0, the default port will be used. If anonymous is zero, a privileged - * port will be allocated to make the connection. This requires super-user - * privileges if anonymous is false. Connection_attempts specifies the - * maximum number of tries, one per second. This returns true on success, - * and zero on failure. If the connection is successful, this calls - * packet_set_connection for the connection. - */ -int -ssh_connect(const char *host, struct sockaddr_storage * hostaddr, - u_short port, int connection_attempts, - int anonymous, uid_t original_real_uid, - const char *proxy_command); - -/* - * 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 - * initializes the random state, and leaves it initialized (it will also have - * references from the packet module). - */ - -void -ssh_login(int host_key_valid, RSA * host_key, const char *host, - struct sockaddr * hostaddr, uid_t original_real_uid); - -/*------------ Definitions for various authentication methods. -------*/ - -/* - * Tries to authenticate the user using the .rhosts file. Returns true if - * authentication succeeds. If ignore_rhosts is non-zero, this will not - * consider .rhosts and .shosts (/etc/hosts.equiv will still be used). - */ -int auth_rhosts(struct passwd * pw, const char *client_user); - -/* - * 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, const char *client_user, RSA* client_host_key); - -/* - * Tries to authenticate the user using password. Returns true if - * authentication succeeds. - */ -int auth_password(struct passwd * pw, const char *password); - -/* - * 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); - -/* - * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer - * over the key. Skips any whitespace at the beginning and at end. - */ -int auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n); - -/* - * Returns the name of the machine at the other end of the socket. The - * returned string should be freed by the caller. - */ -char *get_remote_hostname(int socket); - -/* - * Return the canonical name of the host in the other side of the current - * connection (as returned by packet_get_connection). The host name is - * cached, so it is efficient to call this several times. - */ -const char *get_canonical_hostname(void); - -/* - * Returns the remote IP address as an ascii string. The value need not be - * freed by the caller. - */ -const char *get_remote_ipaddr(void); - -/* Returns the port number of the peer of the socket. */ -int get_peer_port(int sock); - -/* Returns the port number of the remote/local host. */ -int get_remote_port(void); -int get_local_port(void); - - -/* - * 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(RSA *pk); - -/* - * Reads a passphrase from /dev/tty with echo turned off. Returns the - * passphrase (allocated with xmalloc). Exits if EOF is encountered. If - * from_stdin is true, the passphrase will be read from stdin instead. - */ -char *read_passphrase(const char *prompt, int from_stdin); - - -/*------------ Definitions for logging. -----------------------*/ - -/* Supported syslog facilities and levels. */ -typedef enum { - SYSLOG_FACILITY_DAEMON, - SYSLOG_FACILITY_USER, - SYSLOG_FACILITY_AUTH, - SYSLOG_FACILITY_LOCAL0, - SYSLOG_FACILITY_LOCAL1, - SYSLOG_FACILITY_LOCAL2, - SYSLOG_FACILITY_LOCAL3, - SYSLOG_FACILITY_LOCAL4, - SYSLOG_FACILITY_LOCAL5, - SYSLOG_FACILITY_LOCAL6, - SYSLOG_FACILITY_LOCAL7 -} SyslogFacility; - -typedef enum { - SYSLOG_LEVEL_QUIET, - SYSLOG_LEVEL_FATAL, - SYSLOG_LEVEL_ERROR, - SYSLOG_LEVEL_INFO, - SYSLOG_LEVEL_VERBOSE, - SYSLOG_LEVEL_DEBUG -} LogLevel; -/* Initializes logging. */ -void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr); - -/* Logging implementation, depending on server or client */ -void do_log(LogLevel level, const char *fmt, va_list args); - -/* name to facility/level */ -SyslogFacility log_facility_number(char *name); -LogLevel log_level_number(char *name); - -/* Output a message to syslog or stderr */ -void fatal(const char *fmt,...) __attribute__((format(printf, 1, 2))); -void error(const char *fmt,...) __attribute__((format(printf, 1, 2))); -void log(const char *fmt,...) __attribute__((format(printf, 1, 2))); -void verbose(const char *fmt,...) __attribute__((format(printf, 1, 2))); -void debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); - -/* same as fatal() but w/o logging */ -void fatal_cleanup(void); - -/* - * Registers a cleanup function to be called by fatal()/fatal_cleanup() - * before exiting. It is permissible to call fatal_remove_cleanup for the - * function itself from the function. - */ -void fatal_add_cleanup(void (*proc) (void *context), void *context); - -/* Removes a cleanup function to be called at fatal(). */ -void fatal_remove_cleanup(void (*proc) (void *context), void *context); - -/* ---- misc */ - -/* - * 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); - -/* - * 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, int fdout, int fderr); -void server_loop2(void); - -/* Client side main loop for the interactive session. */ -int client_loop(int have_pty, int escape_char); - -/* Linked list of custom environment strings (see auth-rsa.c). */ -struct envstring { - struct envstring *next; - char *s; -}; - -/* - * Ensure all of data on socket comes through. f==read || f==write - */ -ssize_t atomicio(ssize_t (*f)(), int fd, void *s, size_t n); - -#ifdef KRB4 -#include <krb.h> -/* - * Performs Kerberos v4 mutual authentication 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_krb4(const char *server_user, KTEXT auth, char **client); -int krb4_init(uid_t uid); -void krb4_cleanup_proc(void *ignore); -int auth_krb4_password(struct passwd * pw, const char *password); - -#ifdef AFS -#include <kafs.h> - -/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */ -int auth_kerberos_tgt(struct passwd * pw, const char *string); -int auth_afs_token(struct passwd * pw, const char *token_string); - -int creds_to_radix(CREDENTIALS * creds, unsigned char *buf, size_t buflen); -int radix_to_creds(const char *buf, CREDENTIALS * creds); -#endif /* AFS */ - -#endif /* KRB4 */ - -#ifdef SKEY -#include <skey.h> -char *skey_fake_keyinfo(char *username); -int auth_skey_password(struct passwd * pw, const char *password); -#endif /* SKEY */ - -/* AF_UNSPEC or AF_INET or AF_INET6 */ -extern int IPv4or6; - -#endif /* SSH_H */ diff --git a/crypto/openssh/ssh/Makefile b/crypto/openssh/ssh/Makefile deleted file mode 100644 index a87d5dce0a44..000000000000 --- a/crypto/openssh/ssh/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -.PATH: ${.CURDIR}/.. - -PROG= ssh -BINOWN= root - -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else -BINMODE?=4555 -.endif - -BINDIR= /usr/bin -MAN= ssh.1 -LINKS= ${BINDIR}/ssh ${BINDIR}/slogin -MLINKS= ssh.1 slogin.1 - -SRCS= ssh.c log-client.c readconf.c clientloop.c \ - sshconnect.c sshconnect1.c sshconnect2.c - -.include <bsd.own.mk> # for AFS - -.if (${KERBEROS} == "yes") -CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV -LDADD+= -lkrb -DPADD+= ${LIBKRB} -.if (${AFS} == "yes") -CFLAGS+= -DAFS -LDADD+= -lkafs -DPADD+= ${LIBKRBAFS} -.endif # AFS -.endif # KERBEROS - -.include <bsd.prog.mk> - -LDADD+= -lutil -lz -lcrypto -DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h deleted file mode 100644 index cf684bacf969..000000000000 --- a/crypto/openssh/ssh2.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * draft-ietf-secsh-architecture-04.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 - */ - -/* 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 - -/* 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 - -/* 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_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 - -/* 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 diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config deleted file mode 100644 index 6ecb0efde3f8..000000000000 --- a/crypto/openssh/ssh_config +++ /dev/null @@ -1,31 +0,0 @@ -# This is ssh client systemwide configuration file. This file provides -# defaults for users, and the values can be changed in per-user configuration -# files or on the command line. - -# 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. - -# Site-wide defaults for various options - -# Host * -# ForwardAgent yes -# ForwardX11 yes -# RhostsAuthentication yes -# RhostsRSAAuthentication yes -# RSAAuthentication yes -# PasswordAuthentication yes -# FallBackToRsh yes -# UseRsh no -# BatchMode no -# CheckHostIP yes -# StrictHostKeyChecking no -# IdentityFile ~/.ssh/identity -# Port 22 -# Protocol 2,1 -# Cipher blowfish -# EscapeChar ~ diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c deleted file mode 100644 index 80beac30680a..000000000000 --- a/crypto/openssh/sshconnect.c +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Sat Mar 18 22:15:47 1995 ylo - * Code to connect to a remote host, and to perform the client side of the - * login (authentication) dialog. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.72 2000/05/04 09:50:22 markus Exp $"); - -#include <openssl/bn.h> -#include <openssl/dsa.h> -#include <openssl/rsa.h> - -#include "xmalloc.h" -#include "rsa.h" -#include "ssh.h" -#include "buffer.h" -#include "packet.h" -#include "uidswap.h" -#include "compat.h" -#include "readconf.h" -#include "key.h" -#include "sshconnect.h" -#include "hostfile.h" - -char *client_version_string = NULL; -char *server_version_string = NULL; - -extern Options options; -extern char *__progname; - -/* - * Connect to the given ssh server using a proxy command. - */ -int -ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid, - 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. */ - buffer_init(&command); - 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. */ - permanently_set_uid(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] = "/bin/sh"; - argv[1] = "-c"; - argv[2] = command_string; - argv[3] = NULL; - - /* Execute the proxy command. Note that we gave up any - extra privileges above. */ - execv("/bin/sh", argv); - perror("/bin/sh"); - exit(1); - } - /* Parent. */ - if (pid < 0) - fatal("fork failed: %.100s", strerror(errno)); - - /* 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]); - - return 1; -} - -/* - * Creates a (possibly privileged) socket for use as the ssh connection. - */ -int -ssh_create_socket(uid_t original_real_uid, int privileged, int family) -{ - int sock; - - /* - * 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; - sock = rresvport_af(&p, family); - if (sock < 0) - error("rresvport: af=%d %.100s", family, strerror(errno)); - else - debug("Allocated local port %d.", p); - } else { - /* - * Just create an ordinary socket on arbitrary port. We use - * the user's uid to create the socket. - */ - temporarily_use_uid(original_real_uid); - sock = socket(family, SOCK_STREAM, 0); - if (sock < 0) - error("socket: %.100s", strerror(errno)); - restore_uid(); - } - return sock; -} - -/* - * 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 anonymous is zero, - * a privileged port will be allocated to make the connection. - * This requires super-user privileges if anonymous is false. - * 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. - */ -int -ssh_connect(const char *host, struct sockaddr_storage * hostaddr, - u_short port, int connection_attempts, - int anonymous, uid_t original_real_uid, - const char *proxy_command) -{ - int sock = -1, attempt; - struct servent *sp; - struct addrinfo hints, *ai, *aitop; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int gaierr; - struct linger linger; - - debug("ssh_connect: getuid %d geteuid %d anon %d", - (int) getuid(), (int) geteuid(), anonymous); - - /* 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, original_real_uid, proxy_command); - - /* No proxy command. */ - - 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) - 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; attempt < connection_attempts; attempt++) { - 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(original_real_uid, - !anonymous && geteuid() == 0 && port < IPPORT_RESERVED, - ai->ai_family); - if (sock < 0) - continue; - - /* Connect to the host. We use the user's uid in the - * hope that it will help with tcp_wrappers showing - * the remote uid as root. - */ - temporarily_use_uid(original_real_uid); - if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { - /* Successful connection. */ - memcpy(hostaddr, ai->ai_addr, sizeof(*hostaddr)); - restore_uid(); - break; - } else { - debug("connect: %.100s", strerror(errno)); - restore_uid(); - /* - * Close the failed socket; there appear to - * be some problems when reusing a socket for - * which connect() has already returned an - * error. - */ - shutdown(sock, SHUT_RDWR); - close(sock); - } - } - if (ai) - break; /* Successful connection. */ - - /* Sleep a moment before retrying. */ - sleep(1); - } - - freeaddrinfo(aitop); - - /* Return failure if we didn't get a successful connection. */ - if (attempt >= connection_attempts) - return 0; - - debug("Connection established."); - - /* - * Set socket options. We would like the socket to disappear as soon - * as it has been closed for whatever reason. - */ - /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ - linger.l_onoff = 1; - linger.l_linger = 5; - setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); - - /* Set the connection. */ - packet_set_connection(sock, sock); - - return 1; -} - -char * -chop(char *s) -{ - char *t = s; - while (*t) { - if(*t == '\n' || *t == '\r') { - *t = '\0'; - return s; - } - t++; - } - return s; - -} - -/* - * Waits for the server identification string, and sends our own - * identification string. - */ -void -ssh_exchange_identification() -{ - 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(); - - /* Read other side\'s version identification. */ - for (i = 0; i < sizeof(buf) - 1; i++) { - int len = read(connection_in, &buf[i], 1); - if (len < 0) - fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); - if (len != 1) - fatal("ssh_exchange_identification: Connection closed by remote host"); - if (buf[i] == '\r') { - buf[i] = '\n'; - buf[i + 1] = 0; - continue; /**XXX wait for \n */ - } - if (buf[i] == '\n') { - buf[i + 1] = 0; - break; - } - } - buf[sizeof(buf) - 1] = 0; - 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) { - /* We speak 1.3, too. */ - enable_compat13(); - 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); - if (compat20) - packet_set_ssh2_format(); - /* 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 : PROTOCOL_MINOR_1, - 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); -} - -int -read_yes_or_no(const char *prompt, int defval) -{ - char buf[1024]; - FILE *f; - int retval = -1; - - if (isatty(0)) - f = stdin; - else - f = fopen("/dev/tty", "rw"); - - if (f == NULL) - return 0; - - fflush(stdout); - - while (1) { - fprintf(stderr, "%s", prompt); - if (fgets(buf, sizeof(buf), f) == NULL) { - /* Print a newline (the prompt probably didn\'t have one). */ - fprintf(stderr, "\n"); - strlcpy(buf, "no", sizeof buf); - } - /* Remove newline from response. */ - if (strchr(buf, '\n')) - *strchr(buf, '\n') = 0; - - if (buf[0] == 0) - retval = defval; - if (strcmp(buf, "yes") == 0) - retval = 1; - if (strcmp(buf, "no") == 0) - retval = 0; - - if (retval != -1) { - if (f != stdin) - fclose(f); - return retval; - } - } -} - -/* - * check whether the supplied host key is valid, return only if ok. - */ - -void -check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, - const char *user_hostfile, const char *system_hostfile) -{ - Key *file_key; - char *type = key_type(host_key); - char *ip = NULL; - char hostline[1000], *hostp; - HostStatus host_status; - HostStatus ip_status; - int local = 0, host_ip_differ = 0; - char ntop[NI_MAXHOST]; - - /* - * 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: - local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; - break; - case AF_INET6: - local = IN6_IS_ADDR_LOOPBACK(&(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); - break; - default: - local = 0; - break; - } - if (local) { - debug("Forcing accepting of host key for loopback/localhost."); - return; - } - - /* - * Turn off check_host_ip for proxy connects, since - * we don't have the remote ip-address - */ - if (options.proxy_command != NULL && options.check_host_ip) - options.check_host_ip = 0; - - if (options.check_host_ip) { - if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop), - NULL, 0, NI_NUMERICHOST) != 0) - fatal("check_host_key: getnameinfo failed"); - ip = xstrdup(ntop); - } - - /* - * 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_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key); - if (host_status == HOST_NEW) - host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key); - /* - * 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 && !local && strcmp(host, ip)) { - Key *ip_key = key_new(host_key->type); - ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key); - - if (ip_status == HOST_NEW) - ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key); - 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. */ - debug("Host '%.200s' is known and matches the %s host key.", - host, type); - if (options.check_host_ip) { - if (ip_status == HOST_NEW) { - if (!add_host_to_hostfile(user_hostfile, ip, host_key)) - log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).", - type, ip, user_hostfile); - else - log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.", - type, ip); - } else if (ip_status != HOST_OK) - log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'", - type, host, ip); - } - break; - case HOST_NEW: - /* The host is new. */ - if (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. */ - fatal("No %s host key is known for %.200s and you have requested strict checking.", type, host); - } else if (options.strict_host_key_checking == 2) { - /* The default */ - char prompt[1024]; - char *fp = key_fingerprint(host_key); - snprintf(prompt, sizeof(prompt), - "The authenticity of host '%.200s' can't be established.\n" - "%s key fingerprint is %s.\n" - "Are you sure you want to continue connecting (yes/no)? ", - host, type, fp); - if (!read_yes_or_no(prompt, -1)) - fatal("Aborted by user!\n"); - } - if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) { - snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); - hostp = hostline; - } else - hostp = host; - - /* If not in strict mode, add the key automatically to the local known_hosts file. */ - if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) - 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 (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("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("The %s host key for %s has changed,", type, host); - error("and the key for the according IP address %s", ip); - error("%s. This could either mean that", msg); - error("DNS SPOOFING is happening or the IP address for the host"); - error("and its host key have changed at the same time"); - } - /* The host key has changed. */ - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); - error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); - error("It is also possible that the %s host key has just been changed.", type); - error("Please contact your system administrator."); - error("Add correct host key in %.100s to get rid of this message.", - user_hostfile); - - /* - * 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) - fatal("%s host key for %.200s has changed and you have requested strict checking.", type, host); - - /* - * 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 trojan horses."); - options.password_authentication = 0; - } - if (options.forward_agent) { - error("Agent forwarding is disabled to avoid trojan horses."); - options.forward_agent = 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; - } - if (options.check_host_ip) - xfree(ip); -} - -/* - * 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(int host_key_valid, RSA *own_host_key, const char *orighost, - struct sockaddr *hostaddr, uid_t original_real_uid) -{ - struct passwd *pw; - char *host, *cp; - char *server_user, *local_user; - - /* Get local user name. Use it as server user if no user name was given. */ - pw = getpwuid(original_real_uid); - if (!pw) - fatal("User id %d not found from user database.", original_real_uid); - local_user = xstrdup(pw->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(); - - /* Put the connection into non-blocking mode. */ - packet_set_nonblocking(); - - /* key exchange */ - /* authenticate user */ - if (compat20) { - ssh_kex2(host, hostaddr); - ssh_userauth2(server_user, host); - } else { - ssh_kex(host, hostaddr); - ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key); - } -} diff --git a/crypto/openssh/sshconnect.h b/crypto/openssh/sshconnect.h deleted file mode 100644 index 13d395fd634d..000000000000 --- a/crypto/openssh/sshconnect.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef SSHCONNECT_H -#define SSHCONNECT_H - -void -check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, - const char *user_hostfile, const char *system_hostfile); - -void ssh_kex(char *host, struct sockaddr *hostaddr); -void -ssh_userauth(const char* local_user, const char* server_user, char *host, - int host_key_valid, RSA *own_host_key); - -void ssh_kex2(char *host, struct sockaddr *hostaddr); -void ssh_userauth2(const char *server_user, char *host); - -#endif diff --git a/crypto/openssh/sshconnect1.c b/crypto/openssh/sshconnect1.c deleted file mode 100644 index 4360d7283d86..000000000000 --- a/crypto/openssh/sshconnect1.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Sat Mar 18 22:15:47 1995 ylo - * Code to connect to a remote host, and to perform the client side of the - * login (authentication) dialog. - * - */ - -#include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $"); - -#include <openssl/bn.h> -#include <openssl/dsa.h> -#include <openssl/rsa.h> -#include <openssl/evp.h> - -#include "xmalloc.h" -#include "rsa.h" -#include "ssh.h" -#include "buffer.h" -#include "packet.h" -#include "authfd.h" -#include "cipher.h" -#include "mpaux.h" -#include "uidswap.h" -#include "readconf.h" -#include "key.h" -#include "sshconnect.h" -#include "authfile.h" - -/* Session id for the current session. */ -unsigned char session_id[16]; -unsigned 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. - */ -int -try_agent_authentication() -{ - int status, type; - char *comment; - AuthenticationConnection *auth; - unsigned char response[16]; - unsigned int i; - BIGNUM *e, *n, *challenge; - - /* Get connection to the agent. */ - auth = ssh_get_authentication_connection(); - if (!auth) - return 0; - - e = BN_new(); - n = BN_new(); - challenge = BN_new(); - - /* Loop through identities served by the agent. */ - for (status = ssh_get_first_identity(auth, e, n, &comment); - status; - status = ssh_get_next_identity(auth, e, n, &comment)) { - int plen, clen; - - /* 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(n); - packet_send(); - packet_write_wait(); - - /* Wait for server's response. */ - type = packet_read(&plen); - - /* 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."); - 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, &clen); - - packet_integrity_check(plen, clen, type); - - debug("Received RSA challenge from server."); - - /* Ask the agent to decrypt the challenge. */ - if (!ssh_decrypt_challenge(auth, e, n, challenge, - session_id, 1, response)) { - /* The agent failed to authenticate this identifier although it - advertised it supports this. Just return a wrong value. */ - log("Authentication agent failed to decrypt challenge."); - memset(response, 0, sizeof(response)); - } - 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(&plen); - - /* The server returns success if it accepted the authentication. */ - if (type == SSH_SMSG_SUCCESS) { - debug("RSA authentication accepted by server."); - BN_clear_free(e); - BN_clear_free(n); - BN_clear_free(challenge); - return 1; - } - /* Otherwise it should return failure. */ - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error waiting RSA auth response: %d", - type); - } - - BN_clear_free(e); - BN_clear_free(n); - BN_clear_free(challenge); - - debug("RSA authentication using agent refused."); - return 0; -} - -/* - * Computes the proper response to a RSA challenge, and sends the response to - * the server. - */ -void -respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) -{ - unsigned char buf[32], response[16]; - MD5_CTX md; - int i, len; - - /* Decrypt the challenge using the private key. */ - rsa_private_decrypt(challenge, challenge, prv); - - /* 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. - */ -int -try_rsa_authentication(const char *authfile) -{ - BIGNUM *challenge; - Key *public; - Key *private; - char *passphrase, *comment; - int type, i; - int plen, clen; - - /* Try to load identification for the authentication key. */ - public = key_new(KEY_RSA); - if (!load_public_key(authfile, public, &comment)) { - key_free(public); - /* Could not load it. Fail. */ - return 0; - } - 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(); - - /* We no longer need the public key. */ - key_free(public); - - /* Wait for server's response. */ - type = packet_read(&plen); - - /* - * 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. */ - challenge = BN_new(); - packet_get_bignum(challenge, &clen); - - packet_integrity_check(plen, clen, type); - - debug("Received RSA challenge from server."); - - private = key_new(KEY_RSA); - /* - * Load the private key. Try first with empty passphrase; if it - * fails, ask for a passphrase. - */ - if (!load_private_key(authfile, "", private, NULL)) { - char buf[300]; - snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", - comment); - if (!options.batch_mode) - passphrase = read_passphrase(buf, 0); - else { - debug("Will not query passphrase for %.100s in batch mode.", - comment); - passphrase = xstrdup(""); - } - - /* Load the authentication file using the pasphrase. */ - if (!load_private_key(authfile, passphrase, private, NULL)) { - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - 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(&plen, SSH_SMSG_FAILURE); - xfree(comment); - return 0; - } - /* Destroy the passphrase. */ - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - } - /* We no longer need the comment. */ - xfree(comment); - - /* Compute and send a response to the challenge. */ - respond_to_rsa_challenge(challenge, private->rsa); - - /* Destroy the private key. */ - key_free(private); - - /* We no longer need the challenge. */ - BN_clear_free(challenge); - - /* Wait for response from the server. */ - type = packet_read(&plen); - 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. - */ -int -try_rhosts_rsa_authentication(const char *local_user, RSA * host_key) -{ - int type; - BIGNUM *challenge; - int plen, clen; - - 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_string(local_user, strlen(local_user)); - packet_put_int(BN_num_bits(host_key->n)); - packet_put_bignum(host_key->e); - packet_put_bignum(host_key->n); - packet_send(); - packet_write_wait(); - - /* Wait for server's response. */ - type = packet_read(&plen); - - /* 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. */ - challenge = BN_new(); - packet_get_bignum(challenge, &clen); - - packet_integrity_check(plen, clen, type); - - debug("Received RSA challenge for host key from server."); - - /* Compute a response to the challenge. */ - respond_to_rsa_challenge(challenge, host_key); - - /* We no longer need the challenge. */ - BN_clear_free(challenge); - - /* Wait for response from the server. */ - type = packet_read(&plen); - 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 -int -try_kerberos_authentication() -{ - KTEXT_ST auth; /* Kerberos data */ - char *reply; - char inst[INST_SZ]; - char *realm; - CREDENTIALS cred; - int r, type, plen; - 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; - - strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ); - - realm = (char *) krb_realmofhost(get_canonical_hostname()); - if (!realm) { - debug("Kerberos V4: no realm for %s", get_canonical_hostname()); - 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(&plen); - 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((unsigned int *) &auth.length); - memcpy(auth.dat, reply, auth.length); - xfree(reply); - - packet_integrity_check(plen, 4 + auth.length, type); - - /* - * 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. */ - (void) 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 AFS -int -send_kerberos_tgt() -{ - CREDENTIALS *creds; - char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; - int r, type, plen; - char buffer[8192]; - struct stat st; - - /* Don't do anything if we don't have any tickets. */ - if (stat(tkt_string(), &st) < 0) - return 0; - - creds = xmalloc(sizeof(*creds)); - - if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) { - debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]); - return 0; - } - if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { - debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); - return 0; - } - if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { - debug("Kerberos V4 ticket expired: %s", TKT_FILE); - return 0; - } - creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer); - xfree(creds); - - packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); - packet_put_string(buffer, strlen(buffer)); - packet_send(); - packet_write_wait(); - - type = packet_read(&plen); - - if (type == SSH_SMSG_FAILURE) - debug("Kerberos TGT for realm %s rejected.", prealm); - else if (type != SSH_SMSG_SUCCESS) - packet_disconnect("Protocol error on Kerberos TGT response: %d", type); - - return 1; -} - -void -send_afs_tokens(void) -{ - CREDENTIALS creds; - struct ViceIoctl parms; - struct ClearToken ct; - int i, type, len, plen; - 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(unsigned int)); - if (creds.ticket_st.length > MAX_KTXT_LEN) - break; - p += sizeof(unsigned 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, (unsigned char*) buffer, sizeof buffer) <= 0) - break; - packet_start(SSH_CMSG_HAVE_AFS_TOKEN); - packet_put_string(buffer, strlen(buffer)); - packet_send(); - packet_write_wait(); - - /* Roger, Roger. Clearance, Clarence. What's your vector, - Victor? */ - type = packet_read(&plen); - - 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. - */ -int -try_skey_authentication() -{ - int type, i; - int payload_len; - unsigned int clen; - char *challenge, *response; - - debug("Doing skey authentication."); - - /* request a challenge */ - packet_start(SSH_CMSG_AUTH_TIS); - packet_send(); - packet_write_wait(); - - type = packet_read(&payload_len); - if (type != SSH_SMSG_FAILURE && - type != SSH_SMSG_AUTH_TIS_CHALLENGE) { - packet_disconnect("Protocol error: got %d in response " - "to skey-auth", type); - } - if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { - debug("No challenge for skey authentication."); - return 0; - } - challenge = packet_get_string(&clen); - packet_integrity_check(payload_len, (4 + clen), type); - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! " - "Reponse will be transmitted in clear text."); - fprintf(stderr, "%s\n", challenge); - xfree(challenge); - fflush(stderr); - for (i = 0; i < options.number_of_password_prompts; i++) { - if (i != 0) - error("Permission denied, please try again."); - response = read_passphrase("Response: ", 0); - packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); - packet_put_string(response, strlen(response)); - memset(response, 0, strlen(response)); - xfree(response); - packet_send(); - packet_write_wait(); - type = packet_read(&payload_len); - if (type == SSH_SMSG_SUCCESS) - return 1; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response " - "to skey-auth-reponse", type); - } - /* failure */ - return 0; -} - -/* - * Tries to authenticate with plain passwd authentication. - */ -int -try_password_authentication(char *prompt) -{ - int type, i, payload_len; - 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); - packet_put_string(password, strlen(password)); - memset(password, 0, strlen(password)); - xfree(password); - packet_send(); - packet_write_wait(); - - type = packet_read(&payload_len); - 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; - RSA *host_key; - RSA *public_key; - Key k; - int bits, rbits; - int ssh_cipher_default = SSH_CIPHER_3DES; - unsigned char session_key[SSH_SESSION_KEY_LENGTH]; - unsigned char cookie[8]; - unsigned int supported_ciphers; - unsigned int server_flags, client_flags; - int payload_len, clen, sum_len = 0; - u_int32_t rand = 0; - - debug("Waiting for server public key."); - - /* Wait for a public key packet from the server. */ - packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); - - /* Get cookie from the packet. */ - for (i = 0; i < 8; i++) - cookie[i] = packet_get_char(); - - /* Get the public key. */ - public_key = RSA_new(); - bits = packet_get_int();/* bits */ - public_key->e = BN_new(); - packet_get_bignum(public_key->e, &clen); - sum_len += clen; - public_key->n = BN_new(); - packet_get_bignum(public_key->n, &clen); - sum_len += clen; - - rbits = BN_num_bits(public_key->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 = RSA_new(); - bits = packet_get_int();/* bits */ - host_key->e = BN_new(); - packet_get_bignum(host_key->e, &clen); - sum_len += clen; - host_key->n = BN_new(); - packet_get_bignum(host_key->n, &clen); - sum_len += clen; - - rbits = BN_num_bits(host_key->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(); - - debug("Received server public key (%d bits) and host key (%d bits).", - BN_num_bits(public_key->n), BN_num_bits(host_key->n)); - - packet_integrity_check(payload_len, - 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, - SSH_SMSG_PUBLIC_KEY); - k.type = KEY_RSA; - k.rsa = host_key; - check_host_key(host, hostaddr, &k, - options.user_hostfile, options.system_hostfile); - - client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; - - compute_session_id(session_id, cookie, host_key->n, public_key->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. - */ - key = BN_new(); - 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(public_key->n, host_key->n) < 0) { - /* Public key has smaller modulus. */ - if (BN_num_bits(host_key->n) < - BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: host_key %d < public_key %d + " - "SSH_KEY_BITS_RESERVED %d", - BN_num_bits(host_key->n), - BN_num_bits(public_key->n), - SSH_KEY_BITS_RESERVED); - } - rsa_public_encrypt(key, key, public_key); - rsa_public_encrypt(key, key, host_key); - } else { - /* Host key has smaller modulus (or they are equal). */ - if (BN_num_bits(public_key->n) < - BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: public_key %d < host_key %d + " - "SSH_KEY_BITS_RESERVED %d", - BN_num_bits(public_key->n), - BN_num_bits(host_key->n), - SSH_KEY_BITS_RESERVED); - } - rsa_public_encrypt(key, key, host_key); - rsa_public_encrypt(key, key, public_key); - } - - /* Destroy the public keys since we no longer need them. */ - RSA_free(public_key); - RSA_free(host_key); - - if (options.cipher == SSH_CIPHER_ILLEGAL) { - log("No valid SSH1 cipher, using %.100s instead.", - cipher_name(SSH_FALLBACK_CIPHER)); - options.cipher = SSH_FALLBACK_CIPHER; - } else if (options.cipher == SSH_CIPHER_NOT_SET) { - if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default)) - options.cipher = ssh_cipher_default; - else { - debug("Cipher %s not supported, using %.100s instead.", - cipher_name(ssh_cipher_default), - cipher_name(SSH_FALLBACK_CIPHER)); - options.cipher = SSH_FALLBACK_CIPHER; - } - } - /* 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(&payload_len, SSH_SMSG_SUCCESS); - - debug("Received encrypted confirmation."); -} - -/* - * Authenticate user - */ -void -ssh_userauth( - const char* local_user, - const char* server_user, - char *host, - int host_key_valid, RSA *own_host_key) -{ - int i, type; - int payload_len; - - if (supported_authentications == 0) - fatal("ssh_userauth: 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_string(server_user, strlen(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(&payload_len); - - /* check whether the connection was accepted without authentication. */ - if (type == SSH_SMSG_SUCCESS) - return; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", - type); - -#ifdef AFS - /* Try Kerberos 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!"); - (void) send_kerberos_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 */ - -#ifdef KRB4 - if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && - options.kerberos_authentication) { - debug("Trying Kerberos authentication."); - if (try_kerberos_authentication()) { - /* The server should respond with success or failure. */ - type = packet_read(&payload_len); - if (type == SSH_SMSG_SUCCESS) - return; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos 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_string(local_user, strlen(local_user)); - packet_send(); - packet_write_wait(); - - /* The server should respond with success or failure. */ - type = packet_read(&payload_len); - if (type == SSH_SMSG_SUCCESS) - return; - 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 && host_key_valid) { - if (try_rhosts_rsa_authentication(local_user, own_host_key)) - return; - } - /* 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()) - return; - - /* Try RSA authentication for each identity. */ - for (i = 0; i < options.num_identity_files; i++) - if (try_rsa_authentication(options.identity_files[i])) - return; - } - /* Try skey authentication if the server supports it. */ - if ((supported_authentications & (1 << SSH_AUTH_TIS)) && - options.skey_authentication && !options.batch_mode) { - if (try_skey_authentication()) - return; - } - /* 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), "%.30s@%.40s's password: ", - server_user, host); - if (try_password_authentication(prompt)) - return; - } - /* All authentication methods have failed. Exit with an error message. */ - fatal("Permission denied."); - /* NOTREACHED */ -} diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c deleted file mode 100644 index 99ffb2c478d4..000000000000 --- a/crypto/openssh/sshconnect2.c +++ /dev/null @@ -1,474 +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. - * 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. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.10 2000/05/08 17:42:25 markus Exp $"); - -#include <openssl/bn.h> -#include <openssl/rsa.h> -#include <openssl/dsa.h> -#include <openssl/md5.h> -#include <openssl/dh.h> -#include <openssl/hmac.h> - -#include "ssh.h" -#include "xmalloc.h" -#include "rsa.h" -#include "buffer.h" -#include "packet.h" -#include "cipher.h" -#include "uidswap.h" -#include "compat.h" -#include "readconf.h" -#include "bufaux.h" -#include "ssh2.h" -#include "kex.h" -#include "myproposal.h" -#include "key.h" -#include "dsa.h" -#include "sshconnect.h" -#include "authfile.h" - -/* import */ -extern char *client_version_string; -extern char *server_version_string; -extern Options options; - -/* - * SSH2 key exchange - */ - -unsigned char *session_id2 = NULL; -int session_id2_len = 0; - -void -ssh_kex2(char *host, struct sockaddr *hostaddr) -{ - Kex *kex; - char *cprop[PROPOSAL_MAX]; - char *sprop[PROPOSAL_MAX]; - Buffer *client_kexinit; - Buffer *server_kexinit; - int payload_len, dlen; - unsigned int klen, kout; - char *ptr; - char *signature = NULL; - unsigned int slen; - char *server_host_key_blob = NULL; - Key *server_host_key; - unsigned int sbloblen; - DH *dh; - BIGNUM *dh_server_pub = 0; - BIGNUM *shared_secret = 0; - int i; - unsigned char *kbuf; - unsigned char *hash; - -/* KEXINIT */ - - debug("Sending KEX init."); - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; - } else if (options.cipher == SSH_CIPHER_3DES) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = - cipher_name(SSH_CIPHER_3DES_CBC); - } else if (options.cipher == SSH_CIPHER_BLOWFISH) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = - cipher_name(SSH_CIPHER_BLOWFISH_CBC); - } - if (options.compression) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; - myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; - } else { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; - myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; - } - for (i = 0; i < PROPOSAL_MAX; i++) - cprop[i] = xstrdup(myproposal[i]); - - client_kexinit = kex_init(cprop); - packet_start(SSH2_MSG_KEXINIT); - packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit)); - packet_send(); - packet_write_wait(); - - debug("done"); - - packet_read_expect(&payload_len, SSH2_MSG_KEXINIT); - - /* save payload for session_id */ - server_kexinit = xmalloc(sizeof(*server_kexinit)); - buffer_init(server_kexinit); - ptr = packet_get_raw(&payload_len); - buffer_append(server_kexinit, ptr, payload_len); - - /* skip cookie */ - for (i = 0; i < 16; i++) - (void) packet_get_char(); - /* kex init proposal strings */ - for (i = 0; i < PROPOSAL_MAX; i++) { - sprop[i] = packet_get_string(NULL); - debug("got kexinit string: %s", sprop[i]); - } - i = (int) packet_get_char(); - debug("first kex follow == %d", i); - i = packet_get_int(); - debug("reserved == %d", i); - packet_done(); - - debug("done read kexinit"); - kex = kex_choose_conf(cprop, sprop, 0); - -/* KEXDH */ - - debug("Sending SSH2_MSG_KEXDH_INIT."); - - /* generate and send 'e', client DH public key */ - dh = dh_new_group1(); - packet_start(SSH2_MSG_KEXDH_INIT); - packet_put_bignum2(dh->pub_key); - packet_send(); - packet_write_wait(); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "\np= "); - bignum_print(dh->p); - fprintf(stderr, "\ng= "); - bignum_print(dh->g); - fprintf(stderr, "\npub= "); - bignum_print(dh->pub_key); - fprintf(stderr, "\n"); - DHparams_print_fp(stderr, dh); -#endif - - debug("Wait SSH2_MSG_KEXDH_REPLY."); - - packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY); - - debug("Got SSH2_MSG_KEXDH_REPLY."); - - /* key, cert */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - - check_host_key(host, hostaddr, server_host_key, - options.user_hostfile2, options.system_hostfile2); - - /* DH paramter f, server public DH key */ - dh_server_pub = BN_new(); - if (dh_server_pub == NULL) - fatal("dh_server_pub == NULL"); - packet_get_bignum2(dh_server_pub, &dlen); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "\ndh_server_pub= "); - bignum_print(dh_server_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_server_pub)); -#endif - - /* signed H */ - signature = packet_get_string(&slen); - packet_done(); - - 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 - debug("shared secret: len %d/%d", klen, kout); - fprintf(stderr, "shared secret == "); - for (i = 0; i< kout; i++) - fprintf(stderr, "%02x", (kbuf[i])&0xff); - fprintf(stderr, "\n"); -#endif - shared_secret = BN_new(); - - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - /* calc and verify H */ - hash = kex_hash( - client_version_string, - server_version_string, - buffer_ptr(client_kexinit), buffer_len(client_kexinit), - buffer_ptr(server_kexinit), buffer_len(server_kexinit), - server_host_key_blob, sbloblen, - dh->pub_key, - dh_server_pub, - shared_secret - ); - xfree(server_host_key_blob); - buffer_free(client_kexinit); - buffer_free(server_kexinit); - xfree(client_kexinit); - xfree(server_kexinit); -#ifdef DEBUG_KEXDH - fprintf(stderr, "hash == "); - for (i = 0; i< 20; i++) - fprintf(stderr, "%02x", (hash[i])&0xff); - fprintf(stderr, "\n"); -#endif - if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) - fatal("dsa_verify failed for server_host_key"); - key_free(server_host_key); - - kex_derive_keys(kex, hash, shared_secret); - packet_set_kex(kex); - - /* have keys, free DH */ - DH_free(dh); - - /* save session id */ - session_id2_len = 20; - session_id2 = xmalloc(session_id2_len); - memcpy(session_id2, hash, session_id2_len); - - debug("Wait SSH2_MSG_NEWKEYS."); - packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); - packet_done(); - debug("GOT SSH2_MSG_NEWKEYS."); - - debug("send SSH2_MSG_NEWKEYS."); - packet_start(SSH2_MSG_NEWKEYS); - packet_send(); - packet_write_wait(); - debug("done: send SSH2_MSG_NEWKEYS."); - -#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: KEX2."); -} -/* - * Authenticate user - */ -int -ssh2_try_passwd(const char *server_user, const char *host, const char *service) -{ - static int attempt = 0; - char prompt[80]; - char *password; - - if (attempt++ > options.number_of_password_prompts) - return 0; - - snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", - server_user, host); - password = read_passphrase(prompt, 0); - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(server_user); - packet_put_cstring(service); - packet_put_cstring("password"); - packet_put_char(0); - packet_put_cstring(password); - memset(password, 0, strlen(password)); - xfree(password); - packet_send(); - packet_write_wait(); - return 1; -} - -int -ssh2_try_pubkey(char *filename, - const char *server_user, const char *host, const char *service) -{ - Buffer b; - Key *k; - unsigned char *blob, *signature; - int bloblen, slen; - struct stat st; - - if (stat(filename, &st) != 0) { - debug("key does not exist: %s", filename); - return 0; - } - debug("try pubkey: %s", filename); - - k = key_new(KEY_DSA); - if (!load_private_key(filename, "", k, NULL)) { - int success = 0; - char *passphrase; - char prompt[300]; - snprintf(prompt, sizeof prompt, - "Enter passphrase for DSA key '%.100s': ", - filename); - passphrase = read_passphrase(prompt, 0); - success = load_private_key(filename, passphrase, k, NULL); - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - if (!success) - return 0; - } - dsa_make_key_blob(k, &blob, &bloblen); - - /* data to be signed */ - buffer_init(&b); - buffer_append(&b, session_id2, session_id2_len); - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, server_user); - buffer_put_cstring(&b, - datafellows & SSH_BUG_PUBKEYAUTH ? - "ssh-userauth" : - service); - buffer_put_cstring(&b, "publickey"); - buffer_put_char(&b, 1); - buffer_put_cstring(&b, KEX_DSS); - buffer_put_string(&b, blob, bloblen); - - /* generate signature */ - dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); - key_free(k); -#ifdef DEBUG_DSS - buffer_dump(&b); -#endif - if (datafellows & SSH_BUG_PUBKEYAUTH) { - /* e.g. ssh-2.0.13: data-to-be-signed != data-on-the-wire */ - buffer_clear(&b); - buffer_append(&b, session_id2, session_id2_len); - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, server_user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "publickey"); - buffer_put_char(&b, 1); - buffer_put_cstring(&b, KEX_DSS); - 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) < session_id2_len + 1) - fatal("ssh2_try_pubkey: internal error"); - buffer_consume(&b, session_id2_len + 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); - - /* send */ - packet_send(); - packet_write_wait(); - return 1; -} - -void -ssh_userauth2(const char *server_user, char *host) -{ - int type; - int plen; - int sent; - unsigned int dlen; - int partial; - int i = 0; - char *auths; - char *service = "ssh-connection"; /* service name */ - - debug("send SSH2_MSG_SERVICE_REQUEST"); - packet_start(SSH2_MSG_SERVICE_REQUEST); - packet_put_cstring("ssh-userauth"); - packet_send(); - packet_write_wait(); - - type = packet_read(&plen); - if (type != SSH2_MSG_SERVICE_ACCEPT) { - fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); - } - if (packet_remaining() > 0) { - char *reply = packet_get_string(&plen); - debug("service_accept: %s", reply); - xfree(reply); - } else { - /* payload empty for ssh-2.0.13 ?? */ - debug("buggy server: service_accept w/o service"); - } - packet_done(); - debug("got SSH2_MSG_SERVICE_ACCEPT"); - - /* INITIAL request for auth */ - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(server_user); - packet_put_cstring(service); - packet_put_cstring("none"); - packet_send(); - packet_write_wait(); - - for (;;) { - sent = 0; - type = packet_read(&plen); - if (type == SSH2_MSG_USERAUTH_SUCCESS) - break; - if (type != SSH2_MSG_USERAUTH_FAILURE) - fatal("access denied: %d", type); - /* SSH2_MSG_USERAUTH_FAILURE means: try again */ - auths = packet_get_string(&dlen); - debug("authentications that can continue: %s", auths); - partial = packet_get_char(); - packet_done(); - if (partial) - debug("partial success"); - if (options.dsa_authentication && - strstr(auths, "publickey") != NULL) { - while (i < options.num_identity_files2) { - sent = ssh2_try_pubkey( - options.identity_files2[i++], - server_user, host, service); - if (sent) - break; - } - } - if (!sent) { - if (options.password_authentication && - !options.batch_mode && - strstr(auths, "password") != NULL) { - sent = ssh2_try_passwd(server_user, host, service); - } - } - if (!sent) - fatal("Permission denied (%s).", auths); - xfree(auths); - } - packet_done(); - debug("ssh-userauth2 successfull"); -} diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8 deleted file mode 100644 index 3fb255af05f4..000000000000 --- a/crypto/openssh/sshd.8 +++ /dev/null @@ -1,987 +0,0 @@ -.\" -*- nroff -*- -.\" -.\" sshd.8.in -.\" -.\" Author: Tatu Ylonen <ylo@cs.hut.fi> -.\" -.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland -.\" All rights reserved -.\" -.\" Created: Sat Apr 22 21:55:14 1995 ylo -.\" -.\" $Id: sshd.8,v 1.51 2000/05/08 17:42:31 hugh Exp $ -.\" -.Dd September 25, 1999 -.Dt SSHD 8 -.Os -.Sh NAME -.Nm sshd -.Nd secure shell daemon -.Sh SYNOPSIS -.Nm sshd -.Op Fl diqQ46 -.Op Fl b Ar bits -.Op Fl f Ar config_file -.Op Fl g Ar login_grace_time -.Op Fl h Ar host_key_file -.Op Fl k Ar key_gen_time -.Op Fl p Ar port -.Op Fl V Ar client_protocol_id -.Sh DESCRIPTION -.Nm -(Secure Shell Daemon) is the daemon program for -.Xr ssh 1 . -Together these programs replace rlogin and rsh, and -provide secure encrypted communications between two untrusted hosts -over an insecure network. -The programs are intended to be as easy to -install and use as possible. -.Pp -.Nm -is the daemon that listens for connections from clients. -It is normally started at boot from -.Pa /etc/rc . -It forks a new -daemon for each incoming connection. -The forked daemons handle -key exchange, encryption, authentication, command execution, -and data exchange. -This implementation of -.Nm -supports both SSH protocol version 1 and 2 simultaneously. -.Nm -works as follows. -.Pp -.Ss SSH protocol version 1 -.Pp -Each host has a host-specific RSA key -(normally 1024 bits) used to identify the host. -Additionally, when -the daemon starts, it generates a server RSA key (normally 768 bits). -This key is normally regenerated every hour if it has been used, and -is never stored on disk. -.Pp -Whenever a client connects the daemon responds with its public -host and server keys. -The client compares the -RSA host key against its own database to verify that it has not changed. -The client then generates a 256 bit random number. -It encrypts this -random number using both the host key and the server key, and sends -the encrypted number to the server. -Both sides then use this -random number as a session key which is used to encrypt all further -communications in the session. -The rest of the session is encrypted -using a conventional cipher, currently Blowfish or 3DES, with 3DES -being used by default. -The client selects the encryption algorithm -to use from those offered by the server. -.Pp -Next, the server and the client enter an authentication dialog. -The client tries to authenticate itself using -.Pa .rhosts -authentication, -.Pa .rhosts -authentication combined with RSA host -authentication, RSA challenge-response authentication, or password -based authentication. -.Pp -Rhosts authentication is normally disabled -because it is fundamentally insecure, but can be enabled in the server -configuration file if desired. -System security is not improved unless -.Xr rshd 8 , -.Xr rlogind 8 , -.Xr rexecd 8 , -and -.Xr rexd 8 -are disabled (thus completely disabling -.Xr rlogin 1 -and -.Xr rsh 1 -into the machine). -.Pp -.Ss SSH protocol version 2 -.Pp -Version 2 works similar: -Each host has a host-specific DSA key used to identify the host. -However, when the daemon starts, it does not generate a server key. -Forward security is provided through a Diffie-Hellman key agreement. -This key agreement results in a shared session key. -The rest of the session is encrypted -using a symmetric cipher, currently -Blowfish, 3DES or CAST128 in CBC mode or Arcfour. -The client selects the encryption algorithm -to use from those offered by the server. -Additionally, session integrity is provided -through a cryptographic message authentication code -(hmac-sha1 or hmac-md5). -.Pp -Protocol version 2 provides a public key based -user authentication method (DSAAuthentication) -and conventional password authentication. -.Pp -.Ss Command execution and data forwarding -.Pp -If the client successfully authenticates itself, a dialog for -preparing the session is entered. -At this time the client may request -things like allocating a pseudo-tty, forwarding X11 connections, -forwarding TCP/IP connections, or forwarding the authentication agent -connection over the secure channel. -.Pp -Finally, the client either requests a shell or execution of a command. -The sides then enter session mode. -In this mode, either side may send -data at any time, and such data is forwarded to/from the shell or -command on the server side, and the user terminal in the client side. -.Pp -When the user program terminates and all forwarded X11 and other -connections have been closed, the server sends command exit status to -the client, and both sides exit. -.Pp -.Nm -can be configured using command-line options or a configuration -file. -Command-line options override values specified in the -configuration file. -.Pp -.Nm -rereads its configuration file when it receives a hangup signal, -.Dv SIGHUP . -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl b Ar bits -Specifies the number of bits in the server key (default 768). -.Pp -.It Fl d -Debug mode. -The server sends verbose debug output to the system -log, and does not put itself in the background. -The server also will not fork and will only process one connection. -This option is only intended for debugging for the server. -.It Fl f Ar configuration_file -Specifies the name of the configuration file. -The default is -.Pa /etc/sshd_config . -.Nm -refuses to start if there is no configuration file. -.It Fl g Ar login_grace_time -Gives the grace time for clients to authenticate themselves (default -300 seconds). -If the client fails to authenticate the user within -this many seconds, the server disconnects and exits. -A value of zero indicates no limit. -.It Fl h Ar host_key_file -Specifies the file from which the RSA host key is read (default -.Pa /etc/ssh_host_key ) . -This option must be given if -.Nm -is not run as root (as the normal -host file is normally not readable by anyone but root). -.It Fl i -Specifies that -.Nm -is being run from inetd. -.Nm -is normally not run -from inetd because it needs to generate the server key before it can -respond to the client, and this may take tens of seconds. -Clients would have to wait too long if the key was regenerated every time. -However, with small key sizes (e.g., 512) using -.Nm -from inetd may -be feasible. -.It Fl k Ar key_gen_time -Specifies how often the server key is regenerated (default 3600 -seconds, or one hour). -The motivation for regenerating the key fairly -often is that the key is not stored anywhere, and after about an hour, -it becomes impossible to recover the key for decrypting intercepted -communications even if the machine is cracked into or physically -seized. -A value of zero indicates that the key will never be regenerated. -.It Fl p Ar port -Specifies the port on which the server listens for connections -(default 22). -.It Fl q -Quiet mode. -Nothing is sent to the system log. -Normally the beginning, -authentication, and termination of each connection is logged. -.It Fl Q -Do not print an error message if RSA support is missing. -.It Fl V Ar client_protocol_id -SSH2 compatibility mode. -When this option is specified -.Nm -assumes the client has sent the supplied version string -and skips the -Protocol Version Identification Exchange. -.It Fl 4 -Forces -.Nm -to use IPv4 addresses only. -.It Fl 6 -Forces -.Nm -to use IPv6 addresses only. -.El -.Sh CONFIGURATION FILE -.Nm -reads configuration data from -.Pa /etc/sshd_config -(or the file specified with -.Fl f -on the command line). -The file contains keyword-value pairs, one per line. -Lines starting with -.Ql # -and empty lines are interpreted as comments. -.Pp -The following keywords are possible. -.Bl -tag -width Ds -.It Cm AFSTokenPassing -Specifies whether an AFS token may be forwarded to the server. -Default is -.Dq yes . -.It Cm AllowGroups -This keyword can be followed by a number of group names, separated -by spaces. -If specified, login is allowed only for users whose primary -group matches one of the patterns. -.Ql \&* -and -.Ql ? -can be used as -wildcards in the patterns. -Only group names are valid, a numerical group ID isn't recognized. -By default login is allowed regardless of the primary group. -.Pp -.It Cm AllowUsers -This keyword can be followed by a number of user names, separated -by spaces. -If specified, login is allowed only for users names that -match one of the patterns. -.Ql \&* -and -.Ql ? -can be used as -wildcards in the patterns. -Only user names are valid, a numerical user ID isn't recognized. -By default login is allowed regardless of the user name. -.Pp -.It Cm Ciphers -Specifies the ciphers allowed for protocol version 2. -Multiple ciphers must be comma-separated. -The default is -.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc . -.It Cm CheckMail -Specifies whether -.Nm -should check for new mail for interactive logins. -The default is -.Dq no . -.It Cm DenyGroups -This keyword can be followed by a number of group names, separated -by spaces. -Users whose primary group matches one of the patterns -aren't allowed to log in. -.Ql \&* -and -.Ql ? -can be used as -wildcards in the patterns. -Only group names are valid, a numerical group ID isn't recognized. -By default login is allowed regardless of the primary group. -.Pp -.It Cm DenyUsers -This keyword can be followed by a number of user names, separated -by spaces. -Login is disallowed for user names that match one of the patterns. -.Ql \&* -and -.Ql ? -can be used as wildcards in the patterns. -Only user names are valid, a numerical user ID isn't recognized. -By default login is allowed regardless of the user name. -.It Cm DSAAuthentication -Specifies whether DSA authentication is allowed. -The default is -.Dq yes . -Note that this option applies to protocol version 2 only. -.It Cm GatewayPorts -Specifies whether remote hosts are allowed to connect to ports -forwarded for the client. -The argument must be -.Dq yes -or -.Dq no . -The default is -.Dq no . -.It Cm HostDsaKey -Specifies the file containing the private DSA host key (default -.Pa /etc/ssh_host_dsa_key ) -used by SSH protocol 2.0. -Note that -.Nm -disables protocol 2.0 if this file is group/world-accessible. -.It Cm HostKey -Specifies the file containing the private RSA host key (default -.Pa /etc/ssh_host_key ) -used by SSH protocols 1.3 and 1.5. -Note that -.Nm -disables protocols 1.3 and 1.5 if this file is group/world-accessible. -.It Cm IgnoreRhosts -Specifies that -.Pa .rhosts -and -.Pa .shosts -files will not be used in authentication. -.Pa /etc/hosts.equiv -and -.Pa /etc/shosts.equiv -are still used. -The default is -.Dq yes . -.It Cm IgnoreUserKnownHosts -Specifies whether -.Nm -should ignore the user's -.Pa $HOME/.ssh/known_hosts -during -.Cm RhostsRSAAuthentication . -The default is -.Dq no . -.It Cm KeepAlive -Specifies whether the system should send keepalive messages to the -other side. -If they are sent, death of the connection or crash of one -of the machines will be properly noticed. -However, this means that -connections will die if the route is down temporarily, and some people -find it annoying. -On the other hand, if keepalives are not sent, -sessions may hang indefinitely on the server, leaving -.Dq ghost -users and consuming server resources. -.Pp -The default is -.Dq yes -(to send keepalives), and the server will notice -if the network goes down or the client host reboots. -This avoids infinitely hanging sessions. -.Pp -To disable keepalives, the value should be set to -.Dq no -in both the server and the client configuration files. -.It Cm KerberosAuthentication -Specifies whether Kerberos authentication is allowed. -This can be in the form of a Kerberos ticket, or if -.Cm PasswordAuthentication -is yes, the password provided by the user will be validated through -the Kerberos KDC. -Default is -.Dq yes . -.It Cm KerberosOrLocalPasswd -If set then if password authentication through Kerberos fails then -the password will be validated via any additional local mechanism -such as -.Pa /etc/passwd -or SecurID. -Default is -.Dq yes . -.It Cm KerberosTgtPassing -Specifies whether a Kerberos TGT may be forwarded to the server. -Default is -.Dq no , -as this only works when the Kerberos KDC is actually an AFS kaserver. -.It Cm KerberosTicketCleanup -Specifies whether to automatically destroy the user's ticket cache -file on logout. -Default is -.Dq yes . -.It Cm KeyRegenerationInterval -The server key is automatically regenerated after this many seconds -(if it has been used). -The purpose of regeneration is to prevent -decrypting captured sessions by later breaking into the machine and -stealing the keys. -The key is never stored anywhere. -If the value is 0, the key is never regenerated. -The default is 3600 (seconds). -.It Cm ListenAddress -Specifies what local address -.Nm -should listen on. -The default is to listen to all local addresses. -Multiple options of this type are permitted. -Additionally, the -.Cm Ports -options must precede this option. -.It Cm LoginGraceTime -The server disconnects after this time if the user has not -successfully logged in. -If the value is 0, there is no time limit. -The default is 600 (seconds). -.It Cm LogLevel -Gives the verbosity level that is used when logging messages from -.Nm sshd . -The possible values are: -QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. -The default is INFO. -Logging with level DEBUG violates the privacy of users -and is not recommended. -.It Cm PasswordAuthentication -Specifies whether password authentication is allowed. -The default is -.Dq yes . -Note that this option applies to both protocol version 1 and 2. -.It Cm PermitEmptyPasswords -When password authentication is allowed, it specifies whether the -server allows login to accounts with empty password strings. -The default is -.Dq no . -.It Cm PermitRootLogin -Specifies whether the root can log in using -.Xr ssh 1 . -The argument must be -.Dq yes , -.Dq without-password -or -.Dq no . -The default is -.Dq yes . -If this options is set to -.Dq without-password -only password authentication is disabled for root. -.Pp -Root login with RSA authentication when the -.Ar command -option has been -specified will be allowed regardless of the value of this setting -(which may be useful for taking remote backups even if root login is -normally not allowed). -.It Cm PidFile -Specifies the file that contains the process identifier of the -.Nm -daemon. -The default is -.Pa /var/run/sshd.pid . -.It Cm Port -Specifies the port number that -.Nm -listens on. -The default is 22. -Multiple options of this type are permitted. -.It Cm PrintMotd -Specifies whether -.Nm -should print -.Pa /etc/motd -when a user logs in interactively. -(On some systems it is also printed by the shell, -.Pa /etc/profile , -or equivalent.) -The default is -.Dq yes . -.It Cm Protocol -Specifies the protocol versions -.Nm -should support. -The possible values are -.Dq 1 -and -.Dq 2 . -Multiple versions must be comma-separated. -The default is -.Dq 1 . -.It Cm RandomSeed -Obsolete. -Random number generation uses other techniques. -.It Cm RhostsAuthentication -Specifies whether authentication using rhosts or /etc/hosts.equiv -files is sufficient. -Normally, this method should not be permitted because it is insecure. -.Cm RhostsRSAAuthentication -should be used -instead, because it performs RSA-based host authentication in addition -to normal rhosts or /etc/hosts.equiv authentication. -The default is -.Dq no . -.It Cm RhostsRSAAuthentication -Specifies whether rhosts or /etc/hosts.equiv authentication together -with successful RSA host authentication is allowed. -The default is -.Dq no . -.It Cm RSAAuthentication -Specifies whether pure RSA authentication is allowed. -The default is -.Dq yes . -Note that this option applies to protocol version 1 only. -.It Cm ServerKeyBits -Defines the number of bits in the server key. -The minimum value is 512, and the default is 768. -.It Cm SkeyAuthentication -Specifies whether -.Xr skey 1 -authentication is allowed. -The default is -.Dq yes . -Note that s/key authentication is enabled only if -.Cm PasswordAuthentication -is allowed, too. -.It Cm StrictModes -Specifies whether -.Nm -should check file modes and ownership of the -user's files and home directory before accepting login. -This is normally desirable because novices sometimes accidentally leave their -directory or files world-writable. -The default is -.Dq yes . -.It Cm SyslogFacility -Gives the facility code that is used when logging messages from -.Nm sshd . -The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, -LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. -The default is AUTH. -.It Cm UseLogin -Specifies whether -.Xr login 1 -is used. -The default is -.Dq no . -.It Cm X11DisplayOffset -Specifies the first display number available for -.Nm sshd Ns 's -X11 forwarding. -This prevents -.Nm -from interfering with real X11 servers. -The default is 10. -.It Cm X11Forwarding -Specifies whether X11 forwarding is permitted. -The default is -.Dq no . -Note that disabling X11 forwarding does not improve security in any -way, as users can always install their own forwarders. -.El -.Sh LOGIN PROCESS -When a user successfully logs in, -.Nm -does the following: -.Bl -enum -offset indent -.It -If the login is on a tty, and no command has been specified, -prints last login time and -.Pa /etc/motd -(unless prevented in the configuration file or by -.Pa $HOME/.hushlogin ; -see the -.Sx FILES -section). -.It -If the login is on a tty, records login time. -.It -Checks -.Pa /etc/nologin ; -if it exists, prints contents and quits -(unless root). -.It -Changes to run with normal user privileges. -.It -Sets up basic environment. -.It -Reads -.Pa $HOME/.ssh/environment -if it exists. -.It -Changes to user's home directory. -.It -If -.Pa $HOME/.ssh/rc -exists, runs it; else if -.Pa /etc/sshrc -exists, runs -it; otherwise runs xauth. -The -.Dq rc -files are given the X11 -authentication protocol and cookie in standard input. -.It -Runs user's shell or command. -.El -.Sh AUTHORIZED_KEYS FILE FORMAT -The -.Pa $HOME/.ssh/authorized_keys -file lists the RSA keys that are -permitted for RSA authentication in SSH protocols 1.3 and 1.5 -Similarly, the -.Pa $HOME/.ssh/authorized_keys2 -file lists the DSA keys that are -permitted for DSA authentication in SSH protocol 2.0. -Each line of the file contains one -key (empty lines and lines starting with a -.Ql # -are ignored as -comments). -Each line consists of the following fields, separated by -spaces: options, bits, exponent, modulus, comment. -The options field -is optional; its presence is determined by whether the line starts -with a number or not (the option field never starts with a number). -The bits, exponent, modulus and comment fields give the RSA key; the -comment field is not used for anything (but may be convenient for the -user to identify the key). -.Pp -Note that lines in this file are usually several hundred bytes long -(because of the size of the RSA key modulus). -You don't want to type them in; instead, copy the -.Pa identity.pub -file and edit it. -.Pp -The options (if present) consists of comma-separated option -specifications. -No spaces are permitted, except within double quotes. -The following option specifications are supported: -.Bl -tag -width Ds -.It Cm from="pattern-list" -Specifies that in addition to RSA authentication, the canonical name -of the remote host must be present in the comma-separated list of -patterns -.Pf ( Ql * -and -.Ql ? -serve as wildcards). -The list may also contain -patterns negated by prefixing them with -.Ql ! ; -if the canonical host name matches a negated pattern, the key is not accepted. -The purpose -of this option is to optionally increase security: RSA authentication -by itself does not trust the network or name servers or anything (but -the key); however, if somebody somehow steals the key, the key -permits an intruder to log in from anywhere in the world. -This additional option makes using a stolen key more difficult (name -servers and/or routers would have to be compromised in addition to -just the key). -.It Cm command="command" -Specifies that the command is executed whenever this key is used for -authentication. -The command supplied by the user (if any) is ignored. -The command is run on a pty if the connection requests a pty; -otherwise it is run without a tty. -A quote may be included in the command by quoting it with a backslash. -This option might be useful -to restrict certain RSA keys to perform just a specific operation. -An example might be a key that permits remote backups but nothing else. -Note that the client may specify TCP/IP and/or X11 -forwarding unless they are explicitly prohibited. -.It Cm environment="NAME=value" -Specifies that the string is to be added to the environment when -logging in using this key. -Environment variables set this way -override other default environment values. -Multiple options of this type are permitted. -.It Cm no-port-forwarding -Forbids TCP/IP forwarding when this key is used for authentication. -Any port forward requests by the client will return an error. -This might be used, e.g., in connection with the -.Cm command -option. -.It Cm no-X11-forwarding -Forbids X11 forwarding when this key is used for authentication. -Any X11 forward requests by the client will return an error. -.It Cm no-agent-forwarding -Forbids authentication agent forwarding when this key is used for -authentication. -.It Cm no-pty -Prevents tty allocation (a request to allocate a pty will fail). -.El -.Ss Examples -1024 33 12121.\|.\|.\|312314325 ylo@foo.bar -.Pp -from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula -.Pp -command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi -.Sh SSH_KNOWN_HOSTS FILE FORMAT -The -.Pa /etc/ssh_known_hosts , -.Pa /etc/ssh_known_hosts2 , -.Pa $HOME/.ssh/known_hosts , -and -.Pa $HOME/.ssh/known_hosts2 -files contain host public keys for all known hosts. -The global file should -be prepared by the administrator (optional), and the per-user file is -maintained automatically: whenever the user connects an unknown host -its key is added to the per-user file. -.Pp -Each line in these files contains the following fields: hostnames, -bits, exponent, modulus, comment. -The fields are separated by spaces. -.Pp -Hostnames is a comma-separated list of patterns ('*' and '?' act as -wildcards); each pattern in turn is matched against the canonical host -name (when authenticating a client) or against the user-supplied -name (when authenticating a server). -A pattern may also be preceded by -.Ql ! -to indicate negation: if the host name matches a negated -pattern, it is not accepted (by that line) even if it matched another -pattern on the line. -.Pp -Bits, exponent, and modulus are taken directly from the RSA host key; they -can be obtained, e.g., from -.Pa /etc/ssh_host_key.pub . -The optional comment field continues to the end of the line, and is not used. -.Pp -Lines starting with -.Ql # -and empty lines are ignored as comments. -.Pp -When performing host authentication, authentication is accepted if any -matching line has the proper key. -It is thus permissible (but not -recommended) to have several lines or different host keys for the same -names. -This will inevitably happen when short forms of host names -from different domains are put in the file. -It is possible -that the files contain conflicting information; authentication is -accepted if valid information can be found from either file. -.Pp -Note that the lines in these files are typically hundreds of characters -long, and you definitely don't want to type in the host keys by hand. -Rather, generate them by a script -or by taking -.Pa /etc/ssh_host_key.pub -and adding the host names at the front. -.Ss Examples -closenet,closenet.hut.fi,.\|.\|.\|,130.233.208.41 1024 37 159.\|.\|.93 closenet.hut.fi -.Sh FILES -.Bl -tag -width Ds -.It Pa /etc/sshd_config -Contains configuration data for -.Nm sshd . -This file should be writable by root only, but it is recommended -(though not necessary) that it be world-readable. -.It Pa /etc/ssh_host_key -Contains the private part of the host key. -This file should only be owned by root, readable only by root, and not -accessible to others. -Note that -.Nm -does not start if this file is group/world-accessible. -.It Pa /etc/ssh_host_key.pub -Contains the public part of the host key. -This file should be world-readable but writable only by -root. -Its contents should match the private part. -This file is not -really used for anything; it is only provided for the convenience of -the user so its contents can be copied to known hosts files. -These two files are created using -.Xr ssh-keygen 1 . -.It Pa /var/run/sshd.pid -Contains the process ID of the -.Nm -listening for connections (if there are several daemons running -concurrently for different ports, this contains the pid of the one -started last). -The contents of this file are not sensitive; it can be world-readable. -.It Pa $HOME/.ssh/authorized_keys -Lists the RSA keys that can be used to log into the user's account. -This file must be readable by root (which may on some machines imply -it being world-readable if the user's home directory resides on an NFS -volume). -It is recommended that it not be accessible by others. -The format of this file is described above. -Users will place the contents of their -.Pa identity.pub -files into this file, as described in -.Xr ssh-keygen 1 . -.It Pa $HOME/.ssh/authorized_keys2 -Lists the DSA keys that can be used to log into the user's account. -This file must be readable by root (which may on some machines imply -it being world-readable if the user's home directory resides on an NFS -volume). -It is recommended that it not be accessible by others. -The format of this file is described above. -Users will place the contents of their -.Pa id_dsa.pub -files into this file, as described in -.Xr ssh-keygen 1 . -.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts" -These files are consulted when using rhosts with RSA host -authentication to check the public key of the host. -The key must be listed in one of these files to be accepted. -The client uses the same files -to verify that the remote host is the one we intended to connect. -These files should be writable only by root/the owner. -.Pa /etc/ssh_known_hosts -should be world-readable, and -.Pa $HOME/.ssh/known_hosts -can but need not be world-readable. -.It Pa /etc/nologin -If this file exists, -.Nm -refuses to let anyone except root log in. -The contents of the file -are displayed to anyone trying to log in, and non-root connections are -refused. -The file should be world-readable. -.It Pa /etc/hosts.allow, /etc/hosts.deny -If compiled with -.Sy LIBWRAP -support, tcp-wrappers access controls may be defined here as described in -.Xr hosts_access 5 . -.It Pa $HOME/.rhosts -This file contains host-username pairs, separated by a space, one per -line. -The given user on the corresponding host is permitted to log in -without password. -The same file is used by rlogind and rshd. -The file must -be writable only by the user; it is recommended that it not be -accessible by others. -.Pp -If is also possible to use netgroups in the file. -Either host or user -name may be of the form +@groupname to specify all hosts or all users -in the group. -.It Pa $HOME/.shosts -For ssh, -this file is exactly the same as for -.Pa .rhosts . -However, this file is -not used by rlogin and rshd, so using this permits access using SSH only. -.Pa /etc/hosts.equiv -This file is used during -.Pa .rhosts -authentication. -In the simplest form, this file contains host names, one per line. -Users on -those hosts are permitted to log in without a password, provided they -have the same user name on both machines. -The host name may also be -followed by a user name; such users are permitted to log in as -.Em any -user on this machine (except root). -Additionally, the syntax -.Dq +@group -can be used to specify netgroups. -Negated entries start with -.Ql \&- . -.Pp -If the client host/user is successfully matched in this file, login is -automatically permitted provided the client and server user names are the -same. -Additionally, successful RSA host authentication is normally required. -This file must be writable only by root; it is recommended -that it be world-readable. -.Pp -.Sy "Warning: It is almost never a good idea to use user names in" -.Pa hosts.equiv . -Beware that it really means that the named user(s) can log in as -.Em anybody , -which includes bin, daemon, adm, and other accounts that own critical -binaries and directories. -Using a user name practically grants the user root access. -The only valid use for user names that I can think -of is in negative entries. -.Pp -Note that this warning also applies to rsh/rlogin. -.It Pa /etc/shosts.equiv -This is processed exactly as -.Pa /etc/hosts.equiv . -However, this file may be useful in environments that want to run both -rsh/rlogin and ssh. -.It Pa $HOME/.ssh/environment -This file is read into the environment at login (if it exists). -It can only contain empty lines, comment lines (that start with -.Ql # ) , -and assignment lines of the form name=value. -The file should be writable -only by the user; it need not be readable by anyone else. -.It Pa $HOME/.ssh/rc -If this file exists, it is run with /bin/sh after reading the -environment files but before starting the user's shell or command. -If X11 spoofing is in use, this will receive the "proto cookie" pair in -standard input (and -.Ev DISPLAY -in environment). -This must call -.Xr xauth 1 -in that case. -.Pp -The primary purpose of this file is to run any initialization routines -which may be needed before the user's home directory becomes -accessible; AFS is a particular example of such an environment. -.Pp -This file will probably contain some initialization code followed by -something similar to: "if read proto cookie; then echo add $DISPLAY -$proto $cookie | xauth -q -; fi". -.Pp -If this file does not exist, -.Pa /etc/sshrc -is run, and if that -does not exist either, xauth is used to store the cookie. -.Pp -This file should be writable only by the user, and need not be -readable by anyone else. -.It Pa /etc/sshrc -Like -.Pa $HOME/.ssh/rc . -This can be used to specify -machine-specific login-time initializations globally. -This file should be writable only by root, and should be world-readable. -.Sh AUTHOR -OpenSSH -is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, -but with bugs removed and newer features re-added. -Rapidly after the -1.2.12 release, newer versions of the original ssh bore successively -more restrictive licenses, and thus demand for a free version was born. -.Pp -This version of OpenSSH -.Bl -bullet -.It -has all components of a restrictive nature (i.e., patents, see -.Xr ssl 8 ) -directly removed from the source code; any licensed or patented components -are chosen from -external libraries. -.It -has been updated to support SSH protocol 1.5 and 2, making it compatible with -all other SSH clients and servers. -.It -contains added support for -.Xr kerberos 8 -authentication and ticket passing. -.It -supports one-time password authentication with -.Xr skey 1 . -.El -.Pp -The libraries described in -.Xr ssl 8 -are required for proper operation. -.Pp -OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, -Niels Provos, Theo de Raadt, and Dug Song. -.Pp -The support for SSH protocol 2 was written by Markus Friedl. -.Sh SEE ALSO -.Xr scp 1 , -.Xr ssh 1 , -.Xr ssh-add 1 , -.Xr ssh-agent 1 , -.Xr ssh-keygen 1 , -.Xr ssl 8 , -.Xr rlogin 1 , -.Xr rsh 1 diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c deleted file mode 100644 index 0d62320a1183..000000000000 --- a/crypto/openssh/sshd.c +++ /dev/null @@ -1,1345 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Fri Mar 17 17:09:28 1995 ylo - * This program is the ssh daemon. It listens for connections from clients, and - * performs authentication, executes use commands or shell, and forwards - * 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. - * - * SSH2 implementation, - * Copyright (c) 2000 Markus Friedl. All rights reserved. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.115 2000/05/03 10:21:49 markus Exp $"); - -#include "xmalloc.h" -#include "rsa.h" -#include "ssh.h" -#include "pty.h" -#include "packet.h" -#include "cipher.h" -#include "mpaux.h" -#include "servconf.h" -#include "uidswap.h" -#include "compat.h" -#include "buffer.h" - -#include "ssh2.h" -#include <openssl/dh.h> -#include <openssl/bn.h> -#include <openssl/hmac.h> -#include "kex.h" -#include <openssl/dsa.h> -#include <openssl/rsa.h> -#include "key.h" -#include "dsa.h" - -#include "auth.h" -#include "myproposal.h" -#include "authfile.h" - -#ifdef LIBWRAP -#include <tcpd.h> -#include <syslog.h> -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING; -#endif /* LIBWRAP */ - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -/* Server configuration options. */ -ServerOptions options; - -/* Name of the server configuration file. */ -char *config_file_name = 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. - */ -int IPv4or6 = AF_UNSPEC; - -/* - * 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 is being started from inetd. */ -int inetd_flag = 0; - -/* debug goes to stderr unless inetd_flag is set */ -int log_stderr = 0; - -/* argv[0] without path. */ -char *av0; - -/* Saved arguments to main(). */ -char **saved_argv; - -/* - * The sockets that the server is listening; this is used in the SIGHUP - * signal handler. - */ -#define MAX_LISTEN_SOCKS 16 -int listen_socks[MAX_LISTEN_SOCKS]; -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 - */ -char *client_version_string = NULL; -char *server_version_string = NULL; - -/* - * 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. - */ -struct { - RSA *private_key; /* Private part of empheral server key. */ - RSA *host_key; /* Private part of host key. */ - Key *dsa_host_key; /* Private DSA host key. */ -} sensitive_data; - -/* - * Flag indicating whether the current session key has been used. This flag - * is set whenever the key is used, and cleared when the key is regenerated. - */ -int key_used = 0; - -/* This is set to true when SIGHUP is received. */ -int received_sighup = 0; - -/* Public side of the server key. This value is regenerated regularly with - the private key. */ -RSA *public_key; - -/* session identifier, used by RSA-auth */ -unsigned char session_id[16]; - -/* same for ssh2 */ -unsigned char *session_id2 = NULL; -int session_id2_len = 0; - -/* Prototypes for various functions defined later in this file. */ -void do_ssh1_kex(); -void do_ssh2_kex(); - -/* - * Close all listening sockets - */ -void -close_listen_socks(void) -{ - int i; - for (i = 0; i < num_listen_socks; i++) - close(listen_socks[i]); - num_listen_socks = -1; -} - -/* - * 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). - */ -void -sighup_handler(int sig) -{ - received_sighup = 1; - signal(SIGHUP, sighup_handler); -} - -/* - * Called from the main program after receiving SIGHUP. - * Restarts the server. - */ -void -sighup_restart() -{ - log("Received SIGHUP; restarting."); - close_listen_socks(); - execv(saved_argv[0], saved_argv); - log("RESTART FAILED: av0='%s', error: %s.", av0, strerror(errno)); - exit(1); -} - -/* - * Generic signal handler for terminating signals in the master daemon. - * These close the listen socket; not closing it seems to cause "Address - * already in use" problems on some machines, which is inconvenient. - */ -void -sigterm_handler(int sig) -{ - log("Received signal %d; terminating.", sig); - close_listen_socks(); - unlink(options.pid_file); - exit(255); -} - -/* - * SIGCHLD handler. This is called whenever a child dies. This will then - * reap any zombies left by exited c. - */ -void -main_sigchld_handler(int sig) -{ - int save_errno = errno; - int status; - - while (waitpid(-1, &status, WNOHANG) > 0) - ; - - signal(SIGCHLD, main_sigchld_handler); - errno = save_errno; -} - -/* - * Signal handler for the alarm after the login grace period has expired. - */ -void -grace_alarm_handler(int sig) -{ - /* Close the connection. */ - packet_close(); - - /* Log error and exit. */ - fatal("Timeout before authentication for %s.", get_remote_ipaddr()); -} - -/* - * 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. - */ -/* XXX do we really want this work to be done in a signal handler ? -m */ -void -key_regeneration_alarm(int sig) -{ - int save_errno = errno; - - /* Check if we should generate a new key. */ - if (key_used) { - /* This should really be done in the background. */ - log("Generating new %d bit RSA key.", options.server_key_bits); - - if (sensitive_data.private_key != NULL) - RSA_free(sensitive_data.private_key); - sensitive_data.private_key = RSA_new(); - - if (public_key != NULL) - RSA_free(public_key); - public_key = RSA_new(); - - rsa_generate_key(sensitive_data.private_key, public_key, - options.server_key_bits); - arc4random_stir(); - key_used = 0; - log("RSA key generation complete."); - } - /* Reschedule the alarm. */ - signal(SIGALRM, key_regeneration_alarm); - alarm(options.key_regeneration_time); - errno = save_errno; -} - -char * -chop(char *s) -{ - char *t = s; - while (*t) { - if(*t == '\n' || *t == '\r') { - *t = '\0'; - return s; - } - t++; - } - return s; - -} - -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; - } - 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 side\'s version identification. */ - for (i = 0; i < sizeof(buf) - 1; i++) { - if (read(sock_in, &buf[i], 1) != 1) { - log("Did not receive ident string from %s.", get_remote_ipaddr()); - fatal_cleanup(); - } - if (buf[i] == '\r') { - buf[i] = '\n'; - buf[i + 1] = 0; - continue; - } - if (buf[i] == '\n') { - /* buf[i] == '\n' */ - buf[i + 1] = 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)); - close(sock_in); - 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); - - 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); - chop(client_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)); - close(sock_in); - close(sock_out); - log("Protocol major versions differ for %s: %.200s vs. %.200s", - get_remote_ipaddr(), - server_version_string, client_version_string); - fatal_cleanup(); - } - if (compat20) - packet_set_ssh2_format(); -} - - -void -destroy_sensitive_data(void) -{ - /* Destroy the private and public keys. They will no longer be needed. */ - RSA_free(public_key); - RSA_free(sensitive_data.private_key); - RSA_free(sensitive_data.host_key); - if (sensitive_data.dsa_host_key != NULL) - key_free(sensitive_data.dsa_host_key); -} - -/* - * Main program for the daemon. - */ -int -main(int ac, char **av) -{ - extern char *optarg; - extern int optind; - int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1; - pid_t pid; - socklen_t fromlen; - int silent = 0; - fd_set *fdset; - struct sockaddr_storage from; - const char *remote_ip; - int remote_port; - FILE *f; - struct linger linger; - struct addrinfo *ai; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int listen_sock, maxfd; - - /* Save argv[0]. */ - saved_argv = av; - if (strchr(av[0], '/')) - av0 = strrchr(av[0], '/') + 1; - else - av0 = av[0]; - - /* 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:diqQ46")) != EOF) { - switch (opt) { - case '4': - IPv4or6 = AF_INET; - break; - case '6': - IPv4or6 = AF_INET6; - break; - case 'f': - config_file_name = optarg; - break; - case 'd': - debug_flag = 1; - options.log_level = SYSLOG_LEVEL_DEBUG; - break; - case 'i': - inetd_flag = 1; - break; - case 'Q': - silent = 1; - 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) - fatal("too many ports.\n"); - options.ports[options.num_ports++] = atoi(optarg); - break; - case 'g': - options.login_grace_time = atoi(optarg); - break; - case 'k': - options.key_regeneration_time = atoi(optarg); - break; - case 'h': - options.host_key_file = optarg; - break; - case 'V': - client_version_string = optarg; - /* only makes sense with inetd_flag, i.e. no listen() */ - inetd_flag = 1; - break; - case '?': - default: - fprintf(stderr, "sshd version %s\n", SSH_VERSION); - fprintf(stderr, "Usage: %s [options]\n", av0); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -f file Configuration file (default %s)\n", SERVER_CONFIG_FILE); - fprintf(stderr, " -d Debugging mode\n"); - fprintf(stderr, " -i Started from inetd\n"); - fprintf(stderr, " -q Quiet (no logging)\n"); - fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); - fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); - fprintf(stderr, " -g seconds Grace period for authentication (default: 300)\n"); - fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); - fprintf(stderr, " -h file File from which to read host key (default: %s)\n", - HOST_KEY_FILE); - fprintf(stderr, " -4 Use IPv4 only\n"); - fprintf(stderr, " -6 Use IPv6 only\n"); - exit(1); - } - } - - /* - * Force logging to stderr until we have loaded the private host - * key (unless started from inetd) - */ - log_init(av0, - options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, - options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility, - !silent && !inetd_flag); - - /* Read server configuration options from the configuration file. */ - read_server_config(&options, config_file_name); - - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - - /* Check that there are no remaining arguments. */ - if (optind < ac) { - fprintf(stderr, "Extra argument %s.\n", av[optind]); - exit(1); - } - - debug("sshd version %.100s", SSH_VERSION); - - sensitive_data.dsa_host_key = NULL; - sensitive_data.host_key = NULL; - - /* check if RSA support exists */ - if ((options.protocol & SSH_PROTO_1) && - rsa_alive() == 0) { - log("no RSA support in libssl and libcrypto. See ssl(8)"); - log("Disabling protocol version 1"); - options.protocol &= ~SSH_PROTO_1; - } - /* Load the RSA/DSA host key. It must have empty passphrase. */ - if (options.protocol & SSH_PROTO_1) { - Key k; - sensitive_data.host_key = RSA_new(); - k.type = KEY_RSA; - k.rsa = sensitive_data.host_key; - errno = 0; - if (!load_private_key(options.host_key_file, "", &k, NULL)) { - error("Could not load host key: %.200s: %.100s", - options.host_key_file, strerror(errno)); - log("Disabling protocol version 1"); - options.protocol &= ~SSH_PROTO_1; - } - k.rsa = NULL; - } - if (options.protocol & SSH_PROTO_2) { - sensitive_data.dsa_host_key = key_new(KEY_DSA); - if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) { - - error("Could not load DSA host key: %.200s", options.host_dsa_key_file); - log("Disabling protocol version 2"); - options.protocol &= ~SSH_PROTO_2; - } - } - if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { - if (silent == 0) - fprintf(stderr, "sshd: no hostkeys available -- exiting.\n"); - log("sshd: no hostkeys available -- exiting.\n"); - exit(1); - } - - /* Check certain values for sanity. */ - if (options.protocol & SSH_PROTO_1) { - if (options.server_key_bits < 512 || - options.server_key_bits > 32768) { - fprintf(stderr, "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.host_key->n) - SSH_KEY_BITS_RESERVED && - options.server_key_bits < - BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { - options.server_key_bits = - BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED; - debug("Forcing server key to %d bits to make it differ from host key.", - options.server_key_bits); - } - } - - /* Initialize the log (it is reinitialized below in case we forked). */ - if (debug_flag && !inetd_flag) - log_stderr = 1; - log_init(av0, options.log_level, options.log_facility, log_stderr); - - /* - * 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) { -#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("/dev/tty", O_RDWR | O_NOCTTY); - if (fd >= 0) { - (void) ioctl(fd, TIOCNOTTY, NULL); - close(fd); - } -#endif /* TIOCNOTTY */ - } - /* Reinitialize the log (because of the fork above). */ - log_init(av0, options.log_level, options.log_facility, log_stderr); - - /* Do not display messages to stdout in RSA code. */ - rsa_set_verbose(0); - - /* Initialize the random number generator. */ - arc4random_stir(); - - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - chdir("/"); - - /* Start listening for a socket, unless started from inetd. */ - if (inetd_flag) { - int s1, s2; - s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ - s2 = dup(s1); - sock_in = dup(0); - sock_out = dup(1); - /* - * 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) { - public_key = RSA_new(); - sensitive_data.private_key = RSA_new(); - log("Generating %d bit RSA key.", options.server_key_bits); - rsa_generate_key(sensitive_data.private_key, public_key, - options.server_key_bits); - arc4random_stir(); - log("RSA key generation complete."); - } - } 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)); - close(listen_sock); - continue; - } - /* - * Set socket options. We try to make the port - * reusable and have it close as fast as possible - * without waiting in unnecessary wait states on - * close. - */ - setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, - (void *) &on, sizeof(on)); - linger.l_onoff = 1; - linger.l_linger = 5; - setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, - (void *) &linger, sizeof(linger)); - - 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) { - error("Bind to port %s on %s failed: %.200s.", - strport, ntop, strerror(errno)); - 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 (!debug_flag) { - /* - * Record our pid in /etc/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, "w"); - if (f) { - fprintf(f, "%u\n", (unsigned int) getpid()); - fclose(f); - } - } - if (options.protocol & SSH_PROTO_1) { - public_key = RSA_new(); - sensitive_data.private_key = RSA_new(); - - log("Generating %d bit RSA key.", options.server_key_bits); - rsa_generate_key(sensitive_data.private_key, public_key, - options.server_key_bits); - arc4random_stir(); - log("RSA key generation complete."); - - /* Schedule server key regeneration alarm. */ - signal(SIGALRM, key_regeneration_alarm); - alarm(options.key_regeneration_time); - } - - /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ - signal(SIGHUP, sighup_handler); - signal(SIGTERM, sigterm_handler); - signal(SIGQUIT, sigterm_handler); - - /* Arrange SIGCHLD to be caught. */ - signal(SIGCHLD, main_sigchld_handler); - - /* setup fd set for listen */ - maxfd = 0; - for (i = 0; i < num_listen_socks; i++) - if (listen_socks[i] > maxfd) - maxfd = listen_socks[i]; - fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); - fdset = (fd_set *)xmalloc(fdsetsz); - - /* - * Stay listening for connections until the system crashes or - * the daemon is killed with a signal. - */ - for (;;) { - if (received_sighup) - sighup_restart(); - /* Wait in select until there is a connection. */ - memset(fdset, 0, fdsetsz); - for (i = 0; i < num_listen_socks; i++) - FD_SET(listen_socks[i], fdset); - if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) { - if (errno != EINTR) - error("select: %.100s", strerror(errno)); - continue; - } - for (i = 0; i < num_listen_socks; i++) { - if (!FD_ISSET(listen_socks[i], fdset)) - continue; - fromlen = sizeof(from); - newsock = accept(listen_socks[i], (struct sockaddr *)&from, - &fromlen); - if (newsock < 0) { - if (errno != EINTR && errno != EWOULDBLOCK) - error("accept: %.100s", strerror(errno)); - continue; - } - if (fcntl(newsock, F_SETFL, 0) < 0) { - error("newsock del O_NONBLOCK: %s", strerror(errno)); - continue; - } - /* - * Got connection. Fork a child to handle it, unless - * we are in debugging mode. - */ - if (debug_flag) { - /* - * In debugging mode. Close the listening - * socket, and start processing the - * connection without forking. - */ - debug("Server will not fork when running in debugging mode."); - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - pid = getpid(); - break; - } else { - /* - * Normal production daemon. Fork, and have - * the child process the connection. The - * parent continues listening. - */ - if ((pid = fork()) == 0) { - /* - * Child. Close the listening socket, and start using the - * accepted socket. Reinitialize logging (since our pid has - * changed). We break out of the loop to handle the connection. - */ - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - log_init(av0, options.log_level, options.log_facility, log_stderr); - break; - } - } - - /* Parent. Stay in the loop. */ - if (pid < 0) - error("fork: %.100s", strerror(errno)); - else - debug("Forked child %d.", pid); - - /* Mark that the key has been used (it was "given" to the child). */ - key_used = 1; - - arc4random_stir(); - - /* Close the new socket (the child is now taking care of it). */ - close(newsock); - } /* for (i = 0; i < num_listen_socks; i++) */ - /* child process check (or debug mode) */ - if (num_listen_socks < 0) - break; - } - } - - /* This is the child processing a new connection. */ - - /* - * 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. - */ - alarm(0); - signal(SIGALRM, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGCHLD, SIG_DFL); - - /* - * Set socket options for the connection. We want the socket to - * close as fast as possible without waiting for anything. If the - * connection is not a socket, these will do nothing. - */ - /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ - linger.l_onoff = 1; - linger.l_linger = 5; - setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); - - /* - * 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(); - - /* Check whether logins are denied from this host. */ -#ifdef LIBWRAP - /* XXX LIBWRAP noes not know about IPv6 */ - { - struct request_info req; - - request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL); - fromhost(&req); - - if (!hosts_access(&req)) { - close(sock_in); - close(sock_out); - refuse(&req); - } -/*XXX IPv6 verbose("Connection from %.500s port %d", eval_client(&req), remote_port); */ - } -#endif /* LIBWRAP */ - /* Log the connection. */ - verbose("Connection from %.500s port %d", remote_ip, remote_port); - - /* - * 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. - */ - signal(SIGALRM, grace_alarm_handler); - if (!debug_flag) - alarm(options.login_grace_time); - - sshd_exchange_identification(sock_in, sock_out); - /* - * Check that the connection comes from a privileged port. Rhosts- - * and Rhosts-RSA-Authentication only make sense from priviledged - * 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 (remote_port >= IPPORT_RESERVED || - remote_port < IPPORT_RESERVED / 2) { - options.rhosts_authentication = 0; - options.rhosts_rsa_authentication = 0; - } -#ifdef KRB4 - if (!packet_connection_is_ipv4() && - options.kerberos_authentication) { - debug("Kerberos Authentication disabled, only available for IPv4."); - options.kerberos_authentication = 0; - } -#endif /* KRB4 */ - - packet_set_nonblocking(); - - /* perform the key exchange */ - /* authenticate user and start session */ - if (compat20) { - do_ssh2_kex(); - do_authentication2(); - } else { - do_ssh1_kex(); - do_authentication(); - } - -#ifdef KRB4 - /* Cleanup user's ticket cache file. */ - if (options.kerberos_ticket_cleanup) - (void) dest_tkt(); -#endif /* KRB4 */ - - /* The connection has been terminated. */ - verbose("Closing connection to %.100s", remote_ip); - packet_close(); - exit(0); -} - -/* - * SSH1 key exchange - */ -void -do_ssh1_kex() -{ - int i, len; - int plen, slen; - BIGNUM *session_key_int; - unsigned char session_key[SSH_SESSION_KEY_LENGTH]; - unsigned char cookie[8]; - unsigned int cipher_type, auth_mask, protocol_flags; - u_int32_t rand = 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) - rand = arc4random(); - cookie[i] = rand & 0xff; - rand >>= 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(public_key->n)); - packet_put_bignum(public_key->e); - packet_put_bignum(public_key->n); - - /* Store our public host RSA key. */ - packet_put_int(BN_num_bits(sensitive_data.host_key->n)); - packet_put_bignum(sensitive_data.host_key->e); - packet_put_bignum(sensitive_data.host_key->n); - - /* Put protocol flags. */ - packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); - - /* Declare which ciphers we support. */ - packet_put_int(cipher_mask1()); - - /* 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; -#ifdef KRB4 - if (options.kerberos_authentication) - auth_mask |= 1 << SSH_AUTH_KERBEROS; -#endif -#ifdef AFS - if (options.kerberos_tgt_passing) - auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; - if (options.afs_token_passing) - auth_mask |= 1 << SSH_PASS_AFS_TOKEN; -#endif -#ifdef SKEY - if (options.skey_authentication == 1) - auth_mask |= 1 << SSH_AUTH_TIS; -#endif - 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 public key and %d bit host key.", - BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n)); - - /* Read clients reply (cipher type and session key). */ - packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); - - /* Get cipher type and check whether we accept this. */ - cipher_type = packet_get_char(); - - if (!(cipher_mask() & (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. */ - session_key_int = BN_new(); - packet_get_bignum(session_key_int, &slen); - - protocol_flags = packet_get_int(); - packet_set_protocol_flags(protocol_flags); - - packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY); - - /* - * Decrypt it using our private server key and private host key (key - * with larger modulus first). - */ - if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { - /* Private key has bigger modulus. */ - if (BN_num_bits(sensitive_data.private_key->n) < - BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.private_key->n), - BN_num_bits(sensitive_data.host_key->n), - SSH_KEY_BITS_RESERVED); - } - rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.private_key); - rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.host_key); - } else { - /* Host key has bigger modulus (or they are equal). */ - if (BN_num_bits(sensitive_data.host_key->n) < - BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.host_key->n), - BN_num_bits(sensitive_data.private_key->n), - SSH_KEY_BITS_RESERVED); - } - rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.host_key); - rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.private_key); - } - - compute_session_id(session_id, cookie, - sensitive_data.host_key->n, - sensitive_data.private_key->n); - - /* Destroy the private and public keys. They will no longer be needed. */ - destroy_sensitive_data(); - - /* - * 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. - */ - BN_mask_bits(session_key_int, sizeof(session_key) * 8); - len = BN_num_bytes(session_key_int); - if (len < 0 || len > sizeof(session_key)) - fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d", - get_remote_ipaddr(), - len, sizeof(session_key)); - memset(session_key, 0, sizeof(session_key)); - BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); - - /* Destroy the decrypted integer. It is no longer needed. */ - BN_clear_free(session_key_int); - - /* 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]; - - /* 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. */ - memset(session_key, 0, sizeof(session_key)); - - debug("Received session key; encryption turned on."); - - /* Send an acknowledgement packet. Note that this packet is sent encrypted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); -} - -/* - * SSH2 key exchange: diffie-hellman-group1-sha1 - */ -void -do_ssh2_kex() -{ - Buffer *server_kexinit; - Buffer *client_kexinit; - int payload_len, dlen; - int slen; - unsigned int klen, kout; - char *ptr; - unsigned char *signature = NULL; - unsigned char *server_host_key_blob = NULL; - unsigned int sbloblen; - DH *dh; - BIGNUM *dh_client_pub = 0; - BIGNUM *shared_secret = 0; - int i; - unsigned char *kbuf; - unsigned char *hash; - Kex *kex; - char *cprop[PROPOSAL_MAX]; - char *sprop[PROPOSAL_MAX]; - -/* KEXINIT */ - - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; - } - - debug("Sending KEX init."); - - for (i = 0; i < PROPOSAL_MAX; i++) - sprop[i] = xstrdup(myproposal[i]); - server_kexinit = kex_init(sprop); - packet_start(SSH2_MSG_KEXINIT); - packet_put_raw(buffer_ptr(server_kexinit), buffer_len(server_kexinit)); - packet_send(); - packet_write_wait(); - - debug("done"); - - packet_read_expect(&payload_len, SSH2_MSG_KEXINIT); - - /* - * save raw KEXINIT payload in buffer. this is used during - * computation of the session_id and the session keys. - */ - client_kexinit = xmalloc(sizeof(*client_kexinit)); - buffer_init(client_kexinit); - ptr = packet_get_raw(&payload_len); - buffer_append(client_kexinit, ptr, payload_len); - - /* skip cookie */ - for (i = 0; i < 16; i++) - (void) packet_get_char(); - /* save kex init proposal strings */ - for (i = 0; i < PROPOSAL_MAX; i++) { - cprop[i] = packet_get_string(NULL); - debug("got kexinit string: %s", cprop[i]); - } - - i = (int) packet_get_char(); - debug("first kex follow == %d", i); - i = packet_get_int(); - debug("reserved == %d", i); - - debug("done read kexinit"); - kex = kex_choose_conf(cprop, sprop, 1); - -/* KEXDH */ - - debug("Wait SSH2_MSG_KEXDH_INIT."); - packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT); - - /* key, cert */ - dh_client_pub = BN_new(); - if (dh_client_pub == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub, &dlen); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "\ndh_client_pub= "); - bignum_print(dh_client_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_client_pub)); -#endif - - /* generate DH key */ - dh = dh_new_group1(); /* XXX depends on 'kex' */ - -#ifdef DEBUG_KEXDH - fprintf(stderr, "\np= "); - bignum_print(dh->p); - fprintf(stderr, "\ng= "); - bignum_print(dh->g); - fprintf(stderr, "\npub= "); - bignum_print(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 - debug("shared secret: len %d/%d", klen, kout); - fprintf(stderr, "shared secret == "); - for (i = 0; i< kout; i++) - fprintf(stderr, "%02x", (kbuf[i])&0xff); - fprintf(stderr, "\n"); -#endif - shared_secret = BN_new(); - - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - /* XXX precompute? */ - dsa_make_key_blob(sensitive_data.dsa_host_key, &server_host_key_blob, &sbloblen); - - /* calc H */ /* XXX depends on 'kex' */ - hash = kex_hash( - client_version_string, - server_version_string, - buffer_ptr(client_kexinit), buffer_len(client_kexinit), - buffer_ptr(server_kexinit), buffer_len(server_kexinit), - (char *)server_host_key_blob, sbloblen, - dh_client_pub, - dh->pub_key, - shared_secret - ); - buffer_free(client_kexinit); - buffer_free(server_kexinit); - xfree(client_kexinit); - xfree(server_kexinit); -#ifdef DEBUG_KEXDH - fprintf(stderr, "hash == "); - for (i = 0; i< 20; i++) - fprintf(stderr, "%02x", (hash[i])&0xff); - fprintf(stderr, "\n"); -#endif - /* save session id := H */ - /* XXX hashlen depends on KEX */ - session_id2_len = 20; - session_id2 = xmalloc(session_id2_len); - memcpy(session_id2, hash, session_id2_len); - - /* sign H */ - /* XXX hashlen depends on KEX */ - dsa_sign(sensitive_data.dsa_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((char *)server_host_key_blob, sbloblen); - packet_put_bignum2(dh->pub_key); /* f */ - packet_put_string((char *)signature, slen); - packet_send(); - xfree(signature); - xfree(server_host_key_blob); - packet_write_wait(); - - kex_derive_keys(kex, hash, shared_secret); - packet_set_kex(kex); - - /* have keys, free DH */ - DH_free(dh); - - debug("send SSH2_MSG_NEWKEYS."); - packet_start(SSH2_MSG_NEWKEYS); - packet_send(); - packet_write_wait(); - debug("done: send SSH2_MSG_NEWKEYS."); - - debug("Wait SSH2_MSG_NEWKEYS."); - packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); - debug("GOT SSH2_MSG_NEWKEYS."); - -#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: KEX2."); -} diff --git a/crypto/openssh/sshd/Makefile b/crypto/openssh/sshd/Makefile deleted file mode 100644 index f74a03253756..000000000000 --- a/crypto/openssh/sshd/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -.PATH: ${.CURDIR}/.. - -PROG= sshd -BINOWN= root -BINMODE=555 -BINDIR= /usr/sbin -MAN= sshd.8 - -SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \ - pty.c log-server.c login.c servconf.c serverloop.c \ - auth.c auth1.c auth2.c session.c - -.include <bsd.own.mk> # for KERBEROS and AFS - -.if (${KERBEROS} == "yes") -.if (${AFS} == "yes") -CFLAGS+= -DAFS -LDADD+= -lkafs -DPADD+= ${LIBKRBAFS} -.endif # AFS -CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV -SRCS+= auth-krb4.c -LDADD+= -lkrb -DPADD+= ${LIBKRB} -.endif # KERBEROS - -.if (${SKEY} == "yes") -SRCS+= auth-skey.c -.endif - -.include <bsd.prog.mk> - -LDADD+= -lcrypto -lutil -lz -DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} - -.if (${TCP_WRAPPERS} == "yes") -CFLAGS+= -DLIBWRAP -LDADD+= -lwrap -DPADD+= ${LIBWRAP} -.endif - -.if (${SKEY} == "yes") -CFLAGS+= -DSKEY -LDADD+= -lskey -DPADD+= ${SKEY} -.endif diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config deleted file mode 100644 index 0366ee48542e..000000000000 --- a/crypto/openssh/sshd_config +++ /dev/null @@ -1,51 +0,0 @@ -# This is ssh server systemwide configuration file. - -Port 22 -#Protocol 2,1 -#ListenAddress 0.0.0.0 -#ListenAddress :: -HostKey /etc/ssh_host_key -ServerKeyBits 768 -LoginGraceTime 600 -KeyRegenerationInterval 3600 -PermitRootLogin yes -# -# Don't read ~/.rhosts and ~/.shosts files -IgnoreRhosts yes -# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication -#IgnoreUserKnownHosts yes -StrictModes yes -X11Forwarding no -X11DisplayOffset 10 -PrintMotd yes -KeepAlive yes - -# Logging -SyslogFacility AUTH -LogLevel INFO -#obsoletes QuietMode and FascistLogging - -RhostsAuthentication no -# -# For this to work you will also need host keys in /etc/ssh_known_hosts -RhostsRSAAuthentication no -# -RSAAuthentication yes - -# To disable tunneled clear text passwords, change to no here! -PasswordAuthentication yes -PermitEmptyPasswords no -# Uncomment to disable s/key passwords -#SkeyAuthentication no - -# To change Kerberos options -#KerberosAuthentication no -#KerberosOrLocalPasswd yes -#AFSTokenPassing no -#KerberosTicketCleanup no - -# Kerberos TGT Passing does only work with the AFS kaserver -#KerberosTgtPassing yes - -#CheckMail yes -#UseLogin no diff --git a/crypto/openssh/tildexpand.c b/crypto/openssh/tildexpand.c deleted file mode 100644 index 4ecb785be532..000000000000 --- a/crypto/openssh/tildexpand.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Wed Jul 12 01:07:36 1995 ylo - */ - -#include "includes.h" -RCSID("$Id: tildexpand.c,v 1.6 1999/12/06 19:10:38 deraadt Exp $"); - -#include "xmalloc.h" -#include "ssh.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; - unsigned int userlen; - char *expanded; - struct passwd *pw; - 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. */ - if (userlen == 0) - pw = getpwuid(my_uid); /* Own home directory. */ - 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); - } - if (!pw) - fatal("Unknown user %100s.", user); - - /* If referring to someones home directory, return it now. */ - if (!cp) { - /* Only home directory specified */ - return xstrdup(pw->pw_dir); - } - /* Build a path combining the specified directory and path. */ - len = strlen(pw->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", pw->pw_dir, cp + 1); - return expanded; -} diff --git a/crypto/openssh/ttymodes.c b/crypto/openssh/ttymodes.c deleted file mode 100644 index 25f501349424..000000000000 --- a/crypto/openssh/ttymodes.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Tue Mar 21 15:59:15 1995 ylo - * Encoding and decoding of terminal modes in a portable way. - * Much of the format is defined in ttymodes.h; it is included multiple times - * into this file with the appropriate macro definitions to generate the - * suitable code. - */ - -#include "includes.h" -RCSID("$Id: ttymodes.c,v 1.6 2000/04/14 10:30:34 markus Exp $"); - -#include "packet.h" -#include "ssh.h" - -#define TTY_OP_END 0 -#define TTY_OP_ISPEED 192 /* int follows */ -#define TTY_OP_OSPEED 193 /* int follows */ - -/* - * 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 */ - 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 */ - default: - return B9600; - } -} - -/* - * Encodes terminal modes for the terminal referenced by fd - * in a portable manner, and appends the modes to a packet - * being constructed. - */ -void -tty_make_modes(int fd) -{ - struct termios tio; - int baud; - - if (tcgetattr(fd, &tio) < 0) { - packet_put_char(TTY_OP_END); - log("tcgetattr: %.100s", strerror(errno)); - return; - } - /* Store input and output baud rates. */ - baud = speed_to_baud(cfgetospeed(&tio)); - packet_put_char(TTY_OP_OSPEED); - packet_put_int(baud); - baud = speed_to_baud(cfgetispeed(&tio)); - packet_put_char(TTY_OP_ISPEED); - packet_put_int(baud); - - /* Store values of mode flags. */ -#define TTYCHAR(NAME, OP) \ - packet_put_char(OP); packet_put_char(tio.c_cc[NAME]); -#define TTYMODE(NAME, FIELD, OP) \ - packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0); -#define SGTTYCHAR(NAME, OP) -#define SGTTYMODE(NAME, FIELD, OP) -#define SGTTYMODEN(NAME, FIELD, OP) - -#include "ttymodes.h" - -#undef TTYCHAR -#undef TTYMODE -#undef SGTTYCHAR -#undef SGTTYMODE -#undef SGTTYMODEN - - /* Mark end of mode data. */ - packet_put_char(TTY_OP_END); -} - -/* - * 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; - - /* - * 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) < 0) - failure = -1; - - for (;;) { - n_bytes += 1; - opcode = packet_get_char(); - switch (opcode) { - case TTY_OP_END: - goto set; - - case TTY_OP_ISPEED: - n_bytes += 4; - baud = packet_get_int(); - if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0) - error("cfsetispeed failed for %d", baud); - break; - - case TTY_OP_OSPEED: - n_bytes += 4; - baud = packet_get_int(); - if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0) - error("cfsetospeed failed for %d", baud); - break; - -#define TTYCHAR(NAME, OP) \ - case OP: \ - n_bytes += 1; \ - tio.c_cc[NAME] = packet_get_char(); \ - break; -#define TTYMODE(NAME, FIELD, OP) \ - case OP: \ - n_bytes += 1; \ - if (packet_get_char()) \ - tio.FIELD |= NAME; \ - else \ - tio.FIELD &= ~NAME; \ - break; -#define SGTTYCHAR(NAME, OP) -#define SGTTYMODE(NAME, FIELD, OP) -#define SGTTYMODEN(NAME, FIELD, OP) - -#include "ttymodes.h" - -#undef TTYCHAR -#undef TTYMODE -#undef SGTTYCHAR -#undef SGTTYMODE -#undef SGTTYMODEN - - default: - debug("Ignoring unsupported tty mode opcode %d (0x%x)", - opcode, opcode); - /* - * Opcodes 0 to 127 are defined to have - * a one-byte argument. - */ - if (opcode >= 0 && opcode < 128) { - n_bytes += 1; - (void) packet_get_char(); - break; - } else { - /* - * Opcodes 128 to 159 are defined to have - * an integer argument. - */ - if (opcode >= 128 && opcode < 160) { - n_bytes += 4; - (void) packet_get_int(); - break; - } - } - /* - * 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); - packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY); - goto set; - } - } - -set: - if (*n_bytes_ptr != n_bytes) { - *n_bytes_ptr = n_bytes; - return; /* Don't process bytes passed */ - } - if (failure == -1) - return; /* Packet parsed ok but tty stuff failed */ - - /* Set the new modes for the terminal. */ - if (tcsetattr(fd, TCSANOW, &tio) < 0) - log("Setting tty modes failed: %.100s", strerror(errno)); - return; -} diff --git a/crypto/openssh/ttymodes.h b/crypto/openssh/ttymodes.h deleted file mode 100644 index f8243f61f875..000000000000 --- a/crypto/openssh/ttymodes.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * ttymodes.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * SGTTY stuff contributed by Janne Snabb <snabb@niksula.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Tue Mar 21 15:42:09 1995 ylo - * - */ - -/* RCSID("$Id: ttymodes.h,v 1.7 2000/04/14 10:30:34 markus Exp $"); */ - -/* The tty mode description is a stream of bytes. The stream consists of - * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). - * 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). - * - * 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 */ /* sgtty macro */ -/* name, op */ -TTYCHAR(VINTR, 1) SGTTYCHAR(tiotc.t_intrc, 1) -TTYCHAR(VQUIT, 2) SGTTYCHAR(tiotc.t_quitc, 2) -TTYCHAR(VERASE, 3) SGTTYCHAR(tio.sg_erase, 3) -#if defined(VKILL) -TTYCHAR(VKILL, 4) SGTTYCHAR(tio.sg_kill, 4) -#endif /* VKILL */ -TTYCHAR(VEOF, 5) SGTTYCHAR(tiotc.t_eofc, 5) -#if defined(VEOL) -TTYCHAR(VEOL, 6) SGTTYCHAR(tiotc.t_brkc, 6) -#endif /* VEOL */ -#ifdef VEOL2 /* n/a */ -TTYCHAR(VEOL2, 7) -#endif /* VEOL2 */ -TTYCHAR(VSTART, 8) SGTTYCHAR(tiotc.t_startc, 8) -TTYCHAR(VSTOP, 9) SGTTYCHAR(tiotc.t_stopc, 9) -#if defined(VSUSP) -TTYCHAR(VSUSP, 10) SGTTYCHAR(tioltc.t_suspc, 10) -#endif /* VSUSP */ -#if defined(VDSUSP) -TTYCHAR(VDSUSP, 11) SGTTYCHAR(tioltc.t_dsuspc, 11) -#endif /* VDSUSP */ -#if defined(VREPRINT) -TTYCHAR(VREPRINT, 12) SGTTYCHAR(tioltc.t_rprntc, 12) -#endif /* VREPRINT */ -#if defined(VWERASE) -TTYCHAR(VWERASE, 13) SGTTYCHAR(tioltc.t_werasc, 13) -#endif /* VWERASE */ -#if defined(VLNEXT) -TTYCHAR(VLNEXT, 14) SGTTYCHAR(tioltc.t_lnextc, 14) -#endif /* VLNEXT */ -#if defined(VFLUSH) -TTYCHAR(VFLUSH, 15) SGTTYCHAR(tioltc.t_flushc, 15) -#endif /* VFLUSH */ -#ifdef VSWTCH -TTYCHAR(VSWTCH, 16) /* n/a */ -#endif /* VSWTCH */ -#if defined(VSTATUS) -TTYCHAR(VSTATUS, 17) SGTTYCHAR(tiots.tc_statusc, 17) -#endif /* VSTATUS */ -#ifdef VDISCARD -TTYCHAR(VDISCARD, 18) /* n/a */ -#endif /* VDISCARD */ - -/* name, field, op */ -TTYMODE(IGNPAR, c_iflag, 30) /* n/a */ -TTYMODE(PARMRK, c_iflag, 31) /* n/a */ -TTYMODE(INPCK, c_iflag, 32) SGTTYMODEN(ANYP, tio.sg_flags, 32) -TTYMODE(ISTRIP, c_iflag, 33) SGTTYMODEN(LPASS8, tiolm, 33) -TTYMODE(INLCR, c_iflag, 34) /* n/a */ -TTYMODE(IGNCR, c_iflag, 35) /* n/a */ -TTYMODE(ICRNL, c_iflag, 36) SGTTYMODE(CRMOD, tio.sg_flags, 36) -#if defined(IUCLC) -TTYMODE(IUCLC, c_iflag, 37) SGTTYMODE(LCASE, tio.sg_flags, 37) -#endif -TTYMODE(IXON, c_iflag, 38) /* n/a */ -TTYMODE(IXANY, c_iflag, 39) SGTTYMODEN(LDECCTQ, tiolm, 39) -TTYMODE(IXOFF, c_iflag, 40) SGTTYMODE(TANDEM, tio.sg_flags, 40) -#ifdef IMAXBEL -TTYMODE(IMAXBEL,c_iflag, 41) /* n/a */ -#endif /* IMAXBEL */ - -TTYMODE(ISIG, c_lflag, 50) /* n/a */ -TTYMODE(ICANON, c_lflag, 51) SGTTYMODEN(CBREAK, tio.sg_flags, 51) -#ifdef XCASE -TTYMODE(XCASE, c_lflag, 52) /* n/a */ -#endif -TTYMODE(ECHO, c_lflag, 53) SGTTYMODE(ECHO, tio.sg_flags, 53) -TTYMODE(ECHOE, c_lflag, 54) SGTTYMODE(LCRTERA, tiolm, 54) -TTYMODE(ECHOK, c_lflag, 55) SGTTYMODE(LCRTKIL, tiolm, 55) -TTYMODE(ECHONL, c_lflag, 56) /* n/a */ -TTYMODE(NOFLSH, c_lflag, 57) SGTTYMODE(LNOFLSH, tiolm, 57) -TTYMODE(TOSTOP, c_lflag, 58) SGTTYMODE(LTOSTOP, tiolm, 58) -#ifdef IEXTEN -TTYMODE(IEXTEN, c_lflag, 59) /* n/a */ -#endif /* IEXTEN */ -#if defined(ECHOCTL) -TTYMODE(ECHOCTL,c_lflag, 60) SGTTYMODE(LCTLECH, tiolm, 60) -#endif /* ECHOCTL */ -#ifdef ECHOKE -TTYMODE(ECHOKE, c_lflag, 61) /* n/a */ -#endif /* ECHOKE */ -#if defined(PENDIN) -TTYMODE(PENDIN, c_lflag, 62) SGTTYMODE(LPENDIN, tiolm, 62) -#endif /* PENDIN */ - -TTYMODE(OPOST, c_oflag, 70) /* n/a */ -#if defined(OLCUC) -TTYMODE(OLCUC, c_oflag, 71) SGTTYMODE(LCASE, tio.sg_flags, 71) -#endif -TTYMODE(ONLCR, c_oflag, 72) SGTTYMODE(CRMOD, tio.sg_flags, 72) -#ifdef OCRNL -TTYMODE(OCRNL, c_oflag, 73) /* n/a */ -#endif -#ifdef ONOCR -TTYMODE(ONOCR, c_oflag, 74) /* n/a */ -#endif -#ifdef ONLRET -TTYMODE(ONLRET, c_oflag, 75) /* n/a */ -#endif - -TTYMODE(CS7, c_cflag, 90) /* n/a */ -TTYMODE(CS8, c_cflag, 91) SGTTYMODE(LPASS8, tiolm, 91) -TTYMODE(PARENB, c_cflag, 92) /* n/a */ -TTYMODE(PARODD, c_cflag, 93) SGTTYMODE(ODDP, tio.sg_flags, 93) - diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c deleted file mode 100644 index 20f04cf9bdc2..000000000000 --- a/crypto/openssh/uidswap.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Sat Sep 9 01:56:14 1995 ylo - * Code for uid-swapping. - */ - -#include "includes.h" -RCSID("$Id: uidswap.c,v 1.6 2000/04/14 10:30:34 markus Exp $"); - -#include "ssh.h" -#include "uidswap.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. - */ - -#ifdef _POSIX_SAVED_IDS -/* Lets assume that posix saved ids also work with seteuid, even though that - is not part of the posix specification. */ -#define SAVED_IDS_WORK_WITH_SETEUID -#endif /* _POSIX_SAVED_IDS */ - -/* Saved effective uid. */ -static uid_t saved_euid = 0; - -/* - * 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(uid_t uid) -{ -#ifdef SAVED_IDS_WORK_WITH_SETEUID - /* Save the current euid. */ - saved_euid = geteuid(); - - /* Set the effective uid to the given (unprivileged) uid. */ - if (seteuid(uid) == -1) - debug("seteuid %d: %.100s", (int) uid, strerror(errno)); -#else /* SAVED_IDS_WORK_WITH_SETUID */ - /* Propagate the privileged uid to all of our uids. */ - if (setuid(geteuid()) < 0) - debug("setuid %d: %.100s", (int) geteuid(), strerror(errno)); - - /* Set the effective uid to the given (unprivileged) uid. */ - if (seteuid(uid) == -1) - debug("seteuid %d: %.100s", (int) uid, strerror(errno)); -#endif /* SAVED_IDS_WORK_WITH_SETEUID */ -} - -/* - * Restores to the original uid. - */ -void -restore_uid() -{ -#ifdef SAVED_IDS_WORK_WITH_SETEUID - /* Set the effective uid back to the saved uid. */ - if (seteuid(saved_euid) < 0) - debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno)); -#else /* SAVED_IDS_WORK_WITH_SETEUID */ - /* - * 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()); -#endif /* SAVED_IDS_WORK_WITH_SETEUID */ -} - -/* - * Permanently sets all uids to the given uid. This cannot be - * called while temporarily_use_uid is effective. - */ -void -permanently_set_uid(uid_t uid) -{ - if (setuid(uid) < 0) - debug("setuid %d: %.100s", (int) uid, strerror(errno)); -} diff --git a/crypto/openssh/uidswap.h b/crypto/openssh/uidswap.h deleted file mode 100644 index c08a37004616..000000000000 --- a/crypto/openssh/uidswap.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * uidswap.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Sat Sep 9 01:43:15 1995 ylo - * Last modified: Sat Sep 9 02:34:04 1995 ylo - * - */ - -#ifndef UIDSWAP_H -#define UIDSWAP_H - -/* - * 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(uid_t uid); - -/* - * Restores the original effective user id after temporarily_use_uid(). - * This should only be called while temporarily_use_uid is effective. - */ -void restore_uid(); - -/* - * Permanently sets all uids to the given uid. This cannot be called while - * temporarily_use_uid is effective. This must also clear any saved uids. - */ -void permanently_set_uid(uid_t uid); - -#endif /* UIDSWAP_H */ diff --git a/crypto/openssh/uuencode.c b/crypto/openssh/uuencode.c deleted file mode 100644 index fc84d5a5830b..000000000000 --- a/crypto/openssh/uuencode.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - */ -#include "includes.h" -#include "xmalloc.h" - -#include <resolv.h> - -int -uuencode(unsigned char *src, unsigned int srclength, - char *target, size_t targsize) -{ - return __b64_ntop(src, srclength, target, targsize); -} - -int -uudecode(const char *src, unsigned 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 remote trailing whitespace because __b64_pton needs this */ - *p = '\0'; - len = __b64_pton(encoded, target, targsize); - xfree(encoded); - return len; -} - -void -dump_base64(FILE *fp, unsigned char *data, int len) -{ - unsigned 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/crypto/openssh/uuencode.h b/crypto/openssh/uuencode.h deleted file mode 100644 index c92c62744cc2..000000000000 --- a/crypto/openssh/uuencode.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef UUENCODE_H -#define UUENCODE_H -int uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize); -int uudecode(const char *src, unsigned char *target, size_t targsize); -void dump_base64(FILE *fp, unsigned char *data, int len); -#endif diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h deleted file mode 100644 index d577644d61e7..000000000000 --- a/crypto/openssh/version.h +++ /dev/null @@ -1 +0,0 @@ -#define SSH_VERSION "OpenSSH-2.1" diff --git a/crypto/openssh/xmalloc.c b/crypto/openssh/xmalloc.c deleted file mode 100644 index 31550991a2be..000000000000 --- a/crypto/openssh/xmalloc.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * Created: Mon Mar 20 21:23:10 1995 ylo - * Versions of malloc and friends that check their results, and never return - * failure (they call fatal if they encounter an error). - */ - -#include "includes.h" -RCSID("$Id: xmalloc.c,v 1.6 2000/04/14 10:30:34 markus Exp $"); - -#include "ssh.h" - -void * -xmalloc(size_t size) -{ - void *ptr = malloc(size); - if (ptr == NULL) - fatal("xmalloc: out of memory (allocating %d bytes)", (int) size); - return ptr; -} - -void * -xrealloc(void *ptr, size_t new_size) -{ - void *new_ptr; - - if (ptr == NULL) - fatal("xrealloc: NULL pointer given as argument"); - new_ptr = realloc(ptr, new_size); - if (new_ptr == NULL) - fatal("xrealloc: out of memory (new_size %d bytes)", (int) 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) -{ - int len = strlen(str) + 1; - - char *cp = xmalloc(len); - strlcpy(cp, str, len); - return cp; -} diff --git a/crypto/openssh/xmalloc.h b/crypto/openssh/xmalloc.h deleted file mode 100644 index 31291ea4ace5..000000000000 --- a/crypto/openssh/xmalloc.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * xmalloc.h - * - * Author: Tatu Ylonen <ylo@cs.hut.fi> - * - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * Created: Mon Mar 20 22:09:17 1995 ylo - * - * Versions of malloc and friends that check their results, and never return - * failure (they call fatal if they encounter an error). - * - */ - -/* RCSID("$Id: xmalloc.h,v 1.3 2000/04/14 10:30:34 markus Exp $"); */ - -#ifndef XMALLOC_H -#define XMALLOC_H - -/* Like malloc, but calls fatal() if out of memory. */ -void *xmalloc(size_t size); - -/* Like realloc, but calls fatal() if out of memory. */ -void *xrealloc(void *ptr, size_t new_size); - -/* Frees memory allocated using xmalloc or xrealloc. */ -void xfree(void *ptr); - -/* Allocates memory using xmalloc, and copies the string into that memory. */ -char *xstrdup(const char *str); - -#endif /* XMALLOC_H */ |