From: damien Date: Thu, 9 Mar 2000 10:27:49 +0000 (+0000) Subject: - OpenBSD CVS updates to v1.2.3 X-Git-Tag: V_1_2_3_PRE1~5 X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/commitdiff_plain/c8d54615d40279fd33e21e6b10a67cca57656cbb - OpenBSD CVS updates to v1.2.3 [ssh.h atomicio.c] - int atomicio -> ssize_t (for alpha). ok deraadt@ [auth-rsa.c] - delay MD5 computation until client sends response, free() early, cleanup. [cipher.c] - void* -> unsigned char*, ok niels@ [hostfile.c] - remove unused variable 'len'. fix comments. - remove unused variable [log-client.c log-server.c] - rename a cpp symbol, to avoid param.h collision [packet.c] - missing xfree() - getsockname() requires initialized tolen; andy@guildsoftware.com - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; from Holger.Trapp@Informatik.TU-Chemnitz.DE [pty.c pty.h] - register cleanup for pty earlier. move code for pty-owner handling to pty.c ok provos@, dugsong@ [readconf.c] - turn off x11-fwd for the client, too. [rsa.c] - PKCS#1 padding [scp.c] - allow '.' in usernames; from jedgar@fxp.org [servconf.c] - typo: ignore_user_known_hosts int->flag; naddy@mips.rhein-neckar.de - sync with sshd_config [ssh-keygen.c] - enable ssh-keygen -l -f ~/.ssh/known_hosts, ok deraadt@ [ssh.1] - Change invalid 'CHAT' loglevel to 'VERBOSE' [ssh.c] - suppress AAAA query host when '-4' is used; from shin@nd.net.fujitsu.co.jp - turn off x11-fwd for the client, too. [sshconnect.c] - missing xfree() - retry rresvport_af(), too. from sumikawa@ebina.hitachi.co.jp. - read error vs. "Connection closed by remote host" [sshd.8] - ie. -> i.e., - do not link to a commercial page.. - sync with sshd_config [sshd.c] - no need for poll.h; from bright@wintelcom.net - log with level log() not fatal() if peer behaves badly. - don't panic if client behaves strange. ok deraadt@ - make no-port-forwarding for RSA keys deny both -L and -R style fwding - delay close() of pty until the pty has been chowned back to root - oops, fix comment, too. - missing xfree() - move XAUTHORITY to subdir. ok dugsong@. fixes debian bug #57907, too. (http://cgi.debian.org/cgi-bin/bugreport.cgi?archive=no&bug=57907) - register cleanup for pty earlier. move code for pty-owner handling to pty.c ok provos@, dugsong@ - create x11 cookie file - fix pr 1113, fclose() -> pclose(), todo: remote popen() - version 1.2.3 - Cleaned up --- diff --git a/ChangeLog b/ChangeLog index 4eb4ee6a..68c577f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,65 @@ +20000309 + - OpenBSD CVS updates to v1.2.3 + [ssh.h atomicio.c] + - int atomicio -> ssize_t (for alpha). ok deraadt@ + [auth-rsa.c] + - delay MD5 computation until client sends response, free() early, cleanup. + [cipher.c] + - void* -> unsigned char*, ok niels@ + [hostfile.c] + - remove unused variable 'len'. fix comments. + - remove unused variable + [log-client.c log-server.c] + - rename a cpp symbol, to avoid param.h collision + [packet.c] + - missing xfree() + - getsockname() requires initialized tolen; andy@guildsoftware.com + - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; + from Holger.Trapp@Informatik.TU-Chemnitz.DE + [pty.c pty.h] + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + [readconf.c] + - turn off x11-fwd for the client, too. + [rsa.c] + - PKCS#1 padding + [scp.c] + - allow '.' in usernames; from jedgar@fxp.org + [servconf.c] + - typo: ignore_user_known_hosts int->flag; naddy@mips.rhein-neckar.de + - sync with sshd_config + [ssh-keygen.c] + - enable ssh-keygen -l -f ~/.ssh/known_hosts, ok deraadt@ + [ssh.1] + - Change invalid 'CHAT' loglevel to 'VERBOSE' + [ssh.c] + - suppress AAAA query host when '-4' is used; from shin@nd.net.fujitsu.co.jp + - turn off x11-fwd for the client, too. + [sshconnect.c] + - missing xfree() + - retry rresvport_af(), too. from sumikawa@ebina.hitachi.co.jp. + - read error vs. "Connection closed by remote host" + [sshd.8] + - ie. -> i.e., + - do not link to a commercial page.. + - sync with sshd_config + [sshd.c] + - no need for poll.h; from bright@wintelcom.net + - log with level log() not fatal() if peer behaves badly. + - don't panic if client behaves strange. ok deraadt@ + - make no-port-forwarding for RSA keys deny both -L and -R style fwding + - delay close() of pty until the pty has been chowned back to root + - oops, fix comment, too. + - missing xfree() + - move XAUTHORITY to subdir. ok dugsong@. fixes debian bug #57907, too. + (http://cgi.debian.org/cgi-bin/bugreport.cgi?archive=no&bug=57907) + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + - create x11 cookie file + - fix pr 1113, fclose() -> pclose(), todo: remote popen() + - version 1.2.3 + - Cleaned up + 20000308 - Configure fix from Hiroshi Takekawa diff --git a/atomicio.c b/atomicio.c index 47f8190a..321af513 100644 --- a/atomicio.c +++ b/atomicio.c @@ -32,14 +32,14 @@ RCSID("$Id$"); /* * ensure all of data on socket comes through. f==read || f==write */ -int +ssize_t atomicio(f, fd, s, n) - int (*f) (); + ssize_t (*f) (); int fd; void *s; size_t n; { - int res, pos = 0; + ssize_t res, pos = 0; while (n > pos) { res = (f) (fd, (char*)s + pos, n - pos); diff --git a/auth-rsa.c b/auth-rsa.c index 2dcfd749..5fed5b6b 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -68,9 +68,9 @@ extern unsigned char session_id[16]; int auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) { - BIGNUM *challenge, *encrypted_challenge, *aux; + BIGNUM *challenge, *encrypted_challenge; RSA *pk; - BN_CTX *ctx = BN_CTX_new(); + BN_CTX *ctx; unsigned char buf[32], mdbuf[16], response[16]; MD5_CTX md; unsigned int i; @@ -78,11 +78,12 @@ auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) encrypted_challenge = BN_new(); challenge = BN_new(); - aux = BN_new(); /* Generate a random challenge. */ BN_rand(challenge, 256, 0, 0); + ctx = BN_CTX_new(); BN_mod(challenge, challenge, n, ctx); + BN_CTX_free(ctx); /* Create the public key data structure. */ pk = RSA_new(); @@ -99,8 +100,15 @@ auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); packet_put_bignum(encrypted_challenge); packet_send(); + BN_clear_free(encrypted_challenge); packet_write_wait(); + /* Wait for a response. */ + packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); + packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + response[i] = packet_get_char(); + /* The response is MD5 of decrypted challenge plus session id. */ len = BN_num_bytes(challenge); if (len <= 0 || len > 32) @@ -111,18 +119,7 @@ auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) MD5_Update(&md, buf, 32); MD5_Update(&md, session_id, 16); MD5_Final(mdbuf, &md); - - /* We will no longer need these. */ - BN_clear_free(encrypted_challenge); BN_clear_free(challenge); - BN_clear_free(aux); - BN_CTX_free(ctx); - - /* Wait for a response. */ - packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); - packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); - for (i = 0; i < 16; i++) - response[i] = packet_get_char(); /* Verify that the response is the original challenge. */ if (memcmp(response, mdbuf, 16) != 0) { diff --git a/cipher.c b/cipher.c index c6ed6816..ddb2d0e3 100644 --- a/cipher.c +++ b/cipher.c @@ -41,7 +41,7 @@ void SSH_3CBC_ENCRYPT(des_key_schedule ks1, des_key_schedule ks2, des_cblock * iv2, des_key_schedule ks3, des_cblock * iv3, - void *dest, void *src, + unsigned char *dest, unsigned char *src, unsigned int len) { des_cblock iv1; @@ -49,20 +49,20 @@ SSH_3CBC_ENCRYPT(des_key_schedule ks1, memcpy(&iv1, iv2, 8); des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT); - memcpy(&iv1, (char *)dest + len - 8, 8); + memcpy(&iv1, dest + len - 8, 8); des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT); memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT); - memcpy(iv3, (char *)dest + len - 8, 8); + memcpy(iv3, dest + len - 8, 8); } void SSH_3CBC_DECRYPT(des_key_schedule ks1, des_key_schedule ks2, des_cblock * iv2, des_key_schedule ks3, des_cblock * iv3, - void *dest, void *src, + unsigned char *dest, unsigned char *src, unsigned int len) { des_cblock iv1; @@ -70,10 +70,10 @@ SSH_3CBC_DECRYPT(des_key_schedule ks1, memcpy(&iv1, iv2, 8); des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT); - memcpy(iv3, (char *)src + len - 8, 8); + memcpy(iv3, src + len - 8, 8); des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT); - memcpy(iv2, (char *)dest + len - 8, 8); + memcpy(iv2, dest + len - 8, 8); des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT); /* memcpy(&iv1, iv2, 8); */ @@ -273,7 +273,7 @@ cipher_encrypt(CipherContext *context, unsigned char *dest, SSH_3CBC_ENCRYPT(context->u.des3.key1, context->u.des3.key2, &context->u.des3.iv2, context->u.des3.key3, &context->u.des3.iv3, - dest, (void *) src, len); + dest, (unsigned char *) src, len); break; case SSH_CIPHER_BLOWFISH: @@ -308,7 +308,7 @@ cipher_decrypt(CipherContext *context, unsigned char *dest, SSH_3CBC_DECRYPT(context->u.des3.key1, context->u.des3.key2, &context->u.des3.iv2, context->u.des3.key3, &context->u.des3.iv3, - dest, (void *) src, len); + dest, (unsigned char *) src, len); break; case SSH_CIPHER_BLOWFISH: diff --git a/hostfile.c b/hostfile.c index 831ac592..ea92fa04 100644 --- a/hostfile.c +++ b/hostfile.c @@ -14,13 +14,13 @@ */ #include "includes.h" -RCSID("$OpenBSD: hostfile.c,v 1.11 2000/01/04 00:07:59 markus Exp $"); +RCSID("$OpenBSD: hostfile.c,v 1.13 2000/02/18 10:20:20 markus Exp $"); #include "packet.h" #include "ssh.h" /* - * Reads a multiple-precision integer in hex from the buffer, and advances + * Reads a multiple-precision integer in decimal from the buffer, and advances * the pointer. The integer must already be initialized. This function is * permitted to modify the buffer. This leaves *cpp to point just beyond the * last processed (and maybe modified) character. Note that this may modify @@ -31,26 +31,23 @@ int auth_rsa_read_bignum(char **cpp, BIGNUM * value) { char *cp = *cpp; - int len, old; + int old; /* Skip any leading whitespace. */ for (; *cp == ' ' || *cp == '\t'; cp++) ; - /* Check that it begins with a hex digit. */ + /* Check that it begins with a decimal digit. */ if (*cp < '0' || *cp > '9') return 0; /* Save starting position. */ *cpp = cp; - /* Move forward until all hex digits skipped. */ + /* Move forward until all decimal digits skipped. */ for (; *cp >= '0' && *cp <= '9'; cp++) ; - /* Compute the length of the hex number. */ - len = cp - *cpp; - /* Save the old terminating character, and replace it by \0. */ old = *cp; *cp = 0; @@ -179,7 +176,7 @@ check_host_in_hostfile(const char *filename, const char *host, FILE *f; char line[8192]; int linenum = 0; - unsigned int bits, kbits, hostlen; + unsigned int kbits, hostlen; char *cp, *cp2; HostStatus end_return; @@ -198,9 +195,6 @@ check_host_in_hostfile(const char *filename, const char *host, */ end_return = HOST_NEW; - /* size of modulus 'n' */ - bits = BN_num_bits(n); - /* Go trough the file. */ while (fgets(line, sizeof(line), f)) { cp = line; diff --git a/log-client.c b/log-client.c index c1aeb32f..7726631b 100644 --- a/log-client.c +++ b/log-client.c @@ -45,12 +45,12 @@ log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2) } } -#define SSH_MSGBUFSIZE 1024 +#define MSGBUFSIZ 1024 void do_log(LogLevel level, const char *fmt, va_list args) { - char msgbuf[SSH_MSGBUFSIZE]; + char msgbuf[MSGBUFSIZ]; if (level > log_level) return; diff --git a/log-server.c b/log-server.c index 3776f109..38c53442 100644 --- a/log-server.c +++ b/log-server.c @@ -97,13 +97,13 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) log_on_stderr = on_stderr; } -#define SSH_MSGBUFSIZE 1024 +#define MSGBUFSIZ 1024 void do_log(LogLevel level, const char *fmt, va_list args) { - char msgbuf[SSH_MSGBUFSIZE]; - char fmtbuf[SSH_MSGBUFSIZE]; + char msgbuf[MSGBUFSIZ]; + char fmtbuf[MSGBUFSIZ]; char *txt = NULL; int pri = LOG_INFO; diff --git a/packet.c b/packet.c index 9be0ad1b..ec4e5f97 100644 --- a/packet.c +++ b/packet.c @@ -505,7 +505,7 @@ packet_read_poll(int *payload_len_ptr) { unsigned int len, padded_len; unsigned char *ucp; - char buf[8], *cp; + char buf[8], *cp, *msg; unsigned int checksum, stored_checksum; restart: @@ -575,7 +575,9 @@ restart: /* Handle disconnect message. */ if ((unsigned char) buf[0] == SSH_MSG_DISCONNECT) { - log("Received disconnect: %.900s", packet_get_string(NULL)); + msg = packet_get_string(NULL); + log("Received disconnect: %.900s", msg); + xfree(msg); fatal_cleanup(); } @@ -585,7 +587,9 @@ restart: /* Send debug messages as debugging output. */ if ((unsigned char) buf[0] == SSH_MSG_DEBUG) { - debug("Remote: %.900s", packet_get_string(NULL)); + msg = packet_get_string(NULL); + debug("Remote: %.900s", msg); + xfree(msg); goto restart; } /* Return type. */ diff --git a/pty.h b/pty.h index c65f8c93..82da8620 100644 --- a/pty.h +++ b/pty.h @@ -45,4 +45,6 @@ pty_change_window_size(int ptyfd, int row, int col, void pty_setowner(struct passwd *pw, const char *ttyname); +void pty_setowner(struct passwd *pw, const char *ttyname); + #endif /* PTY_H */ diff --git a/readconf.c b/readconf.c index eca13329..4dfeece7 100644 --- a/readconf.c +++ b/readconf.c @@ -638,7 +638,7 @@ fill_default_options(Options * options) if (options->forward_agent == -1) options->forward_agent = 1; if (options->forward_x11 == -1) - options->forward_x11 = 1; + options->forward_x11 = 0; if (options->gateway_ports == -1) options->gateway_ports = 0; if (options->use_privileged_port == -1) diff --git a/rsa.c b/rsa.c index 8db61a9b..90cae578 100644 --- a/rsa.c +++ b/rsa.c @@ -159,7 +159,7 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) BN_bn2bin(in, inbuf); if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, - RSA_PKCS1_PADDING)) <= 0) + RSA_PKCS1_PADDING)) <= 0) fatal("rsa_public_encrypt() failed"); BN_bin2bn(outbuf, len, out); @@ -184,7 +184,7 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) BN_bn2bin(in, inbuf); if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, - RSA_SSLV23_PADDING)) <= 0) + RSA_PKCS1_PADDING)) <= 0) fatal("rsa_private_decrypt() failed"); BN_bin2bn(outbuf, len, out); diff --git a/scp.c b/scp.c index 300d10d0..18e23335 100644 --- a/scp.c +++ b/scp.c @@ -1067,7 +1067,7 @@ okname(cp0) } while (*++cp); return (1); -bad: fprintf(stderr, "%s: invalid user name", cp0); +bad: fprintf(stderr, "%s: invalid user name\n", cp0); return (0); } diff --git a/servconf.c b/servconf.c index 98146b18..31b53248 100644 --- a/servconf.c +++ b/servconf.c @@ -87,7 +87,7 @@ fill_default_server_options(ServerOptions *options) if (options->permit_root_login == -1) options->permit_root_login = 1; /* yes */ if (options->ignore_rhosts == -1) - options->ignore_rhosts = 0; + options->ignore_rhosts = 1; if (options->ignore_user_known_hosts == -1) options->ignore_user_known_hosts = 0; if (options->check_mail == -1) @@ -95,9 +95,9 @@ fill_default_server_options(ServerOptions *options) if (options->print_motd == -1) options->print_motd = 1; if (options->x11_forwarding == -1) - options->x11_forwarding = 1; + options->x11_forwarding = 0; if (options->x11_display_offset == -1) - options->x11_display_offset = 1; + options->x11_display_offset = 10; if (options->strict_modes == -1) options->strict_modes = 1; if (options->keepalives == -1) @@ -109,7 +109,7 @@ fill_default_server_options(ServerOptions *options) if (options->rhosts_authentication == -1) options->rhosts_authentication = 0; if (options->rhosts_rsa_authentication == -1) - options->rhosts_rsa_authentication = 1; + options->rhosts_rsa_authentication = 0; if (options->rsa_authentication == -1) options->rsa_authentication = 1; #ifdef KRB4 @@ -133,7 +133,7 @@ fill_default_server_options(ServerOptions *options) options->skey_authentication = 1; #endif if (options->permit_empty_passwd == -1) - options->permit_empty_passwd = 1; + options->permit_empty_passwd = 0; if (options->use_login == -1) options->use_login = 0; } @@ -402,7 +402,7 @@ parse_flag: case sIgnoreUserKnownHosts: intptr = &options->ignore_user_known_hosts; - goto parse_int; + goto parse_flag; case sRhostsAuthentication: intptr = &options->rhosts_authentication; diff --git a/ssh-keygen.c b/ssh-keygen.c index e7f51708..c50bafa6 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -80,8 +80,11 @@ ask_filename(struct passwd *pw, const char *prompt) void do_fingerprint(struct passwd *pw) { - char *comment; + FILE *f; + BIGNUM *e, *n; RSA *public_key; + char *comment = NULL, *cp, *ep, line[16*1024]; + int i, skip = 0, num = 1, invalid = 1; struct stat st; if (!have_identity) @@ -90,38 +93,71 @@ do_fingerprint(struct passwd *pw) perror(identity_file); exit(1); } + public_key = RSA_new(); - if (!load_public_key(identity_file, public_key, &comment)) { - char *cp, line[1024]; - BIGNUM *e, *n; - int dummy, invalid = 0; - FILE *f = fopen(identity_file, "r"); + if (load_public_key(identity_file, public_key, &comment)) { + printf("%d %s %s\n", BN_num_bits(public_key->n), + fingerprint(public_key->e, public_key->n), + comment); + RSA_free(public_key); + exit(0); + } + RSA_free(public_key); + + f = fopen(identity_file, "r"); + if (f != NULL) { n = BN_new(); e = BN_new(); - if (f && fgets(line, sizeof(line), f)) { - cp = line; - line[strlen(line) - 1] = '\0'; - if (auth_rsa_read_key(&cp, &dummy, e, n)) { - public_key->e = e; - public_key->n = n; - comment = xstrdup(cp ? cp : "no comment"); - } else { - invalid = 1; + while (fgets(line, sizeof(line), f)) { + i = strlen(line) - 1; + if (line[i] != '\n') { + error("line %d too long: %.40s...", num, line); + skip = 1; + continue; + } + num++; + if (skip) { + skip = 0; + continue; + } + line[i] = '\0'; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue ; + i = strtol(cp, &ep, 10); + if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { + int quoted = 0; + comment = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + if (!*cp) + continue; + *cp++ = '\0'; + } + ep = cp; + if (auth_rsa_read_key(&cp, &i, e, n)) { + invalid = 0; + comment = *cp ? cp : comment; + printf("%d %s %s\n", BN_num_bits(n), + fingerprint(e, n), + comment ? comment : "no comment"); } - } else { - invalid = 1; - } - if (invalid) { - printf("%s is not a valid key file.\n", identity_file); - BN_free(e); - BN_free(n); - exit(1); } + BN_free(e); + BN_free(n); + fclose(f); + } + if (invalid) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); } - printf("%d %s %s\n", BN_num_bits(public_key->n), - fingerprint(public_key->e, public_key->n), - comment); - RSA_free(public_key); exit(0); } @@ -314,7 +350,7 @@ void usage(void) { printf("ssh-keygen version %s\n", SSH_VERSION); - printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname); + printf("Usage: %s [-b bits] [-p] [-c] [-l] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname); exit(1); } diff --git a/ssh.1 b/ssh.1 index 3b496edd..3b743be0 100644 --- a/ssh.1 +++ b/ssh.1 @@ -557,6 +557,8 @@ set. The argument must be .Dq yes or .Dq no . +The default is +.Dq no . .It Cm GatewayPorts Specifies whether remote hosts are allowed to connect to local forwarded ports. @@ -813,7 +815,7 @@ and adds lines of the format .Dq VARNAME=value to the environment. .Sh FILES -.Bl -tag -width $HOME/.ssh/known_hosts +.Bl -tag -width Ds .It Pa $HOME/.ssh/known_hosts Records host keys for all hosts the user has logged into (that are not in @@ -958,17 +960,12 @@ above. A version of this library which includes support for the RSA algorithm is required for proper operation. .Sh AUTHOR -Tatu Ylonen -.Pp -Issues can be found from the SSH WWW home page: -.Pp -.Dl http://www.cs.hut.fi/ssh -.Pp OpenSSH -is a derivative of the original (free) ssh 1.2.12 release, but with bugs -removed and newer features re-added. Rapidly after the 1.2.12 release, -newer versions bore successively more restrictive licenses. This version -of OpenSSH +is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, +but with bugs removed and newer features re-added. Rapidly after the +1.2.12 release, newer versions of the original ssh bore successively +more restrictive licenses, and thus demand for a free version was born. +This version of OpenSSH .Bl -bullet .It has all components of a restrictive nature (i.e., patents, see @@ -977,7 +974,8 @@ directly removed from the source code; any licensed or patented components are chosen from external libraries. .It -has been updated to support ssh protocol 1.5. +has been updated to support ssh protocol 1.5, making it compatible with +all other ssh protocol 1 clients and servers. .It contains added support for .Xr kerberos 8 diff --git a/ssh.c b/ssh.c index c3e66485..aac8866e 100644 --- a/ssh.c +++ b/ssh.c @@ -103,6 +103,7 @@ usage() fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); #endif /* AFS */ fprintf(stderr, " -x Disable X11 connection forwarding.\n"); + fprintf(stderr, " -X Enable X11 connection forwarding.\n"); fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); @@ -497,7 +498,7 @@ main(int ac, char **av) struct addrinfo *ai = NULL; int errgai; memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; + hints.ai_family = IPv4or6; hints.ai_flags = AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; errgai = getaddrinfo(host, NULL, &hints, &ai); diff --git a/ssh.h b/ssh.h index 4f352c24..9b6a1acf 100644 --- a/ssh.h +++ b/ssh.h @@ -712,7 +712,7 @@ struct envstring { /* * Ensure all of data on socket comes through. f==read || f==write */ -int atomicio(int (*f)(), int fd, void *s, size_t n); +ssize_t atomicio(ssize_t (*f)(), int fd, void *s, size_t n); #ifdef KRB4 #include diff --git a/sshconnect.c b/sshconnect.c index 5e2a3449..c4c9aee1 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -8,7 +8,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.53 2000/01/18 09:42:17 markus Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.56 2000/02/18 08:50:33 markus Exp $"); #ifdef HAVE_OPENSSL #include @@ -156,8 +156,9 @@ ssh_create_socket(uid_t original_real_uid, int privileged, int family) int p = IPPORT_RESERVED - 1; sock = rresvport_af(&p, family); if (sock < 0) - fatal("rresvport: af=%d %.100s", family, strerror(errno)); - debug("Allocated local port %d.", p); + error("rresvport: af=%d %.100s", family, strerror(errno)); + else + debug("Allocated local port %d.", p); } else { /* * Just create an ordinary socket on arbitrary port. We use @@ -891,6 +892,7 @@ try_skey_authentication() log("WARNING: Encryption is disabled! " "Reponse will be transmitted in clear text."); fprintf(stderr, "%s\n", challenge); + xfree(challenge); fflush(stderr); for (i = 0; i < options.number_of_password_prompts; i++) { if (i != 0) @@ -960,8 +962,11 @@ ssh_exchange_identification() /* Read other side\'s version identification. */ for (i = 0; i < sizeof(buf) - 1; i++) { - if (read(connection_in, &buf[i], 1) != 1) + int len = read(connection_in, &buf[i], 1); + if (len < 0) fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); + if (len != 1) + fatal("ssh_exchange_identification: Connection closed by remote host"); if (buf[i] == '\r') { buf[i] = '\n'; buf[i + 1] = 0; diff --git a/sshd.8 b/sshd.8 index ec164f48..baa471cd 100644 --- a/sshd.8 +++ b/sshd.8 @@ -258,13 +258,16 @@ Note that .Nm does not start if this file is group/world-accessible. .It Cm IgnoreRhosts -Specifies that rhosts and shosts files will not be used in -authentication. +Specifies that +.Pa .rhosts +and +.Pa .shosts +files will not be used in authentication. .Pa /etc/hosts.equiv and .Pa /etc/shosts.equiv are still used. The default is -.Dq no . +.Dq yes . .It Cm IgnoreUserKnownHosts Specifies whether .Nm @@ -352,7 +355,7 @@ The default is When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The default is -.Dq yes . +.Dq no . .It Cm PermitRootLogin Specifies whether the root can log in using .Xr ssh 1 . @@ -403,7 +406,7 @@ The default is .It Cm RhostsRSAAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful RSA host authentication is allowed. The default is -.Dq yes . +.Dq no . .It Cm RSAAuthentication Specifies whether pure RSA authentication is allowed. The default is .Dq yes . @@ -442,9 +445,10 @@ Specifies the first display number available for X11 forwarding. This prevents .Nm from interfering with real X11 servers. +The default is 10. .It Cm X11Forwarding Specifies whether X11 forwarding is permitted. The default is -.Dq yes . +.Dq no . Note that disabling X11 forwarding does not improve security in any way, as users can always install their own forwarders. .El @@ -762,18 +766,12 @@ This can be used to specify machine-specific login-time initializations globally. This file should be writable only by root, and should be world-readable. .Sh AUTHOR -Tatu Ylonen -.Pp -Information about new releases, mailing lists, and other related -issues can be found from the SSH WWW home page: -.Pp -.Dl http://www.cs.hut.fi/ssh. -.Pp OpenSSH -is a derivative of the original (free) ssh 1.2.12 release, but with bugs -removed and newer features re-added. Rapidly after the 1.2.12 release, -newer versions bore successively more restrictive licenses. This version -of OpenSSH +is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, +but with bugs removed and newer features re-added. Rapidly after the +1.2.12 release, newer versions of the original ssh bore successively +more restrictive licenses, and thus demand for a free version was born. +This version of OpenSSH .Bl -bullet .It has all components of a restrictive nature (i.e., patents, see @@ -782,7 +780,8 @@ directly removed from the source code; any licensed or patented components are chosen from external libraries. .It -has been updated to support ssh protocol 1.5. +has been updated to support ssh protocol 1.5, making it compatible with +all other ssh protocol 1 clients and servers. .It contains added support for .Xr kerberos 8 diff --git a/sshd.c b/sshd.c index 0024440e..829c0a71 100644 --- a/sshd.c +++ b/sshd.c @@ -11,7 +11,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.80 2000/01/20 15:19:22 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.90 2000/03/06 20:29:04 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -147,6 +147,27 @@ void do_child(const char *command, struct passwd * pw, const char *term, const char *display, const char *auth_proto, const char *auth_data, const char *ttyname); +/* + * Remove local Xauthority file. + */ +void +xauthfile_cleanup_proc(void *ignore) +{ + debug("xauthfile_cleanup_proc called"); + + if (xauthfile != NULL) { + char *p; + unlink(xauthfile); + p = strrchr(xauthfile, '/'); + if (p != NULL) { + *p = '\0'; + rmdir(xauthfile); + } + xfree(xauthfile); + xauthfile = NULL; + } +} + /* * Close all listening sockets */ @@ -234,6 +255,7 @@ grace_alarm_handler(int sig) char * get_authname(int type) { + static char buf[1024]; switch (type) { case SSH_CMSG_AUTH_PASSWORD: return "password"; @@ -252,8 +274,8 @@ get_authname(int type) return "s/key"; #endif } - fatal("get_authname: unknown auth %d: internal error", type); - return NULL; + snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); + return buf; } /* @@ -878,7 +900,7 @@ main(int ac, char **av) /* Cleanup user's local Xauthority file. */ if (xauthfile) - unlink(xauthfile); + xauthfile_cleanup_proc(NULL); /* The connection has been terminated. */ verbose("Closing connection to %.100s", remote_ip); @@ -1089,12 +1111,14 @@ do_ssh_kex() * DenyUsers or user's primary group is listed in DenyGroups, false will * be returned. If AllowUsers isn't empty and user isn't listed there, or * if AllowGroups isn't empty and user isn't listed there, false will be - * returned. Otherwise true is returned. - * XXX This function should also check if user has a valid shell + * returned. + * If the user's shell is not executable, false will be returned. + * Otherwise true is returned. */ static int allowed_user(struct passwd * pw) { + struct stat st; struct group *grp; int i; #ifdef WITH_AIXAUTHENTICATE @@ -1105,7 +1129,11 @@ allowed_user(struct passwd * pw) if (!pw) return 0; - /* XXX Should check for valid login shell */ + /* deny if shell does not exists or is not executable */ + if (stat(pw->pw_shell, &st) != 0) + return 0; + if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) + return 0; /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { @@ -1202,6 +1230,7 @@ do_authentication() pw = getpwnam(user); if (!pw || !allowed_user(pw)) do_fake_authloop(user); + xfree(user); /* Take a copy of the returned structure. */ memset(&pwcopy, 0, sizeof(pwcopy)); @@ -1224,7 +1253,7 @@ do_authentication() if (getuid() != 0 && pw->pw_uid != getuid()) packet_disconnect("Cannot change user when server not running as root."); - debug("Attempting authentication for %.100s.", user); + debug("Attempting authentication for %.100s.", pw->pw_name); /* If the user has no password, accept authentication immediately. */ if (options.password_authentication && @@ -1510,17 +1539,22 @@ do_authloop(struct passwd * pw) get_remote_port(), user); - if (authenticated) { #ifdef USE_PAM + if (authenticated) { if (!do_pam_account(pw->pw_name, client_user)) { - if (client_user != NULL) + if (client_user != NULL) { xfree(client_user); - + client_user = NULL; + } do_fake_authloop(pw->pw_name); } -#endif /* USE_PAM */ return; } +#else /* USE_PAM */ + if (authenticated) { + return; + } +#endif /* USE_PAM */ if (client_user != NULL) { xfree(client_user); @@ -1572,6 +1606,7 @@ do_fake_authloop(char *user) /* Try to send a fake s/key challenge. */ if (options.skey_authentication == 1 && (skeyinfo = skey_fake_keyinfo(user)) != NULL) { + password = NULL; if (type == SSH_CMSG_AUTH_TIS) { packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); packet_put_string(skeyinfo, strlen(skeyinfo)); @@ -1585,6 +1620,8 @@ do_fake_authloop(char *user) strncasecmp(password, "s/key", 5) == 0 ) { packet_send_debug(skeyinfo); } + if (password != NULL) + xfree(password); } #endif if (attempt > AUTH_FAIL_MAX) @@ -1607,22 +1644,6 @@ do_fake_authloop(char *user) abort(); } - -/* - * Remove local Xauthority file. - */ -static void -xauthfile_cleanup_proc(void *ignore) -{ - debug("xauthfile_cleanup_proc called"); - - if (xauthfile != NULL) { - unlink(xauthfile); - xfree(xauthfile); - xauthfile = NULL; - } -} - struct pty_cleanup_context { const char *ttyname; int pid; @@ -1665,7 +1686,7 @@ do_authenticated(struct passwd * pw) { int type; int compression_level = 0, enable_compression_after_reply = 0; - int have_pty = 0, ptyfd = -1, ttyfd = -1, xauthfd = -1; + int have_pty = 0, ptyfd = -1, ttyfd = -1; int row, col, xpixel, ypixel, screen; char ttyname[64]; char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL; @@ -1684,7 +1705,8 @@ do_authenticated(struct passwd * pw) * by the client telling us, so we can equally well trust the client * not to request anything bogus.) */ - channel_permit_all_opens(); + if (!no_port_forwarding_flag) + channel_permit_all_opens(); /* * We stay in this loop until the client requests to execute a shell @@ -1785,16 +1807,20 @@ do_authenticated(struct passwd * pw) /* Setup to always have a local .Xauthority. */ xauthfile = xmalloc(MAXPATHLEN); - snprintf(xauthfile, MAXPATHLEN, "/tmp/XauthXXXXXX"); - - if ((xauthfd = mkstemp(xauthfile)) != -1) { - fchown(xauthfd, pw->pw_uid, pw->pw_gid); - close(xauthfd); - fatal_add_cleanup(xauthfile_cleanup_proc, NULL); - } else { + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); xfree(xauthfile); xauthfile = NULL; + goto fail; } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, NULL); break; #else /* XAUTH_PATH */ packet_send_debug("No xauth program; cannot forward with spoofing."); @@ -2026,6 +2052,7 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, const char *auth_data) { int pid, fdout; + int ptymaster; const char *hostname; time_t last_login_time; char buf[100], *time_string; @@ -2174,11 +2201,16 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, */ fdout = dup(ptyfd); if (fdout < 0) - packet_disconnect("dup failed: %.100s", strerror(errno)); + packet_disconnect("dup #1 failed: %.100s", strerror(errno)); + + /* we keep a reference to the pty master */ + ptymaster = dup(ptyfd); + if (ptymaster < 0) + packet_disconnect("dup #2 failed: %.100s", strerror(errno)); /* Enter interactive session. */ server_loop(pid, ptyfd, fdout, -1); - /* server_loop has not closed ptyfd and fdout. */ + /* server_loop _has_ closed ptyfd and fdout. */ /* Cancel the cleanup function. */ fatal_remove_cleanup(pty_cleanup_proc, (void *) &cleanup_context); @@ -2194,8 +2226,8 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, * the pty cleanup, so that another process doesn't get this pty * while we're still cleaning up. */ - close(ptyfd); - close(fdout); + if (close(ptymaster) < 0) + error("close(ptymaster): %s", strerror(errno)); } /* @@ -2563,7 +2595,7 @@ do_child(const char *command, struct passwd * pw, const char *term, f = popen(XAUTH_PATH " -q -", "w"); if (f) { fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data); - fclose(f); + pclose(f); } else fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH); } diff --git a/version.h b/version.h index c2ef9ff4..fe2e876e 100644 --- a/version.h +++ b/version.h @@ -1 +1 @@ -#define SSH_VERSION "OpenSSH-1.2.2" +#define SSH_VERSION "OpenSSH-1.2.3"