diff options
Diffstat (limited to 'crypto/openssh')
95 files changed, 0 insertions, 28808 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 04c733c8ac6f..000000000000 --- a/crypto/openssh/README +++ /dev/null @@ -1,563 +0,0 @@ -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/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 01c1f6285ad1..000000000000 --- a/crypto/openssh/atomicio.c +++ /dev/null @@ -1,57 +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.2 2000/02/01 22:32:53 d 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; -{ - 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 8c308bd820c6..000000000000 --- a/crypto/openssh/auth-krb4.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Dug Song <dugsong@UMICH.EDU> - * Kerberos v4 authentication and ticket-passing routines. - * - * $FreeBSD$ - */ - -#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.krb4_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; - 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; - u_int cksum; - Key_schedule schedule; - struct sockaddr_in local, foreign; - - s = packet_get_connection_in(); - - r = sizeof(local); - memset(&local, 0, sizeof(local)); - if (getsockname(s, (struct sockaddr *) & local, &r) < 0) - debug("getsockname failed: %.100s", strerror(errno)); - r = sizeof(foreign); - memset(&foreign, 0, sizeof(foreign)); - if (getpeername(s, (struct sockaddr *) & foreign, &r) < 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_KRB4_RESPONSE); - packet_put_string((char *) reply.dat, reply.length); - packet_send(); - packet_write_wait(); - return 1; -} -#endif /* KRB4 */ - -#ifdef AFS -int -auth_krb4_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-krb5.c b/crypto/openssh/auth-krb5.c deleted file mode 100644 index 0e11c8ae8a7a..000000000000 --- a/crypto/openssh/auth-krb5.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Kerberos v5 authentication and ticket-passing routines. - * - * $FreeBSD$ - */ - -#include "includes.h" -#include "ssh.h" -#include "packet.h" -#include "xmalloc.h" - -#ifdef KRB5 - -extern krb5_context ssh_context; -krb5_auth_context auth_context; -krb5_ccache mem_ccache = NULL; /* Credential cache for acquired ticket */ - -/* Try krb5 authentication. server_user is passed for logging purposes only, - in auth is received ticket, in client is returned principal from the - ticket */ -int -auth_krb5(const char* server_user, krb5_data *auth, krb5_principal *client) -{ - krb5_error_code problem; - krb5_principal server = NULL; - krb5_principal tkt_client = NULL; - krb5_data reply; - krb5_ticket *ticket = NULL; - int fd; - int ret; - - reply.length = 0; - - problem = krb5_init(); - if (problem) - return 0; - - problem = krb5_auth_con_init(ssh_context, &auth_context); - if (problem) { - log("Kerberos v5 authentication failed: %.100s", - krb5_get_err_text(ssh_context, problem)); - - return 0; - } - - fd = packet_get_connection_in(); - problem = krb5_auth_con_setaddrs_from_fd(ssh_context, auth_context, &fd); - if (problem) { - ret = 0; - goto err; - } - - problem = krb5_sname_to_principal(ssh_context, NULL, NULL , - KRB5_NT_SRV_HST, &server); - if (problem) { - ret = 0; - goto err; - } - - problem = krb5_rd_req(ssh_context, &auth_context, auth, server, NULL, - NULL, &ticket); - if (problem) { - ret = 0; - goto err; - } - - problem = krb5_copy_principal(ssh_context, ticket->client, &tkt_client); - if (problem) { - ret = 0; - goto err; - } - - /* if client wants mutual auth */ - problem = krb5_mk_rep(ssh_context, &auth_context, &reply); - if (problem) { - ret = 0; - goto err; - } - - *client = tkt_client; - - packet_start(SSH_SMSG_AUTH_KRB5_RESPONSE); - packet_put_string((char *) reply.data, reply.length); - packet_send(); - packet_write_wait(); - ret = 1; - -err: - if (server) - krb5_free_principal(ssh_context, server); - if (ticket) - krb5_free_ticket(ssh_context, ticket); - if (reply.length) - xfree(reply.data); - return ret; -} - -int -auth_krb5_tgt(char *server_user, krb5_data *tgt, krb5_principal tkt_client) -{ - krb5_error_code problem; - krb5_ccache ccache = NULL; - - if (ssh_context == NULL) { - goto fail; - } - - problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache); - if (problem) { - goto fail; - } - - problem = krb5_cc_initialize(ssh_context, ccache, tkt_client); - if (problem) { - goto fail; - } - - problem = krb5_rd_cred(ssh_context, auth_context, ccache, tgt); - if (problem) { - goto fail; - } - - mem_ccache = ccache; - ccache = NULL; - - /* - problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache); - if (problem) { - mem_ccache = NULL; - goto fail; - } - - - problem = krb5_cc_destroy(ssh_context, ccache); - if (problem) - goto fail; - */ - -#if 0 - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); -#endif - return 1; - -fail: - if (ccache) - krb5_cc_destroy(ssh_context, ccache); -#if 0 - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); -#endif - return 0; -} - -int -auth_krb5_password(struct passwd *pw, const char *password) -{ - krb5_error_code problem; - krb5_ccache ccache = NULL; - krb5_principal client = NULL; - int ret; - - problem = krb5_init(); - if (problem) - return 0; - - problem = krb5_parse_name(ssh_context, pw->pw_name, &client); - if (problem) { - ret = 0; - goto out; - } - - problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache); - if (problem) { - ret = 0; - goto out; - } - - problem = krb5_cc_initialize(ssh_context, ccache, client); - if (problem) { - ret = 0; - goto out; - } - - problem = krb5_verify_user(ssh_context, client, ccache, password, 1, NULL); - if (problem) { - ret = 0; - goto out; - } - -/* - problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache); - if (problem) { - ret = 0; - mem_ccache = NULL; - goto out; - } - */ - mem_ccache = ccache; - ccache = NULL; - - ret = 1; -out: - if (client != NULL) - krb5_free_principal(ssh_context, client); - if (ccache != NULL) - krb5_cc_destroy(ssh_context, ccache); - return ret; -} - -void -krb5_cleanup_proc(void *ignore) -{ - extern krb5_principal tkt_client; - - debug("krb5_cleanup_proc() called"); - if (mem_ccache) - krb5_cc_destroy(ssh_context, mem_ccache); - if (tkt_client) - krb5_free_principal(ssh_context, tkt_client); - if (auth_context) - krb5_auth_con_free(ssh_context, auth_context); - if (ssh_context) - krb5_free_context(ssh_context); -} - -int -krb5_init(void) -{ - krb5_error_code problem; - static cleanup_registered = 0; - - if (ssh_context == NULL) { - problem = krb5_init_context(&ssh_context); - if (problem) - return problem; - krb5_init_ets(ssh_context); - } - - if (!cleanup_registered) { - fatal_add_cleanup(krb5_cleanup_proc, NULL); - cleanup_registered = 1; - } - return 0; -} - -#endif /* KRB5 */ diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c deleted file mode 100644 index 8622dbcd54b9..000000000000 --- a/crypto/openssh/auth-passwd.c +++ /dev/null @@ -1,72 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: auth-passwd.c,v 1.14 1999/12/29 12:47:46 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 KRB5 - if (options.krb5_authentication == 1) { - if (auth_krb5_password(pw, password)) - return 1; - /* Fall back to ordinary passwd authentication. */ - } - -#endif /* KRB5 */ -#ifdef KRB4 - if (options.krb4_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 a9195f0d96be..000000000000 --- a/crypto/openssh/auth-rh-rsa.c +++ /dev/null @@ -1,107 +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.10 1999/11/24 19:53:43 markus Exp $"); - -#include "packet.h" -#include "ssh.h" -#include "xmalloc.h" -#include "uidswap.h" -#include "servconf.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, - BIGNUM *client_host_key_e, BIGNUM *client_host_key_n) -{ - extern ServerOptions options; - const char *canonical_hostname; - HostStatus host_status; - BIGNUM *ke, *kn; - - debug("Trying rhosts with RSA host authentication for %.100s", client_user); - - /* 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); - - /* Check if we know the host and its host key. */ - ke = BN_new(); - kn = BN_new(); - host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, - client_host_key_e, client_host_key_n, - ke, kn); - - /* 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_host_key_e, client_host_key_n, - ke, kn); - restore_uid(); - } - xfree(user_hostfile); - } - BN_free(ke); - BN_free(kn); - - 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_e, client_host_key_n)) { - 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 843242875aea..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.12 1999/12/27 10:46:11 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 d385ab739ee9..000000000000 --- a/crypto/openssh/auth-rsa.c +++ /dev/null @@ -1,478 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: auth-rsa.c,v 1.18 2000/02/11 10:59:11 markus Exp $"); - -#include "rsa.h" -#include "packet.h" -#include "xmalloc.h" -#include "ssh.h" -#include "mpaux.h" -#include "uidswap.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(BIGNUM *e, BIGNUM *n) -{ - BIGNUM *challenge, *encrypted_challenge; - RSA *pk; - 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, n, ctx); - BN_CTX_free(ctx); - - /* Create the public key data structure. */ - pk = RSA_new(); - pk->e = BN_new(); - BN_copy(pk->e, e); - pk->n = BN_new(); - BN_copy(pk->n, n); - - /* Encrypt the challenge with the public key. */ - rsa_public_encrypt(encrypted_challenge, challenge, pk); - RSA_free(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; - BIGNUM *e, *n; - - /* 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) { - log(buf); - packet_send_debug(buf); - restore_uid(); - return 0; - } - } - /* Flag indicating whether authentication has succeeded. */ - authenticated = 0; - - e = BN_new(); - 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, e, 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(n, client_n) != 0) - continue; - - /* check the real bits */ - if (bits != BN_num_bits(n)) - log("Warning: %s, line %ld: keysize mismatch: " - "actual %d vs. announced %d.", - file, linenum, BN_num_bits(n), bits); - - /* We have found the desired key. */ - - /* Perform the challenge-response dialog for this key. */ - if (!auth_rsa_challenge_dialog(e, n)) { - /* 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); - - BN_clear_free(n); - BN_clear_free(e); - - 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 3610a67eff22..000000000000 --- a/crypto/openssh/auth-skey.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "includes.h" -RCSID("$Id: auth-skey.c,v 1.5 1999/12/06 19:04:57 deraadt 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/authfd.c b/crypto/openssh/authfd.c deleted file mode 100644 index 97aacdd27135..000000000000 --- a/crypto/openssh/authfd.c +++ /dev/null @@ -1,579 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: authfd.c,v 1.16 1999/12/15 19:43:10 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)) - error("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 2af4858052fd..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.6 1999/11/24 19:53:44 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 9ab13770c32b..000000000000 --- a/crypto/openssh/authfile.c +++ /dev/null @@ -1,346 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: authfile.c,v 1.11 1999/12/06 19:11:15 deraadt Exp $"); - -#include <openssl/bn.h> -#include "xmalloc.h" -#include "buffer.h" -#include "bufaux.h" -#include "cipher.h" -#include "ssh.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(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, 1); - 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; -} - -/* - * 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(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); - pub->n = BN_new(); - buffer_get_bignum(&buffer, pub->n); - 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; -} - -/* - * 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(const char *filename, const char *passphrase, - RSA * prv, char **comment_return) -{ - int fd, i, check1, check2, cipher_type; - off_t len; - Buffer buffer, decrypted; - char *cp; - CipherContext cipher; - BN_CTX *ctx; - BIGNUM *aux; - 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; - } - 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_mask() | 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, 0); - 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); - BN_clear_free(prv->e); - 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; -} diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c deleted file mode 100644 index 4e25768e6acf..000000000000 --- a/crypto/openssh/bufaux.c +++ /dev/null @@ -1,159 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: bufaux.c,v 1.7 1999/11/24 19:53:44 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 *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, 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 = buffer_ptr(buffer); - BN_bin2bn(bin, bytes, value); - buffer_consume(buffer, bytes); - - return 2 + bytes; -} - -/* - * 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); -} - -/* - * 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 124a2656ba59..000000000000 --- a/crypto/openssh/bufaux.h +++ /dev/null @@ -1,55 +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.4 1999/11/24 19:53:44 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); - -/* Retrieves an BIGNUM from the buffer. */ -int buffer_get_bignum(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); - -#endif /* BUFAUX_H */ diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c deleted file mode 100644 index 65579341b8c7..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.4 1999/11/24 19:53:44 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_get 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_get 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 04efc25221cf..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.3 1999/11/24 19:53:44 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 fcf743cd417b..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.11 2000/01/04 13:41:32 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 b40e965d8a2c..000000000000 --- a/crypto/openssh/channels.c +++ /dev/null @@ -1,1614 +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. - * - */ - -#include "includes.h" -RCSID("$Id: channels.c,v 1.38 2000/01/24 20:37:29 markus Exp $"); - -#include "ssh.h" -#include "packet.h" -#include "xmalloc.h" -#include "buffer.h" -#include "authfd.h" -#include "uidswap.h" -#include "readconf.h" -#include "servconf.h" - -#include "channels.h" -#include "nchan.h" -#include "compat.h" - -/* Maximum number of fake X11 displays to try. */ -#define MAX_DISPLAYS 1000 - -/* Max len of agent socket */ -#define MAX_SOCKET_NAME 100 - -/* - * 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; /* Host name. */ - u_short port; /* 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; -} - -/* - * Allocate a new channel object and set its type and socket. This will cause - * remote_name to be freed. - */ - -int -channel_allocate(int type, int sock, char *remote_name) -{ - int i, found; - Channel *c; - - /* Update the maximum file descriptor value. */ - if (sock > channel_max_fd_value) - channel_max_fd_value = sock; - /* XXX set close-on-exec -markus */ - - /* Do initial allocation if this is the first call. */ - if (channels_alloc == 0) { - channels_alloc = 10; - channels = xmalloc(channels_alloc * sizeof(Channel)); - for (i = 0; i < channels_alloc; i++) - channels[i].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); - chan_init_iostates(c); - c->self = found; - c->type = type; - c->sock = sock; - c->remote_id = -1; - c->remote_name = remote_name; - debug("channel %d: new [%s]", found, remote_name); - return found; -} - -/* Free the channel and close its socket. */ - -void -channel_free(int channel) -{ - if (channel < 0 || channel >= channels_alloc || - channels[channel].type == SSH_CHANNEL_FREE) - packet_disconnect("channel free: bad local channel %d", channel); - - if (compat13) - shutdown(channels[channel].sock, SHUT_RDWR); - close(channels[channel].sock); - buffer_free(&channels[channel].input); - buffer_free(&channels[channel].output); - channels[channel].type = SSH_CHANNEL_FREE; - if (channels[channel].remote_name) { - xfree(channels[channel].remote_name); - channels[channel].remote_name = NULL; - } -} - -/* - * This is called just before select() to add any bits relevant to channels - * in the select bitmasks. - */ - -void -channel_prepare_select(fd_set * readset, fd_set * writeset) -{ - int i; - Channel *ch; - unsigned char *ucp; - unsigned int proto_len, data_len; - - for (i = 0; i < channels_alloc; i++) { - ch = &channels[i]; -redo: - switch (ch->type) { - case SSH_CHANNEL_X11_LISTENER: - case SSH_CHANNEL_PORT_LISTENER: - case SSH_CHANNEL_AUTH_SOCKET: - FD_SET(ch->sock, readset); - break; - - case SSH_CHANNEL_OPEN: - if (compat13) { - if (buffer_len(&ch->input) < packet_get_maxsize()) - FD_SET(ch->sock, readset); - if (buffer_len(&ch->output) > 0) - FD_SET(ch->sock, writeset); - break; - } - /* test whether sockets are 'alive' for read/write */ - if (ch->istate == CHAN_INPUT_OPEN) - if (buffer_len(&ch->input) < packet_get_maxsize()) - FD_SET(ch->sock, readset); - if (ch->ostate == CHAN_OUTPUT_OPEN || - ch->ostate == CHAN_OUTPUT_WAIT_DRAIN) { - if (buffer_len(&ch->output) > 0) { - FD_SET(ch->sock, writeset); - } else if (ch->ostate == CHAN_OUTPUT_WAIT_DRAIN) { - chan_obuf_empty(ch); - } - } - break; - - case SSH_CHANNEL_INPUT_DRAINING: - if (!compat13) - fatal("cannot happen: IN_DRAIN"); - if (buffer_len(&ch->input) == 0) { - packet_start(SSH_MSG_CHANNEL_CLOSE); - packet_put_int(ch->remote_id); - packet_send(); - ch->type = SSH_CHANNEL_CLOSED; - debug("Closing channel %d after input drain.", ch->self); - break; - } - break; - - case SSH_CHANNEL_OUTPUT_DRAINING: - if (!compat13) - fatal("cannot happen: OUT_DRAIN"); - if (buffer_len(&ch->output) == 0) { - channel_free(i); - break; - } - FD_SET(ch->sock, writeset); - break; - - case SSH_CHANNEL_X11_OPEN: - /* - * 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. - */ - /* Check if the fixed size part of the packet is in buffer. */ - if (buffer_len(&ch->output) < 12) - break; - - /* Parse the lengths of variable-length fields. */ - ucp = (unsigned char *) buffer_ptr(&ch->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]); - ch->type = SSH_CHANNEL_OPEN; - goto reject; - } - - /* Check if the whole packet is in buffer. */ - if (buffer_len(&ch->output) < - 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) - break; - - /* 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."); - ch->type = SSH_CHANNEL_OPEN; - goto reject; - } - /* 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."); - ch->type = SSH_CHANNEL_OPEN; - goto reject; - } - /* 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); - ch->type = SSH_CHANNEL_OPEN; - goto reject; - } - /* - * 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); - - /* Start normal processing for the channel. */ - ch->type = SSH_CHANNEL_OPEN; - goto redo; - - reject: - /* - * We have received an X11 connection that has bad - * authentication information. - */ - log("X11 connection rejected because of wrong authentication.\r\n"); - buffer_clear(&ch->input); - buffer_clear(&ch->output); - if (compat13) { - close(ch->sock); - ch->sock = -1; - ch->type = SSH_CHANNEL_CLOSED; - packet_start(SSH_MSG_CHANNEL_CLOSE); - packet_put_int(ch->remote_id); - packet_send(); - } else { - debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate); - chan_read_failed(ch); - chan_write_failed(ch); - debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate); - } - break; - - case SSH_CHANNEL_FREE: - default: - continue; - } - } -} - -/* - * After select, perform any appropriate operations for channels which have - * events pending. - */ - -void -channel_after_select(fd_set * readset, fd_set * writeset) -{ - struct sockaddr addr; - int newsock, i, newch, len; - socklen_t addrlen; - Channel *ch; - char buf[16384], *remote_hostname; - - /* Loop over all channels... */ - for (i = 0; i < channels_alloc; i++) { - ch = &channels[i]; - switch (ch->type) { - case SSH_CHANNEL_X11_LISTENER: - /* This is our fake X11 server socket. */ - if (FD_ISSET(ch->sock, readset)) { - debug("X11 connection requested."); - addrlen = sizeof(addr); - newsock = accept(ch->sock, &addr, &addrlen); - if (newsock < 0) { - error("accept: %.100s", strerror(errno)); - break; - } - remote_hostname = get_remote_hostname(newsock); - snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", - remote_hostname, get_peer_port(newsock)); - xfree(remote_hostname); - newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, - xstrdup(buf)); - packet_start(SSH_SMSG_X11_OPEN); - packet_put_int(newch); - if (have_hostname_in_open) - packet_put_string(buf, strlen(buf)); - packet_send(); - } - break; - - case SSH_CHANNEL_PORT_LISTENER: - /* - * This socket is listening for connections to a - * forwarded TCP/IP port. - */ - if (FD_ISSET(ch->sock, readset)) { - debug("Connection to port %d forwarding to %.100s port %d requested.", - ch->listening_port, ch->path, ch->host_port); - addrlen = sizeof(addr); - newsock = accept(ch->sock, &addr, &addrlen); - if (newsock < 0) { - error("accept: %.100s", strerror(errno)); - break; - } - remote_hostname = get_remote_hostname(newsock); - snprintf(buf, sizeof buf, "listen port %d for %.100s port %d, connect from %.200s port %d", - ch->listening_port, ch->path, ch->host_port, - remote_hostname, get_peer_port(newsock)); - xfree(remote_hostname); - newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, - xstrdup(buf)); - packet_start(SSH_MSG_PORT_OPEN); - packet_put_int(newch); - packet_put_string(ch->path, strlen(ch->path)); - packet_put_int(ch->host_port); - if (have_hostname_in_open) - packet_put_string(buf, strlen(buf)); - packet_send(); - } - break; - - case SSH_CHANNEL_AUTH_SOCKET: - /* - * This is the authentication agent socket listening - * for connections from clients. - */ - if (FD_ISSET(ch->sock, readset)) { - addrlen = sizeof(addr); - newsock = accept(ch->sock, &addr, &addrlen); - if (newsock < 0) { - error("accept from auth socket: %.100s", strerror(errno)); - break; - } - newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, - xstrdup("accepted auth socket")); - packet_start(SSH_SMSG_AGENT_OPEN); - packet_put_int(newch); - packet_send(); - } - break; - - case SSH_CHANNEL_OPEN: - /* - * This is an open two-way communication channel. It - * is not of interest to us at this point what kind - * of data is being transmitted. - */ - - /* - * Read available incoming data and append it to - * buffer; shutdown socket, if read or write failes - */ - if (FD_ISSET(ch->sock, readset)) { - len = read(ch->sock, buf, sizeof(buf)); - if (len <= 0) { - if (compat13) { - buffer_consume(&ch->output, buffer_len(&ch->output)); - ch->type = SSH_CHANNEL_INPUT_DRAINING; - debug("Channel %d status set to input draining.", i); - } else { - chan_read_failed(ch); - } - break; - } - buffer_append(&ch->input, buf, len); - } - /* Send buffered output data to the socket. */ - if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0) { - len = write(ch->sock, buffer_ptr(&ch->output), - buffer_len(&ch->output)); - if (len <= 0) { - if (compat13) { - buffer_consume(&ch->output, buffer_len(&ch->output)); - debug("Channel %d status set to input draining.", i); - ch->type = SSH_CHANNEL_INPUT_DRAINING; - } else { - chan_write_failed(ch); - } - break; - } - buffer_consume(&ch->output, len); - } - break; - - case SSH_CHANNEL_OUTPUT_DRAINING: - if (!compat13) - fatal("cannot happen: OUT_DRAIN"); - /* Send buffered output data to the socket. */ - if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0) { - len = write(ch->sock, buffer_ptr(&ch->output), - buffer_len(&ch->output)); - if (len <= 0) - buffer_consume(&ch->output, buffer_len(&ch->output)); - else - buffer_consume(&ch->output, len); - } - break; - - case SSH_CHANNEL_X11_OPEN: - case SSH_CHANNEL_FREE: - default: - continue; - } - } -} - -/* If there is data to send to the connection, send some of it now. */ - -void -channel_output_poll() -{ - int len, i; - Channel *ch; - - for (i = 0; i < channels_alloc; i++) { - ch = &channels[i]; - - /* We are only interested in channels that can have buffered incoming data. */ - if (compat13) { - if (ch->type != SSH_CHANNEL_OPEN && - ch->type != SSH_CHANNEL_INPUT_DRAINING) - continue; - } else { - if (ch->type != SSH_CHANNEL_OPEN) - continue; - if (ch->istate != CHAN_INPUT_OPEN && - ch->istate != CHAN_INPUT_WAIT_DRAIN) - continue; - } - - /* Get the amount of buffered data for this channel. */ - len = buffer_len(&ch->input); - if (len > 0) { - /* Send some data for the other side over the secure connection. */ - 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; - } - packet_start(SSH_MSG_CHANNEL_DATA); - packet_put_int(ch->remote_id); - packet_put_string(buffer_ptr(&ch->input), len); - packet_send(); - buffer_consume(&ch->input, len); - } else if (ch->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(ch); - } - } -} - -/* - * 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 payload_len) -{ - int id; - char *data; - unsigned int data_len; - Channel *ch; - - /* Get the channel number and verify it. */ - id = packet_get_int(); - if (id < 0 || id >= channels_alloc) - packet_disconnect("Received data for nonexistent channel %d.", id); - ch = &channels[id]; - - if (ch->type == SSH_CHANNEL_FREE) - packet_disconnect("Received data for free channel %d.", ch->self); - - /* Ignore any data for non-open channels (might happen on close) */ - if (ch->type != SSH_CHANNEL_OPEN && - ch->type != SSH_CHANNEL_X11_OPEN) - return; - - /* same for protocol 1.5 if output end is no longer open */ - if (!compat13 && ch->ostate != CHAN_OUTPUT_OPEN) - return; - - /* Get the data. */ - data = packet_get_string(&data_len); - packet_integrity_check(payload_len, 4 + 4 + data_len, SSH_MSG_CHANNEL_DATA); - buffer_append(&ch->output, 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 *ch; - - for (i = 0; i < channels_alloc; i++) { - ch = &channels[i]; - if (ch->type == SSH_CHANNEL_OPEN) { - if (buffer_len(&ch->input) > packet_get_maxsize()) - return 0; - if (buffer_len(&ch->output) > packet_get_maxsize()) - return 0; - } - } - return 1; -} - -/* This is called after receiving CHANNEL_CLOSE/IEOF. */ - -void -channel_input_close() -{ - int channel; - - /* Get the channel number and verify it. */ - channel = packet_get_int(); - if (channel < 0 || channel >= channels_alloc || - channels[channel].type == SSH_CHANNEL_FREE) - packet_disconnect("Received data for nonexistent channel %d.", channel); - - if (!compat13) { - /* proto version 1.5 overloads CLOSE with IEOF */ - chan_rcvd_ieof(&channels[channel]); - return; - } - - /* - * 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(channels[channel].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 (channels[channel].type != SSH_CHANNEL_CLOSED) { - /* - * Not a closed channel - mark it as draining, which will - * cause it to be freed later. - */ - buffer_consume(&channels[channel].input, - buffer_len(&channels[channel].input)); - channels[channel].type = SSH_CHANNEL_OUTPUT_DRAINING; - } -} - -/* This is called after receiving CHANNEL_CLOSE_CONFIRMATION/OCLOSE. */ - -void -channel_input_close_confirmation() -{ - int channel; - - /* Get the channel number and verify it. */ - channel = packet_get_int(); - if (channel < 0 || channel >= channels_alloc) - packet_disconnect("Received close confirmation for out-of-range channel %d.", - channel); - - if (!compat13) { - /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ - chan_rcvd_oclose(&channels[channel]); - return; - } - if (channels[channel].type != SSH_CHANNEL_CLOSED) - packet_disconnect("Received close confirmation for non-closed channel %d (type %d).", - channel, channels[channel].type); - - /* Free the channel. */ - channel_free(channel); -} - -/* This is called after receiving CHANNEL_OPEN_CONFIRMATION. */ - -void -channel_input_open_confirmation() -{ - int channel, remote_channel; - - /* Get the channel number and verify it. */ - channel = packet_get_int(); - if (channel < 0 || channel >= channels_alloc || - channels[channel].type != SSH_CHANNEL_OPENING) - packet_disconnect("Received open confirmation for non-opening channel %d.", - channel); - - /* Get remote side's id for this channel. */ - remote_channel = packet_get_int(); - - /* Record the remote channel number and mark that the channel is now open. */ - channels[channel].remote_id = remote_channel; - channels[channel].type = SSH_CHANNEL_OPEN; -} - -/* This is called after receiving CHANNEL_OPEN_FAILURE from the other side. */ - -void -channel_input_open_failure() -{ - int channel; - - /* Get the channel number and verify it. */ - channel = packet_get_int(); - if (channel < 0 || channel >= channels_alloc || - channels[channel].type != SSH_CHANNEL_OPENING) - packet_disconnect("Received open failure for non-opening channel %d.", - channel); - - /* Free the channel. This will also close the socket. */ - channel_free(channel); -} - -/* - * 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 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) - close(channels[i].sock); - } -} - -/* 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_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_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)\r\n", - c->self, c->remote_name, - c->type, c->remote_id, - c->istate, buffer_len(&c->input), - c->ostate, buffer_len(&c->output)); - buffer_append(&buffer, buf, strlen(buf)); - continue; - default: - fatal("channel_still_open: 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_allocate(SSH_CHANNEL_PORT_LISTENER, sock, - 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 port, const char *host, - u_short remote_port) -{ - 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 = xstrdup(host); - permitted_opens[num_permitted_opens].port = remote_port; - num_permitted_opens++; - - /* Send the forward request to the remote side. */ - packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); - packet_put_int(port); - packet_put_string(host, strlen(host)); - packet_put_int(remote_port); - 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) -{ - 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, - * bind port to localhost only (gateway ports == 0). - */ - channel_request_local_forwarding(port, hostname, host_port, 0); - - /* Free the argument string. */ - xfree(hostname); -} - -/* - * 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 payload_len) -{ - int remote_channel, sock = 0, newch, i; - u_short host_port; - char *host, *originator_string; - int host_len, originator_len; - struct addrinfo hints, *ai, *aitop; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int gaierr; - - /* 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(payload_len, - 4 + 4 + host_len + 4 + originator_len, - SSH_MSG_PORT_OPEN); - - /* Check if opening that port is permitted. */ - if (!all_opens_permitted) { - /* Go trough all permitted ports. */ - for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].port == host_port && - strcmp(permitted_opens[i].host, 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); - goto fail; - } - } - - 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)); - goto fail; - } - - 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_input_port_open: 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); - goto fail; - } - - /* Successful connection. */ - - /* Allocate a channel for this connection. */ - newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string); - 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(); - - /* Free the argument string. */ - xfree(host); - - return; - -fail: - /* Free the argument string. */ - xfree(host); - - /* Send refusal to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_channel); - packet_send(); -} - -/* - * 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_allocate(SSH_CHANNEL_X11_LISTENER, sock, - 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; -} - - -/* - * 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 payload_len) -{ - int remote_channel, display_number, sock = 0, newch; - const char *display; - char buf[1024], *cp, *remote_host; - int remote_len; - struct addrinfo hints, *ai, *aitop; - char strport[NI_MAXSERV]; - int gaierr; - - /* 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(payload_len, 4 + remote_len, SSH_SMSG_X11_OPEN); - - /* Try to open a socket for the local X server. */ - display = getenv("DISPLAY"); - if (!display) { - error("DISPLAY not set."); - goto fail; - } - /* - * 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); - goto fail; - } - /* Create a socket. */ - sock = connect_local_xsocket(display_number); - if (sock < 0) - goto fail; - - /* OK, we now have a connection to the display. */ - goto success; - } - /* - * 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); - goto fail; - } - *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); - goto fail; - } - - /* 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)); - goto fail; - } - 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; - - } /* (ai = aitop, ai; ai = ai->ai_next) */ - freeaddrinfo(aitop); - if (!ai) { - error("connect %.100s port %d: %.100s", buf, 6000 + display_number, - strerror(errno)); - goto fail; - } -success: - /* We have successfully obtained a connection to the real X display. */ - - /* Allocate a channel for this connection. */ - if (x11_saved_proto == NULL) - newch = channel_allocate(SSH_CHANNEL_OPEN, sock, remote_host); - else - newch = channel_allocate(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(); - - return; - -fail: - /* Send refusal to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_channel); - packet_send(); -} - -/* - * Requests forwarding of X11 connections, generates fake authentication - * data, and enables authentication spoofing. - */ - -void -x11_request_forwarding_with_spoofing(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. */ - packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); - packet_put_string(proto, strlen(proto)); - packet_put_string(new_data, strlen(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 remch, sock, newch; - char *dummyname; - - /* 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(); -} diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h deleted file mode 100644 index 93a7b539b76e..000000000000 --- a/crypto/openssh/channels.h +++ /dev/null @@ -1,43 +0,0 @@ -/* RCSID("$Id: channels.h,v 1.6 1999/11/24 19:53:45 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 */ -/* SSH_CHANNEL_AUTH_FD 6 authentication fd */ -#define SSH_CHANNEL_AUTH_SOCKET 7 /* authentication socket */ -/* SSH_CHANNEL_AUTH_SOCKET_FD 8 connection to auth socket */ -#define SSH_CHANNEL_X11_OPEN 9 /* reading first X11 packet */ -#define SSH_CHANNEL_INPUT_DRAINING 10 /* sending remaining data to conn */ -#define SSH_CHANNEL_OUTPUT_DRAINING 11 /* sending remaining data to app */ - -/* - * Data structure for channel data. This is iniailized in channel_allocate - * and cleared in channel_free. - */ - -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 sock; /* data socket, linked to this channel */ - Buffer input; /* data read from socket, to be sent over - * encrypted connection */ - Buffer output; /* data received over encrypted connection for - * send on socket */ - 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 */ -} Channel; -#endif diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c deleted file mode 100644 index e3698f072d05..000000000000 --- a/crypto/openssh/cipher.c +++ /dev/null @@ -1,321 +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 - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: cipher.c,v 1.19 2000/02/22 15:19:29 markus Exp $"); - -#include "ssh.h" -#include "cipher.h" - -#include <openssl/md5.h> - -/* - * What kind of tripple 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. */ -} - -/* - * SSH 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; - } -} - -void (*cipher_attack_detected) (const char *fmt,...) = fatal; - -static inline void -detect_cbc_attack(const unsigned char *src, - unsigned int len) -{ - return; - - log("CRC-32 CBC insertion attack detected"); - cipher_attack_detected("CRC-32 CBC insertion attack detected"); -} - -/* - * 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" -}; - -/* - * 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 mask = 0; - mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ - mask |= 1 << SSH_CIPHER_BLOWFISH; - return mask; -} - -/* 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 number: %d", cipher); - return cipher_names[cipher]; -} - -/* - * 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, int for_encryption) -{ - 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, for_encryption); - - 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, int for_encryption) -{ - 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: - BF_set_key(&context->u.bf.key, keylen, padded); - memset(context->u.bf.iv, 0, 8); - break; - - default: - fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); - } - memset(padded, 0, sizeof(padded)); -} - -/* 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; - - 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: - /* CRC-32 attack? */ - 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: - detect_cbc_attack(src, len); - 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; - - 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 bb87f882dfee..000000000000 --- a/crypto/openssh/cipher.h +++ /dev/null @@ -1,98 +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 - * - * $FreeBSD$ - */ - -/* RCSID("$Id: cipher.h,v 1.10 1999/11/24 19:53:46 markus Exp $"); */ - -#ifndef CIPHER_H -#define CIPHER_H - -#include <openssl/des.h> -#include <openssl/blowfish.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_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 - -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; - } 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(); - -/* 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); - -/* - * 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, int for_encryption); - -/* - * 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, int for_encryption); - -/* 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); - -/* - * If and CRC-32 attack is detected this function is called. Defaults to - * fatal, changed to packet_disconnect in sshd and ssh. - */ -extern void (*cipher_attack_detected) (const char *fmt, ...); - -#endif /* CIPHER_H */ diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c deleted file mode 100644 index 59dad3d7d308..000000000000 --- a/crypto/openssh/clientloop.c +++ /dev/null @@ -1,952 +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). - * - */ - -#include "includes.h" -RCSID("$Id: clientloop.c,v 1.14 1999/12/06 20:15:26 deraadt Exp $"); - -#include "xmalloc.h" -#include "ssh.h" -#include "packet.h" -#include "buffer.h" -#include "authfd.h" -#include "readconf.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. */ - -/* 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(); - } -} - -/* - * Get packets from the connection input buffer, and process them as long as - * there are packets available. - */ - -void -client_process_buffered_input_packets() -{ - int type; - char *data; - unsigned int data_len; - int payload_len; - - /* Process any buffered packets from the server. */ - while (!quit_pending && - (type = packet_read_poll(&payload_len)) != SSH_MSG_NONE) { - switch (type) { - - case SSH_SMSG_STDOUT_DATA: - data = packet_get_string(&data_len); - packet_integrity_check(payload_len, 4 + data_len, type); - buffer_append(&stdout_buffer, data, data_len); - stdout_bytes += data_len; - memset(data, 0, data_len); - xfree(data); - break; - - case SSH_SMSG_STDERR_DATA: - data = packet_get_string(&data_len); - packet_integrity_check(payload_len, 4 + data_len, type); - buffer_append(&stderr_buffer, data, data_len); - stdout_bytes += data_len; - memset(data, 0, data_len); - xfree(data); - break; - - case SSH_SMSG_EXITSTATUS: - packet_integrity_check(payload_len, 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; - break; - - case SSH_SMSG_X11_OPEN: - x11_input_open(payload_len); - break; - - case SSH_MSG_PORT_OPEN: - channel_input_port_open(payload_len); - break; - - case SSH_SMSG_AGENT_OPEN: - packet_integrity_check(payload_len, 4, type); - auth_input_open_request(); - break; - - case SSH_MSG_CHANNEL_OPEN_CONFIRMATION: - packet_integrity_check(payload_len, 4 + 4, type); - channel_input_open_confirmation(); - break; - - case SSH_MSG_CHANNEL_OPEN_FAILURE: - packet_integrity_check(payload_len, 4, type); - channel_input_open_failure(); - break; - - case SSH_MSG_CHANNEL_DATA: - channel_input_data(payload_len); - break; - - case SSH_MSG_CHANNEL_CLOSE: - packet_integrity_check(payload_len, 4, type); - channel_input_close(); - break; - - case SSH_MSG_CHANNEL_CLOSE_CONFIRMATION: - packet_integrity_check(payload_len, 4, type); - channel_input_close_confirmation(); - break; - - default: - /* - * 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. - */ - packet_disconnect("Protocol error during session: type %d", - type); - } - } -} - -/* - * 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() -{ - /* Send possible window change message to the server. */ - if (received_window_change_signal) { - struct winsize ws; - - /* Clear the window change indicator. */ - received_window_change_signal = 0; - - /* Read new window size. */ - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) >= 0) { - /* Successful, send the packet now. */ - 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) -{ - /* Initialize select masks. */ - FD_ZERO(readset); - - /* 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); - - FD_ZERO(writeset); - - /* 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); - - /* Select stdout if have data in buffer. */ - if (buffer_len(&stdout_buffer) > 0) - FD_SET(fileno(stdout), writeset); - - /* Select stderr if have data in buffer. */ - if (buffer_len(&stderr_buffer) > 0) - FD_SET(fileno(stderr), writeset); - - /* 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_input(fd_set * readset) -{ - int len, pid; - char buf[8192], *s; - - /* - * Read input from the server, and add any such data to the buffer of - * the packet subsystem. - */ - if (FD_ISSET(connection_in, readset)) { - /* Read as much as possible. */ - len = read(connection_in, buf, sizeof(buf)); - if (len == 0) { - /* Received EOF. The remote host has closed the connection. */ - snprintf(buf, sizeof buf, "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); - } - /* 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); - } -} - -/* - * 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); - - /* 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. */ - 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(); - - /* - * Make packets of buffered stdin data, and buffer them for - * sending to the server. - */ - 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); - - /* - * Process input from the connection and from stdin. Buffer - * any data that is available. - */ - 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; -} diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c deleted file mode 100644 index 7e21fd080a81..000000000000 --- a/crypto/openssh/compat.c +++ /dev/null @@ -1,42 +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.5 1999/11/24 16:15:24 markus Exp $"); - -#include "ssh.h" - -int compat13 = 0; - -void -enable_compat13(void) -{ - verbose("Enabling compatibility mode for protocol 1.3"); - compat13 = 1; -} diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h deleted file mode 100644 index 68d5e2bd7921..000000000000 --- a/crypto/openssh/compat.h +++ /dev/null @@ -1,35 +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.4 1999/11/24 16:15:24 markus Exp $"); */ - -#ifndef COMPAT_H -#define COMPAT_H -void enable_compat13(void); -extern int compat13; -#endif diff --git a/crypto/openssh/compress.c b/crypto/openssh/compress.c deleted file mode 100644 index f4a87857348f..000000000000 --- a/crypto/openssh/compress.c +++ /dev/null @@ -1,165 +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.4 1999/11/24 19:53:46 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 = buffer_ptr(input_buffer); - outgoing_stream.avail_in = buffer_len(input_buffer); - - /* Loop compressing until deflate() returns with avail_out != 0. */ - do { - /* Set up fixed-size output buffer. */ - outgoing_stream.next_out = buf; - outgoing_stream.avail_out = sizeof(buf); - - /* Compress as much data into the buffer as possible. */ - status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH); - switch (status) { - case Z_OK: - /* Append compressed data to output_buffer. */ - buffer_append(output_buffer, buf, - sizeof(buf) - outgoing_stream.avail_out); - break; - case Z_STREAM_END: - fatal("buffer_compress: deflate returned Z_STREAM_END"); - /* NOTREACHED */ - case Z_STREAM_ERROR: - fatal("buffer_compress: deflate returned Z_STREAM_ERROR"); - /* NOTREACHED */ - case Z_BUF_ERROR: - fatal("buffer_compress: deflate returned Z_BUF_ERROR"); - /* NOTREACHED */ - 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 = buffer_ptr(input_buffer); - incoming_stream.avail_in = buffer_len(input_buffer); - - incoming_stream.next_out = buf; - incoming_stream.avail_out = sizeof(buf); - - for (;;) { - status = inflate(&incoming_stream, Z_PARTIAL_FLUSH); - switch (status) { - case Z_OK: - buffer_append(output_buffer, buf, - sizeof(buf) - incoming_stream.avail_out); - incoming_stream.next_out = buf; - incoming_stream.avail_out = sizeof(buf); - break; - case Z_STREAM_END: - fatal("buffer_uncompress: inflate returned Z_STREAM_END"); - /* NOTREACHED */ - case Z_DATA_ERROR: - fatal("buffer_uncompress: inflate returned Z_DATA_ERROR"); - /* NOTREACHED */ - case Z_STREAM_ERROR: - fatal("buffer_uncompress: inflate returned Z_STREAM_ERROR"); - /* NOTREACHED */ - 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; - case Z_MEM_ERROR: - fatal("buffer_uncompress: inflate returned Z_MEM_ERROR"); - /* NOTREACHED */ - default: - fatal("buffer_uncompress: inflate returned %d", status); - } - } -} diff --git a/crypto/openssh/compress.h b/crypto/openssh/compress.h deleted file mode 100644 index 4e9c598abf5e..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.3 1999/11/24 19:53:46 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 54299fccb114..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.4 1999/11/24 19:53:46 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/fingerprint.c b/crypto/openssh/fingerprint.c deleted file mode 100644 index cf75788b659e..000000000000 --- a/crypto/openssh/fingerprint.c +++ /dev/null @@ -1,71 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: fingerprint.c,v 1.4 1999/11/24 16:15:25 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]; - 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 d2e138089a4f..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.2 1999/11/24 00:26:02 deraadt 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/hostfile.c b/crypto/openssh/hostfile.c deleted file mode 100644 index ea92fa048553..000000000000 --- a/crypto/openssh/hostfile.c +++ /dev/null @@ -1,300 +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.13 2000/02/18 10:20:20 markus Exp $"); - -#include "packet.h" -#include "ssh.h" - -/* - * Reads a multiple-precision integer in decimal from the buffer, and advances - * the pointer. The integer must already be initialized. This function is - * permitted to modify the buffer. This leaves *cpp to point just beyond the - * last processed (and maybe modified) character. Note that this may modify - * the buffer containing the number. - */ - -int -auth_rsa_read_bignum(char **cpp, BIGNUM * value) -{ - char *cp = *cpp; - int old; - - /* Skip any leading whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - - /* Check that it begins with a decimal digit. */ - if (*cp < '0' || *cp > '9') - return 0; - - /* Save starting position. */ - *cpp = cp; - - /* Move forward until all decimal digits skipped. */ - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - - /* Save the old terminating character, and replace it by \0. */ - old = *cp; - *cp = 0; - - /* Parse the number. */ - if (BN_dec2bn(&value, *cpp) == 0) - return 0; - - /* Restore old terminating character. */ - *cp = old; - - /* Move beyond the number and return success. */ - *cpp = cp; - return 1; -} - -/* - * 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) -{ - unsigned int bits; - char *cp; - - /* Skip leading whitespace. */ - for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) - ; - - /* Get number of bits. */ - if (*cp < '0' || *cp > '9') - return 0; /* Bad bit count... */ - for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) - bits = 10 * bits + *cp - '0'; - - /* Get public exponent. */ - if (!auth_rsa_read_bignum(&cp, e)) - return 0; - - /* Get public modulus. */ - if (!auth_rsa_read_bignum(&cp, n)) - return 0; - - /* Skip trailing whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - - /* Return results. */ - *cpp = cp; - *bitsp = bits; - return 1; -} - -/* - * 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; -} - -/* - * 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, - BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn) -{ - FILE *f; - char line[8192]; - int linenum = 0; - unsigned int kbits, hostlen; - char *cp, *cp2; - HostStatus end_return; - - /* 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 (!auth_rsa_read_key(&cp, &kbits, ke, kn)) - continue; - - if (kbits != BN_num_bits(kn)) { - error("Warning: %s, line %d: keysize mismatch for host %s: " - "actual %d vs. announced %d.", - filename, linenum, host, BN_num_bits(kn), kbits); - error("Warning: replace %d with %d in %s, line %d.", - kbits, BN_num_bits(kn), filename, linenum); - } - /* Check if the current key is the same as the given key. */ - if (BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) { - /* 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, - BIGNUM * e, BIGNUM * n) -{ - FILE *f; - char *buf; - unsigned int bits; - - /* Open the file for appending. */ - f = fopen(filename, "a"); - if (!f) - return 0; - - /* size of modulus 'n' */ - bits = BN_num_bits(n); - - /* Print the host name and key to the file. */ - fprintf(f, "%s %u ", host, bits); - buf = BN_bn2dec(e); - if (buf == NULL) { - error("add_host_to_hostfile: BN_bn2dec(e) failed"); - fclose(f); - return 0; - } - fprintf(f, "%s ", buf); - free(buf); - buf = BN_bn2dec(n); - if (buf == NULL) { - error("add_host_to_hostfile: BN_bn2dec(n) failed"); - fclose(f); - return 0; - } - fprintf(f, "%s\n", buf); - free(buf); - - /* Close the file. */ - fclose(f); - return 1; -} diff --git a/crypto/openssh/includes.h b/crypto/openssh/includes.h deleted file mode 100644 index a20318c4976e..000000000000 --- a/crypto/openssh/includes.h +++ /dev/null @@ -1,94 +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. - * - * $FreeBSD$ - */ - -#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/stat.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/un.h> -#include <sys/resource.h> -#include <machine/endian.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 <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 - -#if defined(__FreeBSD__) && __FreeBSD__ <= 3 -/* - * Data types. - */ -typedef u_char sa_family_t; -typedef u_int32_t socklen_t; - -/* - * bsd-api-new-02a: protocol-independent placeholder for socket addresses - */ -#define _SS_MAXSIZE 128 -#define _SS_ALIGNSIZE (sizeof(int64_t)) -#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) -#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ - _SS_PAD1SIZE - _SS_ALIGNSIZE) - -struct sockaddr_storage { - u_char ss_len; /* address length */ - sa_family_t ss_family; /* address family */ - char __ss_pad1[_SS_PAD1SIZE]; - int64_t __ss_align; /* force desired structure storage alignment */ - char __ss_pad2[_SS_PAD2SIZE]; -}; -#endif - -#endif /* INCLUDES_H */ diff --git a/crypto/openssh/lib/Makefile b/crypto/openssh/lib/Makefile deleted file mode 100644 index 8f7e4f75afa9..000000000000 --- a/crypto/openssh/lib/Makefile +++ /dev/null @@ -1,25 +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 - -NOPROFILE= yes -NOPIC= yes - -install: - @echo -n - -.include <bsd.own.mk> - -.if (${KERBEROS} == "yes") -CFLAGS+= -DKRB4 -I/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 62709d96cdc6..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.6 1999/11/24 00:26:02 deraadt 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 MSGBUFSIZE 1024 - -void -do_log(LogLevel level, const char *fmt, va_list args) -{ - char msgbuf[MSGBUFSIZE]; - - 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 52f56a307e8b..000000000000 --- a/crypto/openssh/log-server.c +++ /dev/null @@ -1,140 +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.11 1999/11/24 00:26:02 deraadt 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 MSGBUFSIZE 1024 - -void -do_log(LogLevel level, const char *fmt, va_list args) -{ - char msgbuf[MSGBUFSIZE]; - char fmtbuf[MSGBUFSIZE]; - 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); - 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 6bfba255149a..000000000000 --- a/crypto/openssh/login.c +++ /dev/null @@ -1,129 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: login.c,v 1.11 2000/01/04 00:07:59 markus Exp $"); - -#ifdef __FreeBSD__ -#include <libutil.h> -#else -#include <util.h> -#endif /* __FreeBSD__ */ -#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(int 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)); - realhostname_sa(u.ut_host, sizeof(u.ut_host), addr, addr->sa_len); - - /* 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(int 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 7a63be63fb98..000000000000 --- a/crypto/openssh/match.c +++ /dev/null @@ -1,82 +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.4 1999/11/24 19:53:48 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 */ -} diff --git a/crypto/openssh/mpaux.c b/crypto/openssh/mpaux.c deleted file mode 100644 index ce3e3674c264..000000000000 --- a/crypto/openssh/mpaux.c +++ /dev/null @@ -1,47 +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. - * - * $FreeBSD$ -*/ - -#include "includes.h" -RCSID("$Id: mpaux.c,v 1.9 1999/12/08 22:37:42 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 6b30fe03c4a9..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.5 1999/11/24 19:53:48 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/nchan.c b/crypto/openssh/nchan.c deleted file mode 100644 index 1f30a7cf2c6b..000000000000 --- a/crypto/openssh/nchan.c +++ /dev/null @@ -1,238 +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.10 2000/01/10 10:15:28 markus Exp $"); - -#include "ssh.h" - -#include "buffer.h" -#include "packet.h" -#include "channels.h" -#include "nchan.h" - -static void chan_send_ieof(Channel *c); -static void chan_send_oclose(Channel *c); -static void chan_shutdown_write(Channel *c); -static void chan_shutdown_read(Channel *c); -static void chan_delete_if_full_closed(Channel *c); - -/* - * EVENTS update channel input/output states execute ACTIONS - */ - -/* events concerning the INPUT from socket for channel (istate) */ -void -chan_rcvd_oclose(Channel *c) -{ - switch (c->istate) { - case CHAN_INPUT_WAIT_OCLOSE: - debug("channel %d: INPUT_WAIT_OCLOSE -> INPUT_CLOSED [rcvd OCLOSE]", c->self); - c->istate = CHAN_INPUT_CLOSED; - break; - case CHAN_INPUT_OPEN: - debug("channel %d: INPUT_OPEN -> INPUT_CLOSED [rvcd OCLOSE, send IEOF]", c->self); - chan_shutdown_read(c); - chan_send_ieof(c); - c->istate = CHAN_INPUT_CLOSED; - break; - case CHAN_INPUT_WAIT_DRAIN: - /* both local read_failed and remote write_failed */ - log("channel %d: INPUT_WAIT_DRAIN -> INPUT_CLOSED [rvcd OCLOSE, send IEOF]", c->self); - debug("channel %d: INPUT_WAIT_DRAIN -> INPUT_CLOSED [rvcd OCLOSE, send IEOF]", c->self); - chan_send_ieof(c); - c->istate = CHAN_INPUT_CLOSED; - break; - default: - error("protocol error: chan_rcvd_oclose %d for istate %d", c->self, c->istate); - return; - } - chan_delete_if_full_closed(c); -} -void -chan_read_failed(Channel *c) -{ - switch (c->istate) { - case CHAN_INPUT_OPEN: - debug("channel %d: INPUT_OPEN -> INPUT_WAIT_DRAIN [read failed]", c->self); - chan_shutdown_read(c); - c->istate = CHAN_INPUT_WAIT_DRAIN; - break; - default: - error("internal error: we do not read, but chan_read_failed %d for istate %d", - c->self, c->istate); - break; - } -} -void -chan_ibuf_empty(Channel *c) -{ - if (buffer_len(&c->input)) { - error("internal error: chan_ibuf_empty %d for non empty buffer", c->self); - return; - } - switch (c->istate) { - case CHAN_INPUT_WAIT_DRAIN: - debug("channel %d: INPUT_WAIT_DRAIN -> INPUT_WAIT_OCLOSE [inbuf empty, send IEOF]", c->self); - chan_send_ieof(c); - c->istate = CHAN_INPUT_WAIT_OCLOSE; - break; - default: - error("internal error: chan_ibuf_empty %d for istate %d", c->self, c->istate); - break; - } -} - -/* events concerning the OUTPUT from channel for socket (ostate) */ -void -chan_rcvd_ieof(Channel *c) -{ - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - debug("channel %d: OUTPUT_OPEN -> OUTPUT_WAIT_DRAIN [rvcd IEOF]", c->self); - c->ostate = CHAN_OUTPUT_WAIT_DRAIN; - break; - case CHAN_OUTPUT_WAIT_IEOF: - debug("channel %d: OUTPUT_WAIT_IEOF -> OUTPUT_CLOSED [rvcd IEOF]", c->self); - c->ostate = CHAN_OUTPUT_CLOSED; - chan_delete_if_full_closed(c); - break; - default: - error("protocol error: chan_rcvd_ieof %d for ostate %d", c->self, c->ostate); - break; - } -} -void -chan_write_failed(Channel *c) -{ - switch (c->ostate) { - case CHAN_OUTPUT_OPEN: - debug("channel %d: OUTPUT_OPEN -> OUTPUT_WAIT_IEOF [write failed]", c->self); - chan_send_oclose(c); - c->ostate = CHAN_OUTPUT_WAIT_IEOF; - break; - case CHAN_OUTPUT_WAIT_DRAIN: - debug("channel %d: OUTPUT_WAIT_DRAIN -> OUTPUT_CLOSED [write failed]", c->self); - chan_send_oclose(c); - c->ostate = CHAN_OUTPUT_CLOSED; - chan_delete_if_full_closed(c); - break; - default: - error("internal error: chan_write_failed %d for ostate %d", c->self, c->ostate); - break; - } -} -void -chan_obuf_empty(Channel *c) -{ - if (buffer_len(&c->output)) { - debug("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_WAIT_DRAIN -> OUTPUT_CLOSED [obuf empty, send OCLOSE]", c->self); - chan_send_oclose(c); - c->ostate = CHAN_OUTPUT_CLOSED; - chan_delete_if_full_closed(c); - break; - default: - error("internal error: chan_obuf_empty %d for ostate %d", c->self, c->ostate); - break; - } -} - -/* - * ACTIONS: should never update the channel states: c->istate or c->ostate - */ -static void -chan_send_ieof(Channel *c) -{ - 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("internal error: channel %d: cannot send IEOF for istate %d", c->self, c->istate); - break; - } -} -static void -chan_send_oclose(Channel *c) -{ - 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("internal error: channel %d: cannot send OCLOSE for ostate %d", c->self, c->istate); - break; - } -} - -/* helper */ -static void -chan_shutdown_write(Channel *c) -{ - /* shutdown failure is allowed if write failed already */ - debug("channel %d: shutdown_write", c->self); - if (shutdown(c->sock, SHUT_WR) < 0) - debug("chan_shutdown_write failed for #%d/fd%d: %.100s", - c->self, c->sock, strerror(errno)); -} -static void -chan_shutdown_read(Channel *c) -{ - debug("channel %d: shutdown_read", c->self); - if (shutdown(c->sock, SHUT_RD) < 0) - error("chan_shutdown_read failed for #%d/fd%d [i%d o%d]: %.100s", - c->self, c->sock, c->istate, c->ostate, strerror(errno)); -} -static void -chan_delete_if_full_closed(Channel *c) -{ - if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { - debug("channel %d: full closed", c->self); - channel_free(c->self); - } -} -void -chan_init_iostates(Channel *c) -{ - c->ostate = CHAN_OUTPUT_OPEN; - c->istate = CHAN_INPUT_OPEN; -} diff --git a/crypto/openssh/nchan.h b/crypto/openssh/nchan.h deleted file mode 100644 index 3397be8a54bf..000000000000 --- a/crypto/openssh/nchan.h +++ /dev/null @@ -1,86 +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.5 1999/11/24 16:15:25 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 - -/* EVENTS for the input state */ -void chan_rcvd_oclose(Channel * c); -void chan_read_failed(Channel * c); -void chan_ibuf_empty(Channel * c); - -/* EVENTS for the output state */ -void chan_rcvd_ieof(Channel * c); -void chan_write_failed(Channel * c); -void chan_obuf_empty(Channel * c); - -void chan_init_iostates(Channel * c); -#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/packet.c b/crypto/openssh/packet.c deleted file mode 100644 index af54759233b7..000000000000 --- a/crypto/openssh/packet.c +++ /dev/null @@ -1,845 +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. - * - */ - -#include "includes.h" -RCSID("$Id: packet.c,v 1.22 2000/02/05 10:13:11 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" - -/* - * 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; - -/* - * 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, 1); - cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 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. - */ - -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) - */ - - switch (cc->type) { - case SSH_CIPHER_NONE: - i = DEATTACK_OK; - break; - default: - i = detect_attack(src, bytes, NULL); - break; - } - - 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) -{ - /* All other ciphers use the same key in both directions for now. */ - cipher_set_key(&receive_context, cipher, key, keylen, 0); - cipher_set_key(&send_context, cipher, key, keylen, 1); -} - -/* Starts constructing a packet to send. */ - -void -packet_start(int type) -{ - char buf[9]; - - buffer_clear(&outgoing_packet); - memset(buf, 0, 8); - buf[8] = type; - buffer_append(&outgoing_packet, buf, 9); -} - -/* 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); -} - -/* Appends an arbitrary precision integer to packet data. */ - -void -packet_put_bignum(BIGNUM * value) -{ - buffer_put_bignum(&outgoing_packet, value); -} - -/* - * Finalizes and sends the packet. If the encryption key has been set, - * encrypts the packet before sending. - */ - -void -packet_send() -{ - 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. */ - 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. - */ -} - -/* - * 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]; - - /* 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 (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_poll(int *payload_len_ptr) -{ - unsigned int len, padded_len; - unsigned char *ucp; - char buf[8], *cp, *msg; - unsigned int checksum, stored_checksum; - -restart: - - /* 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); - - /* Handle disconnect message. */ - if ((unsigned char) buf[0] == SSH_MSG_DISCONNECT) { - msg = packet_get_string(NULL); - log("Received disconnect: %.900s", msg); - xfree(msg); - fatal_cleanup(); - } - - /* Ignore ignore messages. */ - if ((unsigned char) buf[0] == SSH_MSG_IGNORE) - goto restart; - - /* Send debug messages as debugging output. */ - if ((unsigned char) buf[0] == SSH_MSG_DEBUG) { - msg = packet_get_string(NULL); - debug("Remote: %.900s", msg); - xfree(msg); - goto restart; - } - /* Return type. */ - return (unsigned char) buf[0]; -} - -/* - * 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); -} - -/* - * 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); - - packet_start(SSH_MSG_DEBUG); - packet_put_string(buf, strlen(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. */ - 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 41f95576ef34..000000000000 --- a/crypto/openssh/packet.h +++ /dev/null @@ -1,199 +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. - * - * $FreeBSD$ - */ - -/* RCSID("$Id: packet.h,v 1.9 2000/01/04 16:54:58 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); - -/* Appends a string to packet data. */ -void packet_put_string(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); - -/* - * 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) - -/* remote host is connected via a socket/ipv4 */ -int packet_connection_is_on_socket(void); -int packet_connection_is_ipv4(void); - -#endif /* PACKET_H */ diff --git a/crypto/openssh/pam_ssh/pam_ssh.c b/crypto/openssh/pam_ssh/pam_ssh.c deleted file mode 100644 index 19f7722af4eb..000000000000 --- a/crypto/openssh/pam_ssh/pam_ssh.c +++ /dev/null @@ -1,489 +0,0 @@ -/*- - * Copyright (c) 1999 Andrew J. Korty - * 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 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 AUTHOR 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. - * - * $FreeBSD$ - * - */ - - -#include <sys/param.h> -#include <sys/queue.h> - -#include <fcntl.h> -#include <paths.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#define PAM_SM_AUTH -#define PAM_SM_SESSION -#include <security/pam_modules.h> -#include <security/pam_mod_misc.h> - -#include "includes.h" -#include "rsa.h" -#include "ssh.h" -#include "authfd.h" - -#define MODULE_NAME "pam_ssh" -#define NEED_PASSPHRASE "Need passphrase for %s (%s).\nEnter passphrase: " -#define PATH_SSH_AGENT "/usr/bin/ssh-agent" - - -void -rsa_cleanup(pam_handle_t *pamh, void *data, int error_status) -{ - if (data) - RSA_free(data); -} - - -void -ssh_cleanup(pam_handle_t *pamh, void *data, int error_status) -{ - if (data) - free(data); -} - - -/* - * The following set of functions allow the module to manipulate the - * environment without calling the putenv() or setenv() stdlib functions. - * At least one version of these functions, on the first call, copies - * the environment into dynamically-allocated memory and then augments - * it. On subsequent calls, the realloc() call is used to grow the - * previously allocated buffer. Problems arise when the "environ" - * variable is changed to point to static memory after putenv()/setenv() - * have been called. - * - * We don't use putenv() or setenv() in case the application subsequently - * manipulates environ, (e.g., to clear the environment by pointing - * environ at an array of one element equal to NULL). - */ - -SLIST_HEAD(env_head, env_entry); - -struct env_entry { - char *ee_env; - SLIST_ENTRY(env_entry) ee_entries; -}; - -typedef struct env { - char **e_environ_orig; - char **e_environ_new; - int e_count; - struct env_head e_head; - int e_committed; -} ENV; - -extern char **environ; - - -static ENV * -env_new(void) -{ - ENV *self; - - if (!(self = malloc(sizeof (ENV)))) { - syslog(LOG_CRIT, "%m"); - return NULL; - } - SLIST_INIT(&self->e_head); - self->e_count = 0; - self->e_committed = 0; - return self; -} - - -static int -env_put(ENV *self, char *s) -{ - struct env_entry *env; - - if (!(env = malloc(sizeof (struct env_entry))) || - !(env->ee_env = strdup(s))) { - syslog(LOG_CRIT, "%m"); - return PAM_SERVICE_ERR; - } - SLIST_INSERT_HEAD(&self->e_head, env, ee_entries); - ++self->e_count; - return PAM_SUCCESS; -} - - -static void -env_swap(ENV *self, int which) -{ - environ = which ? self->e_environ_new : self->e_environ_orig; -} - - -static int -env_commit(ENV *self) -{ - int n; - struct env_entry *p; - char **v; - - for (v = environ, n = 0; v && *v; v++, n++) - ; - if (!(v = malloc((n + self->e_count + 1) * sizeof (char *)))) { - syslog(LOG_CRIT, "%m"); - return PAM_SERVICE_ERR; - } - self->e_committed = 1; - (void)memcpy(v, environ, n * sizeof (char *)); - SLIST_FOREACH(p, &self->e_head, ee_entries) - v[n++] = p->ee_env; - v[n] = NULL; - self->e_environ_orig = environ; - self->e_environ_new = v; - env_swap(self, 1); - return PAM_SUCCESS; -} - - -static void -env_destroy(ENV *self) -{ - struct env_entry *p; - - env_swap(self, 0); - SLIST_FOREACH(p, &self->e_head, ee_entries) { - free(p->ee_env); - free(p); - } - if (self->e_committed) - free(self->e_environ_new); - free(self); -} - - -void -env_cleanup(pam_handle_t *pamh, void *data, int error_status) -{ - if (data) - env_destroy(data); -} - - -typedef struct passwd PASSWD; - -PAM_EXTERN int -pam_sm_authenticate( - pam_handle_t *pamh, - int flags, - int argc, - const char **argv) -{ - char *comment_priv; /* on private key */ - char *comment_pub; /* on public key */ - char *identity; /* user's identity file */ - RSA *key; /* user's private key */ - int options; /* module options */ - const char *pass; /* passphrase */ - char *prompt; /* passphrase prompt */ - RSA *public_key; /* user's public key */ - const PASSWD *pwent; /* user's passwd entry */ - PASSWD *pwent_keep; /* our own copy */ - int retval; /* from calls */ - uid_t saved_uid; /* caller's uid */ - const char *user; /* username */ - - options = 0; - while (argc--) - pam_std_option(&options, *argv++); - if ((retval = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) - return retval; - if (!((pwent = getpwnam(user)) && pwent->pw_dir)) { - /* delay? */ - return PAM_AUTH_ERR; - } - /* locate the user's private key file */ - if (!asprintf(&identity, "%s/%s", pwent->pw_dir, - SSH_CLIENT_IDENTITY)) { - syslog(LOG_CRIT, "%s: %m", MODULE_NAME); - return PAM_SERVICE_ERR; - } - /* - * Fail unless we can load the public key. Change to the - * owner's UID to appease load_public_key(). - */ - key = RSA_new(); - public_key = RSA_new(); - saved_uid = getuid(); - (void)setreuid(pwent->pw_uid, saved_uid); - retval = load_public_key(identity, public_key, &comment_pub); - (void)setuid(saved_uid); - if (!retval) { - free(identity); - return PAM_AUTH_ERR; - } - RSA_free(public_key); - /* build the passphrase prompt */ - retval = asprintf(&prompt, NEED_PASSPHRASE, identity, comment_pub); - free(comment_pub); - if (!retval) { - syslog(LOG_CRIT, "%s: %m", MODULE_NAME); - free(identity); - return PAM_SERVICE_ERR; - } - /* pass prompt message to application and receive passphrase */ - retval = pam_get_pass(pamh, &pass, prompt, options); - free(prompt); - if (retval != PAM_SUCCESS) { - free(identity); - return retval; - } - /* - * Try to decrypt the private key with the passphrase provided. - * If success, the user is authenticated. - */ - (void)setreuid(pwent->pw_uid, saved_uid); - retval = load_private_key(identity, pass, key, &comment_priv); - free(identity); - (void)setuid(saved_uid); - if (!retval) - return PAM_AUTH_ERR; - /* - * Save the key and comment to pass to ssh-agent in the session - * phase. - */ - if ((retval = pam_set_data(pamh, "ssh_private_key", key, - rsa_cleanup)) != PAM_SUCCESS) { - RSA_free(key); - free(comment_priv); - return retval; - } - if ((retval = pam_set_data(pamh, "ssh_key_comment", comment_priv, - ssh_cleanup)) != PAM_SUCCESS) { - free(comment_priv); - return retval; - } - /* - * Copy the passwd entry (in case successive calls are made) - * and save it for the session phase. - */ - if (!(pwent_keep = malloc(sizeof *pwent))) { - syslog(LOG_CRIT, "%m"); - return PAM_SERVICE_ERR; - } - (void)memcpy(pwent_keep, pwent, sizeof *pwent_keep); - if ((retval = pam_set_data(pamh, "ssh_passwd_entry", pwent_keep, - ssh_cleanup)) != PAM_SUCCESS) { - free(pwent_keep); - return retval; - } - return PAM_SUCCESS; -} - - -PAM_EXTERN int -pam_sm_setcred( - pam_handle_t *pamh, - int flags, - int argc, - const char **argv) -{ - return PAM_SUCCESS; -} - - -typedef AuthenticationConnection AC; - -PAM_EXTERN int -pam_sm_open_session( - pam_handle_t *pamh, - int flags, - int argc, - const char **argv) -{ - AC *ac; /* to ssh-agent */ - char *comment; /* on private key */ - char *env_end; /* end of env */ - char *env_file; /* to store env */ - FILE *env_fp; /* env_file handle */ - RSA *key; /* user's private key */ - FILE *pipe; /* ssh-agent handle */ - const PASSWD *pwent; /* user's passwd entry */ - int retval; /* from calls */ - uid_t saved_uid; /* caller's uid */ - ENV *ssh_env; /* env handle */ - const char *tty; /* tty or display name */ - char hname[MAXHOSTNAMELEN]; /* local hostname */ - char parse[BUFSIZ]; /* commands output */ - - /* dump output of ssh-agent in ~/.ssh */ - if ((retval = pam_get_data(pamh, "ssh_passwd_entry", - (const void **)&pwent)) != PAM_SUCCESS) - return retval; - /* use the tty or X display name in the filename */ - if ((retval = pam_get_item(pamh, PAM_TTY, (const void **)&tty)) - != PAM_SUCCESS) - return retval; - if (*tty == ':' && gethostname(hname, sizeof hname) == 0) { - if (asprintf(&env_file, "%s/.ssh/agent-%s%s", - pwent->pw_dir, hname, tty) == -1) { - syslog(LOG_CRIT, "%s: %m", MODULE_NAME); - return PAM_SERVICE_ERR; - } - } else if (asprintf(&env_file, "%s/.ssh/agent-%s", pwent->pw_dir, - tty) == -1) { - syslog(LOG_CRIT, "%s: %m", MODULE_NAME); - return PAM_SERVICE_ERR; - } - /* save the filename so we can delete the file on session close */ - if ((retval = pam_set_data(pamh, "ssh_agent_env", env_file, - ssh_cleanup)) != PAM_SUCCESS) { - free(env_file); - return retval; - } - /* start the agent as the user */ - saved_uid = geteuid(); - (void)seteuid(pwent->pw_uid); - env_fp = fopen(env_file, "w"); - pipe = popen(PATH_SSH_AGENT, "r"); - (void)seteuid(saved_uid); - if (!pipe) { - syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, PATH_SSH_AGENT); - if (env_fp) - (void)fclose(env_fp); - return PAM_SESSION_ERR; - } - if (!(ssh_env = env_new())) - return PAM_SESSION_ERR; - if ((retval = pam_set_data(pamh, "ssh_env_handle", ssh_env, - env_cleanup)) != PAM_SUCCESS) - return retval; - while (fgets(parse, sizeof parse, pipe)) { - if (env_fp) - (void)fputs(parse, env_fp); - /* - * Save environment for application with pam_putenv() - * but also with env_* functions for our own call to - * ssh_get_authentication_connection(). - */ - if (strchr(parse, '=') && (env_end = strchr(parse, ';'))) { - *env_end = '\0'; - /* pass to the application ... */ - if (!((retval = pam_putenv(pamh, parse)) == - PAM_SUCCESS)) { - (void)pclose(pipe); - if (env_fp) - (void)fclose(env_fp); - env_destroy(ssh_env); - return PAM_SERVICE_ERR; - } - env_put(ssh_env, parse); - } - } - if (env_fp) - (void)fclose(env_fp); - switch (retval = pclose(pipe)) { - case -1: - syslog(LOG_ERR, "%s: %s: %m", MODULE_NAME, PATH_SSH_AGENT); - env_destroy(ssh_env); - return PAM_SESSION_ERR; - case 0: - break; - case 127: - syslog(LOG_ERR, "%s: cannot execute %s", MODULE_NAME, - PATH_SSH_AGENT); - env_destroy(ssh_env); - return PAM_SESSION_ERR; - default: - syslog(LOG_ERR, "%s: %s exited with status %d", - MODULE_NAME, PATH_SSH_AGENT, WEXITSTATUS(retval)); - env_destroy(ssh_env); - return PAM_SESSION_ERR; - } - /* connect to the agent and hand off the private key */ - if ((retval = pam_get_data(pamh, "ssh_private_key", - (const void **)&key)) != PAM_SUCCESS || - (retval = pam_get_data(pamh, "ssh_key_comment", - (const void **)&comment)) != PAM_SUCCESS || - (retval = env_commit(ssh_env)) != PAM_SUCCESS) { - env_destroy(ssh_env); - return retval; - } - if (!(ac = ssh_get_authentication_connection())) { - syslog(LOG_ERR, "%s: could not connect to agent", - MODULE_NAME); - env_destroy(ssh_env); - return PAM_SESSION_ERR; - } - retval = ssh_add_identity(ac, key, comment); - ssh_close_authentication_connection(ac); - env_swap(ssh_env, 0); - return retval ? PAM_SUCCESS : PAM_SESSION_ERR; -} - - -PAM_EXTERN int -pam_sm_close_session( - pam_handle_t *pamh, - int flags, - int argc, - const char **argv) -{ - const char *env_file; /* ssh-agent environment */ - int retval; /* from calls */ - ENV *ssh_env; /* env handle */ - - if ((retval = pam_get_data(pamh, "ssh_env_handle", - (const void **)&ssh_env)) != PAM_SUCCESS) - return retval; - env_swap(ssh_env, 1); - /* kill the agent */ - retval = system(PATH_SSH_AGENT " -k"); - env_destroy(ssh_env); - switch (retval) { - case -1: - syslog(LOG_ERR, "%s: %s -k: %m", MODULE_NAME, - PATH_SSH_AGENT); - return PAM_SESSION_ERR; - case 0: - break; - case 127: - syslog(LOG_ERR, "%s: cannot execute %s -k", MODULE_NAME, - PATH_SSH_AGENT); - return PAM_SESSION_ERR; - default: - syslog(LOG_ERR, "%s: %s -k exited with status %d", - MODULE_NAME, PATH_SSH_AGENT, WEXITSTATUS(retval)); - return PAM_SESSION_ERR; - } - /* retrieve environment filename, then remove the file */ - if ((retval = pam_get_data(pamh, "ssh_agent_env", - (const void **)&env_file)) != PAM_SUCCESS) - return retval; - (void)unlink(env_file); - return PAM_SUCCESS; -} - - -PAM_MODULE_ENTRY(MODULE_NAME); diff --git a/crypto/openssh/pty.c b/crypto/openssh/pty.c deleted file mode 100644 index c3545291f147..000000000000 --- a/crypto/openssh/pty.c +++ /dev/null @@ -1,282 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: pty.c,v 1.12 2000/02/15 16:52:58 markus Exp $"); - -#ifdef __FreeBSD__ -#include <libutil.h> -#else -#include <util.h> -#endif -#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 7d8e09d0d86d..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.5 2000/02/15 16:52:58 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 c87dd2d35b2e..000000000000 --- a/crypto/openssh/radix.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * radix.c - * - * base-64 encoding pinched from lynx2-7-2, who pinched it from rpem. - * Originally written by Mark Riordan 12 August 1990 and 17 Feb 1991 - * and placed in the public domain. - * - * Dug Song <dugsong@UMICH.EDU> - */ - -#include "includes.h" - -#ifdef AFS -#include <krb.h> - -char six2pr[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' -}; - -unsigned char pr2six[256]; - -int -uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded) -{ - /* ENC is the basic 1 character encoding function to make a char printing */ -#define ENC(c) six2pr[c] - - register char *outptr = bufcoded; - unsigned int i; - - for (i = 0; i < nbytes; i += 3) { - *(outptr++) = ENC(*bufin >> 2); /* c1 */ - *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /* c2 */ - *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)); /* c3 */ - *(outptr++) = ENC(bufin[2] & 077); /* c4 */ - bufin += 3; - } - if (i == nbytes + 1) { - outptr[-1] = '='; - } else if (i == nbytes + 2) { - outptr[-1] = '='; - outptr[-2] = '='; - } - *outptr = '\0'; - return (outptr - bufcoded); -} - -int -uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize) -{ - /* single character decode */ -#define DEC(c) pr2six[(unsigned char)c] -#define MAXVAL 63 - - static int first = 1; - int nbytesdecoded, j; - const char *bufin = bufcoded; - register unsigned char *bufout = bufplain; - register int nprbytes; - - /* If this is the first call, initialize the mapping table. */ - if (first) { - first = 0; - for (j = 0; j < 256; j++) - pr2six[j] = MAXVAL + 1; - for (j = 0; j < 64; j++) - pr2six[(unsigned char) six2pr[j]] = (unsigned char) j; - } - /* Strip leading whitespace. */ - while (*bufcoded == ' ' || *bufcoded == '\t') - bufcoded++; - - /* - * Figure out how many characters are in the input buffer. If this - * would decode into more bytes than would fit into the output - * buffer, adjust the number of input bytes downwards. - */ - bufin = bufcoded; - while (DEC(*(bufin++)) <= MAXVAL); - nprbytes = bufin - bufcoded - 1; - nbytesdecoded = ((nprbytes + 3) / 4) * 3; - if (nbytesdecoded > outbufsize) - nprbytes = (outbufsize * 4) / 3; - - bufin = bufcoded; - - while (nprbytes > 0) { - *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4); - *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2); - *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3])); - bufin += 4; - nprbytes -= 4; - } - if (nprbytes & 03) { - if (DEC(bufin[-2]) > MAXVAL) - nbytesdecoded -= 2; - else - nbytesdecoded -= 1; - } - return (nbytesdecoded); -} - -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) -{ - 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(temp, len, buf)); -} - -int -radix_to_creds(const char *buf, CREDENTIALS *creds) -{ - - char *p; - int len, tl; - char version; - char temp[2048]; - - if (!(len = uudecode(buf, temp, sizeof(temp)))) - 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 8dd81cfe3939..000000000000 --- a/crypto/openssh/readconf.c +++ /dev/null @@ -1,736 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: readconf.c,v 1.23 2000/02/28 19:51:58 markus Exp $"); - -#include "ssh.h" -#include "cipher.h" -#include "readconf.h" -#include "xmalloc.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 - oKrb4Authentication, -#endif /* KRB4 */ -#ifdef KRB5 - oKrb5Authentication, oKrb5TgtPassing, -#endif /* KRB5 */ -#ifdef AFS - oKrb4TgtPassing, 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 -} 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 }, - { "skeyauthentication", oSkeyAuthentication }, -#ifdef KRB4 - { "kerberos4authentication", oKrb4Authentication }, -#endif /* KRB4 */ -#ifdef KRB5 - { "kerberos5authentication", oKrb5Authentication }, - { "kerberos5tgtpassing", oKrb5TgtPassing }, -#endif /* KRB5 */ -#ifdef AFS - { "kerberos4tgtpassing", oKrb4TgtPassing }, - { "afstokenpassing", oAFSTokenPassing }, -#endif - { "fallbacktorsh", oFallBackToRsh }, - { "usersh", oUseRsh }, - { "identityfile", oIdentityFile }, - { "hostname", oHostName }, - { "proxycommand", oProxyCommand }, - { "port", oPort }, - { "cipher", oCipher }, - { "remoteforward", oRemoteForward }, - { "localforward", oLocalForward }, - { "user", oUser }, - { "host", oHost }, - { "escapechar", oEscapeChar }, - { "rhostsrsaauthentication", oRhostsRSAAuthentication }, - { "globalknownhostsfile", oGlobalKnownHostsFile }, - { "userknownhostsfile", oUserKnownHostsFile }, - { "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 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 oKrb4Authentication: - intptr = &options->krb4_authentication; - goto parse_flag; -#endif /* KRB4 */ - -#ifdef KRB5 - case oKrb5Authentication: - intptr = &options->krb5_authentication; - goto parse_flag; - - case oKrb5TgtPassing: - intptr = &options->krb5_tgt_passing; - goto parse_flag; -#endif /* KRB5 */ - -#ifdef AFS - case oKrb4TgtPassing: - intptr = &options->krb4_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: - cp = strtok(NULL, WHITESPACE); - if (!cp) - fatal("%.200s line %d: Missing argument.", filename, linenum); - if (*activep) { - if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) - fatal("%.200s line %d: Too many identity files specified (max %d).", - filename, linenum, SSH_MAX_IDENTITY_FILES); - options->identity_files[options->num_identity_files++] = xstrdup(cp); - } - 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 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 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->skey_authentication = -1; -#ifdef KRB4 - options->krb4_authentication = -1; -#endif -#ifdef KRB5 - options->krb5_authentication = -1; - options->krb5_tgt_passing = -1; -#endif /* KRB5 */ -#ifdef AFS - options->krb4_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->num_identity_files = 0; - options->hostname = NULL; - options->proxy_command = NULL; - options->user = NULL; - options->escape_char = -1; - options->system_hostfile = NULL; - options->user_hostfile = 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->skey_authentication == -1) - options->skey_authentication = 0; -#ifdef KRB4 - if (options->krb4_authentication == -1) - options->krb4_authentication = 1; -#endif /* KRB4 */ -#ifdef KRB5 - if (options->krb5_authentication == -1) - options->krb5_authentication = 1; - if (options->krb5_tgt_passing == -1) - options->krb5_tgt_passing = 1; -#endif /* KRB5 */ -#ifdef AFS - if (options->krb4_tgt_passing == -1) - options->krb4_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 = 0; - 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; - 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->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->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 5d511aa7677f..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. - * - * $FreeBSD$ - */ - -/* RCSID("$Id: readconf.h,v 1.13 1999/12/01 13:59: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 skey_authentication; /* Try S/Key or TIS authentication. */ -#ifdef KRB4 - int krb4_authentication; /* Try Kerberos v4 - * authentication. */ -#endif - -#ifdef KRB5 - int krb5_authentication; - int krb5_tgt_passing; -#endif /* KRB5 */ - -#ifdef AFS - int krb4_tgt_passing; /* Try Kerberos v4 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 *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. */ - - int num_identity_files; /* Number of files for RSA identities. */ - char *identity_files[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 deb37cab6349..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.9 2000/01/21 21:16:00 deraadt 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 7a2bed69505c..000000000000 --- a/crypto/openssh/rsa.c +++ /dev/null @@ -1,177 +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] - * - * $FreeBSD$ - * -*/ - -#include "includes.h" -RCSID("$Id: rsa.c,v 1.12 2000/02/21 21:47:31 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) -{ - 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) - if (BN_num_bits(key->n) > 1024 && RSA_libversion() == RSALIB_RSAREF) - fatal("rsa_private_encrypt() failed: RSAREF cannot handle keys larger than 1024 bits."); - else - fatal("rsa_private_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) -{ - 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) - if (BN_num_bits(key->n) > 1024 && RSA_libversion() == RSALIB_RSAREF) - fatal("rsa_private_decrypt() failed: RSAREF cannot handle keys larger than 1024 bits."); - else - 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 c5c601f651a4..000000000000 --- a/crypto/openssh/rsa.h +++ /dev/null @@ -1,39 +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. - * - * $FreeBSD$ -*/ - -/* RCSID("$Id: rsa.h,v 1.4 1999/11/24 19:53:50 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 d4c374e5f12c..000000000000 --- a/crypto/openssh/scp.1 +++ /dev/null @@ -1,118 +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.5 2000/01/04 16:57:16 markus 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 16ac0ebc4831..000000000000 --- a/crypto/openssh/scp.c +++ /dev/null @@ -1,1245 +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.25 2000/01/24 22:11:20 markus 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) 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) 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 = read(fd, bp->buf, amt); - if (result != amt) - haderr = result >= 0 ? EIO : errno; - } - if (haderr) - (void) write(remout, bp->buf, amt); - else { - result = 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) 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) 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) 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) 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) write(remout, "", 1); - if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) - targisdir = 1; - for (first = 1;; first = 0) { - cp = buf; - if (read(remin, cp, 1) <= 0) - return; - if (*cp++ == '\n') - SCREWUP("unexpected <newline>"); - do { - if (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) write(STDERR_FILENO, - buf + 1, strlen(buf + 1)); - if (buf[0] == '\02') - exit(1); - ++errs; - continue; - } - if (buf[0] == 'E') { - (void) 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) 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) 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 = 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 = 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 = 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) 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 (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 (read(remin, &ch, sizeof(ch)) != sizeof(ch)) - lostconn(0); - *cp++ = ch; - } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); - - if (!iamremote) - (void) 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.25 2000/01/24 22:11:20 markus 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(void) -{ - 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 { - remaining = (int) (totalbytes / (statbytes / elapsed) - 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 ETA", i / 60, i % 60); - } - atomicio(write, fileno(stdout), buf, strlen(buf)); - - if (flag == -1) { - signal(SIGALRM, (void *) updateprogressmeter); - alarmtimer(1); - } else if (flag == 1) { - alarmtimer(0); - 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 7852348cf62f..000000000000 --- a/crypto/openssh/servconf.c +++ /dev/null @@ -1,605 +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 - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: servconf.c,v 1.30 2000/02/24 18:22:16 markus Exp $"); - -#include "ssh.h" -#include "servconf.h" -#include "xmalloc.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->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; -#ifdef KRB4 - options->krb4_authentication = -1; - options->krb4_or_local_passwd = -1; - options->krb4_ticket_cleanup = -1; -#endif -#ifdef KRB5 - options->krb5_authentication = -1; - options->krb5_tgt_passing = -1; -#endif /* KRB5 */ -#ifdef AFS - options->krb4_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->connections_per_period = 0; - options->connections_period = 0; -} - -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->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 = 1; - 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; -#ifdef KRB4 - if (options->krb4_authentication == -1) - options->krb4_authentication = (access(KEYFILE, R_OK) == 0); - if (options->krb4_or_local_passwd == -1) - options->krb4_or_local_passwd = 1; - if (options->krb4_ticket_cleanup == -1) - options->krb4_ticket_cleanup = 1; -#endif /* KRB4 */ -#ifdef KRB5 - if (options->krb5_authentication == -1) - options->krb5_authentication = 1; - if (options->krb5_tgt_passing == -1) - options->krb5_tgt_passing = 1; -#endif /* KRB5 */ -#ifdef AFS - if (options->krb4_tgt_passing == -1) - options->krb4_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; -} - -#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 - sKrb4Authentication, sKrb4OrLocalPasswd, sKrb4TicketCleanup, -#endif -#ifdef KRB5 - sKrb5Authentication, sKrb5TgtPassing, -#endif /* KRB5 */ -#ifdef AFS - sKrb4TgtPassing, sAFSTokenPassing, -#endif -#ifdef SKEY - sSkeyAuthentication, -#endif - sPasswordAuthentication, sListenAddress, - sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, - sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, - sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, - sIgnoreUserKnownHosts, sConnectionsPerPeriod -} ServerOpCodes; - -/* Textual representation of the tokens. */ -static struct { - const char *name; - ServerOpCodes opcode; -} keywords[] = { - { "port", sPort }, - { "hostkey", sHostKeyFile }, - { "serverkeybits", sServerKeyBits }, - { "logingracetime", sLoginGraceTime }, - { "keyregenerationinterval", sKeyRegenerationTime }, - { "permitrootlogin", sPermitRootLogin }, - { "syslogfacility", sLogFacility }, - { "loglevel", sLogLevel }, - { "rhostsauthentication", sRhostsAuthentication }, - { "rhostsrsaauthentication", sRhostsRSAAuthentication }, - { "rsaauthentication", sRSAAuthentication }, -#ifdef KRB4 - { "kerberos4authentication", sKrb4Authentication }, - { "kerberos4orlocalpasswd", sKrb4OrLocalPasswd }, - { "kerberos4ticketcleanup", sKrb4TicketCleanup }, -#endif -#ifdef KRB5 - { "kerberos5authentication", sKrb5Authentication }, - { "kerberos5tgtpassing", sKrb5TgtPassing }, -#endif /* KRB5 */ -#ifdef AFS - { "kerberos4tgtpassing", sKrb4TgtPassing }, - { "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 }, - { "connectionsperperiod", sConnectionsPerPeriod }, - { 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); - } - if (sscanf(cp, " %d ", &value) != 1) { - fprintf(stderr, "%s line %d: invalid integer value.\n", - filename, linenum); - exit(1); - } - 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: - charptr = &options->host_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 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_int; - - 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; - -#ifdef KRB4 - case sKrb4Authentication: - intptr = &options->krb4_authentication; - goto parse_flag; - - case sKrb4OrLocalPasswd: - intptr = &options->krb4_or_local_passwd; - goto parse_flag; - - case sKrb4TicketCleanup: - intptr = &options->krb4_ticket_cleanup; - goto parse_flag; -#endif - -#ifdef KRB5 - case sKrb5Authentication: - intptr = &options->krb5_authentication; - goto parse_flag; - - case sKrb5TgtPassing: - intptr = &options->krb5_tgt_passing; - goto parse_flag; -#endif /* KRB5 */ - -#ifdef AFS - case sKrb4TgtPassing: - intptr = &options->krb4_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 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("%.200s 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("%.200s 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("%.200s 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("%.200s line %d: too many deny groups.\n", filename, - linenum); - options->deny_groups[options->num_deny_groups++] = xstrdup(cp); - } - break; - - case sConnectionsPerPeriod: - cp = strtok(NULL, WHITESPACE); - if (cp == NULL) - fatal("%.200s line %d: missing (>= 0) number argument.\n", - filename, linenum); - if (sscanf(cp, " %u/%u ", &options->connections_per_period, - &options->connections_period) != 2) - fatal("%.200s line %d: invalid numerical argument(s).\n", - filename, linenum); - if (options->connections_per_period != 0 && - options->connections_period == 0) - fatal("%.200s line %d: invalid connections period.\n", - filename, linenum); - break; - - default: - fatal("%.200s line %d: Missing handler for opcode %s (%d)\n", - filename, linenum, cp, opcode); - } - if (strtok(NULL, WHITESPACE) != NULL) - fatal("%.200s line %d: garbage at end of line.\n", filename, - linenum); - } - fclose(f); - if (bad_options > 0) - fatal("%.200s: terminating, %d bad configuration options\n", - filename, bad_options); -} diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h deleted file mode 100644 index 3e765b8e0005..000000000000 --- a/crypto/openssh/servconf.h +++ /dev/null @@ -1,118 +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. - * - * $FreeBSD$ - */ - -/* RCSID("$Id: servconf.h,v 1.15 2000/01/04 00:08:00 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. */ - 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. */ - 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. */ -#ifdef KRB4 - int krb4_authentication; /* If true, permit Kerberos v4 - * authentication. */ - int krb4_or_local_passwd; /* If true, permit kerberos v4 - * and any other password - * authentication mechanism, - * such as SecurID or - * /etc/passwd */ - int krb4_ticket_cleanup; /* If true, destroy ticket - * file on logout. */ -#endif -#ifdef KRB5 - int krb5_authentication; - int krb5_tgt_passing; - -#endif /* KRB5 */ -#ifdef AFS - int krb4_tgt_passing; /* If true, permit Kerberos v4 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]; - unsigned int connections_per_period; /* - * If not 0, number of sshd - * connections accepted per - * connections_period. - */ - unsigned int connections_period; -} 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 a5ecfe97d5d7..000000000000 --- a/crypto/openssh/serverloop.c +++ /dev/null @@ -1,651 +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. - */ - -#include "includes.h" -#include "xmalloc.h" -#include "ssh.h" -#include "packet.h" -#include "buffer.h" -#include "servconf.h" -#include "pty.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 int 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 -sigchld_handler(int sig) -{ - int save_errno = errno; - int 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; -} - -/* - * Process any buffered packets that have been received from the client. - */ -void -process_buffered_input_packets() -{ - int type; - char *data; - unsigned int data_len; - int row, col, xpixel, ypixel; - int payload_len; - - /* Process buffered packets from the client. */ - while ((type = packet_read_poll(&payload_len)) != SSH_MSG_NONE) { - switch (type) { - case SSH_CMSG_STDIN_DATA: - /* Stdin data from the client. Append it to the buffer. */ - /* Ignore any data if the client has closed stdin. */ - if (fdin == -1) - break; - data = packet_get_string(&data_len); - packet_integrity_check(payload_len, (4 + data_len), type); - buffer_append(&stdin_buffer, data, data_len); - memset(data, 0, data_len); - xfree(data); - break; - - case SSH_CMSG_EOF: - /* - * 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(payload_len, 0, type); - stdin_eof = 1; - break; - - case SSH_CMSG_WINDOW_SIZE: - debug("Window change received."); - packet_integrity_check(payload_len, 4 * 4, type); - row = packet_get_int(); - col = packet_get_int(); - xpixel = packet_get_int(); - ypixel = packet_get_int(); - if (fdin != -1) - pty_change_window_size(fdin, row, col, xpixel, ypixel); - break; - - case SSH_MSG_PORT_OPEN: - debug("Received port open request."); - channel_input_port_open(payload_len); - break; - - case SSH_MSG_CHANNEL_OPEN_CONFIRMATION: - debug("Received channel open confirmation."); - packet_integrity_check(payload_len, 4 + 4, type); - channel_input_open_confirmation(); - break; - - case SSH_MSG_CHANNEL_OPEN_FAILURE: - debug("Received channel open failure."); - packet_integrity_check(payload_len, 4, type); - channel_input_open_failure(); - break; - - case SSH_MSG_CHANNEL_DATA: - channel_input_data(payload_len); - break; - - case SSH_MSG_CHANNEL_CLOSE: - debug("Received channel close."); - packet_integrity_check(payload_len, 4, type); - channel_input_close(); - break; - - case SSH_MSG_CHANNEL_CLOSE_CONFIRMATION: - debug("Received channel close confirmation."); - packet_integrity_check(payload_len, 4, type); - channel_input_close_confirmation(); - break; - - default: - /* - * In this phase, any unexpected messages cause a - * protocol error. This is to ease debugging; also, - * since no confirmations are sent messages, - * unprocessed unknown messages could cause strange - * problems. Any compatible protocol extensions must - * be negotiated before entering the interactive - * session. - */ - packet_disconnect("Protocol error during session: type %d", - type); - } - } -} - -/* - * 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 (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 (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 (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; - } - - /* 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); - } - /* 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 (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 (fdout == -1) - 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(); -} - -/* - * 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(int pid, int fdin_arg, int fdout_arg, int fderr_arg) -{ - int wait_status, wait_pid; /* Status and 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; - - /* 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 (fdout == -1) - 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()) - goto quit; - 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); - } - -quit: - /* 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 */ -} diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1 deleted file mode 100644 index 8872e7154327..000000000000 --- a/crypto/openssh/ssh-add.1 +++ /dev/null @@ -1,124 +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.10 2000/01/22 02:17:50 aaron Exp $ -.\" -.Dd September 25, 1999 -.Dt SSH-ADD 1 -.Os -.Sh NAME -.Nm ssh-add -.Nd adds identities for the authentication agent -.Sh SYNOPSIS -.Nm ssh-add -.Op Fl lLdD -.Op Ar -.Sh DESCRIPTION -.Nm -adds 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 78e152043045..000000000000 --- a/crypto/openssh/ssh-add.c +++ /dev/null @@ -1,255 +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.15 1999/12/02 20:05:40 markus Exp $"); - -#include "rsa.h" -#include "ssh.h" -#include "xmalloc.h" -#include "authfd.h" -#include "fingerprint.h" - -void -delete_file(AuthenticationConnection *ac, const char *filename) -{ - RSA *key; - char *comment; - - key = RSA_new(); - if (!load_public_key(filename, key, &comment)) { - printf("Bad key file %s: %s\n", filename, strerror(errno)); - return; - } - if (ssh_remove_identity(ac, key)) - fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); - else - fprintf(stderr, "Could not remove identity: %s\n", filename); - RSA_free(key); - 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) -{ - RSA *key; - RSA *public_key; - char *saved_comment, *comment, *askpass = NULL; - char buf[1024], msg[1024]; - int success; - int interactive = isatty(STDIN_FILENO); - - key = RSA_new(); - public_key = RSA_new(); - if (!load_public_key(filename, public_key, &saved_comment)) { - printf("Bad key file %s: %s\n", filename, strerror(errno)); - return; - } - RSA_free(public_key); - - if (!interactive && getenv("DISPLAY")) { - if (getenv(SSH_ASKPASS_ENV)) - askpass = getenv(SSH_ASKPASS_ENV); - else - askpass = SSH_ASKPASS_DEFAULT; - } - - /* At first, try empty passphrase */ - success = load_private_key(filename, "", key, &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, key, &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, key, comment)) - fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); - else - fprintf(stderr, "Could not add identity: %s\n", filename); - RSA_free(key); - 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 b98775d90bca..000000000000 --- a/crypto/openssh/ssh-agent.1 +++ /dev/null @@ -1,163 +0,0 @@ -.\" $OpenBSD: ssh-agent.1,v 1.9 2000/01/22 02:17:50 aaron 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 authentication private keys. 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 b15d9989fad3..000000000000 --- a/crypto/openssh/ssh-agent.c +++ /dev/null @@ -1,655 +0,0 @@ -/* $OpenBSD: ssh-agent.c,v 1.25 2000/01/02 21:51:03 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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.25 2000/01/02 21:51:03 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 */ -int 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)) - error("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; - 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)) { - len = sizeof(sunaddr); - sock = accept(sockets[i].fd, (struct sockaddr *) & sunaddr, &len); - 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; - 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; - 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 (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 */ - 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 e7c837c79fbd..000000000000 --- a/crypto/openssh/ssh-keygen.1 +++ /dev/null @@ -1,161 +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.11 2000/01/22 02:17:50 aaron 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 q -.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 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 -.Sh DESCRIPTION -.Nm -generates and manages authentication keys for -.Xr ssh 1 . -Normally each user wishing to use SSH -with RSA authentication runs this once to create the authentication -key in -.Pa $HOME/.ssh/identity . -Additionally, the system administrator may use this to generate host keys. -.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 -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 -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. -.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. -.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. -.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 93ae2da0e42a..000000000000 --- a/crypto/openssh/ssh-keygen.c +++ /dev/null @@ -1,556 +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.16 2000/02/04 14:34:09 markus Exp $"); - -#include "rsa.h" -#include "ssh.h" -#include "xmalloc.h" -#include "fingerprint.h" - -/* Generated private key. */ -RSA *private_key; - -/* Generated public key. */ -RSA *public_key; - -/* Number of bits in the RSA 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; - -/* argv0 */ -extern char *__progname; - -void -ask_filename(struct passwd *pw, const char *prompt) -{ - char buf[1024]; - snprintf(identity_file, sizeof(identity_file), "%s/%s", - pw->pw_dir, 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; -} - -void -do_fingerprint(struct passwd *pw) -{ - FILE *f; - BIGNUM *e, *n; - RSA *public_key; - char *comment = NULL, *cp, *ep, line[16*1024]; - int i, skip = 0, num = 1, invalid = 1; - 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 = RSA_new(); - if (load_public_key(identity_file, public_key, &comment)) { - printf("%d %s %s\n", BN_num_bits(public_key->n), - fingerprint(public_key->e, public_key->n), - comment); - RSA_free(public_key); - exit(0); - } - RSA_free(public_key); - - 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, &i, 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; - RSA *private_key; - - 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 = RSA_new(); - if (!load_public_key(identity_file, public_key, 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. */ - RSA_free(public_key); - - /* Try to load the file with empty passphrase. */ - private_key = RSA_new(); - if (!load_private_key(identity_file, "", private_key, &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_key, &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_key, comment)) { - printf("Saving the key failed: %s: %s.\n", - identity_file, strerror(errno)); - memset(passphrase1, 0, strlen(passphrase1)); - xfree(passphrase1); - RSA_free(private_key); - xfree(comment); - exit(1); - } - /* Destroy the passphrase and the copy of the key in memory. */ - memset(passphrase1, 0, strlen(passphrase1)); - xfree(passphrase1); - RSA_free(private_key); /* 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; - RSA *private_key; - char *passphrase; - struct stat st; - FILE *f; - char *tmpbuf; - - 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 = RSA_new(); - if (!load_public_key(identity_file, public_key, NULL)) { - printf("%s is not a valid key file.\n", identity_file); - exit(1); - } - private_key = RSA_new(); - - if (load_private_key(identity_file, "", private_key, &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_key, &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)); - RSA_free(private_key); - 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_key, new_comment)) { - printf("Saving the key failed: %s: %s.\n", - identity_file, strerror(errno)); - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - RSA_free(private_key); - xfree(comment); - exit(1); - } - memset(passphrase, 0, strlen(passphrase)); - xfree(passphrase); - RSA_free(private_key); - - 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); - } - fprintf(f, "%d ", BN_num_bits(public_key->n)); - tmpbuf = BN_bn2dec(public_key->e); - fprintf(f, "%s ", tmpbuf); - free(tmpbuf); - tmpbuf = BN_bn2dec(public_key->n); - fprintf(f, "%s %s\n", tmpbuf, new_comment); - free(tmpbuf); - fclose(f); - - xfree(comment); - - printf("The comment in your key file has been changed.\n"); - exit(0); -} - -void -usage(void) -{ - printf("ssh-keygen version %s\n", SSH_VERSION); - printf("Usage: %s [-b bits] [-p] [-c] [-l] [-f file] [-P pass] [-N new-pass] [-C comment]\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; - char *tmpbuf; - int opt; - struct stat st; - FILE *f; - char hostname[MAXHOSTNAMELEN]; - extern int optind; - extern char *optarg; - - /* 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); - } - /* we need this for the home * directory. */ - pw = getpwuid(getuid()); - if (!pw) { - printf("You don't exist, go away!\n"); - exit(1); - } - - while ((opt = getopt(ac, av, "qpclb: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 '?': - 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(); - } - if (print_fingerprint) - do_fingerprint(pw); - if (change_passphrase) - do_change_passphrase(pw); - if (change_comment) - do_change_comment(pw); - - arc4random_stir(); - - if (quiet) - rsa_set_verbose(0); - - /* Generate the rsa key pair. */ - private_key = RSA_new(); - public_key = RSA_new(); - rsa_generate_key(private_key, public_key, 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. */ - if (gethostname(hostname, sizeof(hostname)) < 0) { - perror("gethostname"); - exit(1); - } - 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_key, 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. */ - RSA_free(private_key); - 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); - } - fprintf(f, "%d ", BN_num_bits(public_key->n)); - tmpbuf = BN_bn2dec(public_key->e); - fprintf(f, "%s ", tmpbuf); - free(tmpbuf); - tmpbuf = BN_bn2dec(public_key->n); - fprintf(f, "%s %s\n", tmpbuf, comment); - free(tmpbuf); - fclose(f); - - if (!quiet) { - printf("Your public key has been saved in %s.\n", identity_file); - printf("The key fingerprint is:\n"); - printf("%d %s %s\n", BN_num_bits(public_key->n), - fingerprint(public_key->e, public_key->n), - comment); - } - 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 8ba7f69409eb..000000000000 --- a/crypto/openssh/ssh.1 +++ /dev/null @@ -1,1010 +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.38 2000/02/28 19:51:58 markus Exp $ -.\" $FreeBSD$ -.\" -.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 afgknqtvxCPX46 -.Op Fl c Ar blowfish | 3des -.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. -.Pp -First, if the machine the user logs in from is listed in -.Pa /etc/hosts.equiv -or -.Pa /etc/ssh/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 \&.rhosts , -.Pa \&.shosts , -.Pa /etc/hosts.equiv , -or -.Pa /etc/ssh/shosts.equiv , -and if additionally the server can verify the client's -host key (see -.Pa /etc/ssh/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 \&.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 \&.ssh/identity -and the public key in -.Pa \&.ssh/identity.pub -in the user's home directory. The user should then -copy the -.Pa identity.pub -to -.Pa \&.ssh/authorized_keys -in his/her home directory on the remote machine (the -.Pa authorized_keys -file corresponds to the conventional -.Pa \&.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 -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 -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 through firewalls. -.Pp -.Nm -automatically maintains and checks a database containing RSA-based -identifications for all hosts it has ever been used with. The -database is stored in -.Pa \&.ssh/known_hosts -in the user's home directory. Additionally, the file -.Pa /etc/ssh/ssh_known_hosts -is 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 ssh. -.Ar blowfish -is a fast block cipher, it appears very secure and is much faster than -.Ar 3des . -.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 \&.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 may also -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 in 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 arbitary -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 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/ssh_config . -For each parameter, the first obtained value -will be used. The configuration files contain sections bracketed by -"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 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 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/ssh_known_hosts . -.It Cm HostName -Specifies the real host name to log into. This can be used to specify -nicnames 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 .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 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 root 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, CHAT 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 . -.It Cm Port -Specifies the port number to connect on the remote host. Default is -22. -.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, -.Dq %h -will be substituted by the host name to -connect and -.Dq %p -by the port. The command can be basically anything, -and should read from its stdin and write to its stdout. 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 root 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. -.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 -file, 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/ssh_known_hosts -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 in 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 exec -.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. Ssh 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/ssh_known_hosts ) . -See -.Xr sshd 8 . -.It Pa $HOME/.ssh/identity -Contains the RSA authentication identity of the user. This file -contains sensitive data and should be readable by the user but not -accessible by others (read/write/execute). -Note that -.Nm -ignores this 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 -Contains the public key for authentication (public part of the -identity file in human-readable form). 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. This file is not -sensitive and can (but need not) be readable by anyone. This file is -never used automatically and is not necessary; it 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 /etc/ssh/ssh_known_hosts -Systemwide list of known host keys. This file 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/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/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 inxi -.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/ssh/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/ssh/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. -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, making it compatible with -all other ssh protocol 1 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. -.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 cfaab2573c19..000000000000 --- a/crypto/openssh/ssh.c +++ /dev/null @@ -1,810 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$Id: ssh.c,v 1.41 2000/02/28 19:51:58 markus Exp $"); - -#include "xmalloc.h" -#include "ssh.h" -#include "packet.h" -#include "buffer.h" -#include "authfd.h" -#include "readconf.h" -#include "uidswap.h" - -/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. - Default value is AF_UNSPEC means both IPv4 and IPv6. */ -int IPv4or6 = AF_UNSPEC; - -/* Flag indicating whether debug mode is on. This can be set on the command line. */ -int debug_flag = 0; - -int 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; - -/* 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, " -X Enable 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, " -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, " -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, " -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; -#ifndef _PATH_RSH -#define _PATH_RSH "/usr/bin/rsh" -#endif - 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); -} - -/* - * Main program for the ssh client. - */ -int -main(int ac, char **av) -{ - int i, opt, optind, type, exit_status, ok, authfd; - u_short fwd_port, fwd_host_port; - char *optarg, *cp, buf[256]; - Buffer command; - struct winsize ws; - struct stat st; - struct passwd *pw, pwcopy; - int interactive = 0, dummy; - uid_t original_effective_uid; - int plen; - - /* - * 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 '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.krb4_tgt_passing = 0; - options.krb5_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 version %d.%d.\n", - SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); - fprintf(stderr, "Compiled with SSL.\n"); - 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': - 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 '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(); - - /* 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); - } - /* 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; - } - /* 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); - - 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) { - host_private_key = RSA_new(); - if (load_private_key(HOST_KEY_FILE, "", host_private_key, 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. */ - for (i = 0; i < options.num_identity_files; i++) - options.identity_files[i] = - tilde_expand_filename(options.identity_files[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); - - /* 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 */ - - /* Close connection cleanly after attack. */ - cipher_attack_detected = packet_disconnect; - - /* 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; - 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 line[512], proto[512], data[512]; - FILE *f; - int forwarded = 0, 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", sizeof proto); - for (i = 0; i < 16; i++) { - if (i % 4 == 0) - rand = arc4random(); - snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff); - rand >>= 8; - } - } - /* - * Got local authentication reasonable information. Request - * forwarding with authentication spoofing. - */ - debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(proto, data); - - /* Read response from the server. */ - type = packet_read(&plen); - if (type == SSH_SMSG_SUCCESS) { - forwarded = 1; - 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. */ - exit_status = client_loop(tty_flag, tty_flag ? options.escape_char : -1); - - /* Close the connection to the remote host. */ - packet_close(); - - /* Exit with the status returned by the program on the remote side. */ - exit(exit_status); -} diff --git a/crypto/openssh/ssh.h b/crypto/openssh/ssh.h deleted file mode 100644 index 8d6267c02113..000000000000 --- a/crypto/openssh/ssh.h +++ /dev/null @@ -1,743 +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. - * - * $FreeBSD$ - */ - -/* RCSID("$Id: ssh.h,v 1.33 2000/02/01 22:32:53 d Exp $"); */ - -#ifndef SSH_H -#define SSH_H - -#include "rsa.h" -#include "cipher.h" - -/* - * 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. - */ -#define PROTOCOL_MAJOR 1 - -/* - * Minor protocol version. Different version indicates minor incompatibility - * that does not prevent interoperation. - */ -#define PROTOCOL_MINOR 5 - -/* - * Name for the service. The port named by this service overrides the - * default port if present. - */ -#define SSH_SERVICE_NAME "ssh" - -#define ETCDIR "/etc/ssh" -#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" - -/* - * 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 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" - -/* - * 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" - -/* - * 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" - -/* - * 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_KRB4 6 -#define SSH_PASS_KRB4_TGT 7 - /* 8 to 15 are reserved */ -#define SSH_PASS_AFS_TOKEN 21 - -#define SSH_AUTH_KRB5 29 -#define SSH_PASS_KRB5_TGT 30 - -/* 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_KRB4 42 /* (KTEXT) */ -#define SSH_SMSG_AUTH_KRB4_RESPONSE 43 /* (KTEXT) */ -#define SSH_CMSG_HAVE_KRB4_TGT 44 /* credentials (s) */ -#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ - -#define SSH_CMSG_AUTH_KRB5 110 -#define SSH_SMSG_AUTH_KRB5_RESPONSE 111 -#define SSH_CMSG_HAVE_KRB5_TGT 112 - -/*------------ 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(int 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(int 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, - BIGNUM * client_host_key_e, BIGNUM * client_host_key_n); - -/* - * 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); - - -/* - * 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); - -/* - * 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, - BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn); - -/* - * 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, - BIGNUM * e, BIGNUM * n); - -/* - * 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(BIGNUM * e, BIGNUM * n); - -/* - * 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); - -/* - * 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(const char *filename, const char *passphrase, - RSA * 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, RSA * 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, - RSA * private_key, char **comment_return); - -/*------------ 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); - -/*---------------- definitions for channels ------------------*/ - -/* 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); - -/* - * 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 payload_len); - -/* Returns true if no channel has too much buffered data. */ -int channel_not_very_much_buffered_data(void); - -/* This is called after receiving CHANNEL_CLOSE. */ -void channel_input_close(void); - -/* This is called after receiving CHANNEL_CLOSE_CONFIRMATION. */ -void channel_input_close_confirmation(void); - -/* This is called after receiving CHANNEL_OPEN_CONFIRMATION. */ -void channel_input_open_confirmation(void); - -/* This is called after receiving CHANNEL_OPEN_FAILURE from the other side. */ -void channel_input_open_failure(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); - -/* - * 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 payload_len); - -/* - * 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 payload_len); - -/* - * 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(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(void); - -/* - * 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); - -/* - * 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(int pid, int fdin, int fdout, int fderr); - -/* 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 KRB5 -#include <krb5.h> -int auth_krb5(); /* XXX Doplnit prototypy */ -int auth_krb5_tgt(); -int krb5_init(); -void krb5_cleanup_proc(void *ignore); -int auth_krb5_password(struct passwd *pw, const char *password); -#endif /* KRB5 */ - -#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_krb4_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); -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 61a38add711f..000000000000 --- a/crypto/openssh/ssh/Makefile +++ /dev/null @@ -1,36 +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 sshconnect.c log-client.c readconf.c clientloop.c - -.include <bsd.own.mk> # for AFS - -.if (${KERBEROS} == "yes") -CFLAGS+= -DKRB4 -I/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/ssh_config b/crypto/openssh/ssh_config deleted file mode 100644 index 6d823f5ced36..000000000000 --- a/crypto/openssh/ssh_config +++ /dev/null @@ -1,32 +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. -# -# $FreeBSD$ - -# 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 -# Cipher blowfish -# EscapeChar ~ diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c deleted file mode 100644 index bcbd3af91334..000000000000 --- a/crypto/openssh/sshconnect.c +++ /dev/null @@ -1,1911 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.56 2000/02/18 08:50:33 markus Exp $"); - -#include <openssl/bn.h> -#include "xmalloc.h" -#include "rsa.h" -#include "ssh.h" -#include "packet.h" -#include "authfd.h" -#include "cipher.h" -#include "mpaux.h" -#include "uidswap.h" -#include "compat.h" -#include "readconf.h" -#include "fingerprint.h" - -#include <openssl/md5.h> - -/* Session id for the current session. */ -unsigned char session_id[16]; - -/* authentications supported by server */ -unsigned int supported_authentications; - -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]; - int 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; -} - -/* - * 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; - RSA *private_key; - RSA *public_key; - char *passphrase, *comment; - int type, i; - int plen, clen; - - /* Try to load identification for the authentication key. */ - public_key = RSA_new(); - if (!load_public_key(authfile, public_key, &comment)) { - RSA_free(public_key); - /* 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_key->n); - packet_send(); - packet_write_wait(); - - /* We no longer need the public key. */ - RSA_free(public_key); - - /* 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 = RSA_new(); - /* - * Load the private key. Try first with empty passphrase; if it - * fails, ask for a passphrase. - */ - if (!load_private_key(authfile, "", private_key, 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_key, 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_key); - - /* Destroy the private key. */ - RSA_free(private_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("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_krb4_authentication() -{ - KTEXT_ST auth; /* Kerberos data */ - char *reply; - char inst[INST_SZ]; - char *realm; - CREDENTIALS cred; - int r, type, plen; - 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_KRB4); - packet_put_string((char *) auth.dat, auth.length); - packet_send(); - packet_write_wait(); - - /* Zero the buffer. */ - (void) memset(auth.dat, 0, MAX_KTXT_LEN); - - r = sizeof(local); - memset(&local, 0, sizeof(local)); - if (getsockname(packet_get_connection_in(), - (struct sockaddr *) & local, &r) < 0) - debug("getsockname failed: %s", strerror(errno)); - - r = sizeof(foreign); - memset(&foreign, 0, sizeof(foreign)); - if (getpeername(packet_get_connection_in(), - (struct sockaddr *) & foreign, &r) < 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_KRB4_FAILURE */ - debug("Kerberos V4 authentication failed."); - return 0; - break; - - case SSH_SMSG_AUTH_KRB4_RESPONSE: - /* SSH_SMSG_AUTH_KRB4_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_krb4_tgt() -{ - CREDENTIALS *creds; - char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; - int r, type, plen; - unsigned 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, buffer); - xfree(creds); - - packet_start(SSH_CMSG_HAVE_KRB4_TGT); - packet_put_string((char *) 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; - unsigned 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, buffer)) - break; - packet_start(SSH_CMSG_HAVE_AFS_TOKEN); - packet_put_string((char *) 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 */ - -#ifdef KRB5 -int -try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) -{ - krb5_error_code problem; - const char *tkfile; - struct stat buf; - krb5_ccache ccache = NULL; - krb5_creds req_creds; - krb5_creds *new_creds = NULL; - const char *remotehost; - krb5_data ap; - int type, payload_len; - krb5_ap_rep_enc_part *reply = NULL; - int ret; - - memset(&ap, 0, sizeof(ap)); - - problem = krb5_init_context(context); - if (problem) { - ret = 0; - goto out; - } - - tkfile = krb5_cc_default_name(*context); - if (strncmp(tkfile, "FILE:", 5) == 0) - tkfile += 5; - - if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) { - debug("Kerberos V5: could not get default ccache (permission denied)."); - ret = 0; - goto out; - } - - problem = krb5_cc_default(*context, &ccache); - if (problem) { - ret = 0; - goto out; - } - - memset(&req_creds, 0, sizeof(req_creds)); - - remotehost = get_canonical_hostname(); - - problem = krb5_sname_to_principal(*context, remotehost, - "host", KRB5_NT_SRV_HST, - &req_creds.server); - if (problem) { - ret = 0; - goto out; - - } - - problem = krb5_cc_get_principal(*context, ccache, &req_creds.client); - if (problem) { - ret = 0; - goto out; - } - - /* creds.session.keytype=ETYPE_DES_CBC_CRC; */ - - problem = krb5_get_credentials(*context, 0, ccache, &req_creds, &new_creds); - if (problem) { - ret = 0; - goto out; - } - - problem = krb5_auth_con_init(*context, auth_context); - if (problem) { - ret = 0; - goto out; - } - - /* krb5_auth_con_setflags(ssh_context, auth_context, - KRB5_AUTH_CONTEXT_RET_TIME); - */ - problem = krb5_mk_req_extended(*context, auth_context, - AP_OPTS_MUTUAL_REQUIRED /*| AP_OPTS_USE_SUBKEY*/ , - NULL, new_creds, &ap); - if (problem) { - ret = 0; - goto out; - } - - packet_start(SSH_CMSG_AUTH_KRB5); - packet_put_string((char *) ap.data, ap.length); - packet_send(); - packet_write_wait(); - - xfree(ap.data); - ap.length = 0; - - type = packet_read(&payload_len); - switch (type) { - case SSH_SMSG_FAILURE: - /* Should really be SSH_SMSG_AUTH_KRB5_FAILURE */ - debug("Kerberos V5 authentication failed."); - ret = 0; - break; - - case SSH_SMSG_AUTH_KRB5_RESPONSE: - /* SSH_SMSG_AUTH_KRB5_SUCCESS */ - debug("Kerberos V5 authentication accepted."); - - /* Get server's response. */ - ap.data = packet_get_string((unsigned int *) &ap.length); - - packet_integrity_check(payload_len, 4 + ap.length, type); - /* XXX je to dobre? */ - - problem = krb5_rd_rep(*context, *auth_context, &ap, &reply); - if (problem) { - ret = 0; - } - ret = 1; - break; - - default: - packet_disconnect("Protocol error on Kerberos V5 response: %d", type); - ret = 0; - break; - - } - -out: - if (req_creds.server != NULL) - krb5_free_principal(*context, req_creds.server); - if (req_creds.client != NULL) - krb5_free_principal(*context, req_creds.client); - if (new_creds != NULL) - krb5_free_creds(*context, new_creds); - if (ccache != NULL) - krb5_cc_close(*context, ccache); - if (reply != NULL) - krb5_free_ap_rep_enc_part(*context, reply); - if (ap.length > 0) - krb5_data_free(&ap); - - return ret; - -} - -void -send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) -{ - int fd; - int type, payload_len; - krb5_error_code problem; - krb5_data outbuf; - krb5_ccache ccache = NULL; - krb5_creds creds; - krb5_kdc_flags flags; - const char* remotehost = get_canonical_hostname(); - - memset(&creds, 0, sizeof(creds)); - memset(&outbuf, 0, sizeof(outbuf)); - - fd = packet_get_connection_in(); - problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd); - if (problem) { - goto out; - } - -#if 0 - tkfile = krb5_cc_default_name(context); - if (strncmp(tkfile, "FILE:", 5) == 0) - tkfile += 5; - - if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) { - debug("Kerberos V5: could not get default ccache (permission denied)."); - goto out; - } -#endif - - problem = krb5_cc_default(context, &ccache); - if (problem) { - goto out; - } - - problem = krb5_cc_get_principal(context, ccache, &creds.client); - if (problem) { - goto out; - } - - problem = krb5_build_principal(context, &creds.server, - strlen(creds.client->realm), - creds.client->realm, - "krbtgt", - creds.client->realm, - NULL); - if (problem) { - goto out; - } - - creds.times.endtime = 0; - - flags.i = 0; - flags.b.forwarded = 1; - flags.b.forwardable = krb5_config_get_bool(context, NULL, - "libdefaults", "forwardable", NULL); - - problem = krb5_get_forwarded_creds (context, - auth_context, - ccache, - flags.i, - remotehost, - &creds, - &outbuf); - if (problem) { - goto out; - } - - packet_start(SSH_CMSG_HAVE_KRB5_TGT); - packet_put_string((char *)outbuf.data, outbuf.length); - packet_send(); - packet_write_wait(); - - type = packet_read(&payload_len); - switch (type) { - case SSH_SMSG_SUCCESS: - break; - case SSH_SMSG_FAILURE: - break; - default: - break; - } - -out: - if (creds.client) - krb5_free_principal(context, creds.client); - if (creds.server) - krb5_free_principal(context, creds.server); - if (ccache) - krb5_cc_close(context, ccache); - if (outbuf.data) - xfree(outbuf.data); - - return; -} -#endif /* KRB5 */ - -/* - * 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, payload_len; - 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(&payload_len); - 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; -} - -/* - * 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; - 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; - break; - } - if (buf[i] == '\n') { - buf[i + 1] = 0; - break; - } - } - buf[sizeof(buf) - 1] = 0; - - /* - * Check that the versions match. In future this might accept - * several versions and set appropriate flags to handle them. - */ - if (sscanf(buf, "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); - - /* Check if the remote protocol version is too old. */ - if (remote_major == 1 && remote_minor < 3) - fatal("Remote machine has too old SSH software version."); - - /* We speak 1.3, too. */ - if (remote_major == 1 && remote_minor == 3) { - enable_compat13(); - if (options.forward_agent) { - log("Agent forwarding disabled for protocol 1.3"); - options.forward_agent = 0; - } - } -#if 0 - /* - * Removed for now, to permit compatibility with latter versions. The - * server will reject our version and disconnect if it doesn't - * support it. - */ - if (remote_major != PROTOCOL_MAJOR) - fatal("Protocol major versions differ: %d vs. %d", - PROTOCOL_MAJOR, remote_major); -#endif - - /* Send our own protocol version identification. */ - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", - PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION); - if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) - fatal("write: %.100s", strerror(errno)); -} - -int ssh_cipher_default = SSH_CIPHER_3DES; - -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, RSA *host_key) -{ - RSA *file_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. - */ - 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 = RSA_new(); - file_key->n = BN_new(); - file_key->e = BN_new(); - - /* - * 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(options.user_hostfile, host, - host_key->e, host_key->n, - file_key->e, file_key->n); - if (host_status == HOST_NEW) - host_status = check_host_in_hostfile(options.system_hostfile, host, - host_key->e, host_key->n, - file_key->e, file_key->n); - /* - * 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)) { - RSA *ip_key = RSA_new(); - ip_key->n = BN_new(); - ip_key->e = BN_new(); - ip_status = check_host_in_hostfile(options.user_hostfile, ip, - host_key->e, host_key->n, - ip_key->e, ip_key->n); - - if (ip_status == HOST_NEW) - ip_status = check_host_in_hostfile(options.system_hostfile, ip, - host_key->e, host_key->n, - ip_key->e, ip_key->n); - if (host_status == HOST_CHANGED && - (ip_status != HOST_CHANGED || - (BN_cmp(ip_key->e, file_key->e) || BN_cmp(ip_key->n, file_key->n)))) - host_ip_differ = 1; - - RSA_free(ip_key); - } else - ip_status = host_status; - - RSA_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 host key.", host); - if (options.check_host_ip) { - if (ip_status == HOST_NEW) { - if (!add_host_to_hostfile(options.user_hostfile, ip, - host_key->e, host_key->n)) - log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", - ip, options.user_hostfile); - else - log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.", - ip); - } else if (ip_status != HOST_OK) - log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'", - 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 host key is known for %.200s and you have requested strict checking.", host); - } else if (options.strict_host_key_checking == 2) { - /* The default */ - char prompt[1024]; - char *fp = fingerprint(host_key->e, host_key->n); - snprintf(prompt, sizeof(prompt), - "The authenticity of host '%.200s' can't be established.\n" - "Key fingerprint is %d %s.\n" - "Are you sure you want to continue connecting (yes/no)? ", - host, BN_num_bits(host_key->n), 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(options.user_hostfile, hostp, - host_key->e, host_key->n)) - log("Failed to add the host to the list of known hosts (%.500s).", - options.user_hostfile); - else - log("Warning: Permanently added '%.200s' to the list of known hosts.", - hostp); - 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 host key for %s has changed,", 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 host key has just been changed."); - error("Please contact your system administrator."); - error("Add correct host key in %.100s to get rid of this message.", - options.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("Host key for %.200s has changed and you have requested strict checking.", 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); -} - -/* - * SSH1 key exchange - */ -void -ssh_kex(char *host, struct sockaddr *hostaddr) -{ - int i; - BIGNUM *key; - RSA *host_key; - RSA *public_key; - int bits, rbits; - 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); - - check_host_key(host, hostaddr, host_key); - - 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_NOT_SET) { - if (cipher_mask() & 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(int host_key_valid, RSA *own_host_key, - uid_t original_real_uid, char *host) -{ - int i, type; - int payload_len; - struct passwd *pw; - const 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; - - /* 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_KRB4_TGT)) && - options.krb4_tgt_passing) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - (void) send_krb4_tgt(); - } - /* Try AFS token passing if the server supports it. */ - if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && - options.afs_token_passing && k_hasafs()) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); - send_afs_tokens(); - } -#endif /* AFS */ - -#ifdef KRB4 - if ((supported_authentications & (1 << SSH_AUTH_KRB4)) && - options.krb4_authentication) { - debug("Trying Kerberos authentication."); - if (try_krb4_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 */ - -#ifdef KRB5 - if ((supported_authentications & (1 << SSH_AUTH_KRB5)) && - options.krb5_authentication){ - krb5_context ssh_context = NULL; - krb5_auth_context auth_context = NULL; - - debug("Trying Kerberos V5 authentication."); - - if (try_krb5_authentication(&ssh_context, &auth_context)) { - type = packet_read(&payload_len); - if (type == SSH_SMSG_SUCCESS) { - if ((supported_authentications & (1 << SSH_PASS_KRB5_TGT)) && - options.krb5_tgt_passing) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - send_krb5_tgt(ssh_context, auth_context); - - } - krb5_auth_con_free(ssh_context, auth_context); - krb5_free_context(ssh_context); - return; - } - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos5 auth", type); - - } - } -#endif /* KRB5 */ - - /* - * 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 */ -} - -/* - * 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) -{ - char *host, *cp; - - /* 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(); - - supported_authentications = 0; - /* key exchange */ - ssh_kex(host, hostaddr); - if (supported_authentications == 0) - fatal("supported_authentications == 0."); - /* authenticate user */ - ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); -} diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8 deleted file mode 100644 index e490ecc32433..000000000000 --- a/crypto/openssh/sshd.8 +++ /dev/null @@ -1,850 +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.34 2000/02/24 18:22:16 markus Exp $ -.\" $FreeBSD$ -.\" -.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 programs, 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.network . -It forks a new -daemon for each incoming connection. The forked daemons handle -key exchange, encryption, authentication, command execution, -and data exchange. -.Pp -.Nm -works as follows. 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, the daemon sends its host -and server public keys to the client. The client compares the -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 start to 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 and 3DES, with 3DES -being is 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 that machine). -.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/ssh/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 host key is read (default -.Pa /etc/ssh/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 options is specified -.Nm -assumes the client has sent the given 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/ssh/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 CheckMail -Specifies whether -.Nm -should check for new mail for interactive logins. -The default is -.Dq no . -.It Cm ConnectionsPerPeriod -This keyword allows for rate-limiting of connections, and -is followed by two numbers in the format -.Dq n/s , -where -.Ar n -is the number of connections from a certain address group -accepted per period of -.Ar s -seconds. Any connection after the number -.Ar n -connection in the period of -.Ar s -seconds will be dropped, and an informational message will be logged. -A connection will belong to a certain group, of which there are 13 -by default, according to its IP address. -The default for this keyword is -.Dq 0/0 , -and rate-limiting can be explicitly turned off by using an -.Ar n -parameter of -.Ql 0 -and any -.Ar s -parameter. -.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 HostKey -Specifies the file containing the private host key (default -.Pa /etc/ssh/ssh_host_key ) . -Note that -.Nm -does not start 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/ssh/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 send, -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 . -.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 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 RandomSeed -Obsolete - accepted and ignored with a warning. -Random number generation uses other techniques. -.It Cm RhostsAuthentication -Specifies whether authentication using rhosts or -.Pa /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 -.Pa /etc/hosts.equiv -authentication. -The default is -.Dq no . -.It Cm RhostsRSAAuthentication -Specifies whether rhosts or -.Pa /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 . -.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 OPIE 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 yes . -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 and -.Pa /var/run/nologin ; -if one exists, it prints the 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/ssh/sshrc -exists, runs -it; otherwise runs -.Xr xauth 1 . -The -.Dq rc -files are given the X11 -authentication protocol and cookie (if applicable) 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. 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 ('*' and '?' serve as wildcards). The list may also contain -patterns negated by prefixing them with '!'; 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. Notice that the client may specify TCP/IP and/or X11 -forwardings 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 -.Bd -literal -1024 33 12121...312314325 ylo@foo.bar -from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula -command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi -.Ed -.Sh SSH_KNOWN_HOSTS FILE FORMAT -The -.Pa /etc/ssh/ssh_known_hosts -and -.Pa $HOME/.ssh/known_hosts -files contain host public keys for all known hosts. The global file should -be prepared by the admistrator (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 host key; they -can be obtained, e.g., from -.Pa /etc/ssh/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/ssh_host_key.pub -and adding the host names at the front. -.Ss Examples -.Bd -literal -closenet,closenet.hut.fi,...,130.233.208.41 1024 37 159...93 closenet.hut.fi -.Ed -.Sh FILES -.Bl -tag -width Ds -.It Pa /etc/ssh/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/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/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. -.It Pa "/etc/ssh/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/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 -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. -.It 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/ssh/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 -.Pa /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: -.Bd -literal -offset indent -if [ -n "$DISPLAY" ] && read proto cookie; then - echo add $DISPLAY $proto $cookie | xauth -q - -fi -.Ed -.Pp -If this file does not exist, -.Pa /etc/ssh/sshrc -is run, and if that -does not exist either, -.Xr xauth 1 -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/ssh/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. -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, making it compatible with -all other ssh protocol 1 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. -.Sh SEE ALSO -.Xr rlogin 1 , -.Xr rsh 1 , -.Xr scp 1 , -.Xr ssh 1 , -.Xr ssh-add 1 , -.Xr ssh-agent 1 , -.Xr ssh-keygen 1 , -.Xr ssl 8 diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c deleted file mode 100644 index 627d09ce81b5..000000000000 --- a/crypto/openssh/sshd.c +++ /dev/null @@ -1,2984 +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. - * - * $FreeBSD$ - */ - -#include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.88 2000/02/15 16:52:57 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 "uidswap.h" -#include "compat.h" -#include <poll.h> -#include <time.h> - -#ifdef LIBWRAP -#include <tcpd.h> -#include <syslog.h> -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING; -#endif /* LIBWRAP */ - -#ifdef __FreeBSD__ -#define LOGIN_CAP -#define _PATH_CHPASS "/usr/bin/passwd" -#endif /* __FreeBSD__ */ - -#ifdef LOGIN_CAP -#include <login_cap.h> -#endif /* LOGIN_CAP */ - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -#ifdef KRB5 -#include <krb5.h> -krb5_context ssh_context = NULL; -krb5_principal tkt_client = NULL; /* Principal from the received ticket. -Also is used as an indication of succesful krb5 authentization. */ -#endif /* KRB5 */ - - -/* Local Xauthority file. */ -static char *xauthfile = NULL; - -/* 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; - -/* 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; - -/* Session id for the current session. */ -unsigned char session_id[16]; - -/* - * 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 server key. */ - RSA *host_key; /* Private part of 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; - -/* These are used to implement connections_per_period. */ -struct magic_connection { - struct timeval connections_begin; - unsigned int connections_this_period; -} *magic_connections; -/* Magic number, too! TODO: this doesn't have to be static. */ -const size_t MAGIC_CONNECTIONS_SIZE = 1; - -static __inline int -magic_hash(struct sockaddr *sa) { - - return 0; -} - -static __inline struct timeval -timevaldiff(struct timeval *tv1, struct timeval *tv2) { - struct timeval diff; - int carry; - - carry = tv1->tv_usec > tv2->tv_usec; - diff.tv_sec = tv2->tv_sec - tv1->tv_sec - (carry ? 0 : 1); - diff.tv_usec = tv2->tv_usec - tv1->tv_usec + (carry ? 1000000 : 0); - - return diff; -} - -/* Prototypes for various functions defined later in this file. */ -void do_ssh_kex(); -void do_authentication(); -void do_authloop(struct passwd * pw); -void do_fake_authloop(char *user); -void do_authenticated(struct passwd * pw); -void do_exec_pty(const char *command, int ptyfd, int ttyfd, - const char *ttyname, struct passwd * pw, const char *term, - const char *display, const char *auth_proto, - const char *auth_data); -void do_exec_no_pty(const char *command, struct passwd * pw, - const char *display, const char *auth_proto, - const char *auth_data); -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); - -/* - * 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; - } -} - -/* - * 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(); - 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()); -} - -/* - * 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_KRB4: - return "kerberosV4"; -#endif -#ifdef KRB5 - case SSH_CMSG_AUTH_KRB5: - return "kerberosV5"; -#endif /* KRB5 */ -#ifdef SKEY - case SSH_CMSG_AUTH_TIS_RESPONSE: - return "s/key"; -#endif - } - snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); - return buf; -} - -/* - * 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. - */ -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; -} - -/* - * 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, pid, on = 1; - socklen_t fromlen; - int connections_per_period_exceeded = 0; - int remote_major, remote_minor; - int silentrsa = 0; - fd_set *fdset; - struct sockaddr_storage from; - char buf[100]; /* Must not be larger than remote_version. */ - char remote_version[100]; /* Must be at least as big as buf. */ - const char *remote_ip; - int remote_port; - char *comment; - 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': - silentrsa = 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, - !inetd_flag); - - /* check if RSA support exists */ - if (rsa_alive() == 0) { - if (silentrsa == 0) - printf("sshd: no RSA support in libssl and libcrypto -- exiting. See ssl(8)\n"); - log("no RSA support in libssl and libcrypto -- exiting. See ssl(8)"); - exit(1); - } - /* 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 certain values for sanity. */ - if (options.server_key_bits < 512 || - options.server_key_bits > 32768) { - fprintf(stderr, "Bad server key size.\n"); - exit(1); - } - /* 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.host_key = RSA_new(); - errno = 0; - /* Load the host key. It must have empty passphrase. */ - if (!load_private_key(options.host_key_file, "", - sensitive_data.host_key, &comment)) { - error("Could not load host key: %.200s: %.100s", - options.host_key_file, strerror(errno)); - exit(1); - } - xfree(comment); - - /* 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); - - /* 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); - } - /* 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("/"); - - /* Close connection cleanly after attack. */ - cipher_attack_detected = packet_disconnect; - - /* 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); - - 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(SSH_DAEMON_PID_FILE, "w"); - if (f) { - fprintf(f, "%u\n", (unsigned int) getpid()); - fclose(f); - } - } - - 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); - - /* Initialize the magic_connections table. It's magical! */ - magic_connections = calloc(MAGIC_CONNECTIONS_SIZE, - sizeof(struct magic_connection)); - if (magic_connections == NULL) - fatal("calloc: %s", strerror(errno)); - - /* - * 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; - } - if (options.connections_per_period != 0) { - struct timeval diff, connections_end; - struct magic_connection *mc; - - (void)gettimeofday(&connections_end, NULL); - mc = &magic_connections[magic_hash((struct sockaddr *)0)]; - diff = timevaldiff(&mc->connections_begin, &connections_end); - if (diff.tv_sec >= options.connections_period) { - /* - * Slide the window forward only after completely - * leaving it. - */ - mc->connections_begin = connections_end; - mc->connections_this_period = 1; - } else { - if (++mc->connections_this_period > - options.connections_per_period) - connections_per_period_exceeded = 1; - } - } - - /* - * Got connection. Fork a child to handle it unless - * we are in debugging mode or the maximum number of - * connections per period has been exceeded. - */ - 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 if (connections_per_period_exceeded) { - log("Connection rate limit of %u/%us has been exceeded; " - "dropping connection from %s.", - options.connections_per_period, options.connections_period, - ntop); - connections_per_period_exceeded = 0; - } 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 - { - 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); - } - 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); - - if (client_version_string != NULL) { - /* we are exec'ed by sshd2, so skip exchange of protocol version */ - strlcpy(buf, client_version_string, sizeof(buf)); - } else { - /* Send our protocol version identification. */ - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", - PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION); - if (atomicio(write, sock_out, buf, strlen(buf)) != strlen(buf)) { - log("Could not write ident string to %s.", remote_ip); - 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.", remote_ip); - fatal_cleanup(); - } - if (buf[i] == '\r') { - buf[i] = '\n'; - buf[i + 1] = 0; - break; - } - if (buf[i] == '\n') { - /* buf[i] == '\n' */ - buf[i + 1] = 0; - break; - } - } - buf[sizeof(buf) - 1] = 0; - } - - /* - * Check that the versions match. In future this might accept - * several versions and set appropriate flags to handle them. - */ - if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, - remote_version) != 3) { - char *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", - buf, remote_ip); - fatal_cleanup(); - } - debug("Client protocol version %d.%d; client software version %.100s", - remote_major, remote_minor, remote_version); - if (remote_major != PROTOCOL_MAJOR) { - char *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: %d vs. %d", - remote_ip, PROTOCOL_MAJOR, remote_major); - fatal_cleanup(); - } - /* Check that the client has sufficiently high software version. */ - if (remote_major == 1 && remote_minor < 3) - packet_disconnect("Your ssh version is too old and is no longer supported. Please install a newer version."); - - if (remote_major == 1 && remote_minor == 3) { - /* note that this disables agent-forwarding */ - enable_compat13(); - } - /* - * 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.krb4_authentication) { - debug("Kerberos Authentication disabled, only available for IPv4."); - options.krb4_authentication = 0; - } -#endif /* KRB4 */ - - packet_set_nonblocking(); - - /* perform the key exchange */ - do_ssh_kex(); - - /* authenticate user and start session */ - do_authentication(); - -#ifdef KRB4 - /* Cleanup user's ticket cache file. */ - if (options.krb4_ticket_cleanup) - (void) dest_tkt(); -#endif /* KRB4 */ - - /* Cleanup user's local Xauthority file. */ - if (xauthfile) - xauthfile_cleanup_proc(NULL); - - /* The connection has been terminated. */ - verbose("Closing connection to %.100s", remote_ip); - packet_close(); - exit(0); -} - -/* - * SSH1 key exchange - */ -void -do_ssh_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_mask()); - - /* 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.krb4_authentication) - auth_mask |= 1 << SSH_AUTH_KRB4; -#endif -#ifdef KRB5 - if (options.krb5_authentication) { - auth_mask |= 1 << SSH_AUTH_KRB5; - /* compatibility with MetaCentre ssh */ - auth_mask |= 1 << SSH_AUTH_KRB4; - } - if (options.krb5_tgt_passing) - auth_mask |= 1 << SSH_PASS_KRB5_TGT; -#endif /* KRB5 */ - -#ifdef AFS - if (options.krb4_tgt_passing) - auth_mask |= 1 << SSH_PASS_KRB4_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. */ - RSA_free(public_key); - RSA_free(sensitive_data.private_key); - RSA_free(sensitive_data.host_key); - - /* - * 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(); -} - - -/* - * 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. - */ -static 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; - } - } -#ifndef __FreeBSD__ /* FreeBSD handle it later */ - /* Fail if the account's expiration time has passed. */ - if (pw->pw_expire != 0) { - struct timeval tv; - - (void)gettimeofday(&tv, NULL); - if (tv.tv_sec >= pw->pw_expire) - return 0; - } -#endif /* !__FreeBSD__ */ - /* We found no reason not to let this user try to log on... */ - return 1; -} - -/* - * 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, ulen; - char *user; -#ifdef LOGIN_CAP - login_cap_t *lc; -#endif /* LOGIN_CAP */ -#if defined(LOGIN_CAP) || defined(LOGIN_ACCESS) - const char *from_host, *from_ip; - - from_host = get_canonical_hostname(); - from_ip = get_remote_ipaddr(); -#endif /* LOGIN_CAP || LOGIN_ACCESS */ - - /* 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_authloop(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); - pwcopy.pw_class = xstrdup(pw->pw_class); - pwcopy.pw_expire = pw->pw_expire; - pwcopy.pw_change = pw->pw_change; - 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 KRB5 - !options.krb5_authentication && -#endif /* KRB5 */ -#ifdef KRB4 - (!options.krb4_authentication || options.krb4_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); - } - - /* Check if the user is logging in as root and root logins are disallowed. */ - if (pw->pw_uid == 0 && !options.permit_root_login) { - if (forced_command) - log("Root login accepted for forced command."); - else - packet_disconnect("ROOT LOGIN REFUSED FROM %.200s", - get_canonical_hostname()); - } - -#ifdef LOGIN_CAP - lc = login_getpwclass(pw); - if (lc == NULL) - lc = login_getclassbyname(NULL, pw); - if (!auth_hostok(lc, from_host, from_ip)) { - log("Denied connection for %.200s from %.200s [%.200s].", - pw->pw_name, from_host, from_ip); - packet_disconnect("Sorry, you are not allowed to connect."); - } - if (!auth_timeok(lc, time(NULL))) { - log("LOGIN %.200s REFUSED (TIME) FROM %.200s", - pw->pw_name, from_host); - packet_disconnect("Logins not available right now."); - } - login_close(lc); -#endif /* LOGIN_CAP */ -#ifdef LOGIN_ACCESS - if (!login_access(pw->pw_name, from_host)) { - log("Denied connection for %.200s from %.200s [%.200s].", - pw->pw_name, from_host, from_ip); - packet_disconnect("Sorry, you are not allowed to connect."); - } -#endif /* LOGIN_ACCESS */ - - if (pw->pw_uid == 0) - log("ROOT LOGIN as '%.100s' from %.100s", - pw->pw_name, get_canonical_hostname()); - - /* The user has been authenticated and accepted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); - - /* Perform session preparation. */ - do_authenticated(pw); -} - -#define AUTH_FAIL_MAX 6 -#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) -#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" - -/* - * 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; - BIGNUM *client_host_key_e, *client_host_key_n; - BIGNUM *n; - char *client_user, *password; - char user[1024]; - int plen, dlen, nlen, ulen, elen; - int type = 0; - void (*authlog) (const char *fmt,...) = verbose; -#ifdef HAVE_LIBPAM - int pam_retval; -#endif /* HAVE_LIBPAM */ -#if 0 -#ifdef KRB5 - { - krb5_error_code ret; - - ret = krb5_init_context(&ssh_context); - if (ret) - verbose("Error while initializing Kerberos V5."); - krb5_init_ets(ssh_context); - - } -#endif /* KRB5 */ -#endif - - /* 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_KRB4_TGT: - if (!options.krb4_tgt_passing) { - /* packet_get_all(); */ - verbose("Kerberos v4 tgt passing disabled."); - break; - } else { - /* Accept Kerberos v4 tgt. */ - char *tgt = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - if (!auth_krb4_tgt(pw, tgt)) - verbose("Kerberos v4 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_KRB4: - if (!options.krb4_authentication) { - /* packet_get_all(); */ - verbose("Kerberos v4 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 */ -#ifdef KRB5 - case SSH_CMSG_AUTH_KRB5: - if (!options.krb5_authentication) { - verbose("Kerberos v5 authentication disabled."); - break; - } else { - krb5_data k5data; -#if 0 - if (krb5_init_context(&ssh_context)) { - verbose("Error while initializing Kerberos V5."); - break; - } - krb5_init_ets(ssh_context); -#endif - - k5data.data = packet_get_string(&k5data.length); - packet_integrity_check(plen, 4 + k5data.length, type); - if (auth_krb5(pw->pw_name, &k5data, &tkt_client)) { - /* pw->name is passed just for logging purposes - * */ - /* authorize client against .k5login */ - if (krb5_kuserok(ssh_context, - tkt_client, - pw->pw_name)) - authenticated = 1; - } - xfree(k5data.data); - } - break; -#endif /* KRB5 */ - - case SSH_CMSG_AUTH_RHOSTS: - if (!options.rhosts_authentication) { - verbose("Rhosts authentication disabled."); - break; - } - /* - * Get client user name. Note that we just have to - * trust the client; this is one reason why rhosts - * authentication is insecure. (Another is - * IP-spoofing on a local network.) - */ - client_user = packet_get_string(&ulen); - packet_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_e = BN_new(); - client_host_key_n = BN_new(); - 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)) - error("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_e, client_host_key_n); - BN_clear_free(client_host_key_e); - BN_clear_free(client_host_key_n); - - 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; - } - - /* 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(); - } -} - -/* - * The user does not exist or access is denied, - * but fake indication that authentication is needed. - */ -void -do_fake_authloop(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 - int dlen; - char *password, *skeyinfo; - /* Try to send a fake s/key challenge. */ - if (options.skey_authentication == 1 && - (skeyinfo = skey_fake_keyinfo(user)) != NULL) { - password = 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(); -} - -struct pty_cleanup_context { - const char *ttyname; - int pid; -}; - -/* - * Function to perform cleanup if we get aborted abnormally (e.g., due to a - * dropped connection). - */ -void -pty_cleanup_proc(void *context) -{ - struct pty_cleanup_context *cu = context; - - debug("pty_cleanup_proc called"); - - /* Record that the user has logged out. */ - record_logout(cu->pid, cu->ttyname); - - /* Release the pseudo-tty. */ - pty_release(cu->ttyname); -} - -/* simple cleanup: chown tty slave back to root */ -static void -pty_release_proc(void *tty) -{ - char *ttyname = tty; - pty_release(ttyname); -} - -/* - * 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) -{ - int type; - int compression_level = 0, enable_compression_after_reply = 0; - int have_pty = 0, ptyfd = -1, ttyfd = -1; - int row, col, xpixel, ypixel, screen; - char ttyname[64]; - char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL; - int n_bytes; - - /* - * 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(); - - /* - * We stay in this loop until the client requests to execute a shell - * or a command. - */ - while (1) { - int plen, dlen; - - /* 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); - goto fail; - } - /* Enable compression after we have responded with SUCCESS. */ - enable_compression_after_reply = 1; - break; - - case SSH_CMSG_REQUEST_PTY: - if (no_pty_flag) { - debug("Allocating a pty not permitted for this authentication."); - goto fail; - } - if (have_pty) - packet_disconnect("Protocol error: you already have a pty."); - - debug("Allocating pty."); - - /* Allocate a pty and open it. */ - if (!pty_allocate(&ptyfd, &ttyfd, ttyname, - sizeof(ttyname))) { - error("Failed to allocate pty."); - goto fail; - } - fatal_add_cleanup(pty_release_proc, (void *)ttyname); - pty_setowner(pw, ttyname); - - /* Get TERM from the packet. Note that the value may be of arbitrary length. */ - term = packet_get_string(&dlen); - packet_integrity_check(dlen, strlen(term), type); - - /* Remaining bytes */ - n_bytes = plen - (4 + dlen + 4 * 4); - - if (strcmp(term, "") == 0) { - xfree(term); - term = NULL; - } - - /* Get window size from the packet. */ - row = packet_get_int(); - col = packet_get_int(); - xpixel = packet_get_int(); - ypixel = packet_get_int(); - pty_change_window_size(ptyfd, row, col, xpixel, ypixel); - - /* Get tty modes from the packet. */ - tty_parse_modes(ttyfd, &n_bytes); - packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type); - - /* Indicate that we now have a pty. */ - have_pty = 1; - break; - - case SSH_CMSG_X11_REQUEST_FORWARDING: - if (!options.x11_forwarding) { - packet_send_debug("X11 forwarding disabled in server configuration file."); - goto fail; - } -#ifdef XAUTH_PATH - if (no_x11_forwarding_flag) { - packet_send_debug("X11 forwarding not permitted for this authentication."); - goto fail; - } - debug("Received request for X11 forwarding with auth spoofing."); - if (display) - packet_disconnect("Protocol error: X11 display already set."); - { - int proto_len, data_len; - proto = packet_get_string(&proto_len); - 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) - screen = packet_get_int(); - else - screen = 0; - display = x11_create_display_inet(screen, options.x11_display_offset); - if (!display) - goto fail; - - /* 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; - goto fail; - } - restore_uid(); - strlcat(xauthfile, "/cookies", MAXPATHLEN); - fatal_add_cleanup(xauthfile_cleanup_proc, NULL); - break; -#else /* XAUTH_PATH */ - packet_send_debug("No xauth program; cannot forward with spoofing."); - goto fail; -#endif /* XAUTH_PATH */ - - case SSH_CMSG_AGENT_REQUEST_FORWARDING: - if (no_agent_forwarding_flag || compat13) { - debug("Authentication agent forwarding not permitted for this authentication."); - goto fail; - } - debug("Received authentication agent forwarding request."); - auth_input_request_forwarding(pw); - break; - - case SSH_CMSG_PORT_FORWARD_REQUEST: - if (no_port_forwarding_flag) { - debug("Port forwarding not permitted for this authentication."); - goto fail; - } - debug("Received TCP/IP port forwarding request."); - channel_input_port_forward_request(pw->pw_uid == 0); - break; - - case SSH_CMSG_MAX_PACKET_SIZE: - if (packet_set_maxsize(packet_get_int()) < 0) - goto fail; - break; - - case SSH_CMSG_EXEC_SHELL: - /* Set interactive/non-interactive mode. */ - packet_set_interactive(have_pty || display != NULL, - options.keepalives); - - if (forced_command != NULL) - goto do_forced_command; - debug("Forking shell."); - packet_integrity_check(plen, 0, type); - if (have_pty) - do_exec_pty(NULL, ptyfd, ttyfd, ttyname, pw, term, display, proto, data); - else - do_exec_no_pty(NULL, pw, display, proto, data); - return; - - case SSH_CMSG_EXEC_CMD: - /* Set interactive/non-interactive mode. */ - packet_set_interactive(have_pty || display != NULL, - options.keepalives); - - if (forced_command != NULL) - goto do_forced_command; - /* Get command from the packet. */ - { - int dlen; - command = packet_get_string(&dlen); - debug("Executing command '%.500s'", command); - packet_integrity_check(plen, 4 + dlen, type); - } - if (have_pty) - do_exec_pty(command, ptyfd, ttyfd, ttyname, pw, term, display, proto, data); - else - do_exec_no_pty(command, pw, display, proto, data); - xfree(command); - return; -#ifdef KRB5 - case SSH_CMSG_HAVE_KRB5_TGT: - /* Passing krb5 ticket */ - if (!options.krb5_tgt_passing - /*|| !options.krb5_authentication */) { - - } - - if (tkt_client == NULL) { - /* passing tgt without krb5 authentication */ - } - - { - krb5_data tgt; - tgt.data = packet_get_string(&tgt.length); - - if (!auth_krb5_tgt(pw->pw_name, &tgt, tkt_client)) { - verbose ("Kerberos V5 TGT refused for %.100s", pw->pw_name); - xfree(tgt.data); - goto fail; - } - xfree(tgt.data); - - break; - } -#endif /* KRB5 */ - - default: - /* - * Any unknown messages in this phase are ignored, - * and a failure message is returned. - */ - log("Unknown packet type received after authentication: %d", type); - goto fail; - } - - /* The request was successfully processed. */ - packet_start(SSH_SMSG_SUCCESS); - 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); - } - continue; - -fail: - /* The request failed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - continue; - -do_forced_command: - /* - * There is a forced command specified for this login. - * Execute it. - */ - debug("Executing forced command: %.900s", forced_command); - if (have_pty) - do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display, proto, data); - else - do_exec_no_pty(forced_command, pw, display, proto, data); - return; - } -} - -/* - * 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(const char *command, struct passwd * pw, - const char *display, const char *auth_proto, - const char *auth_data) -{ - 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 */ - - setproctitle("%s@notty", pw->pw_name); - - /* Fork the child. */ - if ((pid = fork()) == 0) { - /* Child. Reinitialize the log since the pid has changed. */ - log_init(av0, 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, display, auth_proto, auth_data, NULL); - /* NOTREACHED */ - } - if (pid < 0) - packet_disconnect("fork failed: %.100s", strerror(errno)); -#ifdef USE_PIPES - /* We are the parent. Close the child sides of the pipes. */ - close(pin[0]); - close(pout[1]); - close(perr[1]); - - /* 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. - */ - 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(const char *command, int ptyfd, int ttyfd, - const char *ttyname, struct passwd * pw, const char *term, - const char *display, const char *auth_proto, - const char *auth_data) -{ - int pid, fdout; - int ptymaster; - const char *hostname; - time_t last_login_time; - char buf[100], *time_string; - FILE *f; - char line[256]; - struct stat st; - int quiet_login; - struct sockaddr_storage from; - socklen_t fromlen; - struct pty_cleanup_context cleanup_context; -#ifdef LOGIN_CAP - login_cap_t *lc; - char *fname; -#endif /* LOGIN_CAP */ -#ifdef __FreeBSD__ -#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ - struct timeval tv; - time_t warntime = DEFAULT_WARN; -#endif /* __FreeBSD__ */ - - /* 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)); - } - setproctitle("%s@%s", pw->pw_name, strrchr(ttyname, '/') + 1); - - /* Fork the child. */ - if ((pid = fork()) == 0) { - pid = getpid(); - - /* Child. Reinitialize the log because the pid has - changed. */ - log_init(av0, 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, ttyname); - - /* 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); - - /* - * 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_get_connection_in() == packet_get_connection_out()) { - 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, ttyname, 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; -#ifdef LOGIN_CAP - lc = login_getpwclass(pw); - if (lc == NULL) - lc = login_getclassbyname(NULL, pw); - quiet_login = login_getcapbool(lc, "hushlogin", quiet_login); -#endif /* LOGIN_CAP */ - -#ifdef __FreeBSD__ - if (pw->pw_change || pw->pw_expire) - (void)gettimeofday(&tv, NULL); -#ifdef LOGIN_CAP - warntime = login_getcaptime(lc, "warnpassword", - DEFAULT_WARN, DEFAULT_WARN); -#endif /* LOGIN_CAP */ - /* - * If the password change time is set and has passed, give the - * user a password expiry notice and chance to change it. - */ - if (pw->pw_change != 0) { - if (tv.tv_sec >= pw->pw_change) { - (void)printf( - "Sorry -- your password has expired.\n"); - log("%s Password expired - forcing change", - pw->pw_name); - command = _PATH_CHPASS; - } else if (pw->pw_change - tv.tv_sec < warntime && - !quiet_login) - (void)printf( - "Warning: your password expires on %s", - ctime(&pw->pw_change)); - } -#ifdef LOGIN_CAP - warntime = login_getcaptime(lc, "warnexpire", - DEFAULT_WARN, DEFAULT_WARN); -#endif /* LOGIN_CAP */ - if (pw->pw_expire) { - if (tv.tv_sec >= pw->pw_expire) { - (void)printf( - "Sorry -- your account has expired.\n"); - log( - "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s", - pw->pw_name, hostname, ttyname); - exit(254); - } else if (pw->pw_expire - tv.tv_sec < warntime && - !quiet_login) - (void)printf( - "Warning: your account expires on %s", - ctime(&pw->pw_expire)); - } -#endif /* __FreeBSD__ */ -#ifdef LOGIN_CAP - if (!auth_ttyok(lc, ttyname)) { - (void)printf("Permission denied.\n"); - log( - "LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s", - pw->pw_name, hostname, ttyname); - exit(254); - } -#endif /* LOGIN_CAP */ - - /* - * 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); - } -#ifdef LOGIN_CAP - if (command == NULL && !quiet_login && !options.use_login) { - fname = login_getcapstr(lc, "copyright", NULL, NULL); - if (fname != NULL && (f = fopen(fname, "r")) != NULL) { - while (fgets(line, sizeof(line), f) != NULL) - fputs(line, stdout); - fclose(f); - } else - (void)printf("%s\n\t%s %s\n", - "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", - "The Regents of the University of California. ", - "All rights reserved."); - } -#endif /* LOGIN_CAP */ - /* - * 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) { -#ifdef LOGIN_CAP - fname = login_getcapstr(lc, "welcome", NULL, NULL); - if (fname == NULL || (f = fopen(fname, "r")) == NULL) - f = fopen("/etc/motd", "r"); -#else /* !LOGIN_CAP */ - f = fopen("/etc/motd", "r"); -#endif /* LOGIN_CAP */ - /* Print /etc/motd if it exists. */ - if (f) { - while (fgets(line, sizeof(line), f)) - fputs(line, stdout); - fclose(f); - } - } -#ifdef LOGIN_CAP - login_close(lc); -#endif /* LOGIN_CAP */ - - /* Do common processing for the child, such as execing the command. */ - do_child(command, pw, term, display, auth_proto, auth_data, ttyname); - /* NOTREACHED */ - } - if (pid < 0) - packet_disconnect("fork failed: %.100s", strerror(errno)); - /* Parent. Close the slave side of the pseudo tty. */ - close(ttyfd); - - /* - * Add a cleanup function to clear the utmp entry and record logout - * time in case we call fatal() (e.g., the connection gets closed). - */ - cleanup_context.pid = pid; - cleanup_context.ttyname = ttyname; - fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); - fatal_remove_cleanup(pty_release_proc, (void *) ttyname); - - /* - * 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)); - - /* Enter interactive session. */ - server_loop(pid, ptyfd, fdout, -1); - /* server_loop _has_ closed ptyfd and fdout. */ - - /* Cancel the cleanup function. */ - fatal_remove_cleanup(pty_cleanup_proc, (void *) &cleanup_context); - - /* Record that the user has logged out. */ - record_logout(pid, ttyname); - - /* Release the pseudo-tty. */ - pty_release(ttyname); - - /* - * 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(ptymaster) < 0) - error("close(ptymaster): %s", strerror(errno)); -} - -/* - * 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) -{ - char *shell; - const char *cp = NULL; - char buf[256]; - FILE *f; - unsigned int envsize, i; - char **env = NULL; - extern char **environ; - struct stat st; - char *argv[10]; -#ifdef LOGIN_CAP - login_cap_t *lc; - - lc = login_getpwclass(pw); - if (lc == NULL) - lc = login_getclassbyname(NULL, pw); - if (pw->pw_uid != 0) - auth_checknologin(lc); -#else /* !LOGIN_CAP */ - 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); - - } -#endif /* LOGIN_CAP */ - -#ifdef LOGIN_CAP - if (options.use_login) -#endif /* LOGIN_CAP */ - /* 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) { -#ifdef LOGIN_CAP - char **tmpenv; - - /* Initialize temp environment */ - envsize = 64; - env = xmalloc(envsize * sizeof(char *)); - env[0] = NULL; - - child_set_env(&env, &envsize, "PATH", - (pw->pw_uid == 0) ? - _PATH_STDPATH : _PATH_DEFPATH); - - snprintf(buf, sizeof buf, "%.200s/%.50s", - _PATH_MAILDIR, pw->pw_name); - child_set_env(&env, &envsize, "MAIL", buf); - - if (getenv("TZ")) - child_set_env(&env, &envsize, "TZ", getenv("TZ")); - - /* Save parent environment */ - tmpenv = environ; - environ = env; - - if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0) - fatal("setusercontext failed: %s", strerror(errno)); - - /* Restore parent environment */ - env = environ; - environ = tmpenv; - - for (envsize = 0; env[envsize] != NULL; ++envsize) - ; - envsize = (envsize < 100) ? 100 : envsize + 16; - env = xrealloc(env, envsize * sizeof(char *)); - -#else /* !LOGIN_CAP */ - - 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); -#endif /* LOGIN_CAP */ - } - /* - * 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 LOGIN_CAP - shell = login_getcapstr(lc, "shell", shell, shell); -#endif /* LOGIN_CAP */ - -#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. */ - if (env == NULL) { - 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); -#ifndef LOGIN_CAP - 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); -#endif /* !LOGIN_CAP */ - - /* Normal systems set SHELL by default. */ - child_set_env(&env, &envsize, "SHELL", shell); - } -#ifdef LOGIN_CAP - if (options.use_login) -#endif /* LOGIN_CAP */ - 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 */ - -#ifdef KRB5 - { - extern krb5_ccache mem_ccache; - - if (mem_ccache) { - krb5_error_code problem; - krb5_ccache ccache; -#ifdef AFS - if (k_hasafs()) - krb5_afslog(ssh_context, mem_ccache, NULL, NULL); -#endif /* AFS */ - - problem = krb5_cc_default(ssh_context, &ccache); - if (problem) {} - else { - problem = krb5_cc_copy_cache(ssh_context, mem_ccache, ccache); - if (problem) {} - } - - krb5_cc_close(ssh_context, ccache); - } - - krb5_cleanup_proc(NULL); - } -#endif /* KRB5 */ - - 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 < getdtablesize(); i++) - close(i); - - /* Change current directory to the user\'s home directory. */ - if ( -#ifdef __FreeBSD__ - !*pw->pw_dir || -#endif /* __FreeBSD__ */ - chdir(pw->pw_dir) < 0 - ) { -#ifdef __FreeBSD__ - int quiet_login = 0; -#endif /* __FreeBSD__ */ -#ifdef LOGIN_CAP - if (login_getcapbool(lc, "requirehome", 0)) { - (void)printf("Home directory not available\n"); - log("LOGIN %.200s REFUSED (HOMEDIR) ON TTY %.200s", - pw->pw_name, ttyname); - exit(254); - } -#endif /* LOGIN_CAP */ -#ifdef __FreeBSD__ - if (chdir("/") < 0) { - (void)printf("Cannot find root directory\n"); - log("LOGIN %.200s REFUSED (ROOTDIR) ON TTY %.200s", - pw->pw_name, ttyname); - exit(254); - } -#ifdef LOGIN_CAP - quiet_login = login_getcapbool(lc, "hushlogin", 0); -#endif /* LOGIN_CAP */ - if (!quiet_login || *pw->pw_dir) - (void)printf( - "No home directory.\nLogging in with home = \"/\".\n"); - -#else /* !__FreeBSD__ */ - - fprintf(stderr, "Could not chdir to home directory %s: %s\n", - pw->pw_dir, strerror(errno)); -#endif /* __FreeBSD__ */ - } -#ifdef LOGIN_CAP - login_close(lc); -#endif /* LOGIN_CAP */ - - /* - * 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); - fclose(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) -#ifdef __FreeBSD__ - ; -#else /* !__FreeBSD__ */ - printf("No mail.\n"); -#endif /* __FreeBSD__ */ - 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); -} diff --git a/crypto/openssh/sshd/Makefile b/crypto/openssh/sshd/Makefile deleted file mode 100644 index 15d6eec25546..000000000000 --- a/crypto/openssh/sshd/Makefile +++ /dev/null @@ -1,45 +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 - -.include <bsd.own.mk> # for KERBEROS and AFS - -.if (${KERBEROS} == "yes") -CFLAGS+= -DKRB4 -I/usr/include/kerberosIV -SRCS+= auth-krb4.c -LDADD+= -lkrb -DPADD+= ${LIBKRB} -.if (${AFS} == "yes") -CFLAGS+= -DAFS -LDADD+= -lkafs -DPADD+= ${LIBKRBAFS} -.endif # AFS -.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 7142e2554a5f..000000000000 --- a/crypto/openssh/sshd_config +++ /dev/null @@ -1,53 +0,0 @@ -# This is ssh server systemwide configuration file. -# -# $FreeBSD$ - -Port 22 -#ListenAddress 0.0.0.0 -#ListenAddress :: -HostKey /etc/ssh/ssh_host_key -ServerKeyBits 768 -LoginGraceTime 60 -KeyRegenerationInterval 3600 -PermitRootLogin no -# Rate-limit sshd connections to 5 connections per 10 seconds -ConnectionsPerPeriod 5/10 -# 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 309885efb4cd..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.5 1999/11/24 19:53:54 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 433ff73efa86..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.6 1999/11/24 19:53:54 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 aebff0c73c88..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.5 1999/11/24 19:53:54 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 4755710dea9b..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/version.h b/crypto/openssh/version.h deleted file mode 100644 index c2ef9ff4f202..000000000000 --- a/crypto/openssh/version.h +++ /dev/null @@ -1 +0,0 @@ -#define SSH_VERSION "OpenSSH-1.2.2" diff --git a/crypto/openssh/xmalloc.c b/crypto/openssh/xmalloc.c deleted file mode 100644 index afcdbd97cab6..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.5 1999/11/24 00:26:04 deraadt 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 ec49eb1af494..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.2 1999/11/24 00:26:04 deraadt 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 */ |