diff options
author | damien <damien> | 1999-11-25 00:54:57 +0000 |
---|---|---|
committer | damien <damien> | 1999-11-25 00:54:57 +0000 |
commit | 64e38ead969c1e4718fc96f554093dea93d0a028 (patch) | |
tree | cc1f1e5d7852e1f44d41077f776abf7dab7ac06d | |
parent | aa86c45057232a4a4fdb74f83553b396b2691802 (diff) | |
download | openssh-64e38ead969c1e4718fc96f554093dea93d0a028.tar.gz |
- More reformatting merged from OpenBSD CVS
- Merged OpenBSD CVS changes:
- [channels.c]
report from mrwizard@psu.edu via djm@ibs.com.au
- [channels.c]
set SO_REUSEADDR and SO_LINGER for forwarded ports.
chip@valinux.com via damien@ibs.com.au
- [nchan.c]
it's not an error() if shutdown_write failes in nchan.
- [readconf.c]
remove dead #ifdef-0-code
- [readconf.c servconf.c]
strcasecmp instead of tolower
- [scp.c]
progress meter overflow fix from damien@ibs.com.au
- [ssh-add.1 ssh-add.c]
SSH_ASKPASS support
- [ssh.1 ssh.c]
postpone fork_after_authentication until command execution,
request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au
plus: use daemon() for backgrounding
-rw-r--r-- | auth-passwd.c | 38 | ||||
-rw-r--r-- | auth-rh-rsa.c | 20 | ||||
-rw-r--r-- | auth-rhosts.c | 57 | ||||
-rw-r--r-- | auth-rsa.c | 95 | ||||
-rw-r--r-- | auth-skey.c | 8 | ||||
-rw-r--r-- | authfd.c | 127 | ||||
-rw-r--r-- | authfd.h | 82 | ||||
-rw-r--r-- | authfile.c | 63 | ||||
-rw-r--r-- | bufaux.c | 4 | ||||
-rw-r--r-- | bufaux.h | 22 | ||||
-rw-r--r-- | buffer.c | 22 | ||||
-rw-r--r-- | buffer.h | 16 | ||||
-rw-r--r-- | canohost.c | 79 | ||||
-rw-r--r-- | channels.c | 380 | ||||
-rw-r--r-- | channels.h | 27 | ||||
-rw-r--r-- | cipher.c | 43 | ||||
-rw-r--r-- | cipher.h | 36 | ||||
-rw-r--r-- | clientloop.c | 317 | ||||
-rw-r--r-- | compat.c | 31 | ||||
-rw-r--r-- | compat.h | 30 | ||||
-rw-r--r-- | compress.c | 46 | ||||
-rw-r--r-- | compress.h | 38 | ||||
-rw-r--r-- | crc32.h | 8 | ||||
-rw-r--r-- | fingerprint.c | 31 | ||||
-rw-r--r-- | fingerprint.h | 30 | ||||
-rw-r--r-- | hostfile.c | 119 | ||||
-rw-r--r-- | includes.h | 6 | ||||
-rw-r--r-- | log.c | 6 | ||||
-rw-r--r-- | login.c | 29 | ||||
-rw-r--r-- | match.c | 35 | ||||
-rw-r--r-- | mpaux.h | 10 | ||||
-rw-r--r-- | nchan.c | 34 | ||||
-rw-r--r-- | nchan.h | 31 | ||||
-rw-r--r-- | nchan.ms | 28 | ||||
-rw-r--r-- | packet.c | 181 | ||||
-rw-r--r-- | packet.h | 118 | ||||
-rw-r--r-- | pty.c | 44 | ||||
-rw-r--r-- | pty.h | 24 | ||||
-rw-r--r-- | radix.c | 8 | ||||
-rw-r--r-- | readconf.c | 92 | ||||
-rw-r--r-- | readconf.h | 47 | ||||
-rw-r--r-- | readpass.c | 24 | ||||
-rw-r--r-- | rsa.c | 10 | ||||
-rw-r--r-- | rsa.h | 8 | ||||
-rw-r--r-- | scp.c | 20 | ||||
-rw-r--r-- | servconf.c | 17 | ||||
-rw-r--r-- | servconf.h | 14 | ||||
-rw-r--r-- | serverloop.c | 114 | ||||
-rw-r--r-- | ssh-add.1 | 9 | ||||
-rw-r--r-- | ssh-add.c | 167 | ||||
-rw-r--r-- | ssh-agent.c | 37 | ||||
-rw-r--r-- | ssh-keygen.c | 55 | ||||
-rw-r--r-- | ssh.1 | 4 | ||||
-rw-r--r-- | ssh.c | 181 | ||||
-rw-r--r-- | ssh.h | 518 | ||||
-rw-r--r-- | sshconnect.c | 187 | ||||
-rw-r--r-- | sshd.c | 499 | ||||
-rw-r--r-- | tildexpand.c | 8 | ||||
-rw-r--r-- | ttymodes.c | 3 | ||||
-rw-r--r-- | ttymodes.h | 139 | ||||
-rw-r--r-- | uidswap.c | 11 |
61 files changed, 2685 insertions, 1802 deletions
diff --git a/auth-passwd.c b/auth-passwd.c index d3914fca..e5574ffb 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -11,7 +11,7 @@ #ifndef HAVE_PAM -RCSID("$Id: auth-passwd.c,v 1.6 1999/11/24 13:26:21 damien Exp $"); +RCSID("$Id: auth-passwd.c,v 1.7 1999/11/25 00:54:57 damien Exp $"); #include "packet.h" #include "ssh.h" @@ -39,14 +39,10 @@ auth_password(struct passwd * pw, const char *password) struct spwd *spw; #endif - if (pw->pw_uid == 0 && options.permit_root_login == 2) { - /* Server does not permit root login with password */ + if (pw->pw_uid == 0 && options.permit_root_login == 2) return 0; - } - if (*password == '\0' && options.permit_empty_passwd == 0) { - /* Server does not permit empty password login */ + if (*password == '\0' && options.permit_empty_passwd == 0) return 0; - } /* deny if no user. */ if (pw == NULL) return 0; @@ -74,8 +70,10 @@ auth_password(struct passwd * pw, const char *password) #endif #if defined(KRB4) - /* Support for Kerberos v4 authentication - Dug Song - <dugsong@UMICH.EDU> */ + /* + * Support for Kerberos v4 authentication + * - Dug Song <dugsong@UMICH.EDU> + */ if (options.kerberos_authentication) { AUTH_DAT adata; KTEXT_ST tkt; @@ -86,8 +84,10 @@ auth_password(struct passwd * pw, const char *password) char realm[REALM_SZ]; int r; - /* Try Kerberos password authentication only for non-root - users and only if Kerberos is installed. */ + /* + * 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. */ @@ -144,14 +144,17 @@ auth_password(struct passwd * pw, const char *password) goto kerberos_auth_failure; } } else if (r == KDC_PR_UNKNOWN) { - /* Allow login if no rcmd service exists, - but log the error. */ + /* + * 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! */ + /* + * 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]); @@ -175,11 +178,8 @@ auth_password(struct passwd * pw, const char *password) #endif /* KRB4 */ /* Check for users with no password. */ - if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) { - packet_send_debug("Login permitted without a password " - "because the account has no password."); + if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) return 1; - } #ifdef HAVE_SHADOW_H spw = getspnam(pw->pw_name); diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c index 4e9a383a..1392455c 100644 --- a/auth-rh-rsa.c +++ b/auth-rh-rsa.c @@ -15,7 +15,7 @@ */ #include "includes.h" -RCSID("$Id: auth-rh-rsa.c,v 1.6 1999/11/24 13:26:21 damien Exp $"); +RCSID("$Id: auth-rh-rsa.c,v 1.7 1999/11/25 00:54:57 damien Exp $"); #include "packet.h" #include "ssh.h" @@ -23,8 +23,10 @@ RCSID("$Id: auth-rh-rsa.c,v 1.6 1999/11/24 13:26:21 damien Exp $"); #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. */ +/* + * 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, @@ -57,8 +59,10 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, 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 */ + /* + * 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) || @@ -91,8 +95,10 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, canonical_hostname); return 0; } - /* We have authenticated the user using .rhosts or /etc/hosts.equiv, and the host using RSA. - We accept the authentication. */ + /* + * 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); diff --git a/auth-rhosts.c b/auth-rhosts.c index 500dcebb..2f12f134 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c @@ -16,7 +16,7 @@ */ #include "includes.h" -RCSID("$Id: auth-rhosts.c,v 1.5 1999/11/24 13:26:21 damien Exp $"); +RCSID("$Id: auth-rhosts.c,v 1.6 1999/11/25 00:54:57 damien Exp $"); #include "packet.h" #include "ssh.h" @@ -24,9 +24,11 @@ RCSID("$Id: auth-rhosts.c,v 1.5 1999/11/24 13:26:21 damien Exp $"); #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. */ +/* + * 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, @@ -41,7 +43,6 @@ check_rhosts_file(const char *filename, const char *hostname, if (!f) return 0; - /* Go through the file, checking every entry. */ 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; @@ -52,13 +53,17 @@ check_rhosts_file(const char *filename, const char *hostname, 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). */ + /* + * 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. */ + /* + * 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); @@ -135,10 +140,11 @@ check_rhosts_file(const char *filename, const char *hostname, 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). */ +/* + * 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) @@ -150,11 +156,13 @@ auth_rhosts(struct passwd *pw, const char *client_user) static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; unsigned int rhosts_file_index; - /* Quick check: if the user has no .shosts or .rhosts files, - return failure immediately without doing costly lookups from - name servers. */ /* 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. */ @@ -172,7 +180,6 @@ auth_rhosts(struct passwd *pw, const char *client_user) stat(SSH_HOSTS_EQUIV, &st) < 0) return 0; - /* Get the name, address, and port of the remote host. */ hostname = get_canonical_hostname(); ipaddr = get_remote_ipaddr(); @@ -191,8 +198,10 @@ auth_rhosts(struct passwd *pw, const char *client_user) return 1; } } - /* Check that the home directory is owned by root or the user, and - is not group or world writable. */ + /* + * 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); @@ -221,10 +230,12 @@ auth_rhosts(struct passwd *pw, const char *client_user) 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. */ + /* + * 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)) { @@ -16,7 +16,7 @@ */ #include "includes.h" -RCSID("$Id: auth-rsa.c,v 1.9 1999/11/24 13:26:21 damien Exp $"); +RCSID("$Id: auth-rsa.c,v 1.10 1999/11/25 00:54:57 damien Exp $"); #include "rsa.h" #include "packet.h" @@ -43,22 +43,27 @@ 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. */ +/* + * 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. -*/ +/* + * 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. */ +/* + * 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) @@ -128,9 +133,11 @@ auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) 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. */ +/* + * 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) @@ -204,30 +211,32 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) /* Flag indicating whether authentication has succeeded. */ authenticated = 0; - /* Initialize mp-int variables. */ 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. */ + /* + * 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. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++); - - /* Skip empty and comment lines. */ + /* 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. */ + /* + * 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; @@ -258,7 +267,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) /* Check if the we have found the desired key (identified by its modulus). */ if (BN_cmp(n, client_n) != 0) - continue; /* Wrong key. */ + continue; /* We have found the desired key. */ @@ -269,10 +278,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) 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. */ + /* + * 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. */ @@ -412,7 +423,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) goto next_option; } bad_option: - /* Unknown 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", @@ -421,12 +431,14 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) break; next_option: - /* Skip the comma, and move to the next option - (or break out if there are no more). */ + /* + * 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. */ + break; /* End of options. */ if (*options != ',') goto bad_option; options++; @@ -434,8 +446,10 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) continue; } } - /* Break out of the loop if authentication was successful; - otherwise continue searching. */ + /* + * Break out of the loop if authentication was successful; + * otherwise continue searching. + */ if (authenticated) break; } @@ -446,7 +460,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) /* Close the file. */ fclose(f); - /* Clear any mp-int variables. */ BN_clear_free(n); BN_clear_free(e); diff --git a/auth-skey.c b/auth-skey.c index 457100cc..a0d786cb 100644 --- a/auth-skey.c +++ b/auth-skey.c @@ -1,11 +1,15 @@ #include "includes.h" #ifdef SKEY - RCSID("$Id: auth-skey.c,v 1.3 1999/11/23 22:25:52 markus Exp $"); #include "ssh.h" -#include <sha1.h> +#ifdef HAVE_OPENSSL +#include <openssl/sha1.h> +#endif +#ifdef HAVE_SSL +#include <ssl/sha1.h> +#endif /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: authfd.c,v 1.7 1999/11/24 13:26:21 damien Exp $"); +RCSID("$Id: authfd.c,v 1.8 1999/11/25 00:54:57 damien Exp $"); #include "ssh.h" #include "rsa.h" @@ -63,9 +63,11 @@ ssh_get_authentication_socket() 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(). */ +/* + * 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) @@ -74,11 +76,13 @@ ssh_close_authentication_socket(int sock) 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. */ +/* + * 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() @@ -88,12 +92,13 @@ ssh_get_authentication_connection() sock = ssh_get_authentication_socket(); - /* Fail if we couldn't obtain a connection. This happens if we - exited due to a timeout. */ + /* + * Fail if we couldn't obtain a connection. This happens if we + * exited due to a timeout. + */ if (sock < 0) return NULL; - /* Applocate the connection structure and initialize it. */ auth = xmalloc(sizeof(*auth)); auth->fd = sock; buffer_init(&auth->packet); @@ -103,8 +108,10 @@ ssh_get_authentication_connection() return auth; } -/* Closes the connection to the authentication agent and frees any associated - memory. */ +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ void ssh_close_authentication_connection(AuthenticationConnection *ac) @@ -115,10 +122,12 @@ ssh_close_authentication_connection(AuthenticationConnection *ac) 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). */ +/* + * 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, @@ -127,8 +136,10 @@ ssh_get_first_identity(AuthenticationConnection *auth, unsigned char msg[8192]; int len, l; - /* Send a message to the agent requesting for a list of the - identities it can represent. */ + /* + * 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; @@ -149,8 +160,10 @@ ssh_get_first_identity(AuthenticationConnection *auth, len -= l; } - /* Extract the length, and check it for sanity. (We cannot trust - authentication agents). */ + /* + * 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); @@ -182,10 +195,12 @@ ssh_get_first_identity(AuthenticationConnection *auth, 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. */ +/* + * 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, @@ -197,8 +212,10 @@ ssh_get_next_identity(AuthenticationConnection *auth, 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. */ + /* + * 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); @@ -214,11 +231,13 @@ ssh_get_next_identity(AuthenticationConnection *auth, 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. */ +/* + * 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, @@ -259,8 +278,10 @@ error_cleanup: buffer_free(&buffer); return 0; } - /* Wait for response from the agent. First read the length of the - response packet. */ + /* + * 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); @@ -303,8 +324,10 @@ error_cleanup: 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. */ + /* + * 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); @@ -315,8 +338,10 @@ error_cleanup: return 1; } -/* Adds an identity to the authentication server. This call is not meant to - be used by normal applications. */ +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. + */ int ssh_add_identity(AuthenticationConnection *auth, @@ -401,8 +426,10 @@ error_cleanup: return 0; } -/* Removes an identity from the authentication server. This call is not meant - to be used by normal applications. */ +/* + * 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) @@ -431,8 +458,10 @@ error_cleanup: buffer_free(&buffer); return 0; } - /* Wait for response from the agent. First read the length of the - response packet. */ + /* + * 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); @@ -480,8 +509,10 @@ error_cleanup: return 0; } -/* Removes all identities from the agent. This call is not meant - to be used by normal applications. */ +/* + * Removes all identities from the agent. This call is not meant to be used + * by normal applications. + */ int ssh_remove_all_identities(AuthenticationConnection *auth) @@ -499,8 +530,10 @@ ssh_remove_all_identities(AuthenticationConnection *auth) error("Error writing to authentication socket."); return 0; } - /* Wait for response from the agent. First read the length of the - response packet. */ + /* + * 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); @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: authfd.h,v 1.3 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: authfd.h,v 1.4 1999/11/25 00:54:58 damien Exp $"); */ #ifndef AUTHFD_H #define AUTHFD_H @@ -40,33 +40,43 @@ typedef struct { /* 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. */ +/* + * 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(). */ +/* + * 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. */ +/* + * 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). */ +/* + * 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. */ +/* + * 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); @@ -80,24 +90,30 @@ ssh_decrypt_challenge(AuthenticationConnection * auth, 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); +/* + * 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 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); +/* + * 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); +void ssh_close_authentication(AuthenticationConnection * connection); #endif /* AUTHFD_H */ @@ -15,7 +15,7 @@ */ #include "includes.h" -RCSID("$Id: authfile.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: authfile.c,v 1.5 1999/11/25 00:54:58 damien Exp $"); #ifdef HAVE_OPENSSL #include <openssl/bn.h> @@ -33,10 +33,12 @@ RCSID("$Id: authfile.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); /* 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. */ +/* + * 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, @@ -49,9 +51,10 @@ save_private_key(const char *filename, const char *passphrase, 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 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 @@ -68,9 +71,11 @@ save_private_key(const char *filename, const char *passphrase, 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). */ + /* + * 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 */ @@ -112,11 +117,9 @@ save_private_key(const char *filename, const char *passphrase, memset(buf, 0, sizeof(buf)); buffer_free(&buffer); - /* Write to a file. */ f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (f < 0) return 0; - if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) != buffer_len(&encrypted)) { debug("Write to key file %.200s failed: %.100s", filename, @@ -131,9 +134,11 @@ save_private_key(const char *filename, const char *passphrase, 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. */ +/* + * 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, @@ -144,11 +149,9 @@ load_public_key(const char *filename, RSA * pub, Buffer buffer; char *cp; - /* Read data from the file into the buffer. */ f = open(filename, O_RDONLY); if (f < 0) return 0; - len = lseek(f, (off_t) 0, SEEK_END); lseek(f, (off_t) 0, SEEK_SET); @@ -170,8 +173,10 @@ load_public_key(const char *filename, RSA * pub, buffer_free(&buffer); return 0; } - /* Make sure it begins with the id string. Consume the id string - from the buffer. */ + /* + * 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); @@ -197,9 +202,12 @@ load_public_key(const char *filename, RSA * pub, 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. */ +/* + * 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, @@ -214,12 +222,11 @@ load_private_key(const char *filename, const char *passphrase, BIGNUM *aux; struct stat st; - /* Read the file into the buffer. */ f = open(filename, O_RDONLY); if (f < 0) return 0; - /* We assume we are called under uid of the owner of the file */ + /* check owner and modes */ if (fstat(f, &st) < 0 || (st.st_uid != 0 && st.st_uid != getuid()) || (st.st_mode & 077) != 0) { @@ -252,8 +259,10 @@ load_private_key(const char *filename, const char *passphrase, buffer_free(&buffer); return 0; } - /* Make sure it begins with the id string. Consume the id string - from the buffer. */ + /* + * 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); @@ -15,7 +15,7 @@ */ #include "includes.h" -RCSID("$Id: bufaux.c,v 1.6 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: bufaux.c,v 1.7 1999/11/25 00:54:58 damien Exp $"); #include "ssh.h" @@ -54,7 +54,7 @@ buffer_put_bignum(Buffer *buffer, BIGNUM *value) buffer_append(buffer, msg, 2); /* Store the binary data. */ buffer_append(buffer, buf, oi); - /* Clear the temporary data. */ + memset(buf, 0, bin_size); xfree(buf); } @@ -11,15 +11,17 @@ * */ -/* RCSID("$Id: bufaux.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: bufaux.h,v 1.3 1999/11/25 00:54:58 damien 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. */ +/* + * 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. */ @@ -37,12 +39,14 @@ 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. */ +/* + * 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. */ @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: buffer.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: buffer.c,v 1.3 1999/11/25 00:54:58 damien Exp $"); #include "xmalloc.h" #include "buffer.h" @@ -40,8 +40,10 @@ buffer_free(Buffer *buffer) xfree(buffer->buf); } -/* Clears any data from the buffer, making it empty. This does not actually - zero the memory. */ +/* + * Clears any data from the buffer, making it empty. This does not actually + * zero the memory. + */ void buffer_clear(Buffer *buffer) @@ -60,9 +62,11 @@ buffer_append(Buffer *buffer, const char *data, unsigned int 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. */ +/* + * 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) @@ -79,8 +83,10 @@ restart: 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 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); @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: buffer.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: buffer.h,v 1.3 1999/11/25 00:54:58 damien Exp $"); */ #ifndef BUFFER_H #define BUFFER_H @@ -37,9 +37,11 @@ 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. */ +/* + * 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. */ @@ -57,8 +59,10 @@ 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. */ +/* + * Dumps the contents of the buffer to stderr in hex. This intended for + * debugging purposes only. + */ void buffer_dump(Buffer * buffer); #endif /* BUFFER_H */ @@ -14,14 +14,16 @@ */ #include "includes.h" -RCSID("$Id: canohost.c,v 1.3 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: canohost.c,v 1.4 1999/11/25 00:54:58 damien 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. */ +/* + * 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) @@ -52,19 +54,23 @@ get_remote_hostname(int socket) else strlcpy(name, hp->h_name, sizeof(name)); - /* Convert it to all lowercase (which is expected by the - rest of this software). */ + /* + * 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). */ + /* + * 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). + */ hp = gethostbyname(name); if (!hp) { log("reverse mapping checking gethostbyname for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name); @@ -76,8 +82,10 @@ get_remote_hostname(int socket) if (memcmp(hp->h_addr_list[i], &from.sin_addr, sizeof(from.sin_addr)) == 0) break; - /* If we reached the end of the list, the address was not - there. */ + /* + * If we reached the end of the list, the address was not + * there. + */ if (!hp->h_addr_list[i]) { /* 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!", @@ -94,16 +102,17 @@ get_remote_hostname(int socket) 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. */ + /* + * 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. + */ { unsigned char options[200], *ucp; char text[1024], *cp; @@ -134,9 +143,11 @@ check_ip_options: static char *canonical_host_name = NULL; static char *canonical_host_ip = NULL; -/* 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. */ +/* + * 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() @@ -154,8 +165,10 @@ get_canonical_hostname() return canonical_host_name; } -/* Returns the IP-address of the remote host as a string. The returned - string need not be freed. */ +/* + * Returns the IP-address of the remote host as a string. The returned + * string need not be freed. + */ const char * get_remote_ipaddr() @@ -163,7 +176,7 @@ get_remote_ipaddr() struct sockaddr_in from; int fromlen, socket; - /* Check if we have previously retrieved this same name. */ + /* Check whether we have chached the name. */ if (canonical_host_ip != NULL) return canonical_host_ip; @@ -215,8 +228,10 @@ get_remote_port() { int socket; - /* If the connection is not a socket, return 65535. This is - intentionally chosen to be an unprivileged port number. */ + /* + * If the connection is not a socket, return 65535. This is + * intentionally chosen to be an unprivileged port number. + */ if (packet_get_connection_in() != packet_get_connection_out()) return 65535; @@ -16,7 +16,7 @@ */ #include "includes.h" -RCSID("$Id: channels.c,v 1.7 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: channels.c,v 1.8 1999/11/25 00:54:58 damien Exp $"); #include "ssh.h" #include "packet.h" @@ -37,17 +37,23 @@ RCSID("$Id: channels.c,v 1.7 1999/11/24 13:26:22 damien Exp $"); /* 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ @@ -61,15 +67,19 @@ char *x11_saved_proto = NULL; 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. */ +/* + * 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). */ +/* + * 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. */ int port; /* Port number. */ @@ -79,9 +89,11 @@ typedef struct { 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. */ +/* + * 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. */ @@ -95,9 +107,11 @@ 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. */ +/* + * 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() @@ -105,8 +119,10 @@ 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. */ +/* + * 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) @@ -117,6 +133,7 @@ channel_allocate(int type, int sock, char *remote_name) /* 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) { @@ -124,9 +141,10 @@ channel_allocate(int type, int sock, char *remote_name) 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(). */ + /* + * 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. */ @@ -137,8 +155,7 @@ channel_allocate(int type, int sock, char *remote_name) break; } if (found == -1) { - /* There are no free slots. Take last+1 slot and expand - the array. */ + /* 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); @@ -181,8 +198,10 @@ channel_free(int channel) } } -/* This is called just before select() to add any bits relevant to - channels in the select bitmasks. */ +/* + * 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) @@ -248,15 +267,16 @@ redo: 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. */ - + /* + * 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; @@ -303,9 +323,11 @@ redo: ch->type = SSH_CHANNEL_OPEN; goto reject; } - /* Received authentication protocol and data match - our fake data. Substitute the fake data with - real data. */ + /* + * 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); @@ -314,8 +336,10 @@ redo: goto redo; reject: - /* We have received an X11 connection that has bad - authentication information. */ + /* + * 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); @@ -341,8 +365,10 @@ redo: } } -/* After select, perform any appropriate operations for channels which - have events pending. */ +/* + * After select, perform any appropriate operations for channels which have + * events pending. + */ void channel_after_select(fd_set * readset, fd_set * writeset) @@ -381,8 +407,10 @@ channel_after_select(fd_set * readset, fd_set * writeset) break; case SSH_CHANNEL_PORT_LISTENER: - /* This socket is listening for connections to a - forwarded TCP/IP port. */ + /* + * 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:%d requested.", ch->listening_port, ch->path, ch->host_port); @@ -410,8 +438,10 @@ channel_after_select(fd_set * readset, fd_set * writeset) break; case SSH_CHANNEL_AUTH_SOCKET: - /* This is the authentication agent socket - listening for connections from clients. */ + /* + * This is the authentication agent socket listening + * for connections from clients. + */ if (FD_ISSET(ch->sock, readset)) { int nchan; len = sizeof(addr); @@ -429,13 +459,16 @@ channel_after_select(fd_set * readset, fd_set * writeset) 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 */ + /* + * 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) { @@ -500,8 +533,7 @@ channel_output_poll() for (i = 0; i < channels_alloc; i++) { ch = &channels[i]; - /* We are only interested in channels that can have - buffered incoming data. */ + /* We are only interested in channels that can have buffered incoming data. */ if (ch->type != SSH_CHANNEL_OPEN && ch->type != SSH_CHANNEL_INPUT_DRAINING) continue; @@ -509,8 +541,7 @@ channel_output_poll() /* 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. */ + /* Send some data for the other side over the secure connection. */ if (packet_is_interactive()) { if (len > 1024) len = 512; @@ -527,17 +558,20 @@ channel_output_poll() } 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 */ + /* + * 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. */ +/* + * 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) @@ -564,8 +598,10 @@ channel_input_data(int payload_len) xfree(data); } -/* Returns true if no channel has too much buffered data, and false if - one or more channel is overfull. */ +/* + * 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() @@ -615,20 +651,27 @@ channel_input_close() chan_rcvd_ieof(&channels[channel]); return; } - /* Send a confirmation that we have closed the channel and no more - data is coming for it. */ + + /* + * 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 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. */ + /* + * 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; @@ -678,8 +721,7 @@ channel_input_open_confirmation() /* 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. */ + /* 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; } @@ -702,8 +744,10 @@ channel_input_open_failure() channel_free(channel); } -/* Stops listening for channels, and removes any unix domain sockets that - we might have. */ +/* + * Stops listening for channels, and removes any unix domain sockets that we + * might have. + */ void channel_stop_listening() @@ -727,8 +771,10 @@ channel_stop_listening() } } -/* Closes the sockets of all channels. This is used to close extra file - descriptors after a fork. */ +/* + * Closes the sockets of all channels. This is used to close extra file + * descriptors after a fork. + */ void channel_close_all() @@ -778,9 +824,11 @@ channel_still_open() return 0; } -/* Returns a message describing the currently open forwarded - connections, suitable for sending to the client. The message - contains crlf pairs for newlines. */ +/* + * 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() @@ -822,16 +870,19 @@ channel_open_message() return cp; } -/* Initiate forwarding of connections to local port "port" through the secure - channel to host:port from remote side. */ +/* + * Initiate forwarding of connections to local port "port" through the secure + * channel to host:port from remote side. + */ void channel_request_local_forwarding(int port, const char *host, int host_port) { - int ch, sock; + int ch, sock, on = 1; struct sockaddr_in sin; extern Options options; + struct linger linger; if (strlen(host) > sizeof(channels[0].path) - 1) packet_disconnect("Forward host name too long."); @@ -850,6 +901,15 @@ channel_request_local_forwarding(int port, const char *host, sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sin.sin_port = htons(port); + /* + * 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)); + /* Bind the socket to the address. */ if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) packet_disconnect("bind: %.100s", strerror(errno)); @@ -866,8 +926,10 @@ channel_request_local_forwarding(int port, const char *host, channels[ch].listening_port = port; } -/* Initiate forwarding of connections to port "port" on remote host through - the secure channel to host:port from local side. */ +/* + * 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(int port, const char *host, @@ -890,15 +952,18 @@ channel_request_remote_forwarding(int port, const char *host, 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. */ + /* + * 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. */ +/* + * 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) @@ -915,8 +980,10 @@ channel_input_port_forward_request(int is_root) if ((port & 0xffff) != port) packet_disconnect("Requested forwarding of nonexistent port %d.", port); - /* Check that an unprivileged user is not trying to forward a - privileged port. */ + /* + * 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); @@ -928,9 +995,11 @@ channel_input_port_forward_request(int is_root) 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. */ +/* + * 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) @@ -951,13 +1020,16 @@ channel_input_port_open(int payload_len) host_port = packet_get_int(); /* Get remote originator name. */ - if (have_hostname_in_open) + if (have_hostname_in_open) { originator_string = packet_get_string(&originator_len); - else + 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 + 4 + originator_len, + 4 + 4 + host_len + 4 + originator_len, SSH_MSG_PORT_OPEN); /* Check if opening that port is permitted. */ @@ -1040,9 +1112,11 @@ fail: 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. */ +/* + * 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_number) @@ -1134,9 +1208,11 @@ connect_local_xsocket(unsigned dnr) } -/* 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. */ +/* + * 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) @@ -1152,13 +1228,16 @@ x11_input_open(int payload_len) remote_channel = packet_get_int(); /* Get remote originator name. */ - if (have_hostname_in_open) + if (have_hostname_in_open) { remote_host = packet_get_string(&remote_len); - else + 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 + 4 + remote_len, SSH_SMSG_X11_OPEN); + 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"); @@ -1166,11 +1245,15 @@ x11_input_open(int payload_len) 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] */ + /* + * 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. */ @@ -1187,8 +1270,10 @@ x11_input_open(int payload_len) /* 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. */ + /* + * 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, ':'); @@ -1197,8 +1282,7 @@ x11_input_open(int payload_len) goto fail; } *cp = 0; - /* buf now contains the host name. But first we parse the display - number. */ + /* 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); @@ -1267,8 +1351,10 @@ fail: packet_send(); } -/* Requests forwarding of X11 connections, generates fake authentication - data, and enables authentication spoofing. */ +/* + * 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) @@ -1293,8 +1379,10 @@ x11_request_forwarding_with_spoofing(const char *proto, const char *data) /* Save protocol name. */ x11_saved_proto = xstrdup(proto); - /* Extract real authentication data and generate fake data of the - same length. */ + /* + * 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++) { @@ -1334,9 +1422,11 @@ auth_request_forwarding() 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. */ +/* + * 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() @@ -1353,8 +1443,10 @@ cleanup_socket(void) rmdir(channel_forwarded_auth_socket_dir); } -/* This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. - This starts forwarding authentication requests. */ +/* + * 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) @@ -1422,14 +1514,18 @@ auth_input_open_request() /* 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). */ + /* + * 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 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); @@ -1438,9 +1534,11 @@ auth_input_open_request() } 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. */ + /* + * 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); @@ -1,29 +1,26 @@ -/* RCSID("$Id: channels.h,v 1.3 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: channels.h,v 1.4 1999/11/25 00:54:58 damien 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_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_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 */ +/* 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 */ +#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. */ +/* + * Data structure for channel data. This is iniailized in channel_allocate + * and cleared in channel_free. + */ typedef struct Channel { int type; /* channel type/state */ @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$Id: cipher.c,v 1.7 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: cipher.c,v 1.8 1999/11/25 00:54:58 damien Exp $"); #include "ssh.h" #include "cipher.h" @@ -121,8 +121,10 @@ detect_cbc_attack(const unsigned char *src, cipher_attack_detected("CRC-32 CBC insertion attack detected"); } -/* Names of all encryption algorithms. These must match the numbers defined - int cipher.h. */ +/* + * Names of all encryption algorithms. + * These must match the numbers defined in cipher.h. + */ static char *cipher_names[] = { "none", @@ -134,9 +136,11 @@ static char *cipher_names[] = "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. */ +/* + * 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() @@ -158,8 +162,10 @@ cipher_name(int cipher) return cipher_names[cipher]; } -/* Parses the name of the cipher. Returns the number of the corresponding - cipher, or -1 on error. */ +/* + * Parses the name of the cipher. Returns the number of the corresponding + * cipher, or -1 on error. + */ int cipher_number(const char *name) @@ -172,8 +178,10 @@ cipher_number(const char *name) 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. */ +/* + * 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, @@ -211,15 +219,18 @@ cipher_set_key(CipherContext *context, int cipher, /* Initialize the initialization vector. */ switch (cipher) { case SSH_CIPHER_NONE: - /* Has to stay for authfile saving of private key with - no passphrase */ + /* + * 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). */ + /* + * 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); @@ -11,7 +11,7 @@ * */ -/* RCSID("$Id: cipher.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: cipher.h,v 1.5 1999/11/25 00:54:58 damien Exp $"); */ #ifndef CIPHER_H #define CIPHER_H @@ -54,26 +54,34 @@ typedef struct { } 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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); @@ -88,8 +96,10 @@ 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,...); +/* + * 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/clientloop.c b/clientloop.c index c49346c2..679180f5 100644 --- a/clientloop.c +++ b/clientloop.c @@ -15,7 +15,7 @@ */ #include "includes.h" -RCSID("$Id: clientloop.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: clientloop.c,v 1.6 1999/11/25 00:54:58 damien Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -27,22 +27,28 @@ RCSID("$Id: clientloop.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); /* 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ @@ -64,8 +70,7 @@ 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. */ +/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ void leave_raw_mode() @@ -127,8 +132,10 @@ enter_non_blocking() 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. */ +/* + * 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) @@ -137,8 +144,10 @@ window_change_handler(int sig) signal(SIGWINCH, window_change_handler); } -/* Signal handler for signals that cause the program to terminate. These - signals must be trapped to restore terminal modes. */ +/* + * Signal handler for signals that cause the program to terminate. These + * signals must be trapped to restore terminal modes. + */ void signal_handler(int sig) @@ -152,8 +161,10 @@ signal_handler(int sig) fatal("Killed by signal %d.", sig); } -/* Returns current time in seconds from Jan 1, 1970 with the maximum available - resolution. */ +/* + * Returns current time in seconds from Jan 1, 1970 with the maximum + * available resolution. + */ double get_current_time() @@ -163,9 +174,11 @@ get_current_time() 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. */ +/* + * 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() @@ -173,13 +186,14 @@ 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 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."); @@ -187,22 +201,22 @@ client_check_initial_eof_on_stdin() packet_start(SSH_CMSG_EOF); packet_send(); } else { - /* Enter non-blocking mode for stdin. */ 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. */ + /* 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. */ + /* + * 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 { @@ -210,13 +224,14 @@ client_check_initial_eof_on_stdin() stdin_bytes += 1; } } - /* Leave non-blocking mode. */ leave_non_blocking(); } } -/* Get packets from the connection input buffer, and process them as long - as there are packets available. */ +/* + * Get packets from the connection input buffer, and process them as long as + * there are packets available. + */ void client_process_buffered_input_packets() @@ -255,8 +270,10 @@ client_process_buffered_input_packets() /* Acknowledge the exit. */ packet_start(SSH_CMSG_EXIT_CONFIRMATION); packet_send(); - /* Must wait for packet to be sent since we are - exiting the loop. */ + /* + * 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; @@ -300,20 +317,24 @@ client_process_buffered_input_packets() 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. */ + /* + * 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. */ +/* + * Make packets from buffered stdin data, and buffer them for sending to the + * connection. + */ void client_make_packets_from_stdin_data() @@ -339,10 +360,12 @@ client_make_packets_from_stdin_data() } } -/* 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. */ +/* + * 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() @@ -367,8 +390,10 @@ client_check_window_change() } } -/* Waits until the client can do something (some data becomes available on - one of the file descriptors). */ +/* + * 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) @@ -382,8 +407,10 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) 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. */ + /* + * 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); @@ -408,13 +435,14 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) 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. */ + /* + * 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]; @@ -446,11 +474,12 @@ client_suspend_self() buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); - /* Leave raw mode. */ leave_raw_mode(); - /* Free (and clear) the buffer to reduce the amount of data that - gets written to swap. */ + /* + * 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); @@ -474,7 +503,6 @@ client_suspend_self() buffer_init(&stdout_buffer); buffer_init(&stderr_buffer); - /* Re-enter raw mode. */ enter_raw_mode(); } @@ -484,8 +512,10 @@ 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. */ + /* + * 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)); @@ -498,9 +528,10 @@ client_process_input(fd_set * readset) 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. */ + /* + * 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; @@ -520,9 +551,11 @@ client_process_input(fd_set * 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. */ + /* + * 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)); @@ -530,32 +563,35 @@ client_process_input(fd_set * readset) } /* 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. */ + /* + * 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. */ + /* + * 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. */ + /* + * 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]; - /* Check if we have a pending escape - character. */ if (escape_pending) { /* We have previously seen an escape character. */ /* Clear the flag now. */ @@ -584,12 +620,16 @@ client_process_input(fd_set * readset) continue; case '&': - /* Detach the program (continue to serve connections, - but put in background and no more new connections). */ + /* + * 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. */ + /* + * 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(); @@ -646,22 +686,28 @@ Supported escape sequences:\r\n\ default: if (ch != escape_char) { - /* Escape character followed by non-special character. - Append both to the input buffer. */ + /* + * 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. */ + /* + * 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. */ + /* + * 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; @@ -669,8 +715,10 @@ Supported escape sequences:\r\n\ } } - /* Normal character. Record whether it was a newline, and append it to the - buffer. */ + /* + * 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); @@ -696,8 +744,10 @@ client_process_output(fd_set * writeset) if (errno == EAGAIN) len = 0; else { - /* An error or EOF was encountered. Put - an error message to stderr buffer. */ + /* + * 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); @@ -717,8 +767,7 @@ client_process_output(fd_set * writeset) if (errno == EAGAIN) len = 0; else { - /* EOF or error, but can't even print - error message. */ + /* EOF or error, but can't even print error message. */ quit_pending = 1; return; } @@ -728,11 +777,12 @@ client_process_output(fd_set * writeset) } } -/* 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. */ +/* + * 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) @@ -776,7 +826,6 @@ client_loop(int have_pty, int escape_char_arg) if (have_pty) signal(SIGWINCH, window_change_handler); - /* Enter raw mode if have a pseudo terminal. */ if (have_pty) enter_raw_mode(); @@ -787,27 +836,35 @@ client_loop(int have_pty, int escape_char_arg) while (!quit_pending) { fd_set readset, writeset; - /* Precess buffered packets sent by the server. */ + /* 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. */ + /* + * 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. */ + /* + * 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. */ + /* + * 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). */ + /* + * 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) @@ -816,16 +873,19 @@ client_loop(int have_pty, int escape_char_arg) /* Do channel operations. */ channel_after_select(&readset, &writeset); - /* Process input from the connection and from stdin. - Buffer any data that is available. */ + /* + * 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). */ + /* + * 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. */ + /* Send as much buffered packet data as possible to the sender. */ if (FD_ISSET(connection_out, &writeset)) packet_write_poll(); } @@ -839,8 +899,10 @@ client_loop(int have_pty, int escape_char_arg) /* Stop listening for connections. */ channel_stop_listening(); - /* In interactive mode (with pseudo tty) display a message - indicating that the connection has been closed. */ + /* + * 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)); @@ -868,7 +930,6 @@ client_loop(int have_pty, int escape_char_arg) buffer_consume(&stderr_buffer, len); } - /* Leave raw mode. */ if (have_pty) leave_raw_mode(); @@ -1,5 +1,34 @@ +/* + * 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.2 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: compat.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); #include "ssh.h" @@ -1,4 +1,32 @@ -/* RCSID("$Id: compat.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ +/* + * 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.3 1999/11/25 00:54:59 damien Exp $"); */ #ifndef COMPAT_H #define COMPAT_H @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: compress.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: compress.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); #include "ssh.h" #include "buffer.h" @@ -23,8 +23,10 @@ RCSID("$Id: compress.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); static z_stream incoming_stream; static z_stream outgoing_stream; -/* Initializes compression; level is compression level from 1 to 9 - (as in gzip). */ +/* + * Initializes compression; level is compression level from 1 to 9 + * (as in gzip). + */ void buffer_compress_init(int level) @@ -53,13 +55,14 @@ buffer_compress_uninit() 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. */ +/* + * 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) @@ -106,13 +109,14 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer) 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. */ +/* + * 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) @@ -145,9 +149,11 @@ buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) 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. */ + /* + * 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"); @@ -13,34 +13,38 @@ * */ -/* RCSID("$Id: compress.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: compress.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */ #ifndef COMPRESS_H #define COMPRESS_H -/* Initializes compression; level is compression level from 1 to 9 (as in - gzip). */ +/* + * 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. */ +/* + * 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. */ +/* + * 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 */ @@ -13,13 +13,15 @@ * */ -/* RCSID("$Id: crc32.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: crc32.h,v 1.3 1999/11/25 00:54:59 damien 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. */ +/* + * 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/fingerprint.c b/fingerprint.c index 54fc7e9b..f032a514 100644 --- a/fingerprint.c +++ b/fingerprint.c @@ -1,5 +1,34 @@ +/* + * Copyright (c) 1999 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include "includes.h" -RCSID("$Id: fingerprint.c,v 1.3 1999/11/24 00:26:01 deraadt Exp $"); +RCSID("$Id: fingerprint.c,v 1.4 1999/11/24 16:15:25 markus Exp $"); #include "ssh.h" #include "xmalloc.h" diff --git a/fingerprint.h b/fingerprint.h index 8c603aa1..fbb0d4c4 100644 --- a/fingerprint.h +++ b/fingerprint.h @@ -1,4 +1,32 @@ -/* RCSID("$Id: fingerprint.h,v 1.2 1999/11/24 00:26:02 deraadt Exp $"); */ +/* + * 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 @@ -14,16 +14,18 @@ */ #include "includes.h" -RCSID("$Id: hostfile.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: hostfile.c,v 1.6 1999/11/25 00:54:59 damien Exp $"); #include "packet.h" #include "ssh.h" -/* Reads a multiple-precision integer in hex 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. */ +/* + * Reads a multiple-precision integer in hex 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) @@ -32,7 +34,8 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value) int len, old; /* Skip any leading whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++); + for (; *cp == ' ' || *cp == '\t'; cp++) + ; /* Check that it begins with a hex digit. */ if (*cp < '0' || *cp > '9') @@ -42,7 +45,8 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value) *cpp = cp; /* Move forward until all hex digits skipped. */ - for (; *cp >= '0' && *cp <= '9'; cp++); + for (; *cp >= '0' && *cp <= '9'; cp++) + ; /* Compute the length of the hex number. */ len = cp - *cpp; @@ -51,7 +55,6 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value) old = *cp; *cp = 0; - /* Parse the number. */ if (BN_dec2bn(&value, *cpp) == 0) return 0; @@ -64,8 +67,10 @@ auth_rsa_read_bignum(char **cpp, BIGNUM * value) 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. */ +/* + * 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) @@ -74,7 +79,8 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) char *cp; /* Skip leading whitespace. */ - for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++); + for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) + ; /* Get number of bits. */ if (*cp < '0' || *cp > '9') @@ -91,7 +97,8 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) return 0; /* Skip trailing whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++); + for (; *cp == ' ' || *cp == '\t'; cp++) + ; /* Return results. */ *cpp = cp; @@ -99,10 +106,12 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) 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. */ +/* + * 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) @@ -121,18 +130,19 @@ match_hostname(const char *host, const char *pattern, unsigned int len) } else negated = 0; - /* Extract the subpattern up to a comma or end. Convert - the subpattern to lowercase. */ + /* + * 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] != ','; + 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 the subpattern was terminated by a comma, skip the comma. */ if (i < len && pattern[i] == ',') i++; @@ -142,24 +152,25 @@ match_hostname(const char *host, const char *pattern, unsigned int len) /* Try to match the subpattern against the host name. */ if (match_pattern(host, sub)) { if (negated) - return 0; /* Fail if host matches - any negated subpattern. */ + 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 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. */ +/* + * 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, @@ -180,9 +191,11 @@ check_host_in_hostfile(const char *filename, const char *host, /* 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. */ + /* + * 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; /* size of modulus 'n' */ @@ -193,15 +206,15 @@ check_host_in_hostfile(const char *filename, const char *host, cp = line; linenum++; - /* Skip any leading whitespace. */ - for (; *cp == ' ' || *cp == '\t'; cp++); - - /* Ignore comment lines and empty lines. */ + /* 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++); + for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) + ; /* Check if the host name matches. */ if (!match_hostname(host, cp, (unsigned int) (cp2 - cp))) @@ -210,8 +223,10 @@ check_host_in_hostfile(const char *filename, const char *host, /* Got a match. Skip host name. */ cp = cp2; - /* Extract the key from the line. This will skip any - leading whitespace. Ignore badly formatted lines. */ + /* + * 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; @@ -228,21 +243,27 @@ check_host_in_hostfile(const char *filename, const char *host, 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. */ + /* + * 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 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. */ +/* + * 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, @@ -87,8 +87,10 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #define _PATH_RSH "/usr/bin/rsh" #endif /* _PATH_RSH */ -/* Define this to use pipes instead of socketpairs for communicating with the - client program. Socketpairs do not seem to work on all systems. */ +/* + * Define this to use pipes instead of socketpairs for communicating with the + * client program. Socketpairs do not seem to work on all systems. + */ #define USE_PIPES 1 #endif /* INCLUDES_H */ @@ -1,11 +1,9 @@ /* - * * Shared versions of debug(), log(), etc. - * -*/ + */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.5 1999/11/24 00:26:02 deraadt Exp $"); +RCSID("$OpenBSD: log.c,v 1.6 1999/11/24 19:53:47 markus Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -18,7 +18,7 @@ */ #include "includes.h" -RCSID("$Id: login.c,v 1.3 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: login.c,v 1.4 1999/11/25 00:54:59 damien Exp $"); #include <utmp.h> #include "ssh.h" @@ -30,12 +30,16 @@ RCSID("$Id: login.c,v 1.3 1999/11/24 13:26:22 damien Exp $"); # include <lastlog.h> #endif -/* 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. 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. */ +/* + * 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, @@ -64,8 +68,10 @@ get_last_login_time(uid_t uid, const char *logname, return ll.ll_time; } -/* Records that the user has logged in. I these parts of operating systems - were more standardized. */ +/* + * 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, @@ -95,9 +101,10 @@ record_login(int pid, const char *ttyname, const char *user, uid_t uid, /* 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) */ + /* + * 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. */ @@ -14,12 +14,14 @@ */ #include "includes.h" -RCSID("$Id: match.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: match.c,v 1.3 1999/11/25 00:54:59 damien 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. */ +/* + * 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) @@ -29,7 +31,6 @@ match_pattern(const char *s, const char *pattern) if (!*pattern) return !*s; - /* Process '*'. */ if (*pattern == '*') { /* Skip the asterisk. */ pattern++; @@ -40,9 +41,11 @@ match_pattern(const char *s, const char *pattern) /* 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. */ + /* + * 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)) @@ -50,26 +53,28 @@ match_pattern(const char *s, const char *pattern) /* Failed. */ return 0; } - /* Move ahead one character at a time and try to - match at each position. */ + /* + * 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. */ + /* + * 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. */ + /* 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. */ + /* Move to the next character, both in string and in pattern. */ s++; pattern++; } @@ -13,14 +13,16 @@ * precision integers. */ -/* RCSID("$Id: mpaux.h,v 1.3 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: mpaux.h,v 1.4 1999/11/25 00:54:59 damien 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. */ +/* + * 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], @@ -1,5 +1,34 @@ +/* + * 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.2 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: nchan.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); #include "ssh.h" @@ -173,9 +202,10 @@ chan_send_oclose(Channel *c) 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) - error("chan_shutdown_write failed for #%d/fd%d: %.100s", + debug("chan_shutdown_write failed for #%d/fd%d: %.100s", c->self, c->sock, strerror(errno)); } static void @@ -1,4 +1,33 @@ -/* RCSID("$Id: nchan.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ +/* + * 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.3 1999/11/25 00:54:59 damien Exp $"); */ #ifndef NCHAN_H #define NCHAN_H @@ -1,3 +1,31 @@ +.\" +.\" 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 @@ -15,7 +15,7 @@ */ #include "includes.h" -RCSID("$Id: packet.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: packet.c,v 1.6 1999/11/25 00:54:59 damien Exp $"); #include "xmalloc.h" #include "buffer.h" @@ -29,15 +29,19 @@ RCSID("$Id: packet.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); #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. */ +/* + * 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. */ +/* + * 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. */ @@ -76,8 +80,10 @@ 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. */ +/* + * 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) @@ -171,8 +177,10 @@ 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. */ +/* + * 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) @@ -184,8 +192,10 @@ packet_start_compression(int level) buffer_compress_init(level); } -/* Encrypts the given number of bytes, copying from src to dest. - bytes is known to be a multiple of 8. */ +/* + * 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, @@ -194,8 +204,10 @@ packet_encrypt(CipherContext * cc, void *dest, void *src, 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. */ +/* + * 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, @@ -206,8 +218,10 @@ packet_decrypt(CipherContext * cc, void *dest, void *src, 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) */ + /* + * 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: @@ -224,9 +238,11 @@ packet_decrypt(CipherContext * cc, void *dest, void *src, 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. */ +/* + * 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, @@ -283,8 +299,10 @@ 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. */ +/* + * Finalizes and sends the packet. If the encryption key has been set, + * encrypts the packet before sending. + */ void packet_send() @@ -294,8 +312,10 @@ packet_send() unsigned int checksum; u_int32_t rand = 0; - /* If using packet compression, compress the payload of the - outgoing packet. */ + /* + * If using packet compression, compress the payload of the outgoing + * packet. + */ if (packet_compression) { buffer_clear(&compression_buffer); /* Skip padding. */ @@ -348,14 +368,18 @@ packet_send() 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. */ + /* + * 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. */ +/* + * 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) @@ -379,12 +403,16 @@ packet_read(int *payload_len_ptr) /* 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. */ + /* + * 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) @@ -397,8 +425,10 @@ packet_read(int *payload_len_ptr) /* 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. */ +/* + * 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) @@ -516,8 +546,10 @@ restart: return (unsigned char) buf[0]; } -/* Buffers the given amount of input characters. This is intended to be - used together with packet_read_poll. */ +/* + * 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) @@ -543,8 +575,10 @@ 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. */ +/* + * 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) @@ -552,25 +586,27 @@ 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. */ +/* + * 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 -* +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. */ +/* + * 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,...) @@ -588,10 +624,12 @@ packet_send_debug(const char *fmt,...) 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. */ +/* + * 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,...) @@ -603,8 +641,10 @@ packet_disconnect(const char *fmt,...) fatal("packet_disconnect called recursively."); disconnecting = 1; - /* Format the message. Note that the caller must make sure the - message is of limited size. */ + /* + * 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); @@ -625,8 +665,7 @@ packet_disconnect(const char *fmt,...) fatal("Disconnecting: %.100s", buf); } -/* Checks if there is any buffered output, and tries to write some of the - output. */ +/* Checks if there is any buffered output, and tries to write some of the output. */ void packet_write_poll() @@ -644,8 +683,10 @@ packet_write_poll() } } -/* Calls packet_write_poll repeatedly until all pending output data has - been written. */ +/* + * Calls packet_write_poll repeatedly until all pending output data has been + * written. + */ void packet_write_wait() @@ -689,8 +730,10 @@ packet_set_interactive(int interactive, int keepalives) /* Record that we are in interactive mode. */ interactive_mode = interactive; - /* Only set socket options if using a socket (as indicated by the - descriptors being the same). */ + /* + * Only set socket options if using a socket (as indicated by the + * descriptors being the same). + */ if (connection_in != connection_out) return; @@ -701,8 +744,10 @@ packet_set_interactive(int interactive, int keepalives) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); } if (interactive) { - /* Set IP options for an interactive connection. Use - IPTOS_LOWDELAY and TCP_NODELAY. */ + /* + * 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) @@ -711,8 +756,10 @@ packet_set_interactive(int interactive, int keepalives) sizeof(on)) < 0) error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); } else { - /* Set IP options for a non-interactive connection. Use - IPTOS_THROUGHPUT. */ + /* + * 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) @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: packet.h,v 1.6 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: packet.h,v 1.7 1999/11/25 00:54:59 damien Exp $"); */ #ifndef PACKET_H #define PACKET_H @@ -27,10 +27,11 @@ #include <ssl/bn.h> #endif -/* 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. */ +/* + * 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. */ @@ -42,20 +43,25 @@ 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ @@ -64,8 +70,10 @@ 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. */ +/* + * 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. */ @@ -86,28 +94,35 @@ 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ @@ -116,34 +131,41 @@ 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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,...); -/* 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. */ +/* + * 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,...); -/* Checks if there is any buffered output, and tries to write some of the - output. */ +/* 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. */ @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: pty.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: pty.c,v 1.5 1999/11/25 00:54:59 damien Exp $"); #include "pty.h" #include "ssh.h" @@ -32,10 +32,12 @@ RCSID("$Id: pty.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); #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). */ +/* + * 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) @@ -52,8 +54,10 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf) 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 */ + /* + * _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); @@ -72,8 +76,10 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf) 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.) */ + /* + * 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; @@ -103,8 +109,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf) close(*ptyfd); return 0; } - /* Push the appropriate streams modules, as described in Solaris - pts(7). */ + /* 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) @@ -138,8 +143,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf) /* BSD-style pty code. */ char buf[64]; int i; - const char *ptymajors = - "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ptyminors = "0123456789abcdef"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; @@ -198,8 +202,10 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) if (setsid() < 0) error("setsid: %.100s", strerror(errno)); - /* Verify that we are successfully disconnected from the - controlling tty. */ + /* + * 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."); @@ -208,9 +214,11 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) /* 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. */ + /* + * 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); @@ -13,23 +13,29 @@ * tty. */ -/* RCSID("$Id: pty.h,v 1.2 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: pty.h,v 1.3 1999/11/25 00:54:59 damien 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). */ +/* + * 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); -/* Releases the tty. Its ownership is returned to root, and permissions to - 0666. */ +/* + * 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. */ +/* + * 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. */ @@ -74,9 +74,11 @@ uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize) 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. */ + /* + * 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; @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: readconf.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: readconf.c,v 1.6 1999/11/25 00:54:59 damien Exp $"); #include "ssh.h" #include "cipher.h" @@ -158,8 +158,10 @@ static struct { #define WHITESPACE " \t\r\n" -/* Adds a local TCP/IP port forward to options. Never returns if there - is an error. */ +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ void add_local_forward(Options *options, int port, const char *host, @@ -179,8 +181,10 @@ add_local_forward(Options *options, int port, const char *host, fwd->host_port = host_port; } -/* Adds a remote TCP/IP port forward to options. Never returns if there - is an error. */ +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ void add_remote_forward(Options *options, int port, const char *host, @@ -196,8 +200,10 @@ add_remote_forward(Options *options, int port, const char *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. */ +/* + * 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) @@ -205,7 +211,7 @@ parse_token(const char *cp, const char *filename, int linenum) unsigned int i; for (i = 0; keywords[i].name; i++) - if (strcmp(cp, keywords[i].name) == 0) + if (strcasecmp(cp, keywords[i].name) == 0) return keywords[i].opcode; fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", @@ -213,15 +219,17 @@ parse_token(const char *cp, const char *filename, int linenum) return oBadOption; } -/* Processes a single option line as used in the configuration files. - This only sets those values that have not already been set. */ +/* + * 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; + char buf[256], *cp, *string, **charptr, *cp2; int opcode, *intptr, value, fwd_port, fwd_host_port; /* Skip leading whitespace. */ @@ -229,21 +237,14 @@ process_config_line(Options *options, const char *host, if (!*cp || *cp == '\n' || *cp == '#') return 0; - /* Get the keyword. (Each line is supposed to begin with a - keyword). */ + /* Get the keyword. (Each line is supposed to begin with a keyword). */ cp = strtok(cp, WHITESPACE); - { - char *t = cp; - for (; *t != 0; t++) - if ('A' <= *t && *t <= 'Z') - *t = *t - 'A' + 'a'; /* tolower */ - - } opcode = parse_token(cp, filename, linenum); switch (opcode) { case oBadOption: - return -1; /* don't panic, but count bad options */ + /* don't panic, but count bad options */ + return -1; /* NOTREACHED */ case oForwardAgent: intptr = &options->forward_agent; @@ -419,17 +420,11 @@ parse_int: fatal("%.200s line %d: Missing argument.", filename, linenum); if (cp[0] < '0' || cp[0] > '9') fatal("%.200s line %d: Bad number.", filename, linenum); -#if 0 - value = atoi(cp); -#else - { - char *ptr; - value = strtol(cp, &ptr, 0); /* Octal, decimal, or - hex format? */ - if (cp == ptr) - fatal("%.200s line %d: Bad number.", filename, linenum); - } -#endif + + /* 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; @@ -506,8 +501,7 @@ parse_int: *activep = 1; break; } - /* Avoid garbage check below, as strtok already returned - NULL. */ + /* Avoid garbage check below, as strtok already returned NULL. */ return 0; case oEscapeChar: @@ -544,9 +538,11 @@ parse_int: } -/* 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. */ +/* + * 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) @@ -563,8 +559,10 @@ read_config_file(const char *filename, const char *host, Options *options) debug("Reading configuration data %.200s", filename); - /* Mark that we are now processing the options. This flag is - turned on/off by Host specifications. */ + /* + * 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)) { @@ -579,10 +577,12 @@ read_config_file(const char *filename, const char *host, Options *options) 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. */ +/* + * 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) @@ -628,8 +628,10 @@ initialize_options(Options * options) 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. */ +/* + * 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) @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: readconf.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: readconf.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */ #ifndef READCONF_H #define READCONF_H @@ -85,42 +85,53 @@ typedef struct { } 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. */ +/* + * 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. */ +/* + * 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 */ +/* + * 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. */ +/* + * 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. */ +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ void add_local_forward(Options * options, int port, const char *host, int host_port); -/* Adds a remote TCP/IP port forward to options. Never returns if there - is an error. */ +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ void add_remote_forward(Options * options, int port, const char *host, int host_port); - #endif /* READCONF_H */ @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: readpass.c,v 1.2 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: readpass.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -38,10 +38,12 @@ intr_handler(int sig) kill(getpid(), sig); } -/* Reads a passphrase from /dev/tty with echo turned off. Returns the - passphrase (allocated with xmalloc). Exits if EOF is encountered. - The passphrase if read from stdin if from_stdin is true (as is the - case with ssh-keygen). */ +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc). Exits if EOF is encountered. The + * passphrase if read from stdin if from_stdin is true (as is the case with + * ssh-keygen). + */ char * read_passphrase(const char *prompt, int from_stdin) @@ -53,8 +55,10 @@ read_passphrase(const char *prompt, int from_stdin) if (from_stdin) f = stdin; else { - /* Read the passphrase from /dev/tty to make it possible - to ask it even when stdin has been redirected. */ + /* + * Read the passphrase from /dev/tty to make it possible to + * ask it even when stdin has been redirected. + */ f = fopen("/dev/tty", "r"); if (!f) { /* No controlling terminal and no DISPLAY. Nowhere to read. */ @@ -101,8 +105,10 @@ read_passphrase(const char *prompt, int from_stdin) *strchr(buf, '\n') = 0; /* Allocate a copy of the passphrase. */ cp = xstrdup(buf); - /* Clear the buffer so we don\'t leave copies of the passphrase - laying around. */ + /* + * Clear the buffer so we don\'t leave copies of the passphrase + * laying around. + */ memset(buf, 0, sizeof(buf)); /* Print a newline since the prompt probably didn\'t have one. */ fprintf(stderr, "\n"); @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$Id: rsa.c,v 1.4 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: rsa.c,v 1.5 1999/11/25 00:54:59 damien Exp $"); #include "rsa.h" #include "ssh.h" @@ -55,9 +55,11 @@ rsa_alive() 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. */ +/* + * 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) @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: rsa.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: rsa.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */ #ifndef RSA_H #define RSA_H @@ -33,8 +33,10 @@ /* 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. */ +/* + * 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)); @@ -45,7 +45,7 @@ */ #include "includes.h" -RCSID("$Id: scp.c,v 1.9 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: scp.c,v 1.10 1999/11/25 00:54:59 damien Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -97,9 +97,11 @@ 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. */ +/* + * 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) @@ -110,8 +112,10 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) 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. */ + /* + * 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. */ @@ -970,7 +974,7 @@ run_err(const char *fmt,...) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scp.c,v 1.9 1999/11/24 13:26:22 damien Exp $ + * $Id: scp.c,v 1.10 1999/11/25 00:54:59 damien Exp $ */ char * @@ -1142,7 +1146,7 @@ progressmeter(int flag) (void) gettimeofday(&now, (struct timezone *) 0); cursize = statbytes; if (totalbytes != 0) { - ratio = cursize * 100.0 / totalbytes; + ratio = 100.0 * cursize / totalbytes; ratio = MAX(ratio, 0); ratio = MIN(ratio, 100); } else @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$Id: servconf.c,v 1.6 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: servconf.c,v 1.7 1999/11/25 00:54:59 damien Exp $"); #include "ssh.h" #include "servconf.h" @@ -212,8 +212,10 @@ static struct { { NULL, 0 } }; -/* Returns the number of the token pointed to by cp of length len. - Never returns if the token is not known. */ +/* + * 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, @@ -222,7 +224,7 @@ parse_token(const char *cp, const char *filename, unsigned int i; for (i = 0; keywords[i].name; i++) - if (strcmp(cp, keywords[i].name) == 0) + if (strcasecmp(cp, keywords[i].name) == 0) return keywords[i].opcode; fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", @@ -254,13 +256,6 @@ read_server_config(ServerOptions *options, const char *filename) if (!*cp || *cp == '#') continue; cp = strtok(cp, WHITESPACE); - { - char *t = cp; - for (; *t != 0; t++) - if ('A' <= *t && *t <= 'Z') - *t = *t - 'A' + 'a'; /* tolower */ - - } opcode = parse_token(cp, filename, linenum); switch (opcode) { case sBadOption: @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: servconf.h,v 1.4 1999/11/24 13:26:22 damien Exp $"); */ +/* RCSID("$Id: servconf.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */ #ifndef SERVCONF_H #define SERVCONF_H @@ -84,12 +84,16 @@ typedef struct { unsigned int num_deny_groups; char *deny_groups[MAX_DENY_GROUPS]; } ServerOptions; -/* Initializes the server options to special values that indicate that they - have not yet been set. */ +/* + * 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. */ +/* + * 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. */ diff --git a/serverloop.c b/serverloop.c index fc959bae..683598ef 100644 --- a/serverloop.c +++ b/serverloop.c @@ -33,8 +33,10 @@ 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. */ +/* + * 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. */ @@ -87,9 +89,11 @@ process_buffered_input_packets() break; case SSH_CMSG_EOF: - /* Eof from the client. The stdin descriptor to - the program will be closed when all buffered - data has drained. */ + /* + * 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; @@ -140,13 +144,15 @@ process_buffered_input_packets() 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. */ + /* + * 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); } @@ -230,14 +236,18 @@ retry_select: /* Initialize select() masks. */ FD_ZERO(readset); - /* Read packets from the client unless we have too much buffered - stdin or channel data. */ + /* + * 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 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); @@ -249,8 +259,10 @@ retry_select: /* Set masks for channel descriptors. */ channel_prepare_select(readset, writeset); - /* If we have buffered packet data going to the client, mark that - descriptor. */ + /* + * If we have buffered packet data going to the client, mark that + * descriptor. + */ if (packet_have_data_to_write()) FD_SET(connection_out, writeset); @@ -263,8 +275,10 @@ retry_select: 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 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; @@ -305,9 +319,10 @@ process_input(fd_set * readset) 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. */ + /* + * 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; @@ -456,11 +471,12 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg) 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 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; @@ -471,8 +487,10 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg) /* 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 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); @@ -484,16 +502,16 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg) #endif fdin = -1; } - /* Make packets from buffered stderr data to send to the - client. */ + /* 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. */ + /* + * 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 && @@ -510,9 +528,11 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg) 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. */ + /* + * 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()) @@ -604,11 +624,13 @@ quit: 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. */ + /* + * 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); @@ -9,7 +9,7 @@ .\" .\" Created: Sat Apr 22 23:55:14 1995 ylo .\" -.\" $Id: ssh-add.1,v 1.4 1999/11/17 06:29:08 damien Exp $ +.\" $Id: ssh-add.1,v 1.5 1999/11/25 00:54:59 damien Exp $ .\" .Dd September 25, 1999 .Dt SSH-ADD 1 @@ -71,8 +71,11 @@ terminal if it was run from a terminal. If .Nm does not have a terminal associated with it but .Ev DISPLAY -is set, it -will open an X11 window to read the passphrase. This is particularly +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 @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$Id: ssh-add.c,v 1.13 1999/11/24 13:26:22 damien Exp $"); +RCSID("$Id: ssh-add.c,v 1.14 1999/11/25 00:54:59 damien Exp $"); #include "rsa.h" #include "ssh.h" @@ -15,10 +15,6 @@ RCSID("$Id: ssh-add.c,v 1.13 1999/11/24 13:26:22 damien Exp $"); #include "authfd.h" #include "fingerprint.h" -#ifdef USE_EXTERNAL_ASKPASS -int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment); -#endif /* USE_EXTERNAL_ASKPASS */ - #ifdef HAVE___PROGNAME extern char *__progname; #else /* HAVE___PROGNAME */ @@ -54,13 +50,53 @@ delete_all(AuthenticationConnection *ac) 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; + 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(); @@ -70,29 +106,26 @@ add_file(AuthenticationConnection *ac, const char *filename) } RSA_free(public_key); + if (!interactive && getenv("DISPLAY")) + askpass = getenv("SSH_ASKPASS"); + /* At first, try empty passphrase */ success = load_private_key(filename, "", key, &comment); if (!success) { - printf("Need passphrase for %s (%s).\n", filename, saved_comment); - if (!isatty(STDIN_FILENO)) { -#ifdef USE_EXTERNAL_ASKPASS - int prompts = 3; - while (prompts && !success) { - success = askpass(filename, key, saved_comment, &comment); - prompts--; - } - if (!success) { - xfree(saved_comment); - return; - } -#else /* !USE_EXTERNAL_ASKPASS */ - xfree(saved_comment); - return; -#endif /* USE_EXTERNAL_ASKPASS */ + printf("Need passphrase for %.200s\n", filename); + if (!interactive && askpass == NULL) { + xfree(saved_comment); + return; } - - while (!success) { - char *pass = read_passphrase("Enter passphrase: ", 1); + 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); @@ -103,7 +136,7 @@ add_file(AuthenticationConnection *ac, const char *filename) xfree(pass); if (success) break; - printf("Bad passphrase.\n"); + strlcpy(msg, "Bad passphrase, try again", sizeof msg); } } xfree(saved_comment); @@ -222,85 +255,3 @@ main(int argc, char **argv) ssh_close_authentication_connection(ac); exit(0); } - -#ifdef USE_EXTERNAL_ASKPASS -int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment) -{ - int pipes[2]; - char buf[1024]; - int tmp; - pid_t child; - FILE *pipef; - - /* Check that we are X11-capable */ - if (getenv("DISPLAY") == NULL) - exit(1); - - if (pipe(pipes) == -1) { - fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno)); - exit(1); - } - - if (fflush(NULL) == EOF) { - fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno)); - exit(1); - } - - child = fork(); - if (child == -1) { - fprintf(stderr, "Cannot fork: %s\n", strerror(errno)); - exit(1); - } - - if (child == 0) { - /* In child */ - - close(pipes[0]); - if (dup2(pipes[1], 1) ==-1) { - fprintf(stderr, "dup2 failed: %s\n", strerror(errno)); - exit(1); - } - - tmp = snprintf(buf, sizeof(buf), "Need passphrase for %s", saved_comment); - /* skip the prompt if it won't fit */ - if ((tmp < 0) || (tmp >= sizeof(buf))) - tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", 0); - else - tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0); - - /* Shouldn't get this far */ - fprintf(stderr, "Executing ssh-askpass failed: %s\n", strerror(errno)); - exit(1); - } - - /* In parent */ - close(pipes[1]); - - if ((pipef = fdopen(pipes[0], "r")) == NULL) { - fprintf(stderr, "fdopen failed: %s\n", strerror(errno)); - exit(1); - } - - /* Read passphrase back from child, abort if none presented */ - if(fgets(buf, sizeof(buf), pipef) == NULL) - exit(1); - - fclose(pipef); - - if (strchr(buf, '\n')) - *strchr(buf, '\n') = 0; - - if (waitpid(child, NULL, 0) == -1) { - fprintf(stderr, "Waiting for child failed: %s\n", - strerror(errno)); - exit(1); - } - - /* Try password as it was presented */ - tmp = load_private_key(filename, buf, key, comment); - - memset(buf, 0, sizeof(buf)); - - return(tmp); -} -#endif /* USE_EXTERNAL_ASKPASS */ diff --git a/ssh-agent.c b/ssh-agent.c index 70c2a7f6..90c64ea8 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.22 1999/11/24 00:26:03 deraadt Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.23 1999/11/24 19:53:51 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -9,7 +9,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.22 1999/11/24 00:26:03 deraadt Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.23 1999/11/24 19:53:51 markus Exp $"); #include "ssh.h" #include "rsa.h" @@ -189,10 +189,12 @@ process_remove_identity(SocketEntry *e) /* 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. */ + /* + * 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) @@ -291,8 +293,10 @@ process_add_identity(SocketEntry *e) /* 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. */ + /* + * We already have this key. Clear and free the new + * data and return success. + */ RSA_free(k); xfree(identities[num_identities].comment); @@ -511,11 +515,7 @@ main(int ac, char **av) __progname); exit(1); } -#if defined(__GNU_LIBRARY__) - while ((ch = getopt(ac, av, "+cks")) != -1) { -#else while ((ch = getopt(ac, av, "cks")) != -1) { -#endif /* defined(__GNU_LIBRARY__) */ switch (ch) { case 'c': if (s_flag) @@ -579,8 +579,10 @@ main(int ac, char **av) 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. */ + /* + * 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"); @@ -597,9 +599,10 @@ main(int ac, char **av) 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. */ + /* + * 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"); diff --git a/ssh-keygen.c b/ssh-keygen.c index 6f2d426b..2b674676 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$Id: ssh-keygen.c,v 1.9 1999/11/24 13:26:23 damien Exp $"); +RCSID("$Id: ssh-keygen.c,v 1.10 1999/11/25 00:54:59 damien Exp $"); #include "rsa.h" #include "ssh.h" @@ -20,16 +20,19 @@ 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. */ +/* 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. */ +/* + * 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. */ +/* + * 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; @@ -136,13 +139,10 @@ do_change_passphrase(struct passwd *pw) if (!have_identity) ask_filename(pw, "Enter file in which the key is"); - /* Check if the file exists. */ 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); @@ -154,19 +154,16 @@ do_change_passphrase(struct passwd *pw) /* Try to load the file with empty passphrase. */ private_key = RSA_new(); if (!load_private_key(identity_file, "", private_key, &comment)) { - /* Read passphrase from the user. */ if (identity_passphrase) old_passphrase = xstrdup(identity_passphrase); else old_passphrase = read_passphrase("Enter old passphrase: ", 1); - /* Try to load using the passphrase. */ 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); } - /* Destroy the passphrase. */ memset(old_passphrase, 0, strlen(old_passphrase)); xfree(old_passphrase); } @@ -230,24 +227,24 @@ do_change_comment(struct passwd *pw) if (!have_identity) ask_filename(pw, "Enter file in which the key is"); - /* Check if the file exists. */ 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. */ + /* + * 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(); - /* Try to load the file with empty passphrase. */ + if (load_private_key(identity_file, "", private_key, &comment)) passphrase = xstrdup(""); else { - /* Read passphrase from the user. */ if (identity_passphrase) passphrase = xstrdup(identity_passphrase); else if (identity_new_passphrase) @@ -274,7 +271,6 @@ do_change_comment(struct passwd *pw) RSA_free(private_key); exit(1); } - /* Remove terminating newline from comment. */ if (strchr(new_comment, '\n')) *strchr(new_comment, '\n') = 0; } @@ -289,13 +285,10 @@ do_change_comment(struct passwd *pw) xfree(comment); exit(1); } - /* Destroy the passphrase and the private key in memory. */ memset(passphrase, 0, strlen(passphrase)); xfree(passphrase); RSA_free(private_key); - /* Save the public key in text format in a file with the same name - but .pub appended. */ strlcat(identity_file, ".pub", sizeof(identity_file)); f = fopen(identity_file, "w"); if (!f) { @@ -343,21 +336,18 @@ main(int ac, char **av) /* 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); } - /* Get user\'s passwd structure. We need this for the home - directory. */ + /* we need this for the home * directory. */ pw = getpwuid(getuid()); if (!pw) { printf("You don't exist, go away!\n"); exit(1); } - /* Parse command line arguments. */ + while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF) { switch (opt) { case 'b': @@ -416,14 +406,8 @@ main(int ac, char **av) } if (print_fingerprint) do_fingerprint(pw); - - /* If the user requested to change the passphrase, do it now. - This function never returns. */ if (change_passphrase) do_change_passphrase(pw); - - /* If the user requested to change the comment, do it now. This - function never returns. */ if (change_comment) do_change_comment(pw); @@ -484,11 +468,10 @@ passphrase_again: xfree(passphrase2); } - /* Create default commend field for the passphrase. The user can - later edit this field. */ 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); @@ -515,8 +498,6 @@ passphrase_again: if (!quiet) printf("Your identification has been saved in %s.\n", identity_file); - /* Save the public key in text format in a file with the same name - but .pub appended. */ strlcat(identity_file, ".pub", sizeof(identity_file)); f = fopen(identity_file, "w"); if (!f) { @@ -9,7 +9,7 @@ .\" .\" Created: Sat Apr 22 21:55:14 1995 ylo .\" -.\" $Id: ssh.1,v 1.9 1999/11/24 13:26:23 damien Exp $ +.\" $Id: ssh.1,v 1.10 1999/11/25 00:54:59 damien Exp $ .\" .Dd September 25, 1999 .Dt SSH 1 @@ -293,7 +293,7 @@ disables any escapes and makes the session fully transparent. .It Fl f Requests .Nm -to go to background after authentication. This is useful +to go to background just before command execution. This is useful if .Nm is going to ask for passwords or passphrases, but the user @@ -11,7 +11,7 @@ */ #include "includes.h" -RCSID("$Id: ssh.c,v 1.11 1999/11/24 13:26:23 damien Exp $"); +RCSID("$Id: ssh.c,v 1.12 1999/11/25 00:54:59 damien Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -30,35 +30,43 @@ const char *__progname = "ssh"; /* Flag indicating whether debug mode is on. This can be set on the command line. */ int debug_flag = 0; -/* Flag indicating whether to allocate a pseudo tty. This can be set on the command - line, and is automatically set if no command is given on the command line. */ int tty_flag = 0; -/* Flag indicating that nothing should be read from stdin. This can be set - on the command line. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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_in 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. */ +/* + * 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). */ @@ -165,8 +173,10 @@ main(int ac, char **av) uid_t original_effective_uid; int plen; - /* Save the original real uid. It will be needed later - (uid-swapping may clobber the real uid). */ + /* + * Save the original real uid. It will be needed later (uid-swapping + * may clobber the real uid). + */ original_real_uid = getuid(); original_effective_uid = geteuid(); @@ -177,18 +187,21 @@ main(int ac, char **av) 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). */ + /* + * 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. */ + /* + * 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. */ @@ -387,10 +400,11 @@ main(int ac, char **av) /* 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. */ + /* + * 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; @@ -474,11 +488,15 @@ main(int ac, char **av) 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 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 our superuser privileges. This must be done + * before permanently setting the uid. + */ restore_uid(); /* Switch to the original uid permanently. */ @@ -491,8 +509,10 @@ main(int ac, char **av) /* Restore our superuser privileges. */ restore_uid(); - /* Open a connection to the remote host. This needs root - privileges if rhosts_{rsa_}authentication is enabled. */ + /* + * 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, @@ -501,31 +521,38 @@ main(int ac, char **av) 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 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. */ - + /* + * 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. */ + /* + * 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) @@ -569,15 +596,6 @@ main(int ac, char **av) /* Close connection cleanly after attack. */ cipher_attack_detected = packet_disconnect; - /* If requested, fork and let ssh continue in the background. */ - if (fork_after_authentication_flag) { - int ret = fork(); - if (ret == -1) - fatal("fork failed: %.100s", strerror(errno)); - if (ret != 0) - exit(0); - setsid(); - } /* Enable compression if requested. */ if (options.compression) { debug("Requesting compression at level %d.", options.compression_level); @@ -653,12 +671,14 @@ main(int ac, char **av) 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 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; @@ -670,8 +690,10 @@ main(int ac, char **av) rand >>= 8; } } - /* Got local authentication reasonable information. - Request forwarding with authentication spoofing. */ + /* + * Got local authentication reasonable information. Request + * forwarding with authentication spoofing. + */ debug("Requesting X11 forwarding with authentication spoofing."); x11_request_forwarding_with_spoofing(proto, data); @@ -728,8 +750,15 @@ main(int ac, char **av) options.remote_forwards[i].host_port); } - /* If a command was specified on the command line, execute the - command now. Otherwise request the server to start a shell. */ + /* 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) @@ -13,7 +13,7 @@ * */ -/* RCSID("$Id: ssh.h,v 1.15 1999/11/24 13:26:23 damien Exp $"); */ +/* RCSID("$Id: ssh.h,v 1.16 1999/11/25 00:54:59 damien Exp $"); */ #ifndef SSH_H #define SSH_H @@ -25,9 +25,11 @@ #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. */ +/* + * 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. */ @@ -39,20 +41,28 @@ /* 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * Name for the service. The port named by this service overrides the + * default port if present. + */ #define SSH_SERVICE_NAME "ssh" #ifndef ETCDIR @@ -63,16 +73,16 @@ #define PIDDIR "/var/run" #endif /* PIDDIR */ -/* System-wide file containing host keys of known hosts. This file should be - world-readable. */ +/* + * System-wide file containing host keys of known hosts. This file should be + * world-readable. + */ #define SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts" -/* HOST_KEY_FILE /etc/ssh_host_key, - SERVER_CONFIG_FILE /etc/sshd_config, -and HOST_CONFIG_FILE /etc/ssh_config -are all defined in Makefile.in. Of these, ssh_host_key should be readable -only by root, whereas ssh_config should be world-readable. */ - +/* + * 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" @@ -89,73 +99,95 @@ only by root, whereas ssh_config should be world-readable. */ #define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" #endif /* ASKPASS_PROGRAM */ -/* The process id of the daemon listening for connections is saved - here to make it easier to kill the correct daemon when necessary. */ +/* + * 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). */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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.) */ +/* + * 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. */ +/* + * 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. */ +/* + * 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" -/* Additionally, the daemon may use ~/.rhosts and /etc/hosts.equiv if - rhosts authentication is enabled. */ - -/* Name of the environment variable containing the pathname of the - authentication socket. */ +/* + * 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. */ +/* + * Name of the environment variable containing the pathname of the + * authentication socket. + */ #define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" -/* 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. */ +/* + * 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.) */ +/* + * 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. */ +/* + * 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 @@ -163,20 +195,20 @@ only by root, whereas ssh_config should be world-readable. */ #define SSH_AUTH_TIS 5 #define SSH_AUTH_KERBEROS 6 #define SSH_PASS_KERBEROS_TGT 7 - /* 8 to 15 are reserved */ + /* 8 to 15 are reserved */ #define SSH_PASS_AFS_TOKEN 21 /* Protocol flags. These are bit masks. */ -#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes - * screen */ -#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain - * host */ - -/* Definition of message types. New values can be added, but old values - should not be removed or without careful consideration of the consequences - for compatibility. The maximum value is 254; value 255 is reserved - for future extension. */ - /* Message name *//* msg code *//* arguments */ +#define SSH_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 */ @@ -226,45 +258,54 @@ only by root, whereas ssh_config should be world-readable. */ /*------------ 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. */ +/* + * 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). */ +/* + * 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_in * addr); -/* Records that the user has logged out. This does many thigs normally - done by login(1) or init. */ +/* + * 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. */ +/* + * 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_in * hostaddr, int 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). */ +/* + * 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, @@ -272,41 +313,57 @@ ssh_login(int host_key_valid, RSA * host_key, const char *host, /*------------ 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). */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ @@ -315,16 +372,20 @@ int get_peer_port(int sock); /* Returns the port number of the remote host. */ int get_remote_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. */ +/* + * 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. */ +/* + * 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; @@ -332,43 +393,55 @@ 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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); @@ -418,9 +491,11 @@ 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. */ +/* + * 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(). */ @@ -431,9 +506,11 @@ void fatal_remove_cleanup(void (*proc) (void *context), void *context); /* 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. */ +/* + * 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. */ @@ -442,16 +519,20 @@ 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. */ +/* + * 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. */ +/* + * 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. */ @@ -473,8 +554,10 @@ void channel_input_open_failure(void); 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. */ +/* + * 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. */ @@ -483,92 +566,123 @@ 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. */ +/* + * 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. */ +/* + * 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(int port, const char *host, int remote_port); -/* 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. */ +/* + * 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(int port, const char *host, int 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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); -/* 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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. */ +/* + * 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*. */ +/* + * 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). */ +/* + * 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. */ @@ -582,9 +696,11 @@ struct envstring { #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. */ +/* + * 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); diff --git a/sshconnect.c b/sshconnect.c index 0657c37e..0b1c0901 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -8,7 +8,7 @@ */ #include "includes.h" -RCSID("$Id: sshconnect.c,v 1.14 1999/11/24 13:26:23 damien Exp $"); +RCSID("$Id: sshconnect.c,v 1.15 1999/11/25 00:54:59 damien Exp $"); #ifdef HAVE_OPENSSL #include <openssl/bn.h> @@ -142,8 +142,10 @@ ssh_create_socket(uid_t original_real_uid, int privileged) { 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 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; @@ -227,9 +229,11 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr, !anonymous && geteuid() == 0 && port < IPPORT_RESERVED); - /* Connect to the host. We use the user's uid in - the hope that it will help with the problems of - tcp_wrappers showing the remote uid as root. */ + /* + * Connect to the host. We use the user's uid in the + * hope that it will help with the problems of + * tcp_wrappers showing the remote uid as root. + */ temporarily_use_uid(original_real_uid); if (connect(sock, (struct sockaddr *) hostaddr, sizeof(*hostaddr)) >= 0) { @@ -270,8 +274,12 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr, !anonymous && geteuid() == 0 && port < IPPORT_RESERVED); - /* 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. */ + /* + * 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, (struct sockaddr *) hostaddr, sizeof(*hostaddr)) >= 0) { @@ -282,8 +290,12 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr, 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. */ + /* + * 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); } @@ -300,10 +312,11 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr, 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)); */ + /* + * 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)); */ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &on, sizeof(on)); linger.l_onoff = 1; linger.l_linger = 5; @@ -493,8 +506,10 @@ try_rsa_authentication(struct passwd * pw, const char *authfile) /* 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. */ + /* + * 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); @@ -514,8 +529,10 @@ try_rsa_authentication(struct passwd * pw, const char *authfile) 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. */ + /* + * 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': ", @@ -720,9 +737,11 @@ try_kerberos_authentication() 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. */ + /* + * 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) { @@ -894,8 +913,10 @@ ssh_exchange_identification() } buf[sizeof(buf) - 1] = 0; - /* Check that the versions match. In future this might accept - several versions and set appropriate flags to handle them. */ + /* + * 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); @@ -916,9 +937,11 @@ ssh_exchange_identification() } } #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. */ + /* + * 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); @@ -1086,10 +1109,7 @@ ssh_login(int host_key_valid, protocol_flags = packet_get_int(); packet_set_protocol_flags(protocol_flags); - /* Get supported cipher types. */ supported_ciphers = packet_get_int(); - - /* Get supported authentication types. */ supported_authentications = packet_get_int(); debug("Received server public key (%d bits) and host key (%d bits).", @@ -1099,11 +1119,12 @@ ssh_login(int host_key_valid, 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, SSH_SMSG_PUBLIC_KEY); - /* Compute the session id. */ compute_session_id(session_id, check_bytes, host_key->n, public_key->n); - /* Check if the host key is present in the user\'s list of known - hosts or in the systemwide list. */ + /* + * 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); @@ -1111,18 +1132,22 @@ ssh_login(int host_key_valid, host_status = check_host_in_hostfile(options.system_hostfile, host, host_key->e, host_key->n, file_key->e, file_key->n); - /* Force accepting of the host key for localhost and 127.0.0.1. - 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. */ + /* + * Force accepting of the host key for localhost and 127.0.0.1. 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. + */ if (local) { debug("Forcing accepting of host key for localhost."); host_status = HOST_OK; } - /* Also perform check for the ip address, skip the check if we are - localhost or the hostname was an ip address to begin with */ + /* + * 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(); @@ -1226,13 +1251,18 @@ ssh_login(int host_key_valid, 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 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 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; @@ -1241,11 +1271,13 @@ ssh_login(int host_key_valid, 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. */ + /* + * 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; } @@ -1255,9 +1287,11 @@ ssh_login(int host_key_valid, /* 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. */ + /* + * 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(); @@ -1265,9 +1299,11 @@ ssh_login(int host_key_valid, 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. */ + /* + * 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++) { @@ -1278,8 +1314,10 @@ ssh_login(int host_key_valid, 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). */ + /* + * 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) < @@ -1354,8 +1392,10 @@ ssh_login(int host_key_valid, /* 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. */ + /* + * 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."); @@ -1366,9 +1406,11 @@ ssh_login(int host_key_valid, 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. */ + /* + * 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. */ @@ -1410,8 +1452,10 @@ ssh_login(int host_key_valid, } #endif /* KRB4 */ - /* Use rhosts authentication if running in privileged socket and - we do not wish to remain anonymous. */ + /* + * 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."); @@ -1428,8 +1472,10 @@ ssh_login(int host_key_valid, packet_disconnect("Protocol error: got %d in response to rhosts auth", type); } - /* Try .rhosts or /etc/hosts.equiv authentication with RSA host - authentication. */ + /* + * 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)) @@ -1438,10 +1484,11 @@ ssh_login(int host_key_valid, /* 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. */ + /* + * 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; @@ -11,7 +11,7 @@ */ #include "includes.h" -RCSID("$Id: sshd.c,v 1.31 1999/11/24 23:42:08 damien Exp $"); +RCSID("$Id: sshd.c,v 1.32 1999/11/25 00:54:59 damien Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -65,12 +65,16 @@ char *av0; /* Saved arguments to main(). */ char **saved_argv; -/* This is set to the socket that the server is listening; this is used in - the SIGHUP signal handler. */ +/* + * This is set to the socket that the server is listening; this is used in + * the SIGHUP signal handler. + */ int listen_sock; -/* the client's version string, passed by sshd2 in compat mode. - if != NULL, sshd will skip the version-number exchange */ +/* + * 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. */ @@ -88,19 +92,23 @@ 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. */ +/* + * 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. */ +/* + * 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. */ @@ -466,7 +474,7 @@ main(int ac, char **av) 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/sshd_config)\n", ETCDIR); + 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"); @@ -614,13 +622,11 @@ main(int ac, char **av) setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); - /* Initialize the socket address. */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr = options.listen_addr; sin.sin_port = htons(options.port); - /* Bind the socket to the desired port. */ if (bind(listen_sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) { error("bind: %.100s", strerror(errno)); shutdown(listen_sock, SHUT_RDWR); @@ -628,12 +634,13 @@ main(int ac, char **av) fatal("Bind to port %d failed.", options.port); } 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. */ + /* + * 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()); @@ -666,8 +673,10 @@ main(int ac, char **av) /* Arrange SIGCHLD to be caught. */ signal(SIGCHLD, main_sigchld_handler); - /* Stay listening for connections until the system crashes - or the daemon is killed with a signal. */ + /* + * Stay listening for connections until the system crashes or + * the daemon is killed with a signal. + */ for (;;) { if (received_sighup) sighup_restart(); @@ -682,12 +691,16 @@ main(int ac, char **av) error("accept: %.100s", strerror(errno)); continue; } - /* Got connection. Fork a child to handle it, - unless we are in debugging mode. */ + /* + * Got connection. Fork a child to handle it, unless + * we are in debugging mode. + */ if (debug_flag) { - /* In debugging mode. Close the listening - socket, and start processing the - connection without forking. */ + /* + * 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_sock); sock_in = newsock; @@ -695,16 +708,17 @@ main(int ac, char **av) pid = getpid(); break; } else { - /* Normal production daemon. Fork, and - have the child process the connection. - The parent continues listening. */ + /* + * 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. */ + /* + * 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_sock); sock_in = newsock; sock_out = newsock; @@ -731,9 +745,11 @@ main(int ac, char **av) /* 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. */ + /* + * 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); @@ -741,17 +757,20 @@ main(int ac, char **av) 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)); */ + /* + * 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. */ + /* + * 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(); @@ -777,12 +796,14 @@ main(int ac, char **av) verbose("Connection from %.500s port %d", remote_ip, remote_port); #endif /* LIBWRAP */ - /* 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. */ + /* + * 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); @@ -815,8 +836,10 @@ main(int ac, char **av) buf[sizeof(buf) - 1] = 0; } - /* Check that the versions match. In future this might accept - several versions and set appropriate flags to handle them. */ + /* + * 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) { const char *s = "Protocol mismatch.\n"; @@ -848,11 +871,13 @@ main(int ac, char **av) no_agent_forwarding_flag = 1; } } - /* 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. */ + /* + * 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; @@ -914,13 +939,15 @@ do_connection() int plen, slen; 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. */ + /* + * 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(); @@ -928,9 +955,11 @@ do_connection() 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. */ + /* + * 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(check_bytes[i]); @@ -1002,14 +1031,15 @@ do_connection() session_key_int = BN_new(); packet_get_bignum(session_key_int, &slen); - /* Get protocol flags. */ 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). */ + /* + * 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) < @@ -1040,14 +1070,15 @@ do_connection() sensitive_data.private_key); } - /* Compute session id for this session. */ compute_session_id(session_id, check_bytes, sensitive_data.host_key->n, sensitive_data.private_key->n); - /* 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. */ + /* + * 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)) @@ -1125,8 +1156,7 @@ allowed_user(struct passwd * pw) 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 */ + /* 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; @@ -1151,8 +1181,10 @@ allowed_user(struct passwd * pw) 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 */ + /* + * 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; @@ -1216,8 +1248,10 @@ do_authentication(char *user) } #endif - /* If we are not running as root, the user must have the same uid - as the server. */ + /* + * 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."); @@ -1357,10 +1391,12 @@ do_authloop(struct passwd * pw) 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.) */ + /* + * 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); @@ -1379,9 +1415,11 @@ do_authloop(struct passwd * pw) 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. */ + /* + * 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. */ @@ -1425,9 +1463,11 @@ do_authloop(struct passwd * pw) 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. */ + /* + * 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); @@ -1463,8 +1503,7 @@ do_authloop(struct passwd * pw) skeyinfo = skey_fake_keyinfo(pw->pw_name); } if (skeyinfo != NULL) { - /* we send our s/key- in - tis-challenge messages */ + /* 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)); @@ -1493,8 +1532,10 @@ do_authloop(struct passwd * pw) #endif default: - /* Any unknown messages will be ignored (and - failure returned) during authentication. */ + /* + * Any unknown messages will be ignored (and failure + * returned) during authentication. + */ log("Unknown message during authentication: type %d", type); break; } @@ -1559,11 +1600,12 @@ do_fake_authloop(char *user) 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. */ + /* + * 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. */ + /* Read a packet. This will not return if the client disconnects. */ int plen; int type = packet_read(&plen); #ifdef SKEY @@ -1583,8 +1625,10 @@ do_fake_authloop(char *user) if (attempt > AUTH_FAIL_MAX) packet_disconnect(AUTH_FAIL_MSG, user); - /* Send failure. This should be indistinguishable from a - failed authentication. */ + /* + * Send failure. This should be indistinguishable from a + * failed authentication. + */ packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); @@ -1630,19 +1674,25 @@ do_authenticated(struct passwd * pw) mode_t tty_mode; int n_bytes; - /* Cancel the alarm we set to limit the time taken for - authentication. */ + /* + * 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.) */ + /* + * 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.) + */ channel_permit_all_opens(); - /* We stay in this loop until the client requests to execute a - shell or a command. */ + /* + * We stay in this loop until the client requests to execute a shell + * or a command. + */ while (1) { int plen, dlen; @@ -1826,8 +1876,10 @@ do_authenticated(struct passwd * pw) return; default: - /* Any unknown messages in this phase are ignored, - and a failure message is returned. */ + /* + * 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; } @@ -1852,8 +1904,10 @@ fail: continue; do_forced_command: - /* There is a forced command specified for this login. - Execute it. */ + /* + * 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); @@ -1897,14 +1951,18 @@ do_exec_no_pty(const char *command, struct passwd * pw, /* 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. */ + /* + * 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. */ + /* + * 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"); @@ -1922,9 +1980,11 @@ do_exec_no_pty(const char *command, struct passwd * pw, 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. */ + /* + * 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 */ @@ -1955,8 +2015,10 @@ do_exec_no_pty(const char *command, struct passwd * pw, 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. */ + /* + * 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 */ @@ -2012,8 +2074,10 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, /* Get remote host name. */ hostname = get_canonical_hostname(); - /* Get the time when the user last logged in. Buf will be set to - contain the hostname the last login was from. */ + /* + * 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)); @@ -2049,9 +2113,11 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, /* 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. */ + /* + * 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); @@ -2075,12 +2141,14 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, fprintf(stderr, pamconv_msg); #endif - /* 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 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. */ @@ -2095,10 +2163,12 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, else printf("Last login: %s from %s\r\n", time_string, buf); } - /* Print /etc/motd unless a command was specified or - printing it was disabled in server options or login(1) - will be used. Note that some machines appear to print - it in /etc/profile or similar. */ + /* + * Print /etc/motd unless a command was specified or printing + * it was disabled in server options or login(1) will be + * used. Note that some machines appear to print it in + * /etc/profile or similar. + */ if (command == NULL && options.print_motd && !quiet_login && !options.use_login) { /* Print /etc/motd if it exists. */ @@ -2118,15 +2188,19 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); - /* Create another descriptor of the pty master side for use as the - standard input. We could use the original descriptor, but this - simplifies code in server_loop. The descriptor is bidirectional. */ + /* + * 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 failed: %.100s", strerror(errno)); - /* Add a cleanup function to clear the utmp entry and record logout - time in case we call fatal() (e.g., the connection gets closed). */ + /* + * 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); @@ -2144,9 +2218,11 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, /* 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. */ + /* + * 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. + */ close(ptyfd); close(fdout); } @@ -2162,19 +2238,21 @@ child_set_env(char ***envp, unsigned int *envsizep, const char *name, 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. */ + /* + * 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]) { - /* Name already exists. Reuse the slot. */ + /* Reuse the slot. */ xfree(env[i]); } else { - /* New variable. Expand the array if necessary. */ + /* New variable. Expand if necessary. */ if (i >= (*envsizep) - 1) { (*envsizep) += 50; env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); @@ -2202,40 +2280,27 @@ read_environment_file(char ***env, unsigned int *envsize, char buf[4096]; char *cp, *value; - /* Open the environment file. */ f = fopen(filename, "r"); if (!f) return; - /* Process each line. */ while (fgets(buf, sizeof(buf), f)) { - /* Skip leading whitespace. */ - for (cp = buf; *cp == ' ' || *cp == '\t'; cp++); - - /* Ignore empty and comment lines. */ + for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) + ; if (!*cp || *cp == '#' || *cp == '\n') continue; - - /* Remove newline. */ if (strchr(cp, '\n')) *strchr(cp, '\n') = '\0'; - - /* Find the equals sign. Its lack indicates badly - formatted line. */ 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. */ + /* Replace the equals sign by nul, and advance value to the value string. */ *value = '\0'; value++; - - /* Set the value in environment. */ child_set_env(env, envsize, cp, value); } - fclose(f); } @@ -2299,8 +2364,10 @@ do_child(const char *command, struct passwd * pw, const char *term, if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) fatal("Failed to set uids to %d.", (int) pw->pw_uid); } - /* Get the shell from the password data. An empty shell field is - legal, and means /bin/sh. */ + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; #ifdef AFS @@ -2315,8 +2382,7 @@ do_child(const char *command, struct passwd * pw, const char *term, } #endif /* AFS */ - /* Initialize the environment. In the first part we allocate - space for all environment variables. */ + /* Initialize the environment. */ envsize = 100; env = xmalloc(envsize * sizeof(char *)); env[0] = NULL; @@ -2335,7 +2401,6 @@ do_child(const char *command, struct passwd * pw, const char *term, /* Normal systems set SHELL by default. */ child_set_env(&env, &envsize, "SHELL", shell); } - /* Let it inherit timezone if we have one. */ if (getenv("TZ")) child_set_env(&env, &envsize, "TZ", getenv("TZ")); @@ -2354,20 +2419,14 @@ do_child(const char *command, struct passwd * pw, const char *term, xfree(ce); } - /* Set SSH_CLIENT. */ snprintf(buf, sizeof buf, "%.50s %d %d", get_remote_ipaddr(), get_remote_port(), options.port); child_set_env(&env, &envsize, "SSH_CLIENT", buf); - /* Set SSH_TTY if we have a pty. */ if (ttyname) child_set_env(&env, &envsize, "SSH_TTY", ttyname); - - /* Set TERM if we have a pty. */ if (term) child_set_env(&env, &envsize, "TERM", term); - - /* Set DISPLAY if we have one. */ if (display) child_set_env(&env, &envsize, "DISPLAY", display); @@ -2400,52 +2459,57 @@ do_child(const char *command, struct passwd * pw, const char *term, } #endif /* HAVE_LIBPAM */ - /* Set XAUTHORITY to always be a local file. */ if (xauthfile) child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); - /* Set variable for forwarded authentication connection, if we - have one. */ if (auth_get_socket_name() != NULL) child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, auth_get_socket_name()); - /* Read $HOME/.ssh/environment. */ + /* 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 debugging, dump the environment to stderr. */ 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. */ + /* + * 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. */ + /* + * 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. */ + /* + * Close any extra file descriptors. Note that there may still be + * descriptors left by system functions. They will be closed later. + */ endpwent(); endhostent(); - /* 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. */ + /* + * Close any extra open file descriptors so that we don\'t have them + * hanging around in clients. Note that we want to do this after + * initgroups, because at least on Solaris 2.3 it leaves file + * descriptors open. + */ for (i = 3; i < 64; i++) close(i); @@ -2454,12 +2518,16 @@ do_child(const char *command, struct passwd * pw, const char *term, fprintf(stderr, "Could not chdir to home directory %s: %s\n", pw->pw_dir, strerror(errno)); - /* Must take new environment into use so that .ssh/rc, /etc/sshrc - and xauth are run in the proper environment. */ + /* + * 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). */ + /* + * 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) @@ -2486,8 +2554,7 @@ do_child(const char *command, struct passwd * pw, const char *term, } #ifdef XAUTH_PATH else { - /* Add authority data to .Xauthority if - appropriate. */ + /* 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", @@ -2510,15 +2577,19 @@ do_child(const char *command, struct passwd * pw, const char *term, 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 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. */ + /* + * 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; @@ -2558,8 +2629,10 @@ do_child(const char *command, struct passwd * pw, const char *term, exit(1); } } - /* Execute the command using the user's shell. This uses the -c - option to execute the command. */ + /* + * 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; diff --git a/tildexpand.c b/tildexpand.c index 92422ee3..8ee551f1 100644 --- a/tildexpand.c +++ b/tildexpand.c @@ -6,7 +6,7 @@ */ #include "includes.h" -RCSID("$Id: tildexpand.c,v 1.2 1999/11/24 13:26:23 damien Exp $"); +RCSID("$Id: tildexpand.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -38,7 +38,7 @@ tilde_expand_filename(const char *filename, uid_t my_uid) else userlen = strlen(filename); /* Nothing after username. */ if (userlen == 0) - pw = getpwuid(my_uid); /* Own home directory. */ + pw = getpwuid(my_uid); /* Own home directory. */ else { /* Tilde refers to someone elses home directory. */ if (userlen > sizeof(user) - 1) @@ -47,12 +47,12 @@ tilde_expand_filename(const char *filename, uid_t my_uid) user[userlen] = 0; pw = getpwnam(user); } - /* Check that we found the user. */ if (!pw) fatal("Unknown user %100s.", user); /* If referring to someones home directory, return it now. */ - if (!cp) { /* Only home directory specified */ + if (!cp) { + /* Only home directory specified */ return xstrdup(pw->pw_dir); } /* Build a path combining the specified directory and path. */ @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$Id: ttymodes.c,v 1.2 1999/11/24 13:26:23 damien Exp $"); +RCSID("$Id: ttymodes.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); #include "packet.h" #include "ssh.h" @@ -209,7 +209,6 @@ tty_make_modes(int fd) struct termios tio; int baud; - /* Get the modes. */ if (tcgetattr(fd, &tio) < 0) { packet_put_char(TTY_OP_END); log("tcgetattr: %.100s", strerror(errno)); @@ -12,7 +12,7 @@ * */ -/* RCSID("$Id: ttymodes.h,v 1.2 1999/11/24 13:26:23 damien Exp $"); */ +/* RCSID("$Id: ttymodes.h,v 1.3 1999/11/25 00:54:59 damien 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). @@ -29,112 +29,113 @@ /* * Some constants and prototypes are defined in packet.h; this file - * is only intended for including from ttymodes.h. + * is only intended for including from ttymodes.c. */ - /* termios macro *//* sgtty macro */ +/* 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) +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) +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 */ +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) +#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 */ +TTYCHAR(VSUSP, 10) SGTTYCHAR(tioltc.t_suspc, 10) +#endif /* VSUSP */ #if defined(VDSUSP) -TTYCHAR(VDSUSP, 11) SGTTYCHAR(tioltc.t_dsuspc, 11) -#endif /* VDSUSP */ +TTYCHAR(VDSUSP, 11) SGTTYCHAR(tioltc.t_dsuspc, 11) +#endif /* VDSUSP */ #if defined(VREPRINT) -TTYCHAR(VREPRINT, 12) SGTTYCHAR(tioltc.t_rprntc, 12) -#endif /* VREPRINT */ +TTYCHAR(VREPRINT, 12) SGTTYCHAR(tioltc.t_rprntc, 12) +#endif /* VREPRINT */ #if defined(VWERASE) -TTYCHAR(VWERASE, 13) SGTTYCHAR(tioltc.t_werasc, 13) -#endif /* VWERASE */ +TTYCHAR(VWERASE, 13) SGTTYCHAR(tioltc.t_werasc, 13) +#endif /* VWERASE */ #if defined(VLNEXT) -TTYCHAR(VLNEXT, 14) SGTTYCHAR(tioltc.t_lnextc, 14) -#endif /* VLNEXT */ +TTYCHAR(VLNEXT, 14) SGTTYCHAR(tioltc.t_lnextc, 14) +#endif /* VLNEXT */ #if defined(VFLUSH) -TTYCHAR(VFLUSH, 15) SGTTYCHAR(tioltc.t_flushc, 15) -#endif /* VFLUSH */ +TTYCHAR(VFLUSH, 15) SGTTYCHAR(tioltc.t_flushc, 15) +#endif /* VFLUSH */ #ifdef VSWTCH TTYCHAR(VSWTCH, 16) /* n/a */ -#endif /* VSWTCH */ +#endif /* VSWTCH */ #if defined(VSTATUS) -TTYCHAR(VSTATUS, 17) SGTTYCHAR(tiots.tc_statusc, 17) -#endif /* VSTATUS */ +TTYCHAR(VSTATUS, 17) SGTTYCHAR(tiots.tc_statusc, 17) +#endif /* VSTATUS */ #ifdef VDISCARD TTYCHAR(VDISCARD, 18) /* n/a */ -#endif /* VDISCARD */ +#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) +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) +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) +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(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) +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 */ +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) +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 */ +#endif /* IEXTEN */ #if defined(ECHOCTL) -TTYMODE(ECHOCTL, c_lflag, 60) SGTTYMODE(LCTLECH, tiolm, 60) -#endif /* ECHOCTL */ +TTYMODE(ECHOCTL,c_lflag, 60) SGTTYMODE(LCTLECH, tiolm, 60) +#endif /* ECHOCTL */ #ifdef ECHOKE -TTYMODE(ECHOKE, c_lflag, 61) /* n/a */ -#endif /* 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(PENDIN, c_lflag, 62) SGTTYMODE(LPENDIN, tiolm, 62) +#endif /* PENDIN */ -TTYMODE(OPOST, c_oflag, 70) /* n/a */ +TTYMODE(OPOST, c_oflag, 70) /* n/a */ #if defined(OLCUC) -TTYMODE(OLCUC, c_oflag, 71) SGTTYMODE(LCASE, tio.sg_flags, 71) +TTYMODE(OLCUC, c_oflag, 71) SGTTYMODE(LCASE, tio.sg_flags, 71) #endif -TTYMODE(ONLCR, c_oflag, 72) SGTTYMODE(CRMOD, tio.sg_flags, 72) +TTYMODE(ONLCR, c_oflag, 72) SGTTYMODE(CRMOD, tio.sg_flags, 72) #ifdef OCRNL -TTYMODE(OCRNL, c_oflag, 73) /* n/a */ +TTYMODE(OCRNL, c_oflag, 73) /* n/a */ #endif #ifdef ONOCR -TTYMODE(ONOCR, c_oflag, 74) /* n/a */ +TTYMODE(ONOCR, c_oflag, 74) /* n/a */ #endif #ifdef ONLRET -TTYMODE(ONLRET, c_oflag, 75) /* n/a */ +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) +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) + @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$Id: uidswap.c,v 1.2 1999/11/24 13:26:23 damien Exp $"); +RCSID("$Id: uidswap.c,v 1.3 1999/11/25 00:55:00 damien Exp $"); #include "ssh.h" #include "uidswap.h" @@ -66,10 +66,11 @@ restore_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. */ + /* + * 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 */ } |