summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--auth-krb4.c7
-rw-r--r--auth-rhosts.c18
-rw-r--r--canohost.c17
-rw-r--r--log-server.c9
-rw-r--r--readconf.c34
-rw-r--r--readconf.h7
-rw-r--r--ssh.c7
-rw-r--r--sshconnect.c6
-rw-r--r--sshd.c671
10 files changed, 376 insertions, 417 deletions
diff --git a/ChangeLog b/ChangeLog
index 528994344..d1c75cce8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,23 @@
5 - Changed to ssh-add.c broke askpass support. Revised it to be a little more 5 - Changed to ssh-add.c broke askpass support. Revised it to be a little more
6 modular. 6 modular.
7 - Revised autoconf support for enabling/disabling askpass support. 7 - Revised autoconf support for enabling/disabling askpass support.
8 - Merged more OpenBSD CVS changes:
9 [auth-krb4.c]
10 - disconnect if getpeername() fails
11 - missing xfree(*client)
12 [canohost.c]
13 - disconnect if getpeername() fails
14 - fix comment: we _do_ disconnect if ip-options are set
15 [sshd.c]
16 - disconnect if getpeername() fails
17 - move checking of remote port to central place
18 [auth-rhosts.c] move checking of remote port to central place
19 [log-server.c] avoid extra fd per sshd, from millert@
20 [readconf.c] print _all_ bad config-options in ssh(1), too
21 [readconf.h] print _all_ bad config-options in ssh(1), too
22 [ssh.c] print _all_ bad config-options in ssh(1), too
23 [sshconnect.c] disconnect if getpeername() fails
24 - OpenBSD's changes to sshd.c broke the PAM stuff, re-merged it.
8 25
919991114 2619991114
10 - Solaris compilation fixes (still imcomplete) 27 - Solaris compilation fixes (still imcomplete)
diff --git a/auth-krb4.c b/auth-krb4.c
index 032052338..72acd47db 100644
--- a/auth-krb4.c
+++ b/auth-krb4.c
@@ -6,7 +6,7 @@
6 6
7 Kerberos v4 authentication and ticket-passing routines. 7 Kerberos v4 authentication and ticket-passing routines.
8 8
9 $Id: auth-krb4.c,v 1.3 1999/11/11 06:57:39 damien Exp $ 9 $Id: auth-krb4.c,v 1.4 1999/11/15 04:25:10 damien Exp $
10*/ 10*/
11 11
12#include "includes.h" 12#include "includes.h"
@@ -89,8 +89,10 @@ int auth_krb4(const char *server_user, KTEXT auth, char **client)
89 debug("getsockname failed: %.100s", strerror(errno)); 89 debug("getsockname failed: %.100s", strerror(errno));
90 r = sizeof(foreign); 90 r = sizeof(foreign);
91 memset(&foreign, 0, sizeof(foreign)); 91 memset(&foreign, 0, sizeof(foreign));
92 if (getpeername(s, (struct sockaddr *)&foreign, &r) < 0) 92 if (getpeername(s, (struct sockaddr *)&foreign, &r) < 0) {
93 debug("getpeername failed: %.100s", strerror(errno)); 93 debug("getpeername failed: %.100s", strerror(errno));
94 fatal_cleanup();
95 }
94 96
95 instance[0] = '*'; instance[1] = 0; 97 instance[0] = '*'; instance[1] = 0;
96 98
@@ -110,6 +112,7 @@ int auth_krb4(const char *server_user, KTEXT auth, char **client)
110 packet_send_debug("Kerberos V4 .klogin authorization failed!"); 112 packet_send_debug("Kerberos V4 .klogin authorization failed!");
111 log("Kerberos V4 .klogin authorization failed for %s to account %s", 113 log("Kerberos V4 .klogin authorization failed for %s to account %s",
112 *client, server_user); 114 *client, server_user);
115 xfree(*client);
113 return 0; 116 return 0;
114 } 117 }
115 /* Increment the checksum, and return it encrypted with the session key. */ 118 /* Increment the checksum, and return it encrypted with the session key. */
diff --git a/auth-rhosts.c b/auth-rhosts.c
index 7e5614cb8..8f6655d4d 100644
--- a/auth-rhosts.c
+++ b/auth-rhosts.c
@@ -16,7 +16,7 @@ the login based on rhosts authentication. This file also processes
16*/ 16*/
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: auth-rhosts.c,v 1.2 1999/11/12 04:19:27 damien Exp $"); 19RCSID("$Id: auth-rhosts.c,v 1.3 1999/11/15 04:25:10 damien Exp $");
20 20
21#include "packet.h" 21#include "packet.h"
22#include "ssh.h" 22#include "ssh.h"
@@ -161,7 +161,6 @@ int auth_rhosts(struct passwd *pw, const char *client_user)
161 extern ServerOptions options; 161 extern ServerOptions options;
162 char buf[1024]; 162 char buf[1024];
163 const char *hostname, *ipaddr; 163 const char *hostname, *ipaddr;
164 int port;
165 struct stat st; 164 struct stat st;
166 static const char *rhosts_files[] = { ".shosts", ".rhosts", NULL }; 165 static const char *rhosts_files[] = { ".shosts", ".rhosts", NULL };
167 unsigned int rhosts_file_index; 166 unsigned int rhosts_file_index;
@@ -190,21 +189,6 @@ int auth_rhosts(struct passwd *pw, const char *client_user)
190 /* Get the name, address, and port of the remote host. */ 189 /* Get the name, address, and port of the remote host. */
191 hostname = get_canonical_hostname(); 190 hostname = get_canonical_hostname();
192 ipaddr = get_remote_ipaddr(); 191 ipaddr = get_remote_ipaddr();
193 port = get_remote_port();
194
195 /* Check that the connection comes from a privileged port.
196 Rhosts authentication only makes sense for priviledged programs.
197 Of course, if the intruder has root access on his local machine,
198 he can connect from any port. So do not use .rhosts
199 authentication from machines that you do not trust. */
200 if (port >= IPPORT_RESERVED ||
201 port < IPPORT_RESERVED / 2)
202 {
203 log("Connection from %.100s from nonpriviledged port %d",
204 hostname, port);
205 packet_send_debug("Your ssh client is not running as root.");
206 return 0;
207 }
208 192
209 /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ 193 /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
210 if (pw->pw_uid != 0) 194 if (pw->pw_uid != 0)
diff --git a/canohost.c b/canohost.c
index 85d97292b..08f798758 100644
--- a/canohost.c
+++ b/canohost.c
@@ -14,7 +14,7 @@ Functions for returning the canonical host name of the remote site.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: canohost.c,v 1.1 1999/10/27 03:42:43 damien Exp $"); 17RCSID("$Id: canohost.c,v 1.2 1999/11/15 04:25:10 damien Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "xmalloc.h" 20#include "xmalloc.h"
@@ -35,9 +35,8 @@ char *get_remote_hostname(int socket)
35 memset(&from, 0, sizeof(from)); 35 memset(&from, 0, sizeof(from));
36 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) 36 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0)
37 { 37 {
38 error("getpeername failed: %.100s", strerror(errno)); 38 debug("getpeername failed: %.100s", strerror(errno));
39 strlcpy(name, "UNKNOWN", sizeof name); 39 fatal_cleanup();
40 goto check_ip_options;
41 } 40 }
42 41
43 /* Map the IP address to a host name. */ 42 /* Map the IP address to a host name. */
@@ -99,7 +98,7 @@ char *get_remote_hostname(int socket)
99 98
100 check_ip_options: 99 check_ip_options:
101 100
102 /* If IP options are supported, make sure there are none (log and clear 101 /* If IP options are supported, make sure there are none (log and disconnect
103 them if any are found). Basically we are worried about source routing; 102 them if any are found). Basically we are worried about source routing;
104 it can be used to pretend you are somebody (ip-address) you are not. 103 it can be used to pretend you are somebody (ip-address) you are not.
105 That itself may be "almost acceptable" under certain circumstances, 104 That itself may be "almost acceptable" under certain circumstances,
@@ -184,8 +183,8 @@ const char *get_remote_ipaddr()
184 memset(&from, 0, sizeof(from)); 183 memset(&from, 0, sizeof(from));
185 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) 184 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0)
186 { 185 {
187 error("getpeername failed: %.100s", strerror(errno)); 186 debug("getpeername failed: %.100s", strerror(errno));
188 return NULL; 187 fatal_cleanup();
189 } 188 }
190 189
191 /* Get the IP address in ascii. */ 190 /* Get the IP address in ascii. */
@@ -207,8 +206,8 @@ int get_peer_port(int sock)
207 memset(&from, 0, sizeof(from)); 206 memset(&from, 0, sizeof(from));
208 if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) 207 if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0)
209 { 208 {
210 error("getpeername failed: %.100s", strerror(errno)); 209 debug("getpeername failed: %.100s", strerror(errno));
211 return 0; 210 fatal_cleanup();
212 } 211 }
213 212
214 /* Return port number. */ 213 /* Return port number. */
diff --git a/log-server.c b/log-server.c
index 6642dbedf..805df6b6f 100644
--- a/log-server.c
+++ b/log-server.c
@@ -15,7 +15,7 @@ to the system log.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: log-server.c,v 1.2 1999/11/11 06:57:39 damien Exp $"); 18RCSID("$Id: log-server.c,v 1.3 1999/11/15 04:25:10 damien Exp $");
19 19
20#include <syslog.h> 20#include <syslog.h>
21#include "packet.h" 21#include "packet.h"
@@ -24,6 +24,7 @@ RCSID("$Id: log-server.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
24 24
25static LogLevel log_level = SYSLOG_LEVEL_INFO; 25static LogLevel log_level = SYSLOG_LEVEL_INFO;
26static int log_on_stderr = 0; 26static int log_on_stderr = 0;
27static int log_facility = LOG_AUTH;
27 28
28/* Initialize the log. 29/* Initialize the log.
29 av0 program name (should be argv[0]) 30 av0 program name (should be argv[0])
@@ -33,7 +34,6 @@ static int log_on_stderr = 0;
33 34
34void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) 35void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
35{ 36{
36 int log_facility;
37 37
38 switch (level) 38 switch (level)
39 { 39 {
@@ -93,8 +93,6 @@ void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
93 } 93 }
94 94
95 log_on_stderr = on_stderr; 95 log_on_stderr = on_stderr;
96 closelog(); /* Close any previous log. */
97 openlog(av0, LOG_PID, log_facility);
98} 96}
99 97
100#define MSGBUFSIZE 1024 98#define MSGBUFSIZE 1024
@@ -106,6 +104,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
106 char fmtbuf[MSGBUFSIZE]; 104 char fmtbuf[MSGBUFSIZE];
107 char *txt = NULL; 105 char *txt = NULL;
108 int pri = LOG_INFO; 106 int pri = LOG_INFO;
107 extern char *__progname;
109 108
110 if (level > log_level) 109 if (level > log_level)
111 return; 110 return;
@@ -143,5 +142,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
143 } 142 }
144 if (log_on_stderr) 143 if (log_on_stderr)
145 fprintf(stderr, "%s\n", msgbuf); 144 fprintf(stderr, "%s\n", msgbuf);
145 openlog(__progname, LOG_PID, log_facility);
146 syslog(pri, "%.500s", msgbuf); 146 syslog(pri, "%.500s", msgbuf);
147 closelog();
147} 148}
diff --git a/readconf.c b/readconf.c
index 2a99266aa..b341322c8 100644
--- a/readconf.c
+++ b/readconf.c
@@ -14,7 +14,7 @@ Functions for reading the configuration files.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: readconf.c,v 1.2 1999/11/11 06:57:39 damien Exp $"); 17RCSID("$Id: readconf.c,v 1.3 1999/11/15 04:25:10 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "cipher.h" 20#include "cipher.h"
@@ -88,6 +88,7 @@ RCSID("$Id: readconf.c,v 1.2 1999/11/11 06:57:39 damien Exp $");
88 88
89typedef enum 89typedef enum
90{ 90{
91 oBadOption,
91 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, 92 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
92 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, 93 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
93#ifdef KRB4 94#ifdef KRB4
@@ -222,16 +223,16 @@ static OpCodes parse_token(const char *cp, const char *filename, int linenum)
222 if (strcmp(cp, keywords[i].name) == 0) 223 if (strcmp(cp, keywords[i].name) == 0)
223 return keywords[i].opcode; 224 return keywords[i].opcode;
224 225
225 fatal("%.200s line %d: Bad configuration option.", 226 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
226 filename, linenum); 227 filename, linenum, cp);
227 /*NOTREACHED*/ 228 return oBadOption;
228 return 0;
229} 229}
230 230
231/* Processes a single option line as used in the configuration files. 231/* Processes a single option line as used in the configuration files.
232 This only sets those values that have not already been set. */ 232 This only sets those values that have not already been set. */
233 233
234void process_config_line(Options *options, const char *host, 234int
235process_config_line(Options *options, const char *host,
235 char *line, const char *filename, int linenum, 236 char *line, const char *filename, int linenum,
236 int *activep) 237 int *activep)
237{ 238{
@@ -241,7 +242,7 @@ void process_config_line(Options *options, const char *host,
241 /* Skip leading whitespace. */ 242 /* Skip leading whitespace. */
242 cp = line + strspn(line, WHITESPACE); 243 cp = line + strspn(line, WHITESPACE);
243 if (!*cp || *cp == '\n' || *cp == '#') 244 if (!*cp || *cp == '\n' || *cp == '#')
244 return; 245 return 0;
245 246
246 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 247 /* Get the keyword. (Each line is supposed to begin with a keyword). */
247 cp = strtok(cp, WHITESPACE); 248 cp = strtok(cp, WHITESPACE);
@@ -256,7 +257,9 @@ void process_config_line(Options *options, const char *host,
256 257
257 switch (opcode) 258 switch (opcode)
258 { 259 {
259 260 case oBadOption:
261 return -1; /* don't panic, but count bad options */
262 /*NOTREACHED*/
260 case oForwardAgent: 263 case oForwardAgent:
261 intptr = &options->forward_agent; 264 intptr = &options->forward_agent;
262 parse_flag: 265 parse_flag:
@@ -426,7 +429,7 @@ void process_config_line(Options *options, const char *host,
426 *charptr = string; 429 *charptr = string;
427 else 430 else
428 xfree(string); 431 xfree(string);
429 return; 432 return 0;
430 433
431 case oPort: 434 case oPort:
432 intptr = &options->port; 435 intptr = &options->port;
@@ -533,7 +536,7 @@ void process_config_line(Options *options, const char *host,
533 break; 536 break;
534 } 537 }
535 /* Avoid garbage check below, as strtok already returned NULL. */ 538 /* Avoid garbage check below, as strtok already returned NULL. */
536 return; 539 return 0;
537 540
538 case oEscapeChar: 541 case oEscapeChar:
539 intptr = &options->escape_char; 542 intptr = &options->escape_char;
@@ -561,13 +564,14 @@ void process_config_line(Options *options, const char *host,
561 break; 564 break;
562 565
563 default: 566 default:
564 fatal("parse_config_file: Unimplemented opcode %d", opcode); 567 fatal("process_config_line: Unimplemented opcode %d", opcode);
565 } 568 }
566 569
567 /* Check that there is no garbage at end of line. */ 570 /* Check that there is no garbage at end of line. */
568 if (strtok(NULL, WHITESPACE) != NULL) 571 if (strtok(NULL, WHITESPACE) != NULL)
569 fatal("%.200s line %d: garbage at end of line.", 572 fatal("%.200s line %d: garbage at end of line.",
570 filename, linenum); 573 filename, linenum);
574 return 0;
571} 575}
572 576
573 577
@@ -580,6 +584,7 @@ void read_config_file(const char *filename, const char *host, Options *options)
580 FILE *f; 584 FILE *f;
581 char line[1024]; 585 char line[1024];
582 int active, linenum; 586 int active, linenum;
587 int bad_options = 0;
583 588
584 /* Open the file. */ 589 /* Open the file. */
585 f = fopen(filename, "r"); 590 f = fopen(filename, "r");
@@ -596,10 +601,13 @@ void read_config_file(const char *filename, const char *host, Options *options)
596 { 601 {
597 /* Update line number counter. */ 602 /* Update line number counter. */
598 linenum++; 603 linenum++;
599 604 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
600 process_config_line(options, host, line, filename, linenum, &active); 605 bad_options++;
601 } 606 }
602 fclose(f); 607 fclose(f);
608 if (bad_options > 0)
609 fatal("%s: terminating, %d bad configuration options\n",
610 filename, bad_options);
603} 611}
604 612
605/* Initializes options to special values that indicate that they have not 613/* Initializes options to special values that indicate that they have not
diff --git a/readconf.h b/readconf.h
index 8839a1bd5..d2d387df1 100644
--- a/readconf.h
+++ b/readconf.h
@@ -13,7 +13,7 @@ Functions for reading the configuration file.
13 13
14*/ 14*/
15 15
16/* RCSID("$Id: readconf.h,v 1.2 1999/11/11 06:57:39 damien Exp $"); */ 16/* RCSID("$Id: readconf.h,v 1.3 1999/11/15 04:25:10 damien Exp $"); */
17 17
18#ifndef READCONF_H 18#ifndef READCONF_H
19#define READCONF_H 19#define READCONF_H
@@ -92,8 +92,9 @@ void initialize_options(Options *options);
92void fill_default_options(Options *options); 92void fill_default_options(Options *options);
93 93
94/* Processes a single option line as used in the configuration files. 94/* Processes a single option line as used in the configuration files.
95 This only sets those values that have not already been set. */ 95 This only sets those values that have not already been set.
96void process_config_line(Options *options, const char *host, 96 Returns 0 for legal options */
97int process_config_line(Options *options, const char *host,
97 char *line, const char *filename, int linenum, 98 char *line, const char *filename, int linenum,
98 int *activep); 99 int *activep);
99 100
diff --git a/ssh.c b/ssh.c
index a8a806b8c..2f3b5fc1b 100644
--- a/ssh.c
+++ b/ssh.c
@@ -18,7 +18,7 @@ Modified to work with SSL by Niels Provos <provos@citi.umich.edu> in Canada.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: ssh.c,v 1.7 1999/11/13 02:28:45 damien Exp $"); 21RCSID("$Id: ssh.c,v 1.8 1999/11/15 04:25:10 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "ssh.h" 24#include "ssh.h"
@@ -383,8 +383,9 @@ main(int ac, char **av)
383 383
384 case 'o': 384 case 'o':
385 dummy = 1; 385 dummy = 1;
386 process_config_line(&options, host ? host : "", optarg, 386 if (process_config_line(&options, host ? host : "", optarg,
387 "command-line", 0, &dummy); 387 "command-line", 0, &dummy) != 0)
388 exit(1);
388 break; 389 break;
389 390
390 default: 391 default:
diff --git a/sshconnect.c b/sshconnect.c
index 033184595..f984bcaa0 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -15,7 +15,7 @@ login (authentication) dialog.
15*/ 15*/
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: sshconnect.c,v 1.7 1999/11/12 23:51:58 damien Exp $"); 18RCSID("$Id: sshconnect.c,v 1.8 1999/11/15 04:25:10 damien Exp $");
19 19
20#ifdef HAVE_OPENSSL 20#ifdef HAVE_OPENSSL
21#include <openssl/bn.h> 21#include <openssl/bn.h>
@@ -730,8 +730,10 @@ int try_kerberos_authentication()
730 r = sizeof(foreign); 730 r = sizeof(foreign);
731 memset(&foreign, 0, sizeof(foreign)); 731 memset(&foreign, 0, sizeof(foreign));
732 if (getpeername(packet_get_connection_in(), 732 if (getpeername(packet_get_connection_in(),
733 (struct sockaddr *)&foreign, &r) < 0) 733 (struct sockaddr *)&foreign, &r) < 0) {
734 debug("getpeername failed: %s", strerror(errno)); 734 debug("getpeername failed: %s", strerror(errno));
735 fatal_cleanup();
736 }
735 737
736 /* Get server reply. */ 738 /* Get server reply. */
737 type = packet_read(&plen); 739 type = packet_read(&plen);
diff --git a/sshd.c b/sshd.c
index b975c8dcc..a0cc46638 100644
--- a/sshd.c
+++ b/sshd.c
@@ -18,7 +18,7 @@ agent connections.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: sshd.c,v 1.17 1999/11/12 04:19:27 damien Exp $"); 21RCSID("$Id: sshd.c,v 1.18 1999/11/15 04:25:10 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "rsa.h" 24#include "rsa.h"
@@ -114,9 +114,10 @@ int received_sighup = 0;
114RSA *public_key; 114RSA *public_key;
115 115
116/* Prototypes for various functions defined later in this file. */ 116/* Prototypes for various functions defined later in this file. */
117void do_connection(int privileged_port); 117void do_connection();
118void do_authentication(char *user, int privileged_port); 118void do_authentication(char *user);
119void eat_packets_and_disconnect(const char *user); 119void do_authloop(struct passwd *pw);
120void do_fake_authloop(char *user);
120void do_authenticated(struct passwd *pw); 121void do_authenticated(struct passwd *pw);
121void do_exec_pty(const char *command, int ptyfd, int ttyfd, 122void do_exec_pty(const char *command, int ptyfd, int ttyfd,
122 const char *ttyname, struct passwd *pw, const char *term, 123 const char *ttyname, struct passwd *pw, const char *term,
@@ -128,11 +129,12 @@ void do_exec_no_pty(const char *command, struct passwd *pw,
128void do_child(const char *command, struct passwd *pw, const char *term, 129void do_child(const char *command, struct passwd *pw, const char *term,
129 const char *display, const char *auth_proto, 130 const char *display, const char *auth_proto,
130 const char *auth_data, const char *ttyname); 131 const char *auth_data, const char *ttyname);
132
131#ifdef HAVE_LIBPAM 133#ifdef HAVE_LIBPAM
132static int pamconv(int num_msg, const struct pam_message **msg, 134static int pamconv(int num_msg, const struct pam_message **msg,
133 struct pam_response **resp, void *appdata_ptr); 135 struct pam_response **resp, void *appdata_ptr);
134void do_pam_account_and_session(const char *username, const char *password, 136void do_pam_account_and_session(const char *username,
135 const char *remote_user, const char *remote_host); 137 const char *remote_user, const char *remote_host);
136void pam_cleanup_proc(void *context); 138void pam_cleanup_proc(void *context);
137 139
138static struct pam_conv conv = { 140static struct pam_conv conv = {
@@ -228,7 +230,7 @@ void pam_cleanup_proc(void *context)
228 } 230 }
229} 231}
230 232
231void do_pam_account_and_session(const char *username, const char *password, const char *remote_user, const char *remote_host) 233void do_pam_account_and_session(const char *username, const char *remote_user, const char *remote_host)
232{ 234{
233 int pam_retval; 235 int pam_retval;
234 236
@@ -239,7 +241,7 @@ void do_pam_account_and_session(const char *username, const char *password, cons
239 if (pam_retval != PAM_SUCCESS) 241 if (pam_retval != PAM_SUCCESS)
240 { 242 {
241 log("PAM set rhost failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); 243 log("PAM set rhost failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
242 eat_packets_and_disconnect(username); 244 do_fake_authloop(username);
243 } 245 }
244 } 246 }
245 247
@@ -250,7 +252,7 @@ void do_pam_account_and_session(const char *username, const char *password, cons
250 if (pam_retval != PAM_SUCCESS) 252 if (pam_retval != PAM_SUCCESS)
251 { 253 {
252 log("PAM set ruser failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); 254 log("PAM set ruser failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
253 eat_packets_and_disconnect(username); 255 do_fake_authloop(username);
254 } 256 }
255 } 257 }
256 258
@@ -258,14 +260,14 @@ void do_pam_account_and_session(const char *username, const char *password, cons
258 if (pam_retval != PAM_SUCCESS) 260 if (pam_retval != PAM_SUCCESS)
259 { 261 {
260 log("PAM rejected by account configuration: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); 262 log("PAM rejected by account configuration: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
261 eat_packets_and_disconnect(username); 263 do_fake_authloop(username);
262 } 264 }
263 265
264 pam_retval = pam_open_session((pam_handle_t *)pamh, 0); 266 pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
265 if (pam_retval != PAM_SUCCESS) 267 if (pam_retval != PAM_SUCCESS)
266 { 268 {
267 log("PAM session setup failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); 269 log("PAM session setup failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
268 eat_packets_and_disconnect(username); 270 do_fake_authloop(username);
269 } 271 }
270} 272}
271#endif /* HAVE_LIBPAM */ 273#endif /* HAVE_LIBPAM */
@@ -375,6 +377,7 @@ main(int ac, char **av)
375 struct sockaddr_in sin; 377 struct sockaddr_in sin;
376 char buf[100]; /* Must not be larger than remote_version. */ 378 char buf[100]; /* Must not be larger than remote_version. */
377 char remote_version[100]; /* Must be at least as big as buf. */ 379 char remote_version[100]; /* Must be at least as big as buf. */
380 int remote_port;
378 char *comment; 381 char *comment;
379 FILE *f; 382 FILE *f;
380 struct linger linger; 383 struct linger linger;
@@ -742,6 +745,8 @@ main(int ac, char **av)
742 have a key. */ 745 have a key. */
743 packet_set_connection(sock_in, sock_out); 746 packet_set_connection(sock_in, sock_out);
744 747
748 remote_port = get_remote_port();
749
745 /* Check whether logins are denied from this host. */ 750 /* Check whether logins are denied from this host. */
746#ifdef LIBWRAP 751#ifdef LIBWRAP
747 { 752 {
@@ -755,13 +760,11 @@ main(int ac, char **av)
755 close(sock_out); 760 close(sock_out);
756 refuse(&req); 761 refuse(&req);
757 } 762 }
758 log("Connection from %.500s port %d", 763 log("Connection from %.500s port %d", eval_client(&req), remote_port);
759 eval_client(&req), get_remote_port());
760 } 764 }
761#else 765#else
762 /* Log the connection. */ 766 /* Log the connection. */
763 log("Connection from %.100s port %d", 767 log("Connection from %.100s port %d", get_remote_ipaddr(), remote_port);
764 get_remote_ipaddr(), get_remote_port());
765#endif /* LIBWRAP */ 768#endif /* LIBWRAP */
766 769
767 /* We don\'t want to listen forever unless the other side successfully 770 /* We don\'t want to listen forever unless the other side successfully
@@ -834,11 +837,23 @@ main(int ac, char **av)
834 } 837 }
835 } 838 }
836 839
840 /* Check that the connection comes from a privileged port.
841 Rhosts- and Rhosts-RSA-Authentication only make sense
842 from priviledged programs.
843 Of course, if the intruder has root access on his local machine,
844 he can connect from any port. So do not use these authentication
845 methods from machines that you do not trust. */
846 if (remote_port >= IPPORT_RESERVED ||
847 remote_port < IPPORT_RESERVED / 2)
848 {
849 options.rhosts_authentication = 0;
850 options.rhosts_rsa_authentication = 0;
851 }
852
837 packet_set_nonblocking(); 853 packet_set_nonblocking();
838 854
839 /* Handle the connection. We pass as argument whether the connection 855 /* Handle the connection. */
840 came from a privileged port. */ 856 do_connection();
841 do_connection(get_remote_port() < IPPORT_RESERVED);
842 857
843#ifdef KRB4 858#ifdef KRB4
844 /* Cleanup user's ticket cache file. */ 859 /* Cleanup user's ticket cache file. */
@@ -879,7 +894,8 @@ main(int ac, char **av)
879 been exchanged. This sends server key and performs the key exchange. 894 been exchanged. This sends server key and performs the key exchange.
880 Server and host keys will no longer be needed after this functions. */ 895 Server and host keys will no longer be needed after this functions. */
881 896
882void do_connection(int privileged_port) 897void
898do_connection()
883{ 899{
884 int i, len; 900 int i, len;
885 BIGNUM *session_key_int; 901 BIGNUM *session_key_int;
@@ -1071,7 +1087,7 @@ void do_connection(int privileged_port)
1071 1087
1072 setproctitle("%s", user); 1088 setproctitle("%s", user);
1073 /* Do the authentication. */ 1089 /* Do the authentication. */
1074 do_authentication(user, privileged_port); 1090 do_authentication(user);
1075} 1091}
1076 1092
1077/* Check if the user is allowed to log in via ssh. If user is listed in 1093/* Check if the user is allowed to log in via ssh. If user is listed in
@@ -1154,26 +1170,13 @@ allowed_user(struct passwd *pw)
1154 1170
1155/* Performs authentication of an incoming connection. Session key has already 1171/* Performs authentication of an incoming connection. Session key has already
1156 been exchanged and encryption is enabled. User is the user name to log 1172 been exchanged and encryption is enabled. User is the user name to log
1157 in as (received from the clinet). Privileged_port is true if the 1173 in as (received from the client). */
1158 connection comes from a privileged port (used for .rhosts authentication).*/
1159
1160#define MAX_AUTH_FAILURES 5
1161 1174
1162void 1175void
1163do_authentication(char *user, int privileged_port) 1176do_authentication(char *user)
1164{ 1177{
1165 int type;
1166 int authenticated = 0;
1167 int authentication_failures = 0;
1168 char *password = NULL;
1169 struct passwd *pw, pwcopy; 1178 struct passwd *pw, pwcopy;
1170 char *client_user = NULL; 1179
1171 unsigned int client_host_key_bits;
1172 BIGNUM *client_host_key_e, *client_host_key_n;
1173#ifdef HAVE_LIBPAM
1174 int pam_retval;
1175#endif /* HAVE_LIBPAM */
1176
1177#ifdef AFS 1180#ifdef AFS
1178 /* If machine has AFS, set process authentication group. */ 1181 /* If machine has AFS, set process authentication group. */
1179 if (k_hasafs()) { 1182 if (k_hasafs()) {
@@ -1185,8 +1188,8 @@ do_authentication(char *user, int privileged_port)
1185 /* Verify that the user is a valid user. */ 1188 /* Verify that the user is a valid user. */
1186 pw = getpwnam(user); 1189 pw = getpwnam(user);
1187 if (!pw || !allowed_user(pw)) 1190 if (!pw || !allowed_user(pw))
1188 eat_packets_and_disconnect(user); 1191 do_fake_authloop(user);
1189 1192
1190 /* Take a copy of the returned structure. */ 1193 /* Take a copy of the returned structure. */
1191 memset(&pwcopy, 0, sizeof(pwcopy)); 1194 memset(&pwcopy, 0, sizeof(pwcopy));
1192 pwcopy.pw_name = xstrdup(pw->pw_name); 1195 pwcopy.pw_name = xstrdup(pw->pw_name);
@@ -1199,13 +1202,11 @@ do_authentication(char *user, int privileged_port)
1199 1202
1200#ifdef HAVE_LIBPAM 1203#ifdef HAVE_LIBPAM
1201 debug("Starting up PAM with username \"%.200s\"", pw->pw_name); 1204 debug("Starting up PAM with username \"%.200s\"", pw->pw_name);
1202 pam_retval = pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh); 1205
1203 if (pam_retval != PAM_SUCCESS) 1206 if (pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh) != PAM_SUCCESS)
1204 { 1207 fatal("PAM initialisation failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
1205 log("PAM initialisation failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); 1208
1206 eat_packets_and_disconnect(user); 1209 fatal_add_cleanup(&pam_cleanup_proc, NULL);
1207 }
1208 fatal_add_cleanup(&pam_cleanup_proc, NULL);
1209#endif 1210#endif
1210 1211
1211 /* If we are not running as root, the user must have the same uid as the 1212 /* If we are not running as root, the user must have the same uid as the
@@ -1224,313 +1225,263 @@ do_authentication(char *user, int privileged_port)
1224 { 1225 {
1225 /* Authentication with empty password succeeded. */ 1226 /* Authentication with empty password succeeded. */
1226 debug("Login for user %.100s accepted without authentication.", user); 1227 debug("Login for user %.100s accepted without authentication.", user);
1227 /* authentication_type = SSH_AUTH_PASSWORD; */ 1228 } else {
1228 authenticated = 1; 1229 /* Loop until the user has been authenticated or the connection is closed,
1229 /* Success packet will be sent after loop below. */ 1230 do_authloop() returns only if authentication is successfull */
1231 do_authloop(pw);
1230 } 1232 }
1231 else 1233
1234 /* XXX log unified auth message */
1235
1236 /* Check if the user is logging in as root and root logins are disallowed. */
1237 if (pw->pw_uid == 0 && !options.permit_root_login)
1232 { 1238 {
1233 /* Indicate that authentication is needed. */ 1239 if (forced_command)
1234 packet_start(SSH_SMSG_FAILURE); 1240 log("Root login accepted for forced command.");
1235 packet_send(); 1241 else
1236 packet_write_wait(); 1242 packet_disconnect("ROOT LOGIN REFUSED FROM %.200s",
1243 get_canonical_hostname());
1237 } 1244 }
1238 1245
1239 /* Loop until the user has been authenticated or the connection is closed. */ 1246 /* The user has been authenticated and accepted. */
1240 while (!authenticated) 1247 packet_start(SSH_SMSG_SUCCESS);
1241 { 1248 packet_send();
1242 int plen; 1249 packet_write_wait();
1243 /* Get a packet from the client. */
1244 type = packet_read(&plen);
1245
1246 /* Process the packet. */
1247 switch (type)
1248 {
1249 1250
1250#ifdef AFS 1251 /* Perform session preparation. */
1251 case SSH_CMSG_HAVE_KERBEROS_TGT: 1252 do_authenticated(pw);
1252 if (!options.kerberos_tgt_passing) 1253}
1253 { 1254
1254 /* packet_get_all(); */ 1255#define MAX_AUTH_FAILURES 5
1255 log("Kerberos tgt passing disabled."); 1256
1256 break; 1257/* read packets and try to authenticate local user *pw.
1257 } 1258 return if authentication is successfull */
1258 else { 1259void
1259 /* Accept Kerberos tgt. */ 1260do_authloop(struct passwd *pw)
1260 int dlen; 1261{
1261 char *tgt = packet_get_string(&dlen); 1262 int authentication_failures = 0;
1262 packet_integrity_check(plen, 4 + dlen, type); 1263 unsigned int client_host_key_bits;
1263 if (!auth_kerberos_tgt(pw, tgt)) 1264 BIGNUM *client_host_key_e, *client_host_key_n;
1264 debug("Kerberos tgt REFUSED for %s", user); 1265 BIGNUM *n;
1265 xfree(tgt); 1266 char *client_user, *password;
1266 } 1267 int plen, dlen, nlen, ulen, elen;
1267 continue; 1268
1269 /* Indicate that authentication is needed. */
1270 packet_start(SSH_SMSG_FAILURE);
1271 packet_send();
1272 packet_write_wait();
1273
1274 for (;;) {
1275 int authenticated = 0;
1268 1276
1269 case SSH_CMSG_HAVE_AFS_TOKEN: 1277 /* Get a packet from the client. */
1270 if (!options.afs_token_passing || !k_hasafs()) { 1278 int type = packet_read(&plen);
1279
1280 /* Process the packet. */
1281 switch (type)
1282 {
1283#ifdef AFS
1284 case SSH_CMSG_HAVE_KERBEROS_TGT:
1285 if (!options.kerberos_tgt_passing)
1286 {
1271 /* packet_get_all(); */ 1287 /* packet_get_all(); */
1272 log("AFS token passing disabled."); 1288 log("Kerberos tgt passing disabled.");
1273 break; 1289 break;
1274 } 1290 }
1275 else { 1291 else {
1276 /* Accept AFS token. */ 1292 /* Accept Kerberos tgt. */
1277 int dlen; 1293 char *tgt = packet_get_string(&dlen);
1278 char *token_string = packet_get_string(&dlen); 1294 packet_integrity_check(plen, 4 + dlen, type);
1279 packet_integrity_check(plen, 4 + dlen, type); 1295 if (!auth_kerberos_tgt(pw, tgt))
1280 if (!auth_afs_token(pw, token_string)) 1296 debug("Kerberos tgt REFUSED for %s", pw->pw_name);
1281 debug("AFS token REFUSED for %s", user); 1297 xfree(tgt);
1282 xfree(token_string); 1298 }
1283 continue; 1299 continue;
1284 } 1300
1301 case SSH_CMSG_HAVE_AFS_TOKEN:
1302 if (!options.afs_token_passing || !k_hasafs()) {
1303 /* packet_get_all(); */
1304 log("AFS token passing disabled.");
1305 break;
1306 }
1307 else {
1308 /* Accept AFS token. */
1309 char *token_string = packet_get_string(&dlen);
1310 packet_integrity_check(plen, 4 + dlen, type);
1311 if (!auth_afs_token(pw, token_string))
1312 debug("AFS token REFUSED for %s", pw->pw_name);
1313 xfree(token_string);
1314 }
1315 continue;
1285#endif /* AFS */ 1316#endif /* AFS */
1286
1287#ifdef KRB4
1288 case SSH_CMSG_AUTH_KERBEROS:
1289 if (!options.kerberos_authentication)
1290 {
1291 /* packet_get_all(); */
1292 log("Kerberos authentication disabled.");
1293 break;
1294 }
1295 else {
1296 /* Try Kerberos v4 authentication. */
1297 KTEXT_ST auth;
1298 char *tkt_user = NULL;
1299 char *kdata = packet_get_string((unsigned int *)&auth.length);
1300 packet_integrity_check(plen, 4 + auth.length, type);
1301
1302 if (auth.length < MAX_KTXT_LEN)
1303 memcpy(auth.dat, kdata, auth.length);
1304 xfree(kdata);
1305 1317
1306 if (auth_krb4(user, &auth, &tkt_user)) { 1318#ifdef KRB4
1307 /* Client has successfully authenticated to us. */ 1319 case SSH_CMSG_AUTH_KERBEROS:
1308 log("Kerberos authentication accepted %s for account " 1320 if (!options.kerberos_authentication)
1309 "%s from %s", tkt_user, user, get_canonical_hostname()); 1321 {
1310 /* authentication_type = SSH_AUTH_KERBEROS; */ 1322 /* packet_get_all(); */
1311 authenticated = 1; 1323 log("Kerberos authentication disabled.");
1312 xfree(tkt_user); 1324 break;
1313 }
1314 else {
1315 log("Kerberos authentication failed for account "
1316 "%s from %s", user, get_canonical_hostname());
1317 }
1318 } 1325 }
1319 break; 1326 else {
1320#endif /* KRB4 */ 1327 /* Try Kerberos v4 authentication. */
1328 KTEXT_ST auth;
1329 char *tkt_user = NULL;
1330 char *kdata = packet_get_string((unsigned int *)&auth.length);
1331 packet_integrity_check(plen, 4 + auth.length, type);
1332
1333 if (auth.length < MAX_KTXT_LEN)
1334 memcpy(auth.dat, kdata, auth.length);
1335 xfree(kdata);
1321 1336
1322 case SSH_CMSG_AUTH_RHOSTS: 1337 authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
1323 if (!options.rhosts_authentication) 1338
1324 { 1339 log("Kerberos authentication %s%s for account %s from %s",
1325 log("Rhosts authentication disabled."); 1340 authenticated ? "accepted " : "failed",
1326 break; 1341 tkt_user != NULL ? tkt_user : "",
1327 } 1342 pw->pw_name, get_canonical_hostname());
1328 1343 if (authenticated)
1329 /* Rhosts authentication (also uses /etc/hosts.equiv). */ 1344 xfree(tkt_user);
1330 if (!privileged_port) 1345 }
1331 { 1346 break;
1332 log("Rhosts authentication not available for connections from unprivileged port."); 1347#endif /* KRB4 */
1333 break; 1348
1334 } 1349 case SSH_CMSG_AUTH_RHOSTS:
1335 1350 if (!options.rhosts_authentication)
1336 /* Get client user name. Note that we just have to trust the client;
1337 this is one reason why rhosts authentication is insecure.
1338 (Another is IP-spoofing on a local network.) */
1339 { 1351 {
1340 int dlen; 1352 log("Rhosts authentication disabled.");
1341 client_user = packet_get_string(&dlen); 1353 break;
1342 packet_integrity_check(plen, 4 + dlen, type);
1343 } 1354 }
1355
1356 /* Get client user name. Note that we just have to trust the client;
1357 this is one reason why rhosts authentication is insecure.
1358 (Another is IP-spoofing on a local network.) */
1359 client_user = packet_get_string(&dlen);
1360 packet_integrity_check(plen, 4 + dlen, type);
1361
1362 /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
1363 authenticated = auth_rhosts(pw, client_user);
1344 1364
1345 /* Try to authenticate using /etc/hosts.equiv and .rhosts. */ 1365 log("Rhosts authentication %s for %.100s, remote %.100s on %.700s.",
1346 if (auth_rhosts(pw, client_user)) 1366 authenticated ? "accepted" : "failed",
1347 { 1367 pw->pw_name, client_user, get_canonical_hostname());
1348 /* Authentication accepted. */
1349 log("Rhosts authentication accepted for %.100s, remote %.100s on %.700s.",
1350 user, client_user, get_canonical_hostname());
1351 authenticated = 1;
1352#ifndef HAVE_LIBPAM 1368#ifndef HAVE_LIBPAM
1353 xfree(client_user); 1369 xfree(client_user);
1354#endif /* HAVE_LIBPAM */ 1370#endif /* HAVE_LIBPAM */
1355 break; 1371 break;
1356 } 1372
1357 log("Rhosts authentication failed for %.100s, remote %.100s.", 1373 case SSH_CMSG_AUTH_RHOSTS_RSA:
1358 user, client_user); 1374 if (!options.rhosts_rsa_authentication)
1359#ifndef HAVE_LIBPAM
1360 xfree(client_user);
1361#endif /* HAVE_LIBPAM */
1362 break;
1363
1364 case SSH_CMSG_AUTH_RHOSTS_RSA:
1365 if (!options.rhosts_rsa_authentication)
1366 {
1367 log("Rhosts with RSA authentication disabled.");
1368 break;
1369 }
1370
1371 /* Rhosts authentication (also uses /etc/hosts.equiv) with RSA
1372 host authentication. */
1373 if (!privileged_port)
1374 {
1375 log("Rhosts authentication not available for connections from unprivileged port.");
1376 break;
1377 }
1378
1379 { 1375 {
1380 int ulen, elen, nlen; 1376 log("Rhosts with RSA authentication disabled.");
1381 /* Get client user name. Note that we just have to trust 1377 break;
1382 the client; root on the client machine can claim to be
1383 any user. */
1384 client_user = packet_get_string(&ulen);
1385
1386 /* Get the client host key. */
1387 client_host_key_e = BN_new();
1388 client_host_key_n = BN_new();
1389 client_host_key_bits = packet_get_int();
1390 packet_get_bignum(client_host_key_e, &elen);
1391 packet_get_bignum(client_host_key_n, &nlen);
1392
1393 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
1394 } 1378 }
1395 1379
1396 if (auth_rhosts_rsa(pw, client_user, 1380 /* Get client user name. Note that we just have to trust
1397 client_host_key_bits, client_host_key_e, client_host_key_n)) 1381 the client; root on the client machine can claim to be
1398 { 1382 any user. */
1399 /* Authentication accepted. */ 1383 client_user = packet_get_string(&ulen);
1400 authenticated = 1; 1384
1401#ifndef HAVE_LIBPAM 1385 /* Get the client host key. */
1402 xfree(client_user); 1386 client_host_key_e = BN_new();
1403#endif /* HAVE_LIBPAM */ 1387 client_host_key_n = BN_new();
1404 BN_clear_free(client_host_key_e); 1388 client_host_key_bits = packet_get_int();
1405 BN_clear_free(client_host_key_n); 1389 packet_get_bignum(client_host_key_e, &elen);
1406 break; 1390 packet_get_bignum(client_host_key_n, &nlen);
1407 } 1391
1408 log("Rhosts authentication failed for %.100s, remote %.100s.", 1392 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
1409 user, client_user); 1393
1394 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key_bits,
1395 client_host_key_e, client_host_key_n);
1396 log("Rhosts authentication %s for %.100s, remote %.100s.",
1397 authenticated ? "accepted" : "failed",
1398 pw->pw_name, client_user);
1410#ifndef HAVE_LIBPAM 1399#ifndef HAVE_LIBPAM
1411 xfree(client_user); 1400 xfree(client_user);
1412#endif /* HAVE_LIBPAM */ 1401#endif /* HAVE_LIBPAM */
1413 BN_clear_free(client_host_key_e); 1402 BN_clear_free(client_host_key_e);
1414 BN_clear_free(client_host_key_n); 1403 BN_clear_free(client_host_key_n);
1415 break; 1404 break;
1416 1405
1417 case SSH_CMSG_AUTH_RSA: 1406 case SSH_CMSG_AUTH_RSA:
1418 if (!options.rsa_authentication) 1407 if (!options.rsa_authentication)
1419 {
1420 log("RSA authentication disabled.");
1421 break;
1422 }
1423
1424 /* RSA authentication requested. */
1425 { 1408 {
1426 int nlen; 1409 log("RSA authentication disabled.");
1427 BIGNUM *n; 1410 break;
1428 n = BN_new();
1429 packet_get_bignum(n, &nlen);
1430
1431 packet_integrity_check(plen, nlen, type);
1432
1433 if (auth_rsa(pw, n))
1434 {
1435 /* Successful authentication. */
1436 BN_clear_free(n);
1437 log("RSA authentication for %.100s accepted.", user);
1438 authenticated = 1;
1439 break;
1440 }
1441 BN_clear_free(n);
1442 log("RSA authentication for %.100s failed.", user);
1443 } 1411 }
1444 break; 1412
1445 1413 /* RSA authentication requested. */
1446 case SSH_CMSG_AUTH_PASSWORD: 1414 n = BN_new();
1447 if (!options.password_authentication) 1415 packet_get_bignum(n, &nlen);
1448 { 1416 packet_integrity_check(plen, nlen, type);
1449 log("Password authentication disabled."); 1417 authenticated = auth_rsa(pw, n);
1450 break; 1418 BN_clear_free(n);
1451 } 1419 log("RSA authentication %s for %.100s.",
1452 1420 authenticated ? "accepted" : "failed",
1453 /* Password authentication requested. */ 1421 pw->pw_name);
1454 /* Read user password. It is in plain text, but was transmitted 1422 break;
1455 over the encrypted channel so it is not visible to an outside 1423
1456 observer. */ 1424 case SSH_CMSG_AUTH_PASSWORD:
1425 if (!options.password_authentication)
1457 { 1426 {
1458 int passw_len; 1427 log("Password authentication disabled.");
1459 password = packet_get_string(&passw_len); 1428 break;
1460 packet_integrity_check(plen, 4 + passw_len, type);
1461 } 1429 }
1462 1430
1431 /* Read user password. It is in plain text, but was transmitted
1432 over the encrypted channel so it is not visible to an outside
1433 observer. */
1434 password = packet_get_string(&dlen);
1435 packet_integrity_check(plen, 4 + dlen, type);
1436
1463#ifdef HAVE_LIBPAM 1437#ifdef HAVE_LIBPAM
1464 pampasswd = password; 1438 /* Do PAM auth with password */
1465 1439 pampasswd = password;
1466 pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); 1440 pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
1467 if (pam_retval == PAM_SUCCESS) 1441 if (pam_retval == PAM_SUCCESS)
1468 { 1442 {
1469 log("PAM Password authentication accepted for \"%.100s\"", user); 1443 log("PAM Password authentication accepted for user \"%.100s\"", user);
1470 authenticated = 1; 1444 authenticated = 1;
1471 break; 1445 break;
1472 } else 1446 }
1473 { 1447
1474 log("PAM Password authentication for \"%.100s\" failed: %s", 1448 log("PAM Password authentication for \"%.100s\" failed: %s",
1475 user, pam_strerror((pam_handle_t *)pamh, pam_retval)); 1449 user, pam_strerror((pam_handle_t *)pamh, pam_retval));
1476 break; 1450 break;
1477 }
1478#else /* HAVE_LIBPAM */ 1451#else /* HAVE_LIBPAM */
1479 /* Try authentication with the password. */ 1452 /* Try authentication with the password. */
1480 if (auth_password(pw, password)) 1453 authenticated = auth_password(pw, password);
1481 {
1482 /* Successful authentication. */
1483 /* Clear the password from memory. */
1484 memset(password, 0, strlen(password));
1485 xfree(password);
1486 log("Password authentication for %.100s accepted.", user);
1487 authenticated = 1;
1488 break;
1489 }
1490 log("Password authentication for %.100s failed.", user);
1491 memset(password, 0, strlen(password));
1492 xfree(password);
1493 break;
1494#endif /* HAVE_LIBPAM */
1495
1496 case SSH_CMSG_AUTH_TIS:
1497 /* TIS Authentication is unsupported */
1498 log("TIS authentication disabled.");
1499 break;
1500 1454
1501 default: 1455 memset(password, 0, strlen(password));
1502 /* Any unknown messages will be ignored (and failure returned) 1456 xfree(password);
1503 during authentication. */
1504 log("Unknown message during authentication: type %d", type);
1505 break; /* Respond with a failure message. */
1506 }
1507 /* If successfully authenticated, break out of loop. */
1508 if (authenticated)
1509 break; 1457 break;
1510 1458#endif /* HAVE_LIBPAM */
1511 if (++authentication_failures >= MAX_AUTH_FAILURES) { 1459
1512 packet_disconnect("Too many authentication failures for %.100s from %.200s", 1460 case SSH_CMSG_AUTH_TIS:
1513 pw->pw_name, get_canonical_hostname()); 1461 /* TIS Authentication is unsupported */
1462 log("TIS authentication disabled.");
1463 break;
1464
1465 default:
1466 /* Any unknown messages will be ignored (and failure returned)
1467 during authentication. */
1468 log("Unknown message during authentication: type %d", type);
1469 break; /* Respond with a failure message. */
1514 } 1470 }
1515 /* Send a message indicating that the authentication attempt failed. */
1516 packet_start(SSH_SMSG_FAILURE);
1517 packet_send();
1518 packet_write_wait();
1519 1471
1520 } 1472 if (authenticated)
1521 1473 break;
1522 /* Check if the user is logging in as root and root logins are disallowed. */ 1474 if (++authentication_failures >= MAX_AUTH_FAILURES)
1523 if (pw->pw_uid == 0 && !options.permit_root_login) 1475 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1524 { 1476 pw->pw_name, get_canonical_hostname());
1525 if (forced_command) 1477 /* Send a message indicating that the authentication attempt failed. */
1526 log("Root login accepted for forced command."); 1478 packet_start(SSH_SMSG_FAILURE);
1527 else 1479 packet_send();
1528 packet_disconnect("ROOT LOGIN REFUSED FROM %.200s", 1480 packet_write_wait();
1529 get_canonical_hostname()); 1481 }
1530 }
1531 1482
1532#ifdef HAVE_LIBPAM 1483#ifdef HAVE_LIBPAM
1533 do_pam_account_and_session(pw->pw_name, password, client_user, get_canonical_hostname()); 1484 do_pam_account_and_session(pw->pw_name, client_user, get_canonical_hostname());
1534 1485
1535 /* Clean up */ 1486 /* Clean up */
1536 if (client_user != NULL) 1487 if (client_user != NULL)
@@ -1542,65 +1493,55 @@ do_authentication(char *user, int privileged_port)
1542 xfree(password); 1493 xfree(password);
1543 } 1494 }
1544#endif /* HAVE_LIBPAM */ 1495#endif /* HAVE_LIBPAM */
1545
1546 /* The user has been authenticated and accepted. */
1547 packet_start(SSH_SMSG_SUCCESS);
1548 packet_send();
1549 packet_write_wait();
1550
1551 /* Perform session preparation. */
1552 do_authenticated(pw);
1553} 1496}
1554 1497
1555/* Read authentication messages, but return only failures until */ 1498/* The user does not exist or access is denied,
1556/* max auth attempts exceeded, then disconnect */ 1499 but fake indication that authentication is needed. */
1557void eat_packets_and_disconnect(const char *user) 1500void
1501do_fake_authloop(char *user)
1558{ 1502{
1559 int authentication_failures = 0; 1503 int authentication_failures = 0;
1560 1504
1505 /* Indicate that authentication is needed. */
1561 packet_start(SSH_SMSG_FAILURE); 1506 packet_start(SSH_SMSG_FAILURE);
1562 packet_send(); 1507 packet_send();
1563 packet_write_wait(); 1508 packet_write_wait();
1564 1509
1565 /* Keep reading packets, and always respond with a failure. This is to 1510 /* Keep reading packets, and always respond with a failure. This is to
1566 avoid disclosing whether such a user really exists. */ 1511 avoid disclosing whether such a user really exists. */
1567 while(1) 1512 for (;;)
1568 {
1569 /* Read a packet. This will not return if the client disconnects. */
1570 int plen;
1571#ifndef SKEY
1572 (void) packet_read(&plen);
1573#else /* SKEY */
1574 int type = packet_read(&plen);
1575 int passw_len;
1576 char *password, *skeyinfo;
1577 if (options.password_authentication &&
1578 options.skey_authentication == 1 &&
1579 type == SSH_CMSG_AUTH_PASSWORD &&
1580 (password = packet_get_string(&passw_len)) != NULL &&
1581 passw_len == 5 &&
1582 strncasecmp(password, "s/key", 5) == 0 &&
1583 (skeyinfo = skey_fake_keyinfo(user)) != NULL )
1584 { 1513 {
1585 /* Send a fake s/key challenge. */ 1514 /* Read a packet. This will not return if the client disconnects. */
1586 packet_send_debug(skeyinfo); 1515 int plen;
1587 } 1516 int type = packet_read(&plen);
1588#endif /* SKEY */ 1517#ifdef SKEY
1589 if (++authentication_failures >= MAX_AUTH_FAILURES) 1518 int passw_len;
1590 { 1519 char *password, *skeyinfo;
1591 packet_disconnect("Too many authentication failures for %.100s from %.200s", 1520 if (options.password_authentication &&
1592 user, get_canonical_hostname()); 1521 options.skey_authentication == 1 &&
1522 type == SSH_CMSG_AUTH_PASSWORD &&
1523 (password = packet_get_string(&passw_len)) != NULL &&
1524 passw_len == 5 &&
1525 strncasecmp(password, "s/key", 5) == 0 &&
1526 (skeyinfo = skey_fake_keyinfo(user)) != NULL ){
1527 /* Send a fake s/key challenge. */
1528 packet_send_debug(skeyinfo);
1529 }
1530#endif
1531 if (++authentication_failures >= MAX_AUTH_FAILURES)
1532 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1533 user, get_canonical_hostname());
1534 /* Send failure. This should be indistinguishable from a failed
1535 authentication. */
1536 packet_start(SSH_SMSG_FAILURE);
1537 packet_send();
1538 packet_write_wait();
1593 } 1539 }
1594 /* Send failure. This should be indistinguishable from a failed
1595 authentication. */
1596 packet_start(SSH_SMSG_FAILURE);
1597 packet_send();
1598 packet_write_wait();
1599 }
1600 /*NOTREACHED*/ 1540 /*NOTREACHED*/
1601 abort(); 1541 abort();
1602} 1542}
1603 1543
1544
1604/* Remove local Xauthority file. */ 1545/* Remove local Xauthority file. */
1605static void 1546static void
1606xauthfile_cleanup_proc(void *ignore) 1547xauthfile_cleanup_proc(void *ignore)
@@ -2075,8 +2016,10 @@ void do_exec_pty(const char *command, int ptyfd, int ttyfd,
2075 { 2016 {
2076 fromlen = sizeof(from); 2017 fromlen = sizeof(from);
2077 if (getpeername(packet_get_connection_in(), 2018 if (getpeername(packet_get_connection_in(),
2078 (struct sockaddr *)&from, &fromlen) < 0) 2019 (struct sockaddr *)&from, &fromlen) < 0) {
2079 fatal("getpeername: %.100s", strerror(errno)); 2020 debug("getpeername: %.100s", strerror(errno));
2021 fatal_cleanup();
2022 }
2080 } 2023 }
2081 2024
2082 /* Record that there was a login on that terminal. */ 2025 /* Record that there was a login on that terminal. */