blob: b975c8dcc5a8d700ac361bc4b1fed07281c16c59 [file] [log] [blame]
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001/*
2
3sshd.c
4
5Author: Tatu Ylonen <ylo@cs.hut.fi>
6
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved
9
10Created: Fri Mar 17 17:09:28 1995 ylo
11
12This program is the ssh daemon. It listens for connections from clients, and
13performs authentication, executes use commands or shell, and forwards
14information to/from the application to the user client over an encrypted
15connection. This can also handle forwarding of X11, TCP/IP, and authentication
16agent connections.
17
18*/
19
20#include "includes.h"
Damien Miller6d7b2cd1999-11-12 15:19:27 +110021RCSID("$Id: sshd.c,v 1.17 1999/11/12 04:19:27 damien Exp $");
Damien Millerd4a8b7e1999-10-27 13:42:43 +100022
23#include "xmalloc.h"
24#include "rsa.h"
25#include "ssh.h"
26#include "pty.h"
27#include "packet.h"
28#include "buffer.h"
29#include "cipher.h"
30#include "mpaux.h"
31#include "servconf.h"
32#include "uidswap.h"
33#include "compat.h"
34
35#ifdef LIBWRAP
36#include <tcpd.h>
37#include <syslog.h>
38int allow_severity = LOG_INFO;
39int deny_severity = LOG_WARNING;
40#endif /* LIBWRAP */
41
42#ifndef O_NOCTTY
43#define O_NOCTTY 0
44#endif
45
Damien Millerd4a8b7e1999-10-27 13:42:43 +100046/* Local Xauthority file. */
Damien Miller5ce662a1999-11-11 17:57:39 +110047static char *xauthfile = NULL;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100048
49/* Server configuration options. */
50ServerOptions options;
51
52/* Name of the server configuration file. */
53char *config_file_name = SERVER_CONFIG_FILE;
54
55/* Debug mode flag. This can be set on the command line. If debug
56 mode is enabled, extra debugging output will be sent to the system
57 log, the daemon will not go to background, and will exit after processing
58 the first connection. */
59int debug_flag = 0;
60
61/* Flag indicating that the daemon is being started from inetd. */
62int inetd_flag = 0;
63
Damien Miller5ce662a1999-11-11 17:57:39 +110064/* debug goes to stderr unless inetd_flag is set */
65int log_stderr = 0;
66
Damien Millerd4a8b7e1999-10-27 13:42:43 +100067/* argv[0] without path. */
68char *av0;
69
70/* Saved arguments to main(). */
71char **saved_argv;
72
73/* This is set to the socket that the server is listening; this is used in
74 the SIGHUP signal handler. */
75int listen_sock;
76
77/* Flags set in auth-rsa from authorized_keys flags. These are set in
78 auth-rsa.c. */
79int no_port_forwarding_flag = 0;
80int no_agent_forwarding_flag = 0;
81int no_x11_forwarding_flag = 0;
82int no_pty_flag = 0;
83char *forced_command = NULL; /* RSA authentication "command=" option. */
84struct envstring *custom_environment = NULL;
85 /* RSA authentication "environment=" options. */
86
87/* Session id for the current session. */
88unsigned char session_id[16];
89
90/* Any really sensitive data in the application is contained in this structure.
91 The idea is that this structure could be locked into memory so that the
92 pages do not get written into swap. However, there are some problems.
93 The private key contains BIGNUMs, and we do not (in principle) have
94 access to the internals of them, and locking just the structure is not
95 very useful. Currently, memory locking is not implemented. */
96struct
97{
98 /* Private part of server key. */
99 RSA *private_key;
100
101 /* Private part of host key. */
102 RSA *host_key;
103} sensitive_data;
104
105/* Flag indicating whether the current session key has been used. This flag
106 is set whenever the key is used, and cleared when the key is regenerated. */
107int key_used = 0;
108
109/* This is set to true when SIGHUP is received. */
110int received_sighup = 0;
111
112/* Public side of the server key. This value is regenerated regularly with
113 the private key. */
114RSA *public_key;
115
116/* Prototypes for various functions defined later in this file. */
117void do_connection(int privileged_port);
118void do_authentication(char *user, int privileged_port);
Damien Miller3d112ef1999-10-28 13:20:30 +1000119void eat_packets_and_disconnect(const char *user);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000120void do_authenticated(struct passwd *pw);
121void do_exec_pty(const char *command, int ptyfd, int ttyfd,
122 const char *ttyname, struct passwd *pw, const char *term,
123 const char *display, const char *auth_proto,
124 const char *auth_data);
125void do_exec_no_pty(const char *command, struct passwd *pw,
126 const char *display, const char *auth_proto,
127 const char *auth_data);
128void do_child(const char *command, struct passwd *pw, const char *term,
129 const char *display, const char *auth_proto,
130 const char *auth_data, const char *ttyname);
Damien Miller06230761999-10-28 14:03:14 +1000131#ifdef HAVE_LIBPAM
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000132static int pamconv(int num_msg, const struct pam_message **msg,
133 struct pam_response **resp, void *appdata_ptr);
Damien Miller3d112ef1999-10-28 13:20:30 +1000134void do_pam_account_and_session(const char *username, const char *password,
Damien Miller332e67f1999-10-27 23:42:05 +1000135 const char *remote_user, const char *remote_host);
136void pam_cleanup_proc(void *context);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000137
138static struct pam_conv conv = {
139 pamconv,
140 NULL
141};
Damien Miller332e67f1999-10-27 23:42:05 +1000142struct pam_handle_t *pamh = NULL;
143const char *pampasswd = NULL;
Damien Miller356a0b01999-11-08 15:30:59 +1100144char *pamconv_msg = NULL;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000145
146static int pamconv(int num_msg, const struct pam_message **msg,
147 struct pam_response **resp, void *appdata_ptr)
148{
149 int count = 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000150 struct pam_response *reply = NULL;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000151
Damien Miller332e67f1999-10-27 23:42:05 +1000152 /* PAM will free this later */
153 reply = malloc(num_msg * sizeof(*reply));
154 if (reply == NULL)
155 return PAM_CONV_ERR;
156
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000157 for(count = 0; count < num_msg; count++)
158 {
159 switch (msg[count]->msg_style)
160 {
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000161 case PAM_PROMPT_ECHO_OFF:
Damien Miller3d112ef1999-10-28 13:20:30 +1000162 if (pampasswd == NULL)
Damien Miller332e67f1999-10-27 23:42:05 +1000163 {
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000164 free(reply);
Damien Miller332e67f1999-10-27 23:42:05 +1000165 return PAM_CONV_ERR;
166 }
167 reply[count].resp_retcode = PAM_SUCCESS;
168 reply[count].resp = xstrdup(pampasswd);
169 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000170
Damien Miller332e67f1999-10-27 23:42:05 +1000171 case PAM_TEXT_INFO:
172 reply[count].resp_retcode = PAM_SUCCESS;
173 reply[count].resp = xstrdup("");
Damien Miller356a0b01999-11-08 15:30:59 +1100174
175 if (msg[count]->msg == NULL) break;
176 debug("Adding PAM message: %s", msg[count]->msg);
177 if (pamconv_msg == NULL)
178 {
179 pamconv_msg = malloc(strlen(msg[count]->msg) + 2);
180
181 if (pamconv_msg == NULL)
182 return PAM_CONV_ERR;
183
184 strncpy(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
185 pamconv_msg[strlen(msg[count]->msg)] = '\n';
186 pamconv_msg[strlen(msg[count]->msg) + 1] = '\0';
187 } else
188 {
189 pamconv_msg = realloc(pamconv_msg, strlen(pamconv_msg) + strlen(msg[count]->msg) + 2);
190 strncat(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
191 pamconv_msg[strlen(pamconv_msg)] = '\n';
192 pamconv_msg[strlen(pamconv_msg) + 1] = '\0';
193 }
Damien Miller332e67f1999-10-27 23:42:05 +1000194 break;
195
196 case PAM_PROMPT_ECHO_ON:
197 case PAM_ERROR_MSG:
198 default:
199 free(reply);
200 return PAM_CONV_ERR;
201 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000202 }
203
Damien Miller332e67f1999-10-27 23:42:05 +1000204 *resp = reply;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000205
206 return PAM_SUCCESS;
207}
208
209void pam_cleanup_proc(void *context)
210{
Damien Miller07a826d1999-10-29 11:49:20 +1000211 int pam_retval;
Damien Miller332e67f1999-10-27 23:42:05 +1000212
213 if (pamh != NULL)
214 {
Damien Miller07a826d1999-10-29 11:49:20 +1000215 pam_retval = pam_close_session((pam_handle_t *)pamh, 0);
216 if (pam_retval != PAM_SUCCESS)
217 {
218 log("Cannot close PAM session: %.200s",
219 pam_strerror((pam_handle_t *)pamh, pam_retval));
220 }
221
222 pam_retval = pam_end((pam_handle_t *)pamh, pam_retval);
223 if (pam_retval != PAM_SUCCESS)
224 {
225 log("Cannot release PAM authentication: %.200s",
226 pam_strerror((pam_handle_t *)pamh, pam_retval));
227 }
Damien Miller332e67f1999-10-27 23:42:05 +1000228 }
229}
230
Damien Miller3d112ef1999-10-28 13:20:30 +1000231void do_pam_account_and_session(const char *username, const char *password, const char *remote_user, const char *remote_host)
Damien Miller332e67f1999-10-27 23:42:05 +1000232{
Damien Miller07a826d1999-10-29 11:49:20 +1000233 int pam_retval;
234
235 if (remote_host != NULL)
Damien Miller332e67f1999-10-27 23:42:05 +1000236 {
Damien Miller07a826d1999-10-29 11:49:20 +1000237 debug("PAM setting rhost to \"%.200s\"", remote_host);
238 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, remote_host);
239 if (pam_retval != PAM_SUCCESS)
240 {
241 log("PAM set rhost failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
242 eat_packets_and_disconnect(username);
243 }
244 }
245
246 if (remote_user != NULL)
247 {
248 debug("PAM setting ruser to \"%.200s\"", remote_user);
249 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user);
250 if (pam_retval != PAM_SUCCESS)
251 {
252 log("PAM set ruser failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
253 eat_packets_and_disconnect(username);
254 }
255 }
256
257 pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0);
258 if (pam_retval != PAM_SUCCESS)
259 {
260 log("PAM rejected by account configuration: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
Damien Miller3d112ef1999-10-28 13:20:30 +1000261 eat_packets_and_disconnect(username);
262 }
Damien Miller332e67f1999-10-27 23:42:05 +1000263
Damien Miller07a826d1999-10-29 11:49:20 +1000264 pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
265 if (pam_retval != PAM_SUCCESS)
Damien Miller3d112ef1999-10-28 13:20:30 +1000266 {
Damien Miller07a826d1999-10-29 11:49:20 +1000267 log("PAM session setup failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
Damien Miller3d112ef1999-10-28 13:20:30 +1000268 eat_packets_and_disconnect(username);
Damien Miller332e67f1999-10-27 23:42:05 +1000269 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000270}
Damien Miller06230761999-10-28 14:03:14 +1000271#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000272
273/* Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP;
274 the effect is to reread the configuration file (and to regenerate
275 the server key). */
276
277void sighup_handler(int sig)
278{
279 received_sighup = 1;
280 signal(SIGHUP, sighup_handler);
281}
282
283/* Called from the main program after receiving SIGHUP. Restarts the
284 server. */
285
286void sighup_restart()
287{
288 log("Received SIGHUP; restarting.");
289 close(listen_sock);
290 execv(saved_argv[0], saved_argv);
291 log("RESTART FAILED: av0='%s', error: %s.", av0, strerror(errno));
292 exit(1);
293}
294
295/* Generic signal handler for terminating signals in the master daemon.
296 These close the listen socket; not closing it seems to cause "Address
297 already in use" problems on some machines, which is inconvenient. */
298
299void sigterm_handler(int sig)
300{
301 log("Received signal %d; terminating.", sig);
302 close(listen_sock);
303 exit(255);
304}
305
306/* SIGCHLD handler. This is called whenever a child dies. This will then
307 reap any zombies left by exited c. */
308
309void main_sigchld_handler(int sig)
310{
311 int save_errno = errno;
312 int status;
313 wait(&status);
314 signal(SIGCHLD, main_sigchld_handler);
315 errno = save_errno;
316}
317
318/* Signal handler for the alarm after the login grace period has expired. */
319
320void grace_alarm_handler(int sig)
321{
322 /* Close the connection. */
323 packet_close();
324
325 /* Log error and exit. */
326 fatal("Timeout before authentication.");
327}
328
329/* Signal handler for the key regeneration alarm. Note that this
330 alarm only occurs in the daemon waiting for connections, and it does not
331 do anything with the private key or random state before forking. Thus there
332 should be no concurrency control/asynchronous execution problems. */
333
334void key_regeneration_alarm(int sig)
335{
336 int save_errno = errno;
337
338 /* Check if we should generate a new key. */
339 if (key_used)
340 {
341 /* This should really be done in the background. */
342 log("Generating new %d bit RSA key.", options.server_key_bits);
343
344 if (sensitive_data.private_key != NULL)
345 RSA_free(sensitive_data.private_key);
346 sensitive_data.private_key = RSA_new();
347
348 if (public_key != NULL)
349 RSA_free(public_key);
350 public_key = RSA_new();
351
352 rsa_generate_key(sensitive_data.private_key, public_key,
353 options.server_key_bits);
354 arc4random_stir();
355 key_used = 0;
356 log("RSA key generation complete.");
357 }
358
359 /* Reschedule the alarm. */
360 signal(SIGALRM, key_regeneration_alarm);
361 alarm(options.key_regeneration_time);
362 errno = save_errno;
363}
364
365/* Main program for the daemon. */
366
367int
368main(int ac, char **av)
369{
370 extern char *optarg;
371 extern int optind;
372 int opt, aux, sock_in, sock_out, newsock, i, pid, on = 1;
373 int remote_major, remote_minor;
374 int silentrsa = 0;
375 struct sockaddr_in sin;
376 char buf[100]; /* Must not be larger than remote_version. */
377 char remote_version[100]; /* Must be at least as big as buf. */
378 char *comment;
379 FILE *f;
380 struct linger linger;
381
382 /* Save argv[0]. */
383 saved_argv = av;
384 if (strchr(av[0], '/'))
385 av0 = strrchr(av[0], '/') + 1;
386 else
387 av0 = av[0];
388
389 /* Initialize configuration options to their default values. */
390 initialize_server_options(&options);
391
392 /* Parse command-line arguments. */
393 while ((opt = getopt(ac, av, "f:p:b:k:h:g:diqQ")) != EOF)
394 {
395 switch (opt)
396 {
397 case 'f':
398 config_file_name = optarg;
399 break;
400 case 'd':
401 debug_flag = 1;
Damien Miller5ce662a1999-11-11 17:57:39 +1100402 options.log_level = SYSLOG_LEVEL_DEBUG;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000403 break;
404 case 'i':
405 inetd_flag = 1;
406 break;
407 case 'Q':
408 silentrsa = 1;
409 break;
410 case 'q':
Damien Miller5ce662a1999-11-11 17:57:39 +1100411 options.log_level = SYSLOG_LEVEL_QUIET;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000412 break;
413 case 'b':
414 options.server_key_bits = atoi(optarg);
415 break;
416 case 'p':
417 options.port = atoi(optarg);
418 break;
419 case 'g':
420 options.login_grace_time = atoi(optarg);
421 break;
422 case 'k':
423 options.key_regeneration_time = atoi(optarg);
424 break;
425 case 'h':
426 options.host_key_file = optarg;
427 break;
428 case '?':
429 default:
430 fprintf(stderr, "sshd version %s\n", SSH_VERSION);
431 fprintf(stderr, "Usage: %s [options]\n", av0);
432 fprintf(stderr, "Options:\n");
433 fprintf(stderr, " -f file Configuration file (default %s/sshd_config)\n", ETCDIR);
434 fprintf(stderr, " -d Debugging mode\n");
435 fprintf(stderr, " -i Started from inetd\n");
436 fprintf(stderr, " -q Quiet (no logging)\n");
437 fprintf(stderr, " -p port Listen on the specified port (default: 22)\n");
438 fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n");
439 fprintf(stderr, " -g seconds Grace period for authentication (default: 300)\n");
440 fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n");
441 fprintf(stderr, " -h file File from which to read host key (default: %s)\n",
442 HOST_KEY_FILE);
443 exit(1);
444 }
445 }
446
447 /* check if RSA support exists */
448 if (rsa_alive() == 0) {
449 if (silentrsa == 0)
450 printf("sshd: no RSA support in libssl and libcrypto -- exiting. See ssl(8)\n");
451 log("no RSA support in libssl and libcrypto -- exiting. See ssl(8)");
452 exit(1);
453 }
454
455 /* Read server configuration options from the configuration file. */
456 read_server_config(&options, config_file_name);
457
458 /* Fill in default values for those options not explicitly set. */
459 fill_default_server_options(&options);
460
461 /* Check certain values for sanity. */
462 if (options.server_key_bits < 512 ||
463 options.server_key_bits > 32768)
464 {
465 fprintf(stderr, "Bad server key size.\n");
466 exit(1);
467 }
468 if (options.port < 1 || options.port > 65535)
469 {
470 fprintf(stderr, "Bad port number.\n");
471 exit(1);
472 }
473
474 /* Check that there are no remaining arguments. */
475 if (optind < ac)
476 {
477 fprintf(stderr, "Extra argument %s.\n", av[optind]);
478 exit(1);
479 }
480
481 /* Initialize the log (it is reinitialized below in case we forked). */
Damien Miller5ce662a1999-11-11 17:57:39 +1100482
483 if (debug_flag && !inetd_flag)
484 log_stderr = 1;
485
486 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000487
488 debug("sshd version %.100s", SSH_VERSION);
489
490 sensitive_data.host_key = RSA_new();
491 /* Load the host key. It must have empty passphrase. */
492 if (!load_private_key(options.host_key_file, "",
493 sensitive_data.host_key, &comment))
494 {
495 if (debug_flag)
496 fprintf(stderr, "Could not load host key: %s: %s\n",
497 options.host_key_file, strerror(errno));
498 else
499 {
500 int err = errno;
Damien Miller5ce662a1999-11-11 17:57:39 +1100501 /* force logging */
502 log_init(av0, SYSLOG_LEVEL_DEBUG, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000503 error("Could not load host key: %.200s: %.100s",
504 options.host_key_file, strerror(err));
505 }
506 exit(1);
507 }
508 xfree(comment);
509
510 /* If not in debugging mode, and not started from inetd, disconnect from
511 the controlling terminal, and fork. The original process exits. */
512 if (!debug_flag && !inetd_flag)
513 {
514#ifdef TIOCNOTTY
515 int fd;
516#endif /* TIOCNOTTY */
517 if (daemon(0, 0) < 0)
518 fatal("daemon() failed: %.200s", strerror(errno));
519
520 /* Disconnect from the controlling tty. */
521#ifdef TIOCNOTTY
522 fd = open("/dev/tty", O_RDWR|O_NOCTTY);
523 if (fd >= 0)
524 {
525 (void)ioctl(fd, TIOCNOTTY, NULL);
526 close(fd);
527 }
528#endif /* TIOCNOTTY */
529 }
530
531 /* Reinitialize the log (because of the fork above). */
Damien Miller5ce662a1999-11-11 17:57:39 +1100532 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000533
534 /* Check that server and host key lengths differ sufficiently. This is
535 necessary to make double encryption work with rsaref. Oh, I hate
536 software patents. I dont know if this can go? Niels */
537 if (options.server_key_bits >
538 BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED &&
539 options.server_key_bits <
540 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED)
541 {
542 options.server_key_bits =
543 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED;
544 debug("Forcing server key to %d bits to make it differ from host key.",
545 options.server_key_bits);
546 }
547
548 /* Do not display messages to stdout in RSA code. */
549 rsa_set_verbose(0);
550
551 /* Initialize the random number generator. */
552 arc4random_stir();
553
554 /* Chdir to the root directory so that the current disk can be unmounted
555 if desired. */
556 chdir("/");
557
558 /* Close connection cleanly after attack. */
559 cipher_attack_detected = packet_disconnect;
560
561 /* Start listening for a socket, unless started from inetd. */
562 if (inetd_flag)
563 {
564 int s1, s2;
565 s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */
566 s2 = dup(s1);
567 sock_in = dup(0);
568 sock_out = dup(1);
569 /* We intentionally do not close the descriptors 0, 1, and 2 as our
570 code for setting the descriptors won\'t work if ttyfd happens to
571 be one of those. */
572 debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);
573
574 public_key = RSA_new();
575 sensitive_data.private_key = RSA_new();
576 /* Generate an rsa key. */
577 log("Generating %d bit RSA key.", options.server_key_bits);
578 rsa_generate_key(sensitive_data.private_key, public_key,
579 options.server_key_bits);
580 arc4random_stir();
581 log("RSA key generation complete.");
582 }
583 else
584 {
585 /* Create socket for listening. */
586 listen_sock = socket(AF_INET, SOCK_STREAM, 0);
587 if (listen_sock < 0)
588 fatal("socket: %.100s", strerror(errno));
589
590 /* Set socket options. We try to make the port reusable and have it
591 close as fast as possible without waiting in unnecessary wait states
592 on close. */
593 setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
594 sizeof(on));
595 linger.l_onoff = 1;
596 linger.l_linger = 5;
597 setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *)&linger,
598 sizeof(linger));
599
600 /* Initialize the socket address. */
601 memset(&sin, 0, sizeof(sin));
602 sin.sin_family = AF_INET;
603 sin.sin_addr = options.listen_addr;
604 sin.sin_port = htons(options.port);
605
606 /* Bind the socket to the desired port. */
607 if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
608 {
609 error("bind: %.100s", strerror(errno));
610 shutdown(listen_sock, SHUT_RDWR);
611 close(listen_sock);
612 fatal("Bind to port %d failed.", options.port);
613 }
614
615 if (!debug_flag)
616 {
617 /* Record our pid in /etc/sshd_pid to make it easier to kill the
618 correct sshd. We don\'t want to do this before the bind above
619 because the bind will fail if there already is a daemon, and this
620 will overwrite any old pid in the file. */
621 f = fopen(SSH_DAEMON_PID_FILE, "w");
622 if (f)
623 {
624 fprintf(f, "%u\n", (unsigned int)getpid());
625 fclose(f);
626 }
627 }
628
629 /* Start listening on the port. */
630 log("Server listening on port %d.", options.port);
631 if (listen(listen_sock, 5) < 0)
632 fatal("listen: %.100s", strerror(errno));
633
634 public_key = RSA_new();
635 sensitive_data.private_key = RSA_new();
636 /* Generate an rsa key. */
637 log("Generating %d bit RSA key.", options.server_key_bits);
638 rsa_generate_key(sensitive_data.private_key, public_key,
639 options.server_key_bits);
640 arc4random_stir();
641 log("RSA key generation complete.");
642
643 /* Schedule server key regeneration alarm. */
644 signal(SIGALRM, key_regeneration_alarm);
645 alarm(options.key_regeneration_time);
646
647 /* Arrange to restart on SIGHUP. The handler needs listen_sock. */
648 signal(SIGHUP, sighup_handler);
649 signal(SIGTERM, sigterm_handler);
650 signal(SIGQUIT, sigterm_handler);
651
652 /* Arrange SIGCHLD to be caught. */
653 signal(SIGCHLD, main_sigchld_handler);
654
655 /* Stay listening for connections until the system crashes or the
656 daemon is killed with a signal. */
657 for (;;)
658 {
659 if (received_sighup)
660 sighup_restart();
661 /* Wait in accept until there is a connection. */
662 aux = sizeof(sin);
663 newsock = accept(listen_sock, (struct sockaddr *)&sin, &aux);
664 if (received_sighup)
665 sighup_restart();
666 if (newsock < 0)
667 {
668 if (errno == EINTR)
669 continue;
670 error("accept: %.100s", strerror(errno));
671 continue;
672 }
673
674 /* Got connection. Fork a child to handle it, unless we are in
675 debugging mode. */
676 if (debug_flag)
677 {
678 /* In debugging mode. Close the listening socket, and start
679 processing the connection without forking. */
680 debug("Server will not fork when running in debugging mode.");
681 close(listen_sock);
682 sock_in = newsock;
683 sock_out = newsock;
684 pid = getpid();
685 break;
686 }
687 else
688 {
689 /* Normal production daemon. Fork, and have the child process
690 the connection. The parent continues listening. */
691 if ((pid = fork()) == 0)
692 {
693 /* Child. Close the listening socket, and start using
694 the accepted socket. Reinitialize logging (since our
695 pid has changed). We break out of the loop to handle
696 the connection. */
697 close(listen_sock);
698 sock_in = newsock;
699 sock_out = newsock;
Damien Miller5ce662a1999-11-11 17:57:39 +1100700 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000701 break;
702 }
703 }
704
705 /* Parent. Stay in the loop. */
706 if (pid < 0)
707 error("fork: %.100s", strerror(errno));
708 else
709 debug("Forked child %d.", pid);
710
711 /* Mark that the key has been used (it was "given" to the child). */
712 key_used = 1;
713
714 arc4random_stir();
715
716 /* Close the new socket (the child is now taking care of it). */
717 close(newsock);
718 }
719 }
720
721 /* This is the child processing a new connection. */
722
723 /* Disable the key regeneration alarm. We will not regenerate the key
724 since we are no longer in a position to give it to anyone. We will
725 not restart on SIGHUP since it no longer makes sense. */
726 alarm(0);
727 signal(SIGALRM, SIG_DFL);
728 signal(SIGHUP, SIG_DFL);
729 signal(SIGTERM, SIG_DFL);
730 signal(SIGQUIT, SIG_DFL);
731 signal(SIGCHLD, SIG_DFL);
732
733 /* Set socket options for the connection. We want the socket to close
734 as fast as possible without waiting for anything. If the connection
735 is not a socket, these will do nothing. */
736 /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
737 linger.l_onoff = 1;
738 linger.l_linger = 5;
739 setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
740
741 /* Register our connection. This turns encryption off because we do not
742 have a key. */
743 packet_set_connection(sock_in, sock_out);
744
745 /* Check whether logins are denied from this host. */
746#ifdef LIBWRAP
747 {
748 struct request_info req;
749
750 request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL);
751 fromhost(&req);
752
753 if (!hosts_access(&req)) {
754 close(sock_in);
755 close(sock_out);
756 refuse(&req);
757 }
758 log("Connection from %.500s port %d",
759 eval_client(&req), get_remote_port());
760 }
761#else
762 /* Log the connection. */
763 log("Connection from %.100s port %d",
764 get_remote_ipaddr(), get_remote_port());
765#endif /* LIBWRAP */
766
767 /* We don\'t want to listen forever unless the other side successfully
768 authenticates itself. So we set up an alarm which is cleared after
769 successful authentication. A limit of zero indicates no limit.
770 Note that we don\'t set the alarm in debugging mode; it is just annoying
771 to have the server exit just when you are about to discover the bug. */
772 signal(SIGALRM, grace_alarm_handler);
773 if (!debug_flag)
774 alarm(options.login_grace_time);
775
776 /* Send our protocol version identification. */
777 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
778 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
779 if (write(sock_out, buf, strlen(buf)) != strlen(buf))
780 fatal("Could not write ident string.");
781
782 /* Read other side\'s version identification. */
783 for (i = 0; i < sizeof(buf) - 1; i++)
784 {
785 if (read(sock_in, &buf[i], 1) != 1)
786 fatal("Did not receive ident string.");
787 if (buf[i] == '\r')
788 {
789 buf[i] = '\n';
790 buf[i + 1] = 0;
791 break;
792 }
793 if (buf[i] == '\n')
794 {
795 /* buf[i] == '\n' */
796 buf[i + 1] = 0;
797 break;
798 }
799 }
800 buf[sizeof(buf) - 1] = 0;
801
802 /* Check that the versions match. In future this might accept several
803 versions and set appropriate flags to handle them. */
804 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
805 remote_version) != 3)
806 {
807 const char *s = "Protocol mismatch.\n";
808 (void) write(sock_out, s, strlen(s));
809 close(sock_in);
810 close(sock_out);
811 fatal("Bad protocol version identification: %.100s", buf);
812 }
813 debug("Client protocol version %d.%d; client software version %.100s",
814 remote_major, remote_minor, remote_version);
815 if (remote_major != PROTOCOL_MAJOR)
816 {
817 const char *s = "Protocol major versions differ.\n";
818 (void) write(sock_out, s, strlen(s));
819 close(sock_in);
820 close(sock_out);
821 fatal("Protocol major versions differ: %d vs. %d",
822 PROTOCOL_MAJOR, remote_major);
823 }
824
825 /* Check that the client has sufficiently high software version. */
826 if (remote_major == 1 && remote_minor < 3)
827 packet_disconnect("Your ssh version is too old and is no longer supported. Please install a newer version.");
828
829 if (remote_major == 1 && remote_minor == 3) {
830 enable_compat13();
831 if (strcmp(remote_version, "OpenSSH-1.1") != 0) {
832 debug("Agent forwarding disabled, remote version is not compatible.");
833 no_agent_forwarding_flag = 1;
834 }
835 }
836
837 packet_set_nonblocking();
838
839 /* Handle the connection. We pass as argument whether the connection
840 came from a privileged port. */
841 do_connection(get_remote_port() < IPPORT_RESERVED);
842
843#ifdef KRB4
844 /* Cleanup user's ticket cache file. */
845 if (options.kerberos_ticket_cleanup)
846 (void) dest_tkt();
847#endif /* KRB4 */
848
849 /* Cleanup user's local Xauthority file. */
850 if (xauthfile) unlink(xauthfile);
851
852 /* The connection has been terminated. */
853 log("Closing connection to %.100s", inet_ntoa(sin.sin_addr));
854
Damien Miller06230761999-10-28 14:03:14 +1000855#ifdef HAVE_LIBPAM
Damien Miller332e67f1999-10-27 23:42:05 +1000856 {
857 int retval;
858
859 if (pamh != NULL)
860 {
Damien Miller07a826d1999-10-29 11:49:20 +1000861 debug("Closing PAM session.");
Damien Miller332e67f1999-10-27 23:42:05 +1000862 retval = pam_close_session((pam_handle_t *)pamh, 0);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000863
Damien Miller07a826d1999-10-29 11:49:20 +1000864 debug("Terminating PAM library.");
Damien Miller332e67f1999-10-27 23:42:05 +1000865 if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
866 log("Cannot release PAM authentication.");
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000867
Damien Miller332e67f1999-10-27 23:42:05 +1000868 fatal_remove_cleanup(&pam_cleanup_proc, NULL);
869 }
870 }
Damien Miller06230761999-10-28 14:03:14 +1000871#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000872
873 packet_close();
874
875 exit(0);
876}
877
878/* Process an incoming connection. Protocol version identifiers have already
879 been exchanged. This sends server key and performs the key exchange.
880 Server and host keys will no longer be needed after this functions. */
881
882void do_connection(int privileged_port)
883{
Damien Miller9fa19b61999-11-11 20:44:05 +1100884 int i, len;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000885 BIGNUM *session_key_int;
886 unsigned char session_key[SSH_SESSION_KEY_LENGTH];
887 unsigned char check_bytes[8];
888 char *user;
889 unsigned int cipher_type, auth_mask, protocol_flags;
890 int plen, slen;
891 u_int32_t rand = 0;
892
893 /* Generate check bytes that the client must send back in the user packet
894 in order for it to be accepted; this is used to defy ip spoofing
895 attacks. Note that this only works against somebody doing IP spoofing
896 from a remote machine; any machine on the local network can still see
897 outgoing packets and catch the random cookie. This only affects
898 rhosts authentication, and this is one of the reasons why it is
899 inherently insecure. */
900 for (i = 0; i < 8; i++) {
901 if (i % 4 == 0)
902 rand = arc4random();
903 check_bytes[i] = rand & 0xff;
904 rand >>= 8;
905 }
906
907 /* Send our public key. We include in the packet 64 bits of random
908 data that must be matched in the reply in order to prevent IP spoofing. */
909 packet_start(SSH_SMSG_PUBLIC_KEY);
910 for (i = 0; i < 8; i++)
911 packet_put_char(check_bytes[i]);
912
913 /* Store our public server RSA key. */
914 packet_put_int(BN_num_bits(public_key->n));
915 packet_put_bignum(public_key->e);
916 packet_put_bignum(public_key->n);
917
918 /* Store our public host RSA key. */
919 packet_put_int(BN_num_bits(sensitive_data.host_key->n));
920 packet_put_bignum(sensitive_data.host_key->e);
921 packet_put_bignum(sensitive_data.host_key->n);
922
923 /* Put protocol flags. */
924 packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
925
926 /* Declare which ciphers we support. */
927 packet_put_int(cipher_mask());
928
929 /* Declare supported authentication types. */
930 auth_mask = 0;
931 if (options.rhosts_authentication)
932 auth_mask |= 1 << SSH_AUTH_RHOSTS;
933 if (options.rhosts_rsa_authentication)
934 auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
935 if (options.rsa_authentication)
936 auth_mask |= 1 << SSH_AUTH_RSA;
937#ifdef KRB4
938 if (options.kerberos_authentication)
939 auth_mask |= 1 << SSH_AUTH_KERBEROS;
940#endif
941#ifdef AFS
942 if (options.kerberos_tgt_passing)
943 auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
944 if (options.afs_token_passing)
945 auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
946#endif
947 if (options.password_authentication)
948 auth_mask |= 1 << SSH_AUTH_PASSWORD;
949 packet_put_int(auth_mask);
950
951 /* Send the packet and wait for it to be sent. */
952 packet_send();
953 packet_write_wait();
954
955 debug("Sent %d bit public key and %d bit host key.",
956 BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n));
957
958 /* Read clients reply (cipher type and session key). */
959 packet_read_expect(&plen, SSH_CMSG_SESSION_KEY);
960
961 /* Get cipher type. */
962 cipher_type = packet_get_char();
963
964 /* Get check bytes from the packet. These must match those we sent earlier
965 with the public key packet. */
966 for (i = 0; i < 8; i++)
967 if (check_bytes[i] != packet_get_char())
968 packet_disconnect("IP Spoofing check bytes do not match.");
969
970 debug("Encryption type: %.200s", cipher_name(cipher_type));
971
972 /* Get the encrypted integer. */
973 session_key_int = BN_new();
974 packet_get_bignum(session_key_int, &slen);
975
976 /* Get protocol flags. */
977 protocol_flags = packet_get_int();
978 packet_set_protocol_flags(protocol_flags);
979
980 packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY);
981
982 /* Decrypt it using our private server key and private host key (key with
983 larger modulus first). */
984 if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0)
985 {
986 /* Private key has bigger modulus. */
Damien Miller356a0b01999-11-08 15:30:59 +1100987 if (BN_num_bits(sensitive_data.private_key->n) <
988 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) {
989 fatal("do_connection: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
990 BN_num_bits(sensitive_data.private_key->n),
991 BN_num_bits(sensitive_data.host_key->n),
992 SSH_KEY_BITS_RESERVED);
993 }
994
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000995 rsa_private_decrypt(session_key_int, session_key_int,
996 sensitive_data.private_key);
997 rsa_private_decrypt(session_key_int, session_key_int,
998 sensitive_data.host_key);
999 }
1000 else
1001 {
1002 /* Host key has bigger modulus (or they are equal). */
Damien Miller356a0b01999-11-08 15:30:59 +11001003 if (BN_num_bits(sensitive_data.host_key->n) <
1004 BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) {
1005 fatal("do_connection: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d",
1006 BN_num_bits(sensitive_data.host_key->n),
1007 BN_num_bits(sensitive_data.private_key->n),
1008 SSH_KEY_BITS_RESERVED);
1009 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001010 rsa_private_decrypt(session_key_int, session_key_int,
1011 sensitive_data.host_key);
1012 rsa_private_decrypt(session_key_int, session_key_int,
1013 sensitive_data.private_key);
1014 }
1015
1016 /* Compute session id for this session. */
1017 compute_session_id(session_id, check_bytes,
1018 BN_num_bits(sensitive_data.host_key->n),
1019 sensitive_data.host_key->n,
1020 BN_num_bits(sensitive_data.private_key->n),
1021 sensitive_data.private_key->n);
1022
1023 /* Extract session key from the decrypted integer. The key is in the
1024 least significant 256 bits of the integer; the first byte of the
1025 key is in the highest bits. */
1026 BN_mask_bits(session_key_int, sizeof(session_key) * 8);
Damien Miller9fa19b61999-11-11 20:44:05 +11001027 len = BN_num_bytes(session_key_int);
Damien Miller776af5d1999-11-12 08:49:09 +11001028 if (len < 0 || len > sizeof(session_key))
Damien Miller9fa19b61999-11-11 20:44:05 +11001029 fatal("do_connection: bad len: session_key_int %d > sizeof(session_key) %d",
1030 len, sizeof(session_key));
1031 memset(session_key, 0, sizeof(session_key));
1032 BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001033
1034 /* Xor the first 16 bytes of the session key with the session id. */
1035 for (i = 0; i < 16; i++)
1036 session_key[i] ^= session_id[i];
1037
1038 /* Destroy the decrypted integer. It is no longer needed. */
1039 BN_clear_free(session_key_int);
1040
1041 /* Set the session key. From this on all communications will be
1042 encrypted. */
1043 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH,
1044 cipher_type, 0);
1045
1046 /* Destroy our copy of the session key. It is no longer needed. */
1047 memset(session_key, 0, sizeof(session_key));
1048
1049 debug("Received session key; encryption turned on.");
1050
1051 /* Send an acknowledgement packet. Note that this packet is sent
1052 encrypted. */
1053 packet_start(SSH_SMSG_SUCCESS);
1054 packet_send();
1055 packet_write_wait();
1056
1057 /* Get the name of the user that we wish to log in as. */
1058 packet_read_expect(&plen, SSH_CMSG_USER);
1059
1060 /* Get the user name. */
1061 {
1062 int ulen;
1063 user = packet_get_string(&ulen);
1064 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
1065 }
1066
1067 /* Destroy the private and public keys. They will no longer be needed. */
1068 RSA_free(public_key);
1069 RSA_free(sensitive_data.private_key);
1070 RSA_free(sensitive_data.host_key);
1071
1072 setproctitle("%s", user);
1073 /* Do the authentication. */
1074 do_authentication(user, privileged_port);
1075}
1076
1077/* Check if the user is allowed to log in via ssh. If user is listed in
1078 DenyUsers or user's primary group is listed in DenyGroups, false will
1079 be returned. If AllowUsers isn't empty and user isn't listed there, or
1080 if AllowGroups isn't empty and user isn't listed there, false will be
1081 returned. Otherwise true is returned.
1082 XXX This function should also check if user has a valid shell */
1083
1084static int
1085allowed_user(struct passwd *pw)
1086{
1087 struct group *grp;
1088 int i;
1089
1090 /* Shouldn't be called if pw is NULL, but better safe than sorry... */
1091 if (!pw)
1092 return 0;
1093
1094 /* XXX Should check for valid login shell */
1095
1096 /* Return false if user is listed in DenyUsers */
1097 if (options.num_deny_users > 0)
1098 {
1099 if (!pw->pw_name)
1100 return 0;
1101 for (i = 0; i < options.num_deny_users; i++)
1102 if (match_pattern(pw->pw_name, options.deny_users[i]))
1103 return 0;
1104 }
1105
1106 /* Return false if AllowUsers isn't empty and user isn't listed there */
1107 if (options.num_allow_users > 0)
1108 {
1109 if (!pw->pw_name)
1110 return 0;
1111 for (i = 0; i < options.num_allow_users; i++)
1112 if (match_pattern(pw->pw_name, options.allow_users[i]))
1113 break;
1114 /* i < options.num_allow_users iff we break for loop */
1115 if (i >= options.num_allow_users)
1116 return 0;
1117 }
1118
1119 /* Get the primary group name if we need it. Return false if it fails */
1120 if (options.num_deny_groups > 0 || options.num_allow_groups > 0 )
1121 {
1122 grp = getgrgid(pw->pw_gid);
1123 if (!grp)
1124 return 0;
1125
1126 /* Return false if user's group is listed in DenyGroups */
1127 if (options.num_deny_groups > 0)
1128 {
1129 if (!grp->gr_name)
1130 return 0;
1131 for (i = 0; i < options.num_deny_groups; i++)
1132 if (match_pattern(grp->gr_name, options.deny_groups[i]))
1133 return 0;
1134 }
1135
1136 /* Return false if AllowGroups isn't empty and user's group isn't
1137 listed there */
1138 if (options.num_allow_groups > 0)
1139 {
1140 if (!grp->gr_name)
1141 return 0;
1142 for (i = 0; i < options.num_allow_groups; i++)
1143 if (match_pattern(grp->gr_name, options.allow_groups[i]))
1144 break;
1145 /* i < options.num_allow_groups iff we break for loop */
1146 if (i >= options.num_allow_groups)
1147 return 0;
1148 }
1149 }
1150
1151 /* We found no reason not to let this user try to log on... */
1152 return 1;
1153}
1154
1155/* Performs authentication of an incoming connection. Session key has already
1156 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
1158 connection comes from a privileged port (used for .rhosts authentication).*/
1159
1160#define MAX_AUTH_FAILURES 5
1161
1162void
1163do_authentication(char *user, int privileged_port)
1164{
1165 int type;
1166 int authenticated = 0;
1167 int authentication_failures = 0;
Damien Miller332e67f1999-10-27 23:42:05 +10001168 char *password = NULL;
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001169 struct passwd *pw, pwcopy;
Damien Miller332e67f1999-10-27 23:42:05 +10001170 char *client_user = NULL;
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001171 unsigned int client_host_key_bits;
1172 BIGNUM *client_host_key_e, *client_host_key_n;
Damien Miller07a826d1999-10-29 11:49:20 +10001173#ifdef HAVE_LIBPAM
1174 int pam_retval;
1175#endif /* HAVE_LIBPAM */
1176
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001177#ifdef AFS
1178 /* If machine has AFS, set process authentication group. */
1179 if (k_hasafs()) {
1180 k_setpag();
1181 k_unlog();
1182 }
1183#endif /* AFS */
1184
1185 /* Verify that the user is a valid user. */
1186 pw = getpwnam(user);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001187 if (!pw || !allowed_user(pw))
Damien Miller3d112ef1999-10-28 13:20:30 +10001188 eat_packets_and_disconnect(user);
1189
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001190 /* Take a copy of the returned structure. */
1191 memset(&pwcopy, 0, sizeof(pwcopy));
1192 pwcopy.pw_name = xstrdup(pw->pw_name);
1193 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
1194 pwcopy.pw_uid = pw->pw_uid;
1195 pwcopy.pw_gid = pw->pw_gid;
1196 pwcopy.pw_dir = xstrdup(pw->pw_dir);
1197 pwcopy.pw_shell = xstrdup(pw->pw_shell);
1198 pw = &pwcopy;
1199
Damien Miller06230761999-10-28 14:03:14 +10001200#ifdef HAVE_LIBPAM
Damien Miller07a826d1999-10-29 11:49:20 +10001201 debug("Starting up PAM with username \"%.200s\"", pw->pw_name);
1202 pam_retval = pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh);
1203 if (pam_retval != PAM_SUCCESS)
Damien Miller3d112ef1999-10-28 13:20:30 +10001204 {
Damien Miller07a826d1999-10-29 11:49:20 +10001205 log("PAM initialisation failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
1206 eat_packets_and_disconnect(user);
Damien Miller3d112ef1999-10-28 13:20:30 +10001207 }
Damien Miller07a826d1999-10-29 11:49:20 +10001208 fatal_add_cleanup(&pam_cleanup_proc, NULL);
Damien Miller06230761999-10-28 14:03:14 +10001209#endif
Damien Miller3d112ef1999-10-28 13:20:30 +10001210
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001211 /* If we are not running as root, the user must have the same uid as the
1212 server. */
1213 if (getuid() != 0 && pw->pw_uid != getuid())
1214 packet_disconnect("Cannot change user when server not running as root.");
1215
1216 debug("Attempting authentication for %.100s.", user);
1217
1218 /* If the user has no password, accept authentication immediately. */
1219 if (options.password_authentication &&
1220#ifdef KRB4
1221 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
1222#endif /* KRB4 */
1223 auth_password(pw, ""))
1224 {
1225 /* Authentication with empty password succeeded. */
1226 debug("Login for user %.100s accepted without authentication.", user);
1227 /* authentication_type = SSH_AUTH_PASSWORD; */
1228 authenticated = 1;
1229 /* Success packet will be sent after loop below. */
1230 }
1231 else
1232 {
1233 /* Indicate that authentication is needed. */
1234 packet_start(SSH_SMSG_FAILURE);
1235 packet_send();
1236 packet_write_wait();
1237 }
1238
1239 /* Loop until the user has been authenticated or the connection is closed. */
1240 while (!authenticated)
1241 {
1242 int plen;
1243 /* Get a packet from the client. */
1244 type = packet_read(&plen);
1245
1246 /* Process the packet. */
1247 switch (type)
1248 {
1249
1250#ifdef AFS
1251 case SSH_CMSG_HAVE_KERBEROS_TGT:
1252 if (!options.kerberos_tgt_passing)
1253 {
1254 /* packet_get_all(); */
1255 log("Kerberos tgt passing disabled.");
1256 break;
1257 }
1258 else {
1259 /* Accept Kerberos tgt. */
1260 int dlen;
1261 char *tgt = packet_get_string(&dlen);
1262 packet_integrity_check(plen, 4 + dlen, type);
1263 if (!auth_kerberos_tgt(pw, tgt))
1264 debug("Kerberos tgt REFUSED for %s", user);
1265 xfree(tgt);
1266 }
1267 continue;
1268
1269 case SSH_CMSG_HAVE_AFS_TOKEN:
1270 if (!options.afs_token_passing || !k_hasafs()) {
1271 /* packet_get_all(); */
1272 log("AFS token passing disabled.");
1273 break;
1274 }
1275 else {
1276 /* Accept AFS token. */
1277 int dlen;
1278 char *token_string = packet_get_string(&dlen);
1279 packet_integrity_check(plen, 4 + dlen, type);
Damien Miller356a0b01999-11-08 15:30:59 +11001280 if (!auth_afs_token(pw, token_string))
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001281 debug("AFS token REFUSED for %s", user);
1282 xfree(token_string);
1283 continue;
1284 }
1285#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
1306 if (auth_krb4(user, &auth, &tkt_user)) {
1307 /* Client has successfully authenticated to us. */
1308 log("Kerberos authentication accepted %s for account "
1309 "%s from %s", tkt_user, user, get_canonical_hostname());
1310 /* authentication_type = SSH_AUTH_KERBEROS; */
1311 authenticated = 1;
1312 xfree(tkt_user);
1313 }
1314 else {
1315 log("Kerberos authentication failed for account "
1316 "%s from %s", user, get_canonical_hostname());
1317 }
1318 }
1319 break;
1320#endif /* KRB4 */
1321
1322 case SSH_CMSG_AUTH_RHOSTS:
1323 if (!options.rhosts_authentication)
1324 {
1325 log("Rhosts authentication disabled.");
1326 break;
1327 }
1328
1329 /* Rhosts authentication (also uses /etc/hosts.equiv). */
1330 if (!privileged_port)
1331 {
1332 log("Rhosts authentication not available for connections from unprivileged port.");
1333 break;
1334 }
1335
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 {
1340 int dlen;
1341 client_user = packet_get_string(&dlen);
1342 packet_integrity_check(plen, 4 + dlen, type);
1343 }
1344
1345 /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
Damien Miller6d7b2cd1999-11-12 15:19:27 +11001346 if (auth_rhosts(pw, client_user))
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001347 {
1348 /* Authentication accepted. */
1349 log("Rhosts authentication accepted for %.100s, remote %.100s on %.700s.",
1350 user, client_user, get_canonical_hostname());
1351 authenticated = 1;
Damien Miller06230761999-10-28 14:03:14 +10001352#ifndef HAVE_LIBPAM
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001353 xfree(client_user);
Damien Miller06230761999-10-28 14:03:14 +10001354#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001355 break;
1356 }
1357 log("Rhosts authentication failed for %.100s, remote %.100s.",
1358 user, client_user);
Damien Miller06230761999-10-28 14:03:14 +10001359#ifndef HAVE_LIBPAM
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001360 xfree(client_user);
Damien Miller06230761999-10-28 14:03:14 +10001361#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001362 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 {
1380 int ulen, elen, nlen;
1381 /* Get client user name. Note that we just have to trust
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 }
1395
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001396 if (auth_rhosts_rsa(pw, client_user,
Damien Miller32265091999-11-12 11:33:04 +11001397 client_host_key_bits, client_host_key_e, client_host_key_n))
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001398 {
1399 /* Authentication accepted. */
1400 authenticated = 1;
Damien Miller06230761999-10-28 14:03:14 +10001401#ifndef HAVE_LIBPAM
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001402 xfree(client_user);
Damien Miller06230761999-10-28 14:03:14 +10001403#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001404 BN_clear_free(client_host_key_e);
1405 BN_clear_free(client_host_key_n);
1406 break;
1407 }
1408 log("Rhosts authentication failed for %.100s, remote %.100s.",
1409 user, client_user);
Damien Miller06230761999-10-28 14:03:14 +10001410#ifndef HAVE_LIBPAM
Damien Miller332e67f1999-10-27 23:42:05 +10001411 xfree(client_user);
Damien Miller06230761999-10-28 14:03:14 +10001412#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001413 BN_clear_free(client_host_key_e);
1414 BN_clear_free(client_host_key_n);
1415 break;
1416
1417 case SSH_CMSG_AUTH_RSA:
1418 if (!options.rsa_authentication)
1419 {
1420 log("RSA authentication disabled.");
1421 break;
1422 }
1423
1424 /* RSA authentication requested. */
1425 {
1426 int nlen;
1427 BIGNUM *n;
1428 n = BN_new();
1429 packet_get_bignum(n, &nlen);
1430
1431 packet_integrity_check(plen, nlen, type);
1432
Damien Miller6d7b2cd1999-11-12 15:19:27 +11001433 if (auth_rsa(pw, n))
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001434 {
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 }
1444 break;
1445
1446 case SSH_CMSG_AUTH_PASSWORD:
1447 if (!options.password_authentication)
1448 {
1449 log("Password authentication disabled.");
1450 break;
1451 }
1452
1453 /* Password authentication requested. */
1454 /* Read user password. It is in plain text, but was transmitted
1455 over the encrypted channel so it is not visible to an outside
1456 observer. */
1457 {
1458 int passw_len;
1459 password = packet_get_string(&passw_len);
1460 packet_integrity_check(plen, 4 + passw_len, type);
1461 }
1462
Damien Miller06230761999-10-28 14:03:14 +10001463#ifdef HAVE_LIBPAM
Damien Miller3d112ef1999-10-28 13:20:30 +10001464 pampasswd = password;
Damien Miller07a826d1999-10-29 11:49:20 +10001465
1466 pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
1467 if (pam_retval == PAM_SUCCESS)
Damien Miller3d112ef1999-10-28 13:20:30 +10001468 {
Damien Miller07a826d1999-10-29 11:49:20 +10001469 log("PAM Password authentication accepted for \"%.100s\"", user);
Damien Miller3d112ef1999-10-28 13:20:30 +10001470 authenticated = 1;
1471 break;
1472 } else
1473 {
Damien Miller07a826d1999-10-29 11:49:20 +10001474 log("PAM Password authentication for \"%.100s\" failed: %s",
1475 user, pam_strerror((pam_handle_t *)pamh, pam_retval));
Damien Miller3d112ef1999-10-28 13:20:30 +10001476 break;
1477 }
Damien Miller06230761999-10-28 14:03:14 +10001478#else /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001479 /* Try authentication with the password. */
1480 if (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;
Damien Miller06230761999-10-28 14:03:14 +10001494#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001495
1496 case SSH_CMSG_AUTH_TIS:
1497 /* TIS Authentication is unsupported */
1498 log("TIS authentication disabled.");
1499 break;
1500
1501 default:
1502 /* Any unknown messages will be ignored (and failure returned)
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;
1510
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001511 if (++authentication_failures >= MAX_AUTH_FAILURES) {
1512 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1513 pw->pw_name, get_canonical_hostname());
1514 }
Damien Miller356a0b01999-11-08 15:30:59 +11001515 /* Send a message indicating that the authentication attempt failed. */
1516 packet_start(SSH_SMSG_FAILURE);
1517 packet_send();
1518 packet_write_wait();
Damien Miller776af5d1999-11-12 08:49:09 +11001519
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001520 }
1521
1522 /* Check if the user is logging in as root and root logins are disallowed. */
1523 if (pw->pw_uid == 0 && !options.permit_root_login)
1524 {
1525 if (forced_command)
Damien Miller0aa8e531999-11-02 19:05:02 +11001526 log("Root login accepted for forced command.");
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001527 else
1528 packet_disconnect("ROOT LOGIN REFUSED FROM %.200s",
1529 get_canonical_hostname());
1530 }
1531
Damien Miller06230761999-10-28 14:03:14 +10001532#ifdef HAVE_LIBPAM
Damien Miller3d112ef1999-10-28 13:20:30 +10001533 do_pam_account_and_session(pw->pw_name, password, client_user, get_canonical_hostname());
Damien Miller332e67f1999-10-27 23:42:05 +10001534
1535 /* Clean up */
1536 if (client_user != NULL)
1537 xfree(client_user);
1538
1539 if (password != NULL)
1540 {
1541 memset(password, 0, strlen(password));
1542 xfree(password);
1543 }
Damien Miller06230761999-10-28 14:03:14 +10001544#endif /* HAVE_LIBPAM */
Damien Miller332e67f1999-10-27 23:42:05 +10001545
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001546 /* 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}
1554
Damien Miller3d112ef1999-10-28 13:20:30 +10001555/* Read authentication messages, but return only failures until */
1556/* max auth attempts exceeded, then disconnect */
1557void eat_packets_and_disconnect(const char *user)
1558{
1559 int authentication_failures = 0;
1560
1561 packet_start(SSH_SMSG_FAILURE);
1562 packet_send();
1563 packet_write_wait();
1564
1565 /* Keep reading packets, and always respond with a failure. This is to
1566 avoid disclosing whether such a user really exists. */
1567 while(1)
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 {
1585 /* Send a fake s/key challenge. */
1586 packet_send_debug(skeyinfo);
1587 }
1588#endif /* SKEY */
Damien Miller3d112ef1999-10-28 13:20:30 +10001589 if (++authentication_failures >= MAX_AUTH_FAILURES)
1590 {
1591 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1592 user, get_canonical_hostname());
1593 }
Damien Miller356a0b01999-11-08 15:30:59 +11001594 /* Send failure. This should be indistinguishable from a failed
1595 authentication. */
1596 packet_start(SSH_SMSG_FAILURE);
1597 packet_send();
1598 packet_write_wait();
Damien Miller3d112ef1999-10-28 13:20:30 +10001599 }
1600 /*NOTREACHED*/
1601 abort();
1602}
1603
Damien Miller5ce662a1999-11-11 17:57:39 +11001604/* Remove local Xauthority file. */
1605static void
1606xauthfile_cleanup_proc(void *ignore)
1607{
1608 debug("xauthfile_cleanup_proc called");
1609
1610 if (xauthfile != NULL) {
1611 unlink(xauthfile);
1612 xfree(xauthfile);
1613 xauthfile = NULL;
1614 }
1615}
1616
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001617/* Prepares for an interactive session. This is called after the user has
1618 been successfully authenticated. During this message exchange, pseudo
1619 terminals are allocated, X11, TCP/IP, and authentication agent forwardings
1620 are requested, etc. */
1621
1622void do_authenticated(struct passwd *pw)
1623{
1624 int type;
1625 int compression_level = 0, enable_compression_after_reply = 0;
1626 int have_pty = 0, ptyfd = -1, ttyfd = -1, xauthfd = -1;
1627 int row, col, xpixel, ypixel, screen;
1628 char ttyname[64];
1629 char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL;
1630 struct group *grp;
1631 gid_t tty_gid;
1632 mode_t tty_mode;
1633 int n_bytes;
1634
1635 /* Cancel the alarm we set to limit the time taken for authentication. */
1636 alarm(0);
1637
1638 /* Inform the channel mechanism that we are the server side and that
1639 the client may request to connect to any port at all. (The user could
1640 do it anyway, and we wouldn\'t know what is permitted except by the
1641 client telling us, so we can equally well trust the client not to request
1642 anything bogus.) */
1643 channel_permit_all_opens();
1644
1645 /* We stay in this loop until the client requests to execute a shell or a
1646 command. */
1647 while (1)
1648 {
1649 int plen, dlen;
1650
1651 /* Get a packet from the client. */
1652 type = packet_read(&plen);
1653
1654 /* Process the packet. */
1655 switch (type)
1656 {
1657 case SSH_CMSG_REQUEST_COMPRESSION:
1658 packet_integrity_check(plen, 4, type);
1659 compression_level = packet_get_int();
1660 if (compression_level < 1 || compression_level > 9)
1661 {
1662 packet_send_debug("Received illegal compression level %d.",
1663 compression_level);
1664 goto fail;
1665 }
1666 /* Enable compression after we have responded with SUCCESS. */
1667 enable_compression_after_reply = 1;
1668 break;
1669
1670 case SSH_CMSG_REQUEST_PTY:
1671 if (no_pty_flag)
1672 {
1673 debug("Allocating a pty not permitted for this authentication.");
1674 goto fail;
1675 }
1676 if (have_pty)
1677 packet_disconnect("Protocol error: you already have a pty.");
1678
1679 debug("Allocating pty.");
1680
1681 /* Allocate a pty and open it. */
1682 if (!pty_allocate(&ptyfd, &ttyfd, ttyname))
1683 {
1684 error("Failed to allocate pty.");
1685 goto fail;
1686 }
1687
1688 /* Determine the group to make the owner of the tty. */
1689 grp = getgrnam("tty");
1690 if (grp)
1691 {
1692 tty_gid = grp->gr_gid;
1693 tty_mode = S_IRUSR|S_IWUSR|S_IWGRP;
1694 }
1695 else
1696 {
1697 tty_gid = pw->pw_gid;
1698 tty_mode = S_IRUSR|S_IWUSR|S_IWGRP|S_IWOTH;
1699 }
1700
1701 /* Change ownership of the tty. */
1702 if (chown(ttyname, pw->pw_uid, tty_gid) < 0)
1703 fatal("chown(%.100s, %d, %d) failed: %.100s",
1704 ttyname, pw->pw_uid, tty_gid, strerror(errno));
1705 if (chmod(ttyname, tty_mode) < 0)
1706 fatal("chmod(%.100s, 0%o) failed: %.100s",
1707 ttyname, tty_mode, strerror(errno));
1708
1709 /* Get TERM from the packet. Note that the value may be of arbitrary
1710 length. */
1711
1712 term = packet_get_string(&dlen);
1713 packet_integrity_check(dlen, strlen(term), type);
1714 /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */
1715 /* Remaining bytes */
1716 n_bytes = plen - (4 + dlen + 4*4);
1717
1718 if (strcmp(term, "") == 0)
1719 term = NULL;
1720
1721 /* Get window size from the packet. */
1722 row = packet_get_int();
1723 col = packet_get_int();
1724 xpixel = packet_get_int();
1725 ypixel = packet_get_int();
1726 pty_change_window_size(ptyfd, row, col, xpixel, ypixel);
1727
1728 /* Get tty modes from the packet. */
1729 tty_parse_modes(ttyfd, &n_bytes);
1730 packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type);
1731
1732 /* Indicate that we now have a pty. */
1733 have_pty = 1;
1734 break;
1735
1736 case SSH_CMSG_X11_REQUEST_FORWARDING:
1737 if (!options.x11_forwarding)
1738 {
1739 packet_send_debug("X11 forwarding disabled in server configuration file.");
1740 goto fail;
1741 }
1742#ifdef XAUTH_PATH
1743 if (no_x11_forwarding_flag)
1744 {
1745 packet_send_debug("X11 forwarding not permitted for this authentication.");
1746 goto fail;
1747 }
1748 debug("Received request for X11 forwarding with auth spoofing.");
1749 if (display)
1750 packet_disconnect("Protocol error: X11 display already set.");
1751 {
1752 int proto_len, data_len;
1753 proto = packet_get_string(&proto_len);
1754 data = packet_get_string(&data_len);
1755 packet_integrity_check(plen, 4+proto_len + 4+data_len + 4, type);
1756 }
1757 if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER)
1758 screen = packet_get_int();
1759 else
1760 screen = 0;
1761 display = x11_create_display_inet(screen);
1762 if (!display)
1763 goto fail;
1764
1765 /* Setup to always have a local .Xauthority. */
1766 xauthfile = xmalloc(MAXPATHLEN);
1767 snprintf(xauthfile, MAXPATHLEN, "/tmp/XauthXXXXXX");
1768
1769 if ((xauthfd = mkstemp(xauthfile)) != -1) {
1770 fchown(xauthfd, pw->pw_uid, pw->pw_gid);
1771 close(xauthfd);
Damien Miller5ce662a1999-11-11 17:57:39 +11001772 fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001773 }
1774 else {
1775 xfree(xauthfile);
1776 xauthfile = NULL;
1777 }
1778 break;
1779#else /* XAUTH_PATH */
1780 /* No xauth program; we won't accept forwarding with spoofing. */
1781 packet_send_debug("No xauth program; cannot forward with spoofing.");
1782 goto fail;
1783#endif /* XAUTH_PATH */
1784
1785 case SSH_CMSG_AGENT_REQUEST_FORWARDING:
1786 if (no_agent_forwarding_flag)
1787 {
1788 debug("Authentication agent forwarding not permitted for this authentication.");
1789 goto fail;
1790 }
1791 debug("Received authentication agent forwarding request.");
1792 auth_input_request_forwarding(pw);
1793 break;
1794
1795 case SSH_CMSG_PORT_FORWARD_REQUEST:
1796 if (no_port_forwarding_flag)
1797 {
1798 debug("Port forwarding not permitted for this authentication.");
1799 goto fail;
1800 }
1801 debug("Received TCP/IP port forwarding request.");
1802 channel_input_port_forward_request(pw->pw_uid == 0);
1803 break;
1804
1805 case SSH_CMSG_EXEC_SHELL:
1806 /* Set interactive/non-interactive mode. */
1807 packet_set_interactive(have_pty || display != NULL,
1808 options.keepalives);
1809
1810 if (forced_command != NULL)
1811 goto do_forced_command;
1812 debug("Forking shell.");
1813 packet_integrity_check(plen, 0, type);
1814 if (have_pty)
1815 do_exec_pty(NULL, ptyfd, ttyfd, ttyname, pw, term, display, proto,
1816 data);
1817 else
1818 do_exec_no_pty(NULL, pw, display, proto, data);
1819 return;
1820
1821 case SSH_CMSG_EXEC_CMD:
1822 /* Set interactive/non-interactive mode. */
1823 packet_set_interactive(have_pty || display != NULL,
1824 options.keepalives);
1825
1826 if (forced_command != NULL)
1827 goto do_forced_command;
1828 /* Get command from the packet. */
1829 {
1830 int dlen;
1831 command = packet_get_string(&dlen);
1832 debug("Executing command '%.500s'", command);
1833 packet_integrity_check(plen, 4 + dlen, type);
1834 }
1835 if (have_pty)
1836 do_exec_pty(command, ptyfd, ttyfd, ttyname, pw, term, display,
1837 proto, data);
1838 else
1839 do_exec_no_pty(command, pw, display, proto, data);
1840 xfree(command);
1841 return;
1842
1843 case SSH_CMSG_MAX_PACKET_SIZE:
1844 debug("The server does not support limiting packet size.");
1845 goto fail;
1846
1847 default:
1848 /* Any unknown messages in this phase are ignored, and a failure
1849 message is returned. */
1850 log("Unknown packet type received after authentication: %d", type);
1851 goto fail;
1852 }
1853
1854 /* The request was successfully processed. */
1855 packet_start(SSH_SMSG_SUCCESS);
1856 packet_send();
1857 packet_write_wait();
1858
1859 /* Enable compression now that we have replied if appropriate. */
1860 if (enable_compression_after_reply)
1861 {
1862 enable_compression_after_reply = 0;
1863 packet_start_compression(compression_level);
1864 }
1865
1866 continue;
1867
1868 fail:
1869 /* The request failed. */
1870 packet_start(SSH_SMSG_FAILURE);
1871 packet_send();
1872 packet_write_wait();
1873 continue;
1874
1875 do_forced_command:
1876 /* There is a forced command specified for this login. Execute it. */
1877 debug("Executing forced command: %.900s", forced_command);
1878 if (have_pty)
1879 do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display,
1880 proto, data);
1881 else
1882 do_exec_no_pty(forced_command, pw, display, proto, data);
1883 return;
1884 }
1885}
1886
1887/* This is called to fork and execute a command when we have no tty. This
1888 will call do_child from the child, and server_loop from the parent after
1889 setting up file descriptors and such. */
1890
1891void do_exec_no_pty(const char *command, struct passwd *pw,
1892 const char *display, const char *auth_proto,
1893 const char *auth_data)
1894{
1895 int pid;
1896
1897#ifdef USE_PIPES
1898 int pin[2], pout[2], perr[2];
1899 /* Allocate pipes for communicating with the program. */
1900 if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
1901 packet_disconnect("Could not create pipes: %.100s",
1902 strerror(errno));
1903#else /* USE_PIPES */
1904 int inout[2], err[2];
1905 /* Uses socket pairs to communicate with the program. */
1906 if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
1907 socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
1908 packet_disconnect("Could not create socket pairs: %.100s",
1909 strerror(errno));
1910#endif /* USE_PIPES */
1911
1912 setproctitle("%s@notty", pw->pw_name);
1913
1914 /* Fork the child. */
1915 if ((pid = fork()) == 0)
1916 {
1917 /* Child. Reinitialize the log since the pid has changed. */
Damien Miller5ce662a1999-11-11 17:57:39 +11001918 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001919
1920 /* Create a new session and process group since the 4.4BSD setlogin()
1921 affects the entire process group. */
1922 if (setsid() < 0)
1923 error("setsid failed: %.100s", strerror(errno));
1924
1925#ifdef USE_PIPES
1926 /* Redirect stdin. We close the parent side of the socket pair,
1927 and make the child side the standard input. */
1928 close(pin[1]);
1929 if (dup2(pin[0], 0) < 0)
1930 perror("dup2 stdin");
1931 close(pin[0]);
1932
1933 /* Redirect stdout. */
1934 close(pout[0]);
1935 if (dup2(pout[1], 1) < 0)
1936 perror("dup2 stdout");
1937 close(pout[1]);
1938
1939 /* Redirect stderr. */
1940 close(perr[0]);
1941 if (dup2(perr[1], 2) < 0)
1942 perror("dup2 stderr");
1943 close(perr[1]);
1944#else /* USE_PIPES */
1945 /* Redirect stdin, stdout, and stderr. Stdin and stdout will use the
1946 same socket, as some programs (particularly rdist) seem to depend
1947 on it. */
1948 close(inout[1]);
1949 close(err[1]);
1950 if (dup2(inout[0], 0) < 0) /* stdin */
1951 perror("dup2 stdin");
1952 if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */
1953 perror("dup2 stdout");
1954 if (dup2(err[0], 2) < 0) /* stderr */
1955 perror("dup2 stderr");
1956#endif /* USE_PIPES */
1957
1958 /* Do processing for the child (exec command etc). */
1959 do_child(command, pw, NULL, display, auth_proto, auth_data, NULL);
1960 /*NOTREACHED*/
1961 }
1962 if (pid < 0)
1963 packet_disconnect("fork failed: %.100s", strerror(errno));
1964#ifdef USE_PIPES
1965 /* We are the parent. Close the child sides of the pipes. */
1966 close(pin[0]);
1967 close(pout[1]);
1968 close(perr[1]);
1969
1970 /* Enter the interactive session. */
1971 server_loop(pid, pin[1], pout[0], perr[0]);
1972 /* server_loop has closed pin[1], pout[1], and perr[1]. */
1973#else /* USE_PIPES */
1974 /* We are the parent. Close the child sides of the socket pairs. */
1975 close(inout[0]);
1976 close(err[0]);
1977
1978 /* Enter the interactive session. Note: server_loop must be able to handle
1979 the case that fdin and fdout are the same. */
1980 server_loop(pid, inout[1], inout[1], err[1]);
1981 /* server_loop has closed inout[1] and err[1]. */
1982#endif /* USE_PIPES */
1983}
1984
1985struct pty_cleanup_context
1986{
1987 const char *ttyname;
1988 int pid;
1989};
1990
1991/* Function to perform cleanup if we get aborted abnormally (e.g., due to a
1992 dropped connection). */
1993
1994void pty_cleanup_proc(void *context)
1995{
1996 struct pty_cleanup_context *cu = context;
1997
1998 debug("pty_cleanup_proc called");
1999
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002000 /* Record that the user has logged out. */
2001 record_logout(cu->pid, cu->ttyname);
2002
2003 /* Release the pseudo-tty. */
2004 pty_release(cu->ttyname);
2005}
2006
2007/* This is called to fork and execute a command when we have a tty. This
2008 will call do_child from the child, and server_loop from the parent after
2009 setting up file descriptors, controlling tty, updating wtmp, utmp,
2010 lastlog, and other such operations. */
2011
2012void do_exec_pty(const char *command, int ptyfd, int ttyfd,
2013 const char *ttyname, struct passwd *pw, const char *term,
2014 const char *display, const char *auth_proto,
2015 const char *auth_data)
2016{
2017 int pid, fdout;
2018 const char *hostname;
2019 time_t last_login_time;
2020 char buf[100], *time_string;
2021 FILE *f;
2022 char line[256];
2023 struct stat st;
2024 int quiet_login;
2025 struct sockaddr_in from;
2026 int fromlen;
2027 struct pty_cleanup_context cleanup_context;
2028
2029 /* Get remote host name. */
2030 hostname = get_canonical_hostname();
2031
2032 /* Get the time when the user last logged in. Buf will be set to contain
2033 the hostname the last login was from. */
2034 if(!options.use_login) {
2035 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
2036 buf, sizeof(buf));
2037 }
2038
2039 setproctitle("%s@%s", pw->pw_name, strrchr(ttyname, '/') + 1);
2040
2041 /* Fork the child. */
2042 if ((pid = fork()) == 0)
2043 {
2044 pid = getpid();
2045
2046 /* Child. Reinitialize the log because the pid has changed. */
Damien Miller5ce662a1999-11-11 17:57:39 +11002047 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002048
2049 /* Close the master side of the pseudo tty. */
2050 close(ptyfd);
2051
2052 /* Make the pseudo tty our controlling tty. */
2053 pty_make_controlling_tty(&ttyfd, ttyname);
2054
2055 /* Redirect stdin from the pseudo tty. */
2056 if (dup2(ttyfd, fileno(stdin)) < 0)
2057 error("dup2 stdin failed: %.100s", strerror(errno));
2058
2059 /* Redirect stdout to the pseudo tty. */
2060 if (dup2(ttyfd, fileno(stdout)) < 0)
2061 error("dup2 stdin failed: %.100s", strerror(errno));
2062
2063 /* Redirect stderr to the pseudo tty. */
2064 if (dup2(ttyfd, fileno(stderr)) < 0)
2065 error("dup2 stdin failed: %.100s", strerror(errno));
2066
2067 /* Close the extra descriptor for the pseudo tty. */
2068 close(ttyfd);
2069
2070 /* Get IP address of client. This is needed because we want to record
2071 where the user logged in from. If the connection is not a socket,
2072 let the ip address be 0.0.0.0. */
2073 memset(&from, 0, sizeof(from));
2074 if (packet_get_connection_in() == packet_get_connection_out())
2075 {
2076 fromlen = sizeof(from);
2077 if (getpeername(packet_get_connection_in(),
2078 (struct sockaddr *)&from, &fromlen) < 0)
2079 fatal("getpeername: %.100s", strerror(errno));
2080 }
2081
2082 /* Record that there was a login on that terminal. */
2083 record_login(pid, ttyname, pw->pw_name, pw->pw_uid, hostname,
2084 &from);
2085
2086 /* Check if .hushlogin exists. */
2087 snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
2088 quiet_login = stat(line, &st) >= 0;
Damien Miller356a0b01999-11-08 15:30:59 +11002089
2090#ifdef HAVE_LIBPAM
2091 /* output the results of the pamconv() */
2092 if (!quiet_login && pamconv_msg != NULL)
2093 fprintf(stderr, pamconv_msg);
2094#endif
2095
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002096 /* If the user has logged in before, display the time of last login.
2097 However, don't display anything extra if a command has been
2098 specified (so that ssh can be used to execute commands on a remote
2099 machine without users knowing they are going to another machine).
2100 Login(1) will do this for us as well, so check if login(1) is used */
2101 if (command == NULL && last_login_time != 0 && !quiet_login &&
2102 !options.use_login)
2103 {
2104 /* Convert the date to a string. */
2105 time_string = ctime(&last_login_time);
2106 /* Remove the trailing newline. */
2107 if (strchr(time_string, '\n'))
2108 *strchr(time_string, '\n') = 0;
2109 /* Display the last login time. Host if displayed if known. */
2110 if (strcmp(buf, "") == 0)
2111 printf("Last login: %s\r\n", time_string);
2112 else
2113 printf("Last login: %s from %s\r\n", time_string, buf);
2114 }
2115
2116 /* Print /etc/motd unless a command was specified or printing it was
2117 disabled in server options or login(1) will be used. Note that
2118 some machines appear to print it in /etc/profile or similar. */
2119 if (command == NULL && options.print_motd && !quiet_login &&
2120 !options.use_login)
2121 {
2122 /* Print /etc/motd if it exists. */
2123 f = fopen("/etc/motd", "r");
2124 if (f)
2125 {
2126 while (fgets(line, sizeof(line), f))
2127 fputs(line, stdout);
2128 fclose(f);
2129 }
2130 }
2131
2132 /* Do common processing for the child, such as execing the command. */
2133 do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
2134 /*NOTREACHED*/
2135 }
2136 if (pid < 0)
2137 packet_disconnect("fork failed: %.100s", strerror(errno));
2138 /* Parent. Close the slave side of the pseudo tty. */
2139 close(ttyfd);
2140
2141 /* Create another descriptor of the pty master side for use as the standard
2142 input. We could use the original descriptor, but this simplifies code
2143 in server_loop. The descriptor is bidirectional. */
2144 fdout = dup(ptyfd);
2145 if (fdout < 0)
2146 packet_disconnect("dup failed: %.100s", strerror(errno));
2147
2148 /* Add a cleanup function to clear the utmp entry and record logout time
2149 in case we call fatal() (e.g., the connection gets closed). */
2150 cleanup_context.pid = pid;
2151 cleanup_context.ttyname = ttyname;
2152 fatal_add_cleanup(pty_cleanup_proc, (void *)&cleanup_context);
2153
2154 /* Enter interactive session. */
2155 server_loop(pid, ptyfd, fdout, -1);
2156 /* server_loop has not closed ptyfd and fdout. */
2157
2158 /* Cancel the cleanup function. */
2159 fatal_remove_cleanup(pty_cleanup_proc, (void *)&cleanup_context);
2160
2161 /* Record that the user has logged out. */
2162 record_logout(pid, ttyname);
2163
2164 /* Release the pseudo-tty. */
2165 pty_release(ttyname);
2166
2167 /* Close the server side of the socket pairs. We must do this after the
2168 pty cleanup, so that another process doesn't get this pty while we're
2169 still cleaning up. */
2170 close(ptyfd);
2171 close(fdout);
2172}
2173
2174/* Sets the value of the given variable in the environment. If the variable
2175 already exists, its value is overriden. */
2176
2177void child_set_env(char ***envp, unsigned int *envsizep, const char *name,
2178 const char *value)
2179{
2180 unsigned int i, namelen;
2181 char **env;
2182
2183 /* Find the slot where the value should be stored. If the variable already
2184 exists, we reuse the slot; otherwise we append a new slot at the end
2185 of the array, expanding if necessary. */
2186 env = *envp;
2187 namelen = strlen(name);
2188 for (i = 0; env[i]; i++)
2189 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
2190 break;
2191 if (env[i])
2192 {
2193 /* Name already exists. Reuse the slot. */
2194 xfree(env[i]);
2195 }
2196 else
2197 {
2198 /* New variable. Expand the array if necessary. */
2199 if (i >= (*envsizep) - 1)
2200 {
2201 (*envsizep) += 50;
2202 env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
2203 }
2204
2205 /* Need to set the NULL pointer at end of array beyond the new
2206 slot. */
2207 env[i + 1] = NULL;
2208 }
2209
2210 /* Allocate space and format the variable in the appropriate slot. */
2211 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
2212 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
2213}
2214
2215/* Reads environment variables from the given file and adds/overrides them
2216 into the environment. If the file does not exist, this does nothing.
2217 Otherwise, it must consist of empty lines, comments (line starts with '#')
2218 and assignments of the form name=value. No other forms are allowed. */
2219
2220void read_environment_file(char ***env, unsigned int *envsize,
2221 const char *filename)
2222{
2223 FILE *f;
2224 char buf[4096];
2225 char *cp, *value;
2226
2227 /* Open the environment file. */
2228 f = fopen(filename, "r");
2229 if (!f)
2230 return; /* Not found. */
2231
2232 /* Process each line. */
2233 while (fgets(buf, sizeof(buf), f))
2234 {
2235 /* Skip leading whitespace. */
2236 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
2237 ;
2238
2239 /* Ignore empty and comment lines. */
2240 if (!*cp || *cp == '#' || *cp == '\n')
2241 continue;
2242
2243 /* Remove newline. */
2244 if (strchr(cp, '\n'))
2245 *strchr(cp, '\n') = '\0';
2246
2247 /* Find the equals sign. Its lack indicates badly formatted line. */
2248 value = strchr(cp, '=');
2249 if (value == NULL)
2250 {
2251 fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
2252 continue;
2253 }
2254
2255 /* Replace the equals sign by nul, and advance value to the value
2256 string. */
2257 *value = '\0';
2258 value++;
2259
2260 /* Set the value in environment. */
2261 child_set_env(env, envsize, cp, value);
2262 }
2263
2264 fclose(f);
2265}
2266
2267/* Performs common processing for the child, such as setting up the
2268 environment, closing extra file descriptors, setting the user and group
2269 ids, and executing the command or shell. */
2270
2271void do_child(const char *command, struct passwd *pw, const char *term,
2272 const char *display, const char *auth_proto,
2273 const char *auth_data, const char *ttyname)
2274{
2275 const char *shell, *cp = NULL;
2276 char buf[256];
2277 FILE *f;
2278 unsigned int envsize, i;
2279 char **env;
2280 extern char **environ;
2281 struct stat st;
2282 char *argv[10];
2283
Damien Miller356a0b01999-11-08 15:30:59 +11002284#ifndef HAVE_LIBPAM /* pam_nologin handles this */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002285 /* Check /etc/nologin. */
2286 f = fopen("/etc/nologin", "r");
2287 if (f)
2288 { /* /etc/nologin exists. Print its contents and exit. */
2289 while (fgets(buf, sizeof(buf), f))
2290 fputs(buf, stderr);
2291 fclose(f);
2292 if (pw->pw_uid != 0)
2293 exit(254);
2294 }
Damien Miller776af5d1999-11-12 08:49:09 +11002295#endif /* HAVE_LIBPAM */
2296
2297#ifdef HAVE_SETLOGIN
2298 /* Set login name in the kernel. */
2299 if (setlogin(pw->pw_name) < 0)
2300 error("setlogin failed: %s", strerror(errno));
2301#endif /* HAVE_SETLOGIN */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002302
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002303 /* Set uid, gid, and groups. */
2304 /* Login(1) does this as well, and it needs uid 0 for the "-h" switch,
2305 so we let login(1) to this for us. */
2306 if(!options.use_login) {
2307 if (getuid() == 0 || geteuid() == 0)
2308 {
2309 if (setgid(pw->pw_gid) < 0)
2310 {
2311 perror("setgid");
2312 exit(1);
2313 }
2314 /* Initialize the group list. */
2315 if (initgroups(pw->pw_name, pw->pw_gid) < 0)
2316 {
2317 perror("initgroups");
2318 exit(1);
2319 }
2320 endgrent();
2321
2322 /* Permanently switch to the desired uid. */
2323 permanently_set_uid(pw->pw_uid);
2324 }
2325
2326 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
2327 fatal("Failed to set uids to %d.", (int)pw->pw_uid);
2328 }
2329
2330 /* Get the shell from the password data. An empty shell field is legal,
2331 and means /bin/sh. */
2332 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
2333
2334#ifdef AFS
2335 /* Try to get AFS tokens for the local cell. */
2336 if (k_hasafs()) {
2337 char cell[64];
2338
2339 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
2340 krb_afslog(cell, 0);
2341
2342 krb_afslog(0, 0);
2343 }
2344#endif /* AFS */
2345
2346 /* Initialize the environment. In the first part we allocate space for
2347 all environment variables. */
2348 envsize = 100;
2349 env = xmalloc(envsize * sizeof(char *));
2350 env[0] = NULL;
2351
2352 if(!options.use_login) {
2353 /* Set basic environment. */
2354 child_set_env(&env, &envsize, "USER", pw->pw_name);
2355 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
2356 child_set_env(&env, &envsize, "HOME", pw->pw_dir);
2357 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
2358
2359 snprintf(buf, sizeof buf, "%.200s/%.50s",
2360 _PATH_MAILDIR, pw->pw_name);
2361 child_set_env(&env, &envsize, "MAIL", buf);
2362
2363 /* Normal systems set SHELL by default. */
2364 child_set_env(&env, &envsize, "SHELL", shell);
2365 }
2366
2367 /* Let it inherit timezone if we have one. */
2368 if (getenv("TZ"))
2369 child_set_env(&env, &envsize, "TZ", getenv("TZ"));
2370
2371 /* Set custom environment options from RSA authentication. */
2372 while (custom_environment)
2373 {
2374 struct envstring *ce = custom_environment;
2375 char *s = ce->s;
2376 int i;
2377 for (i = 0; s[i] != '=' && s[i]; i++)
2378 ;
2379 if (s[i] == '=')
2380 {
2381 s[i] = 0;
2382 child_set_env(&env, &envsize, s, s + i + 1);
2383 }
2384 custom_environment = ce->next;
2385 xfree(ce->s);
2386 xfree(ce);
2387 }
2388
2389 /* Set SSH_CLIENT. */
2390 snprintf(buf, sizeof buf, "%.50s %d %d",
2391 get_remote_ipaddr(), get_remote_port(), options.port);
2392 child_set_env(&env, &envsize, "SSH_CLIENT", buf);
2393
2394 /* Set SSH_TTY if we have a pty. */
2395 if (ttyname)
2396 child_set_env(&env, &envsize, "SSH_TTY", ttyname);
2397
2398 /* Set TERM if we have a pty. */
2399 if (term)
2400 child_set_env(&env, &envsize, "TERM", term);
2401
2402 /* Set DISPLAY if we have one. */
2403 if (display)
2404 child_set_env(&env, &envsize, "DISPLAY", display);
2405
2406#ifdef KRB4
Damien Miller5ce662a1999-11-11 17:57:39 +11002407 {
Damien Miller776af5d1999-11-12 08:49:09 +11002408 extern char *ticket;
2409
2410 if (ticket)
2411 child_set_env(&env, &envsize, "KRBTKFILE", ticket);
Damien Miller5ce662a1999-11-11 17:57:39 +11002412 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002413#endif /* KRB4 */
2414
Damien Miller94388161999-10-29 09:57:31 +10002415#ifdef HAVE_LIBPAM
2416 /* Pull in any environment variables that may have been set by PAM. */
2417 {
2418 char *equal_sign, var_name[256], var_val[256];
2419 long this_var;
Damien Miller5eeedae1999-10-29 10:21:15 +10002420 char **pam_env = pam_getenvlist((pam_handle_t *)pamh);
Damien Miller94388161999-10-29 09:57:31 +10002421 for(this_var = 0; pam_env && pam_env[this_var]; this_var++)
2422 {
Damien Millerd0562b31999-10-29 13:09:40 +10002423 if(strlen(pam_env[this_var]) < (sizeof(var_name) - 1))
Damien Miller94388161999-10-29 09:57:31 +10002424 if((equal_sign = strstr(pam_env[this_var], "=")) != NULL)
2425 {
2426 memset(var_name, 0, sizeof(var_name));
2427 memset(var_val, 0, sizeof(var_val));
2428 strncpy(var_name, pam_env[this_var],
2429 equal_sign - pam_env[this_var]);
2430 strcpy(var_val, equal_sign + 1);
2431 child_set_env(&env, &envsize, var_name, var_val);
2432 }
2433 }
2434 }
2435#endif /* HAVE_LIBPAM */
2436
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002437 /* Set XAUTHORITY to always be a local file. */
2438 if (xauthfile)
2439 child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
2440
2441 /* Set variable for forwarded authentication connection, if we have one. */
2442 if (auth_get_socket_name() != NULL)
2443 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
2444 auth_get_socket_name());
Damien Miller776af5d1999-11-12 08:49:09 +11002445
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002446 /* Read $HOME/.ssh/environment. */
2447 if(!options.use_login) {
2448 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);
2449 read_environment_file(&env, &envsize, buf);
2450 }
2451
2452 /* If debugging, dump the environment to stderr. */
2453 if (debug_flag)
2454 {
2455 fprintf(stderr, "Environment:\n");
2456 for (i = 0; env[i]; i++)
2457 fprintf(stderr, " %.200s\n", env[i]);
2458 }
2459
2460 /* Close the connection descriptors; note that this is the child, and the
2461 server will still have the socket open, and it is important that we
2462 do not shutdown it. Note that the descriptors cannot be closed before
2463 building the environment, as we call get_remote_ipaddr there. */
2464 if (packet_get_connection_in() == packet_get_connection_out())
2465 close(packet_get_connection_in());
2466 else
2467 {
2468 close(packet_get_connection_in());
2469 close(packet_get_connection_out());
2470 }
2471 /* Close all descriptors related to channels. They will still remain
2472 open in the parent. */
2473 channel_close_all();
2474
2475 /* Close any extra file descriptors. Note that there may still be
2476 descriptors left by system functions. They will be closed later. */
2477 endpwent();
2478 endhostent();
2479
2480 /* Close any extra open file descriptors so that we don\'t have them
2481 hanging around in clients. Note that we want to do this after
2482 initgroups, because at least on Solaris 2.3 it leaves file descriptors
2483 open. */
2484 for (i = 3; i < 64; i++)
2485 close(i);
2486
2487 /* Change current directory to the user\'s home directory. */
2488 if (chdir(pw->pw_dir) < 0)
2489 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
2490 pw->pw_dir, strerror(errno));
2491
2492 /* Must take new environment into use so that .ssh/rc, /etc/sshrc and
2493 xauth are run in the proper environment. */
2494 environ = env;
2495
2496 /* Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
2497 in this order). */
2498 if(!options.use_login) {
2499 if (stat(SSH_USER_RC, &st) >= 0)
2500 {
2501 if (debug_flag)
2502 fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);
2503
2504 f = popen("/bin/sh " SSH_USER_RC, "w");
2505 if (f)
2506 {
2507 if (auth_proto != NULL && auth_data != NULL)
2508 fprintf(f, "%s %s\n", auth_proto, auth_data);
2509 pclose(f);
2510 }
2511 else
2512 fprintf(stderr, "Could not run %s\n", SSH_USER_RC);
2513 }
2514 else
2515 if (stat(SSH_SYSTEM_RC, &st) >= 0)
2516 {
2517 if (debug_flag)
2518 fprintf(stderr, "Running /bin/sh %s\n", SSH_SYSTEM_RC);
2519
2520 f = popen("/bin/sh " SSH_SYSTEM_RC, "w");
2521 if (f)
2522 {
2523 if (auth_proto != NULL && auth_data != NULL)
2524 fprintf(f, "%s %s\n", auth_proto, auth_data);
2525 pclose(f);
2526 }
2527 else
2528 fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC);
2529 }
2530#ifdef XAUTH_PATH
2531 else
2532 {
2533 /* Add authority data to .Xauthority if appropriate. */
2534 if (auth_proto != NULL && auth_data != NULL)
2535 {
2536 if (debug_flag)
2537 fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n",
2538 XAUTH_PATH, display, auth_proto, auth_data);
2539
2540 f = popen(XAUTH_PATH " -q -", "w");
2541 if (f)
2542 {
2543 fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data);
2544 fclose(f);
2545 }
2546 else
2547 fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH);
2548 }
2549 }
2550#endif /* XAUTH_PATH */
2551
2552 /* Get the last component of the shell name. */
2553 cp = strrchr(shell, '/');
2554 if (cp)
2555 cp++;
2556 else
2557 cp = shell;
2558 }
2559
2560 /* If we have no command, execute the shell. In this case, the shell name
2561 to be passed in argv[0] is preceded by '-' to indicate that this is
2562 a login shell. */
2563 if (!command)
2564 {
2565 if(!options.use_login) {
2566 char buf[256];
2567
2568 /* Check for mail if we have a tty and it was enabled in server options. */
2569 if (ttyname && options.check_mail) {
2570 char *mailbox;
2571 struct stat mailstat;
2572 mailbox = getenv("MAIL");
2573 if(mailbox != NULL) {
2574 if(stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0) {
2575 printf("No mail.\n");
2576 } else if(mailstat.st_mtime < mailstat.st_atime) {
2577 printf("You have mail.\n");
2578 } else {
2579 printf("You have new mail.\n");
2580 }
2581 }
2582 }
2583 /* Start the shell. Set initial character to '-'. */
2584 buf[0] = '-';
2585 strncpy(buf + 1, cp, sizeof(buf) - 1);
2586 buf[sizeof(buf) - 1] = 0;
2587 /* Execute the shell. */
2588 argv[0] = buf;
2589 argv[1] = NULL;
2590 execve(shell, argv, env);
2591 /* Executing the shell failed. */
2592 perror(shell);
2593 exit(1);
2594
2595 } else {
2596 /* Launch login(1). */
2597
Damien Miller356a0b01999-11-08 15:30:59 +11002598 execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002599
2600 /* Login couldn't be executed, die. */
2601
2602 perror("login");
2603 exit(1);
2604 }
2605 }
2606
2607 /* Execute the command using the user's shell. This uses the -c option
2608 to execute the command. */
2609 argv[0] = (char *)cp;
2610 argv[1] = "-c";
2611 argv[2] = (char *)command;
2612 argv[3] = NULL;
2613 execve(shell, argv, env);
2614 perror(shell);
2615 exit(1);
2616}