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