blob: 9e33f69f77f6451fe15b35cab1d7748d6254f0fb [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 Miller81428f91999-11-18 09:28:11 +110021RCSID("$Id: sshd.c,v 1.23 1999/11/17 22:28:11 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
Damien Miller10f6f6b1999-11-17 17:29:08 +1100489 /* Force logging to stderr while loading the private host key
490 unless started from inetd */
491 log_init(av0, options.log_level, options.log_facility, !inetd_flag);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000492
493 debug("sshd version %.100s", SSH_VERSION);
494
495 sensitive_data.host_key = RSA_new();
Damien Miller10f6f6b1999-11-17 17:29:08 +1100496 errno = 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000497 /* Load the host key. It must have empty passphrase. */
498 if (!load_private_key(options.host_key_file, "",
499 sensitive_data.host_key, &comment))
500 {
Damien Miller10f6f6b1999-11-17 17:29:08 +1100501 error("Could not load host key: %.200s: %.100s",
502 options.host_key_file, strerror(errno));
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000503 exit(1);
504 }
505 xfree(comment);
506
Damien Miller10f6f6b1999-11-17 17:29:08 +1100507 /* Initialize the log (it is reinitialized below in case we forked). */
508 if (debug_flag && !inetd_flag)
509 log_stderr = 1;
510 log_init(av0, options.log_level, options.log_facility, log_stderr);
511
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000512 /* If not in debugging mode, and not started from inetd, disconnect from
513 the controlling terminal, and fork. The original process exits. */
514 if (!debug_flag && !inetd_flag)
515 {
516#ifdef TIOCNOTTY
517 int fd;
518#endif /* TIOCNOTTY */
519 if (daemon(0, 0) < 0)
520 fatal("daemon() failed: %.200s", strerror(errno));
521
522 /* Disconnect from the controlling tty. */
523#ifdef TIOCNOTTY
524 fd = open("/dev/tty", O_RDWR|O_NOCTTY);
525 if (fd >= 0)
526 {
527 (void)ioctl(fd, TIOCNOTTY, NULL);
528 close(fd);
529 }
530#endif /* TIOCNOTTY */
531 }
532
533 /* Reinitialize the log (because of the fork above). */
Damien Miller5ce662a1999-11-11 17:57:39 +1100534 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000535
536 /* Check that server and host key lengths differ sufficiently. This is
537 necessary to make double encryption work with rsaref. Oh, I hate
538 software patents. I dont know if this can go? Niels */
539 if (options.server_key_bits >
540 BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED &&
541 options.server_key_bits <
542 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED)
543 {
544 options.server_key_bits =
545 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED;
546 debug("Forcing server key to %d bits to make it differ from host key.",
547 options.server_key_bits);
548 }
549
550 /* Do not display messages to stdout in RSA code. */
551 rsa_set_verbose(0);
552
553 /* Initialize the random number generator. */
554 arc4random_stir();
555
556 /* Chdir to the root directory so that the current disk can be unmounted
557 if desired. */
558 chdir("/");
559
560 /* Close connection cleanly after attack. */
561 cipher_attack_detected = packet_disconnect;
562
563 /* Start listening for a socket, unless started from inetd. */
564 if (inetd_flag)
565 {
566 int s1, s2;
567 s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */
568 s2 = dup(s1);
569 sock_in = dup(0);
570 sock_out = dup(1);
571 /* We intentionally do not close the descriptors 0, 1, and 2 as our
572 code for setting the descriptors won\'t work if ttyfd happens to
573 be one of those. */
574 debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);
575
576 public_key = RSA_new();
577 sensitive_data.private_key = RSA_new();
578 /* Generate an rsa key. */
579 log("Generating %d bit RSA key.", options.server_key_bits);
580 rsa_generate_key(sensitive_data.private_key, public_key,
581 options.server_key_bits);
582 arc4random_stir();
583 log("RSA key generation complete.");
584 }
585 else
586 {
587 /* Create socket for listening. */
588 listen_sock = socket(AF_INET, SOCK_STREAM, 0);
589 if (listen_sock < 0)
590 fatal("socket: %.100s", strerror(errno));
591
592 /* Set socket options. We try to make the port reusable and have it
593 close as fast as possible without waiting in unnecessary wait states
594 on close. */
595 setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
596 sizeof(on));
597 linger.l_onoff = 1;
598 linger.l_linger = 5;
599 setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *)&linger,
600 sizeof(linger));
601
602 /* Initialize the socket address. */
603 memset(&sin, 0, sizeof(sin));
604 sin.sin_family = AF_INET;
605 sin.sin_addr = options.listen_addr;
606 sin.sin_port = htons(options.port);
607
608 /* Bind the socket to the desired port. */
609 if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
610 {
611 error("bind: %.100s", strerror(errno));
612 shutdown(listen_sock, SHUT_RDWR);
613 close(listen_sock);
614 fatal("Bind to port %d failed.", options.port);
615 }
616
617 if (!debug_flag)
618 {
619 /* Record our pid in /etc/sshd_pid to make it easier to kill the
620 correct sshd. We don\'t want to do this before the bind above
621 because the bind will fail if there already is a daemon, and this
622 will overwrite any old pid in the file. */
623 f = fopen(SSH_DAEMON_PID_FILE, "w");
624 if (f)
625 {
626 fprintf(f, "%u\n", (unsigned int)getpid());
627 fclose(f);
628 }
629 }
630
631 /* Start listening on the port. */
632 log("Server listening on port %d.", options.port);
633 if (listen(listen_sock, 5) < 0)
634 fatal("listen: %.100s", strerror(errno));
635
636 public_key = RSA_new();
637 sensitive_data.private_key = RSA_new();
638 /* Generate an rsa key. */
639 log("Generating %d bit RSA key.", options.server_key_bits);
640 rsa_generate_key(sensitive_data.private_key, public_key,
641 options.server_key_bits);
642 arc4random_stir();
643 log("RSA key generation complete.");
644
645 /* Schedule server key regeneration alarm. */
646 signal(SIGALRM, key_regeneration_alarm);
647 alarm(options.key_regeneration_time);
648
649 /* Arrange to restart on SIGHUP. The handler needs listen_sock. */
650 signal(SIGHUP, sighup_handler);
651 signal(SIGTERM, sigterm_handler);
652 signal(SIGQUIT, sigterm_handler);
653
654 /* Arrange SIGCHLD to be caught. */
655 signal(SIGCHLD, main_sigchld_handler);
656
657 /* Stay listening for connections until the system crashes or the
658 daemon is killed with a signal. */
659 for (;;)
660 {
661 if (received_sighup)
662 sighup_restart();
663 /* Wait in accept until there is a connection. */
664 aux = sizeof(sin);
665 newsock = accept(listen_sock, (struct sockaddr *)&sin, &aux);
666 if (received_sighup)
667 sighup_restart();
668 if (newsock < 0)
669 {
670 if (errno == EINTR)
671 continue;
672 error("accept: %.100s", strerror(errno));
673 continue;
674 }
675
676 /* Got connection. Fork a child to handle it, unless we are in
677 debugging mode. */
678 if (debug_flag)
679 {
680 /* In debugging mode. Close the listening socket, and start
681 processing the connection without forking. */
682 debug("Server will not fork when running in debugging mode.");
683 close(listen_sock);
684 sock_in = newsock;
685 sock_out = newsock;
686 pid = getpid();
687 break;
688 }
689 else
690 {
691 /* Normal production daemon. Fork, and have the child process
692 the connection. The parent continues listening. */
693 if ((pid = fork()) == 0)
694 {
695 /* Child. Close the listening socket, and start using
696 the accepted socket. Reinitialize logging (since our
697 pid has changed). We break out of the loop to handle
698 the connection. */
699 close(listen_sock);
700 sock_in = newsock;
701 sock_out = newsock;
Damien Miller5ce662a1999-11-11 17:57:39 +1100702 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000703 break;
704 }
705 }
706
707 /* Parent. Stay in the loop. */
708 if (pid < 0)
709 error("fork: %.100s", strerror(errno));
710 else
711 debug("Forked child %d.", pid);
712
713 /* Mark that the key has been used (it was "given" to the child). */
714 key_used = 1;
715
716 arc4random_stir();
717
718 /* Close the new socket (the child is now taking care of it). */
719 close(newsock);
720 }
721 }
722
723 /* This is the child processing a new connection. */
724
725 /* Disable the key regeneration alarm. We will not regenerate the key
726 since we are no longer in a position to give it to anyone. We will
727 not restart on SIGHUP since it no longer makes sense. */
728 alarm(0);
729 signal(SIGALRM, SIG_DFL);
730 signal(SIGHUP, SIG_DFL);
731 signal(SIGTERM, SIG_DFL);
732 signal(SIGQUIT, SIG_DFL);
733 signal(SIGCHLD, SIG_DFL);
734
735 /* Set socket options for the connection. We want the socket to close
736 as fast as possible without waiting for anything. If the connection
737 is not a socket, these will do nothing. */
738 /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
739 linger.l_onoff = 1;
740 linger.l_linger = 5;
741 setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
742
743 /* Register our connection. This turns encryption off because we do not
744 have a key. */
745 packet_set_connection(sock_in, sock_out);
746
Damien Miller2ccf6611999-11-15 15:25:10 +1100747 remote_port = get_remote_port();
748
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000749 /* Check whether logins are denied from this host. */
750#ifdef LIBWRAP
751 {
752 struct request_info req;
753
754 request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL);
755 fromhost(&req);
756
757 if (!hosts_access(&req)) {
758 close(sock_in);
759 close(sock_out);
760 refuse(&req);
761 }
Damien Miller2ccf6611999-11-15 15:25:10 +1100762 log("Connection from %.500s port %d", eval_client(&req), remote_port);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000763 }
764#else
765 /* Log the connection. */
Damien Miller2ccf6611999-11-15 15:25:10 +1100766 log("Connection from %.100s port %d", get_remote_ipaddr(), remote_port);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000767#endif /* LIBWRAP */
768
769 /* We don\'t want to listen forever unless the other side successfully
770 authenticates itself. So we set up an alarm which is cleared after
771 successful authentication. A limit of zero indicates no limit.
772 Note that we don\'t set the alarm in debugging mode; it is just annoying
773 to have the server exit just when you are about to discover the bug. */
774 signal(SIGALRM, grace_alarm_handler);
775 if (!debug_flag)
776 alarm(options.login_grace_time);
777
778 /* Send our protocol version identification. */
779 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
780 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
781 if (write(sock_out, buf, strlen(buf)) != strlen(buf))
782 fatal("Could not write ident string.");
783
784 /* Read other side\'s version identification. */
785 for (i = 0; i < sizeof(buf) - 1; i++)
786 {
787 if (read(sock_in, &buf[i], 1) != 1)
788 fatal("Did not receive ident string.");
789 if (buf[i] == '\r')
790 {
791 buf[i] = '\n';
792 buf[i + 1] = 0;
793 break;
794 }
795 if (buf[i] == '\n')
796 {
797 /* buf[i] == '\n' */
798 buf[i + 1] = 0;
799 break;
800 }
801 }
802 buf[sizeof(buf) - 1] = 0;
803
804 /* Check that the versions match. In future this might accept several
805 versions and set appropriate flags to handle them. */
806 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
807 remote_version) != 3)
808 {
809 const char *s = "Protocol mismatch.\n";
810 (void) write(sock_out, s, strlen(s));
811 close(sock_in);
812 close(sock_out);
813 fatal("Bad protocol version identification: %.100s", buf);
814 }
815 debug("Client protocol version %d.%d; client software version %.100s",
816 remote_major, remote_minor, remote_version);
817 if (remote_major != PROTOCOL_MAJOR)
818 {
819 const char *s = "Protocol major versions differ.\n";
820 (void) write(sock_out, s, strlen(s));
821 close(sock_in);
822 close(sock_out);
823 fatal("Protocol major versions differ: %d vs. %d",
824 PROTOCOL_MAJOR, remote_major);
825 }
826
827 /* Check that the client has sufficiently high software version. */
828 if (remote_major == 1 && remote_minor < 3)
829 packet_disconnect("Your ssh version is too old and is no longer supported. Please install a newer version.");
830
831 if (remote_major == 1 && remote_minor == 3) {
832 enable_compat13();
833 if (strcmp(remote_version, "OpenSSH-1.1") != 0) {
834 debug("Agent forwarding disabled, remote version is not compatible.");
835 no_agent_forwarding_flag = 1;
836 }
837 }
838
Damien Miller2ccf6611999-11-15 15:25:10 +1100839 /* Check that the connection comes from a privileged port.
840 Rhosts- and Rhosts-RSA-Authentication only make sense
841 from priviledged programs.
842 Of course, if the intruder has root access on his local machine,
843 he can connect from any port. So do not use these authentication
844 methods from machines that you do not trust. */
845 if (remote_port >= IPPORT_RESERVED ||
846 remote_port < IPPORT_RESERVED / 2)
847 {
848 options.rhosts_authentication = 0;
849 options.rhosts_rsa_authentication = 0;
850 }
851
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000852 packet_set_nonblocking();
853
Damien Miller2ccf6611999-11-15 15:25:10 +1100854 /* Handle the connection. */
855 do_connection();
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000856
857#ifdef KRB4
858 /* Cleanup user's ticket cache file. */
859 if (options.kerberos_ticket_cleanup)
860 (void) dest_tkt();
861#endif /* KRB4 */
862
863 /* Cleanup user's local Xauthority file. */
864 if (xauthfile) unlink(xauthfile);
865
866 /* The connection has been terminated. */
867 log("Closing connection to %.100s", inet_ntoa(sin.sin_addr));
868
Damien Miller06230761999-10-28 14:03:14 +1000869#ifdef HAVE_LIBPAM
Damien Miller332e67f1999-10-27 23:42:05 +1000870 {
871 int retval;
872
873 if (pamh != NULL)
874 {
Damien Miller07a826d1999-10-29 11:49:20 +1000875 debug("Closing PAM session.");
Damien Miller332e67f1999-10-27 23:42:05 +1000876 retval = pam_close_session((pam_handle_t *)pamh, 0);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000877
Damien Miller07a826d1999-10-29 11:49:20 +1000878 debug("Terminating PAM library.");
Damien Miller332e67f1999-10-27 23:42:05 +1000879 if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
880 log("Cannot release PAM authentication.");
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000881
Damien Miller332e67f1999-10-27 23:42:05 +1000882 fatal_remove_cleanup(&pam_cleanup_proc, NULL);
883 }
884 }
Damien Miller06230761999-10-28 14:03:14 +1000885#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000886
887 packet_close();
888
889 exit(0);
890}
891
892/* Process an incoming connection. Protocol version identifiers have already
893 been exchanged. This sends server key and performs the key exchange.
894 Server and host keys will no longer be needed after this functions. */
895
Damien Miller2ccf6611999-11-15 15:25:10 +1100896void
897do_connection()
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000898{
Damien Miller9fa19b61999-11-11 20:44:05 +1100899 int i, len;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000900 BIGNUM *session_key_int;
901 unsigned char session_key[SSH_SESSION_KEY_LENGTH];
902 unsigned char check_bytes[8];
903 char *user;
904 unsigned int cipher_type, auth_mask, protocol_flags;
905 int plen, slen;
906 u_int32_t rand = 0;
907
908 /* Generate check bytes that the client must send back in the user packet
909 in order for it to be accepted; this is used to defy ip spoofing
910 attacks. Note that this only works against somebody doing IP spoofing
911 from a remote machine; any machine on the local network can still see
912 outgoing packets and catch the random cookie. This only affects
913 rhosts authentication, and this is one of the reasons why it is
914 inherently insecure. */
915 for (i = 0; i < 8; i++) {
916 if (i % 4 == 0)
917 rand = arc4random();
918 check_bytes[i] = rand & 0xff;
919 rand >>= 8;
920 }
921
922 /* Send our public key. We include in the packet 64 bits of random
923 data that must be matched in the reply in order to prevent IP spoofing. */
924 packet_start(SSH_SMSG_PUBLIC_KEY);
925 for (i = 0; i < 8; i++)
926 packet_put_char(check_bytes[i]);
927
928 /* Store our public server RSA key. */
929 packet_put_int(BN_num_bits(public_key->n));
930 packet_put_bignum(public_key->e);
931 packet_put_bignum(public_key->n);
932
933 /* Store our public host RSA key. */
934 packet_put_int(BN_num_bits(sensitive_data.host_key->n));
935 packet_put_bignum(sensitive_data.host_key->e);
936 packet_put_bignum(sensitive_data.host_key->n);
937
938 /* Put protocol flags. */
939 packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
940
941 /* Declare which ciphers we support. */
942 packet_put_int(cipher_mask());
943
944 /* Declare supported authentication types. */
945 auth_mask = 0;
946 if (options.rhosts_authentication)
947 auth_mask |= 1 << SSH_AUTH_RHOSTS;
948 if (options.rhosts_rsa_authentication)
949 auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
950 if (options.rsa_authentication)
951 auth_mask |= 1 << SSH_AUTH_RSA;
952#ifdef KRB4
953 if (options.kerberos_authentication)
954 auth_mask |= 1 << SSH_AUTH_KERBEROS;
955#endif
956#ifdef AFS
957 if (options.kerberos_tgt_passing)
958 auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
959 if (options.afs_token_passing)
960 auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
961#endif
962 if (options.password_authentication)
963 auth_mask |= 1 << SSH_AUTH_PASSWORD;
964 packet_put_int(auth_mask);
965
966 /* Send the packet and wait for it to be sent. */
967 packet_send();
968 packet_write_wait();
969
970 debug("Sent %d bit public key and %d bit host key.",
971 BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n));
972
973 /* Read clients reply (cipher type and session key). */
974 packet_read_expect(&plen, SSH_CMSG_SESSION_KEY);
975
976 /* Get cipher type. */
977 cipher_type = packet_get_char();
978
979 /* Get check bytes from the packet. These must match those we sent earlier
980 with the public key packet. */
981 for (i = 0; i < 8; i++)
982 if (check_bytes[i] != packet_get_char())
983 packet_disconnect("IP Spoofing check bytes do not match.");
984
985 debug("Encryption type: %.200s", cipher_name(cipher_type));
986
987 /* Get the encrypted integer. */
988 session_key_int = BN_new();
989 packet_get_bignum(session_key_int, &slen);
990
991 /* Get protocol flags. */
992 protocol_flags = packet_get_int();
993 packet_set_protocol_flags(protocol_flags);
994
995 packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY);
996
997 /* Decrypt it using our private server key and private host key (key with
998 larger modulus first). */
999 if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0)
1000 {
1001 /* Private key has bigger modulus. */
Damien Miller356a0b01999-11-08 15:30:59 +11001002 if (BN_num_bits(sensitive_data.private_key->n) <
1003 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) {
1004 fatal("do_connection: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
1005 BN_num_bits(sensitive_data.private_key->n),
1006 BN_num_bits(sensitive_data.host_key->n),
1007 SSH_KEY_BITS_RESERVED);
1008 }
1009
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001010 rsa_private_decrypt(session_key_int, session_key_int,
1011 sensitive_data.private_key);
1012 rsa_private_decrypt(session_key_int, session_key_int,
1013 sensitive_data.host_key);
1014 }
1015 else
1016 {
1017 /* Host key has bigger modulus (or they are equal). */
Damien Miller356a0b01999-11-08 15:30:59 +11001018 if (BN_num_bits(sensitive_data.host_key->n) <
1019 BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) {
1020 fatal("do_connection: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d",
1021 BN_num_bits(sensitive_data.host_key->n),
1022 BN_num_bits(sensitive_data.private_key->n),
1023 SSH_KEY_BITS_RESERVED);
1024 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001025 rsa_private_decrypt(session_key_int, session_key_int,
1026 sensitive_data.host_key);
1027 rsa_private_decrypt(session_key_int, session_key_int,
1028 sensitive_data.private_key);
1029 }
1030
1031 /* Compute session id for this session. */
1032 compute_session_id(session_id, check_bytes,
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001033 sensitive_data.host_key->n,
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001034 sensitive_data.private_key->n);
1035
1036 /* Extract session key from the decrypted integer. The key is in the
1037 least significant 256 bits of the integer; the first byte of the
1038 key is in the highest bits. */
1039 BN_mask_bits(session_key_int, sizeof(session_key) * 8);
Damien Miller9fa19b61999-11-11 20:44:05 +11001040 len = BN_num_bytes(session_key_int);
Damien Miller776af5d1999-11-12 08:49:09 +11001041 if (len < 0 || len > sizeof(session_key))
Damien Miller9fa19b61999-11-11 20:44:05 +11001042 fatal("do_connection: bad len: session_key_int %d > sizeof(session_key) %d",
1043 len, sizeof(session_key));
1044 memset(session_key, 0, sizeof(session_key));
1045 BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001046
1047 /* Xor the first 16 bytes of the session key with the session id. */
1048 for (i = 0; i < 16; i++)
1049 session_key[i] ^= session_id[i];
1050
1051 /* Destroy the decrypted integer. It is no longer needed. */
1052 BN_clear_free(session_key_int);
1053
1054 /* Set the session key. From this on all communications will be
1055 encrypted. */
Damien Miller7e8e8201999-11-16 13:37:16 +11001056 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001057
1058 /* Destroy our copy of the session key. It is no longer needed. */
1059 memset(session_key, 0, sizeof(session_key));
1060
1061 debug("Received session key; encryption turned on.");
1062
1063 /* Send an acknowledgement packet. Note that this packet is sent
1064 encrypted. */
1065 packet_start(SSH_SMSG_SUCCESS);
1066 packet_send();
1067 packet_write_wait();
1068
1069 /* Get the name of the user that we wish to log in as. */
1070 packet_read_expect(&plen, SSH_CMSG_USER);
1071
1072 /* Get the user name. */
1073 {
1074 int ulen;
1075 user = packet_get_string(&ulen);
1076 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
1077 }
1078
1079 /* Destroy the private and public keys. They will no longer be needed. */
1080 RSA_free(public_key);
1081 RSA_free(sensitive_data.private_key);
1082 RSA_free(sensitive_data.host_key);
1083
1084 setproctitle("%s", user);
1085 /* Do the authentication. */
Damien Miller2ccf6611999-11-15 15:25:10 +11001086 do_authentication(user);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001087}
1088
1089/* Check if the user is allowed to log in via ssh. If user is listed in
1090 DenyUsers or user's primary group is listed in DenyGroups, false will
1091 be returned. If AllowUsers isn't empty and user isn't listed there, or
1092 if AllowGroups isn't empty and user isn't listed there, false will be
1093 returned. Otherwise true is returned.
1094 XXX This function should also check if user has a valid shell */
1095
1096static int
1097allowed_user(struct passwd *pw)
1098{
1099 struct group *grp;
1100 int i;
1101
1102 /* Shouldn't be called if pw is NULL, but better safe than sorry... */
1103 if (!pw)
1104 return 0;
1105
1106 /* XXX Should check for valid login shell */
1107
1108 /* Return false if user is listed in DenyUsers */
1109 if (options.num_deny_users > 0)
1110 {
1111 if (!pw->pw_name)
1112 return 0;
1113 for (i = 0; i < options.num_deny_users; i++)
1114 if (match_pattern(pw->pw_name, options.deny_users[i]))
1115 return 0;
1116 }
1117
1118 /* Return false if AllowUsers isn't empty and user isn't listed there */
1119 if (options.num_allow_users > 0)
1120 {
1121 if (!pw->pw_name)
1122 return 0;
1123 for (i = 0; i < options.num_allow_users; i++)
1124 if (match_pattern(pw->pw_name, options.allow_users[i]))
1125 break;
1126 /* i < options.num_allow_users iff we break for loop */
1127 if (i >= options.num_allow_users)
1128 return 0;
1129 }
1130
1131 /* Get the primary group name if we need it. Return false if it fails */
1132 if (options.num_deny_groups > 0 || options.num_allow_groups > 0 )
1133 {
1134 grp = getgrgid(pw->pw_gid);
1135 if (!grp)
1136 return 0;
1137
1138 /* Return false if user's group is listed in DenyGroups */
1139 if (options.num_deny_groups > 0)
1140 {
1141 if (!grp->gr_name)
1142 return 0;
1143 for (i = 0; i < options.num_deny_groups; i++)
1144 if (match_pattern(grp->gr_name, options.deny_groups[i]))
1145 return 0;
1146 }
1147
1148 /* Return false if AllowGroups isn't empty and user's group isn't
1149 listed there */
1150 if (options.num_allow_groups > 0)
1151 {
1152 if (!grp->gr_name)
1153 return 0;
1154 for (i = 0; i < options.num_allow_groups; i++)
1155 if (match_pattern(grp->gr_name, options.allow_groups[i]))
1156 break;
1157 /* i < options.num_allow_groups iff we break for loop */
1158 if (i >= options.num_allow_groups)
1159 return 0;
1160 }
1161 }
1162
1163 /* We found no reason not to let this user try to log on... */
1164 return 1;
1165}
1166
1167/* Performs authentication of an incoming connection. Session key has already
1168 been exchanged and encryption is enabled. User is the user name to log
Damien Miller2ccf6611999-11-15 15:25:10 +11001169 in as (received from the client). */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001170
1171void
Damien Miller2ccf6611999-11-15 15:25:10 +11001172do_authentication(char *user)
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001173{
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001174 struct passwd *pw, pwcopy;
Damien Miller2ccf6611999-11-15 15:25:10 +11001175
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001176#ifdef AFS
1177 /* If machine has AFS, set process authentication group. */
1178 if (k_hasafs()) {
1179 k_setpag();
1180 k_unlog();
1181 }
1182#endif /* AFS */
1183
1184 /* Verify that the user is a valid user. */
1185 pw = getpwnam(user);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001186 if (!pw || !allowed_user(pw))
Damien Miller2ccf6611999-11-15 15:25:10 +11001187 do_fake_authloop(user);
1188
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001189 /* Take a copy of the returned structure. */
1190 memset(&pwcopy, 0, sizeof(pwcopy));
1191 pwcopy.pw_name = xstrdup(pw->pw_name);
1192 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
1193 pwcopy.pw_uid = pw->pw_uid;
1194 pwcopy.pw_gid = pw->pw_gid;
1195 pwcopy.pw_dir = xstrdup(pw->pw_dir);
1196 pwcopy.pw_shell = xstrdup(pw->pw_shell);
1197 pw = &pwcopy;
1198
Damien Miller06230761999-10-28 14:03:14 +10001199#ifdef HAVE_LIBPAM
Damien Miller3bd49ec1999-11-15 15:40:55 +11001200 {
1201 int pam_retval;
1202
1203 debug("Starting up PAM with username \"%.200s\"", pw->pw_name);
Damien Miller2ccf6611999-11-15 15:25:10 +11001204
Damien Miller3bd49ec1999-11-15 15:40:55 +11001205 pam_retval = pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh);
1206 if (pam_retval != PAM_SUCCESS)
1207 fatal("PAM initialisation failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
Damien Miller2ccf6611999-11-15 15:25:10 +11001208
Damien Miller3bd49ec1999-11-15 15:40:55 +11001209 fatal_add_cleanup(&pam_cleanup_proc, NULL);
1210 }
Damien Miller06230761999-10-28 14:03:14 +10001211#endif
Damien Miller3d112ef1999-10-28 13:20:30 +10001212
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001213 /* If we are not running as root, the user must have the same uid as the
1214 server. */
1215 if (getuid() != 0 && pw->pw_uid != getuid())
1216 packet_disconnect("Cannot change user when server not running as root.");
1217
1218 debug("Attempting authentication for %.100s.", user);
1219
1220 /* If the user has no password, accept authentication immediately. */
1221 if (options.password_authentication &&
1222#ifdef KRB4
1223 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
1224#endif /* KRB4 */
1225 auth_password(pw, ""))
1226 {
1227 /* Authentication with empty password succeeded. */
1228 debug("Login for user %.100s accepted without authentication.", user);
Damien Miller2ccf6611999-11-15 15:25:10 +11001229 } else {
1230 /* Loop until the user has been authenticated or the connection is closed,
1231 do_authloop() returns only if authentication is successfull */
1232 do_authloop(pw);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001233 }
1234
Damien Miller2ccf6611999-11-15 15:25:10 +11001235 /* XXX log unified auth message */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001236
1237 /* Check if the user is logging in as root and root logins are disallowed. */
1238 if (pw->pw_uid == 0 && !options.permit_root_login)
1239 {
1240 if (forced_command)
Damien Miller0aa8e531999-11-02 19:05:02 +11001241 log("Root login accepted for forced command.");
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001242 else
1243 packet_disconnect("ROOT LOGIN REFUSED FROM %.200s",
1244 get_canonical_hostname());
1245 }
1246
Damien Miller2ccf6611999-11-15 15:25:10 +11001247 /* The user has been authenticated and accepted. */
1248 packet_start(SSH_SMSG_SUCCESS);
1249 packet_send();
1250 packet_write_wait();
1251
1252 /* Perform session preparation. */
1253 do_authenticated(pw);
1254}
1255
1256#define MAX_AUTH_FAILURES 5
1257
1258/* read packets and try to authenticate local user *pw.
1259 return if authentication is successfull */
1260void
1261do_authloop(struct passwd *pw)
1262{
1263 int authentication_failures = 0;
Damien Miller7e8e8201999-11-16 13:37:16 +11001264 unsigned int bits;
Damien Miller2ccf6611999-11-15 15:25:10 +11001265 BIGNUM *client_host_key_e, *client_host_key_n;
1266 BIGNUM *n;
Damien Miller3bd49ec1999-11-15 15:40:55 +11001267 char *client_user = NULL, *password = NULL;
Damien Miller2ccf6611999-11-15 15:25:10 +11001268 int plen, dlen, nlen, ulen, elen;
Damien Miller3bd49ec1999-11-15 15:40:55 +11001269#ifdef HAVE_LIBPAM
1270 int pam_retval;
1271#endif /* HAVE_LIBPAM */
Damien Miller2ccf6611999-11-15 15:25:10 +11001272
1273 /* Indicate that authentication is needed. */
1274 packet_start(SSH_SMSG_FAILURE);
1275 packet_send();
1276 packet_write_wait();
1277
1278 for (;;) {
1279 int authenticated = 0;
1280
1281 /* Get a packet from the client. */
1282 int type = packet_read(&plen);
1283
1284 /* Process the packet. */
1285 switch (type)
1286 {
1287#ifdef AFS
1288 case SSH_CMSG_HAVE_KERBEROS_TGT:
1289 if (!options.kerberos_tgt_passing)
1290 {
1291 /* packet_get_all(); */
1292 log("Kerberos tgt passing disabled.");
1293 break;
1294 }
1295 else {
1296 /* Accept Kerberos tgt. */
1297 char *tgt = packet_get_string(&dlen);
1298 packet_integrity_check(plen, 4 + dlen, type);
1299 if (!auth_kerberos_tgt(pw, tgt))
1300 debug("Kerberos tgt REFUSED for %s", pw->pw_name);
1301 xfree(tgt);
1302 }
1303 continue;
1304
1305 case SSH_CMSG_HAVE_AFS_TOKEN:
1306 if (!options.afs_token_passing || !k_hasafs()) {
1307 /* packet_get_all(); */
1308 log("AFS token passing disabled.");
1309 break;
1310 }
1311 else {
1312 /* Accept AFS token. */
1313 char *token_string = packet_get_string(&dlen);
1314 packet_integrity_check(plen, 4 + dlen, type);
1315 if (!auth_afs_token(pw, token_string))
1316 debug("AFS token REFUSED for %s", pw->pw_name);
1317 xfree(token_string);
1318 }
1319 continue;
1320#endif /* AFS */
1321
1322#ifdef KRB4
1323 case SSH_CMSG_AUTH_KERBEROS:
1324 if (!options.kerberos_authentication)
1325 {
1326 /* packet_get_all(); */
1327 log("Kerberos authentication disabled.");
1328 break;
1329 }
1330 else {
1331 /* Try Kerberos v4 authentication. */
1332 KTEXT_ST auth;
1333 char *tkt_user = NULL;
1334 char *kdata = packet_get_string((unsigned int *)&auth.length);
1335 packet_integrity_check(plen, 4 + auth.length, type);
1336
1337 if (auth.length < MAX_KTXT_LEN)
1338 memcpy(auth.dat, kdata, auth.length);
1339 xfree(kdata);
1340
1341 authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
1342
1343 log("Kerberos authentication %s%s for account %s from %s",
1344 authenticated ? "accepted " : "failed",
1345 tkt_user != NULL ? tkt_user : "",
1346 pw->pw_name, get_canonical_hostname());
1347 if (authenticated)
1348 xfree(tkt_user);
1349 }
1350 break;
1351#endif /* KRB4 */
1352
1353 case SSH_CMSG_AUTH_RHOSTS:
1354 if (!options.rhosts_authentication)
1355 {
1356 log("Rhosts authentication disabled.");
1357 break;
1358 }
1359
1360 /* Get client user name. Note that we just have to trust the client;
1361 this is one reason why rhosts authentication is insecure.
1362 (Another is IP-spoofing on a local network.) */
1363 client_user = packet_get_string(&dlen);
1364 packet_integrity_check(plen, 4 + dlen, type);
1365
1366 /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
1367 authenticated = auth_rhosts(pw, client_user);
1368
1369 log("Rhosts authentication %s for %.100s, remote %.100s on %.700s.",
1370 authenticated ? "accepted" : "failed",
1371 pw->pw_name, client_user, get_canonical_hostname());
1372#ifndef HAVE_LIBPAM
1373 xfree(client_user);
1374#endif /* HAVE_LIBPAM */
1375 break;
1376
1377 case SSH_CMSG_AUTH_RHOSTS_RSA:
1378 if (!options.rhosts_rsa_authentication)
1379 {
1380 log("Rhosts with RSA authentication disabled.");
1381 break;
1382 }
1383
1384 /* Get client user name. Note that we just have to trust
1385 the client; root on the client machine can claim to be
1386 any user. */
1387 client_user = packet_get_string(&ulen);
1388
1389 /* Get the client host key. */
1390 client_host_key_e = BN_new();
1391 client_host_key_n = BN_new();
Damien Miller7e8e8201999-11-16 13:37:16 +11001392 bits = packet_get_int();
Damien Miller2ccf6611999-11-15 15:25:10 +11001393 packet_get_bignum(client_host_key_e, &elen);
1394 packet_get_bignum(client_host_key_n, &nlen);
Damien Miller7e8e8201999-11-16 13:37:16 +11001395
1396 if (bits != BN_num_bits(client_host_key_n))
1397 error("Warning: keysize mismatch for client_host_key: "
1398 "actual %d, announced %s", BN_num_bits(client_host_key_n), bits);
Damien Miller2ccf6611999-11-15 15:25:10 +11001399
1400 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
1401
Damien Miller7e8e8201999-11-16 13:37:16 +11001402 authenticated = auth_rhosts_rsa(pw, client_user,
Damien Miller2ccf6611999-11-15 15:25:10 +11001403 client_host_key_e, client_host_key_n);
1404 log("Rhosts authentication %s for %.100s, remote %.100s.",
1405 authenticated ? "accepted" : "failed",
1406 pw->pw_name, client_user);
1407#ifndef HAVE_LIBPAM
1408 xfree(client_user);
1409#endif /* HAVE_LIBPAM */
1410 BN_clear_free(client_host_key_e);
1411 BN_clear_free(client_host_key_n);
1412 break;
1413
1414 case SSH_CMSG_AUTH_RSA:
1415 if (!options.rsa_authentication)
1416 {
1417 log("RSA authentication disabled.");
1418 break;
1419 }
1420
1421 /* RSA authentication requested. */
1422 n = BN_new();
1423 packet_get_bignum(n, &nlen);
1424 packet_integrity_check(plen, nlen, type);
Damien Miller81428f91999-11-18 09:28:11 +11001425
Damien Miller2ccf6611999-11-15 15:25:10 +11001426 authenticated = auth_rsa(pw, n);
Damien Miller2ccf6611999-11-15 15:25:10 +11001427 log("RSA authentication %s for %.100s.",
1428 authenticated ? "accepted" : "failed",
1429 pw->pw_name);
Damien Miller81428f91999-11-18 09:28:11 +11001430 BN_clear_free(n);
Damien Miller2ccf6611999-11-15 15:25:10 +11001431 break;
1432
1433 case SSH_CMSG_AUTH_PASSWORD:
1434 if (!options.password_authentication)
1435 {
1436 log("Password authentication disabled.");
1437 break;
1438 }
1439
1440 /* Read user password. It is in plain text, but was transmitted
1441 over the encrypted channel so it is not visible to an outside
1442 observer. */
1443 password = packet_get_string(&dlen);
1444 packet_integrity_check(plen, 4 + dlen, type);
1445
Damien Miller06230761999-10-28 14:03:14 +10001446#ifdef HAVE_LIBPAM
Damien Miller3bd49ec1999-11-15 15:40:55 +11001447 /* Do PAM auth with password */
Damien Miller2ccf6611999-11-15 15:25:10 +11001448 pampasswd = password;
Damien Miller3bd49ec1999-11-15 15:40:55 +11001449 pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
Damien Miller2ccf6611999-11-15 15:25:10 +11001450 if (pam_retval == PAM_SUCCESS)
1451 {
Damien Miller3bd49ec1999-11-15 15:40:55 +11001452 log("PAM Password authentication accepted for user \"%.100s\"", pw->pw_name);
Damien Miller2ccf6611999-11-15 15:25:10 +11001453 authenticated = 1;
1454 break;
1455 }
Damien Miller3bd49ec1999-11-15 15:40:55 +11001456
1457 log("PAM Password authentication for \"%.100s\" failed: %s",
1458 pw->pw_name, pam_strerror((pam_handle_t *)pamh, pam_retval));
Damien Miller2ccf6611999-11-15 15:25:10 +11001459 break;
1460#else /* HAVE_LIBPAM */
1461 /* Try authentication with the password. */
1462 authenticated = auth_password(pw, password);
Damien Miller81428f91999-11-18 09:28:11 +11001463 log("Password authentication %s for %.100s.",
1464 authenticated ? "accepted" : "failed",
1465 pw->pw_name);
Damien Miller2ccf6611999-11-15 15:25:10 +11001466
1467 memset(password, 0, strlen(password));
1468 xfree(password);
1469 break;
1470#endif /* HAVE_LIBPAM */
1471
1472 case SSH_CMSG_AUTH_TIS:
1473 /* TIS Authentication is unsupported */
1474 log("TIS authentication disabled.");
1475 break;
1476
1477 default:
1478 /* Any unknown messages will be ignored (and failure returned)
1479 during authentication. */
1480 log("Unknown message during authentication: type %d", type);
1481 break; /* Respond with a failure message. */
1482 }
1483
1484 if (authenticated)
1485 break;
1486 if (++authentication_failures >= MAX_AUTH_FAILURES)
1487 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1488 pw->pw_name, get_canonical_hostname());
1489 /* Send a message indicating that the authentication attempt failed. */
1490 packet_start(SSH_SMSG_FAILURE);
1491 packet_send();
1492 packet_write_wait();
1493 }
1494
1495#ifdef HAVE_LIBPAM
1496 do_pam_account_and_session(pw->pw_name, client_user, get_canonical_hostname());
Damien Miller332e67f1999-10-27 23:42:05 +10001497
1498 /* Clean up */
1499 if (client_user != NULL)
1500 xfree(client_user);
1501
1502 if (password != NULL)
1503 {
1504 memset(password, 0, strlen(password));
1505 xfree(password);
1506 }
Damien Miller06230761999-10-28 14:03:14 +10001507#endif /* HAVE_LIBPAM */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001508}
1509
Damien Miller2ccf6611999-11-15 15:25:10 +11001510/* The user does not exist or access is denied,
1511 but fake indication that authentication is needed. */
1512void
1513do_fake_authloop(char *user)
Damien Miller3d112ef1999-10-28 13:20:30 +10001514{
1515 int authentication_failures = 0;
Damien Miller2ccf6611999-11-15 15:25:10 +11001516
1517 /* Indicate that authentication is needed. */
Damien Miller3d112ef1999-10-28 13:20:30 +10001518 packet_start(SSH_SMSG_FAILURE);
1519 packet_send();
1520 packet_write_wait();
1521
1522 /* Keep reading packets, and always respond with a failure. This is to
1523 avoid disclosing whether such a user really exists. */
Damien Miller2ccf6611999-11-15 15:25:10 +11001524 for (;;)
Damien Miller3d112ef1999-10-28 13:20:30 +10001525 {
Damien Miller2ccf6611999-11-15 15:25:10 +11001526 /* Read a packet. This will not return if the client disconnects. */
1527 int plen;
1528 int type = packet_read(&plen);
1529#ifdef SKEY
1530 int passw_len;
1531 char *password, *skeyinfo;
1532 if (options.password_authentication &&
1533 options.skey_authentication == 1 &&
1534 type == SSH_CMSG_AUTH_PASSWORD &&
1535 (password = packet_get_string(&passw_len)) != NULL &&
1536 passw_len == 5 &&
1537 strncasecmp(password, "s/key", 5) == 0 &&
1538 (skeyinfo = skey_fake_keyinfo(user)) != NULL ){
1539 /* Send a fake s/key challenge. */
1540 packet_send_debug(skeyinfo);
1541 }
1542#endif
1543 if (++authentication_failures >= MAX_AUTH_FAILURES)
1544 packet_disconnect("Too many authentication failures for %.100s from %.200s",
1545 user, get_canonical_hostname());
1546 /* Send failure. This should be indistinguishable from a failed
1547 authentication. */
1548 packet_start(SSH_SMSG_FAILURE);
1549 packet_send();
1550 packet_write_wait();
Damien Miller3d112ef1999-10-28 13:20:30 +10001551 }
Damien Miller3d112ef1999-10-28 13:20:30 +10001552 /*NOTREACHED*/
1553 abort();
1554}
1555
Damien Miller2ccf6611999-11-15 15:25:10 +11001556
Damien Miller5ce662a1999-11-11 17:57:39 +11001557/* Remove local Xauthority file. */
1558static void
1559xauthfile_cleanup_proc(void *ignore)
1560{
1561 debug("xauthfile_cleanup_proc called");
1562
1563 if (xauthfile != NULL) {
1564 unlink(xauthfile);
1565 xfree(xauthfile);
1566 xauthfile = NULL;
1567 }
1568}
1569
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001570/* Prepares for an interactive session. This is called after the user has
1571 been successfully authenticated. During this message exchange, pseudo
1572 terminals are allocated, X11, TCP/IP, and authentication agent forwardings
1573 are requested, etc. */
1574
1575void do_authenticated(struct passwd *pw)
1576{
1577 int type;
1578 int compression_level = 0, enable_compression_after_reply = 0;
1579 int have_pty = 0, ptyfd = -1, ttyfd = -1, xauthfd = -1;
1580 int row, col, xpixel, ypixel, screen;
1581 char ttyname[64];
1582 char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL;
1583 struct group *grp;
1584 gid_t tty_gid;
1585 mode_t tty_mode;
1586 int n_bytes;
1587
1588 /* Cancel the alarm we set to limit the time taken for authentication. */
1589 alarm(0);
1590
1591 /* Inform the channel mechanism that we are the server side and that
1592 the client may request to connect to any port at all. (The user could
1593 do it anyway, and we wouldn\'t know what is permitted except by the
1594 client telling us, so we can equally well trust the client not to request
1595 anything bogus.) */
1596 channel_permit_all_opens();
1597
1598 /* We stay in this loop until the client requests to execute a shell or a
1599 command. */
1600 while (1)
1601 {
1602 int plen, dlen;
1603
1604 /* Get a packet from the client. */
1605 type = packet_read(&plen);
1606
1607 /* Process the packet. */
1608 switch (type)
1609 {
1610 case SSH_CMSG_REQUEST_COMPRESSION:
1611 packet_integrity_check(plen, 4, type);
1612 compression_level = packet_get_int();
1613 if (compression_level < 1 || compression_level > 9)
1614 {
1615 packet_send_debug("Received illegal compression level %d.",
1616 compression_level);
1617 goto fail;
1618 }
1619 /* Enable compression after we have responded with SUCCESS. */
1620 enable_compression_after_reply = 1;
1621 break;
1622
1623 case SSH_CMSG_REQUEST_PTY:
1624 if (no_pty_flag)
1625 {
1626 debug("Allocating a pty not permitted for this authentication.");
1627 goto fail;
1628 }
1629 if (have_pty)
1630 packet_disconnect("Protocol error: you already have a pty.");
1631
1632 debug("Allocating pty.");
1633
1634 /* Allocate a pty and open it. */
1635 if (!pty_allocate(&ptyfd, &ttyfd, ttyname))
1636 {
1637 error("Failed to allocate pty.");
1638 goto fail;
1639 }
1640
1641 /* Determine the group to make the owner of the tty. */
1642 grp = getgrnam("tty");
1643 if (grp)
1644 {
1645 tty_gid = grp->gr_gid;
1646 tty_mode = S_IRUSR|S_IWUSR|S_IWGRP;
1647 }
1648 else
1649 {
1650 tty_gid = pw->pw_gid;
1651 tty_mode = S_IRUSR|S_IWUSR|S_IWGRP|S_IWOTH;
1652 }
1653
1654 /* Change ownership of the tty. */
1655 if (chown(ttyname, pw->pw_uid, tty_gid) < 0)
1656 fatal("chown(%.100s, %d, %d) failed: %.100s",
1657 ttyname, pw->pw_uid, tty_gid, strerror(errno));
1658 if (chmod(ttyname, tty_mode) < 0)
1659 fatal("chmod(%.100s, 0%o) failed: %.100s",
1660 ttyname, tty_mode, strerror(errno));
1661
1662 /* Get TERM from the packet. Note that the value may be of arbitrary
1663 length. */
1664
1665 term = packet_get_string(&dlen);
1666 packet_integrity_check(dlen, strlen(term), type);
1667 /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */
1668 /* Remaining bytes */
1669 n_bytes = plen - (4 + dlen + 4*4);
1670
1671 if (strcmp(term, "") == 0)
1672 term = NULL;
1673
1674 /* Get window size from the packet. */
1675 row = packet_get_int();
1676 col = packet_get_int();
1677 xpixel = packet_get_int();
1678 ypixel = packet_get_int();
1679 pty_change_window_size(ptyfd, row, col, xpixel, ypixel);
1680
1681 /* Get tty modes from the packet. */
1682 tty_parse_modes(ttyfd, &n_bytes);
1683 packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type);
1684
1685 /* Indicate that we now have a pty. */
1686 have_pty = 1;
1687 break;
1688
1689 case SSH_CMSG_X11_REQUEST_FORWARDING:
1690 if (!options.x11_forwarding)
1691 {
1692 packet_send_debug("X11 forwarding disabled in server configuration file.");
1693 goto fail;
1694 }
1695#ifdef XAUTH_PATH
1696 if (no_x11_forwarding_flag)
1697 {
1698 packet_send_debug("X11 forwarding not permitted for this authentication.");
1699 goto fail;
1700 }
1701 debug("Received request for X11 forwarding with auth spoofing.");
1702 if (display)
1703 packet_disconnect("Protocol error: X11 display already set.");
1704 {
1705 int proto_len, data_len;
1706 proto = packet_get_string(&proto_len);
1707 data = packet_get_string(&data_len);
1708 packet_integrity_check(plen, 4+proto_len + 4+data_len + 4, type);
1709 }
1710 if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER)
1711 screen = packet_get_int();
1712 else
1713 screen = 0;
1714 display = x11_create_display_inet(screen);
1715 if (!display)
1716 goto fail;
1717
1718 /* Setup to always have a local .Xauthority. */
1719 xauthfile = xmalloc(MAXPATHLEN);
1720 snprintf(xauthfile, MAXPATHLEN, "/tmp/XauthXXXXXX");
1721
1722 if ((xauthfd = mkstemp(xauthfile)) != -1) {
1723 fchown(xauthfd, pw->pw_uid, pw->pw_gid);
1724 close(xauthfd);
Damien Miller5ce662a1999-11-11 17:57:39 +11001725 fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001726 }
1727 else {
1728 xfree(xauthfile);
1729 xauthfile = NULL;
1730 }
1731 break;
1732#else /* XAUTH_PATH */
1733 /* No xauth program; we won't accept forwarding with spoofing. */
1734 packet_send_debug("No xauth program; cannot forward with spoofing.");
1735 goto fail;
1736#endif /* XAUTH_PATH */
1737
1738 case SSH_CMSG_AGENT_REQUEST_FORWARDING:
1739 if (no_agent_forwarding_flag)
1740 {
1741 debug("Authentication agent forwarding not permitted for this authentication.");
1742 goto fail;
1743 }
1744 debug("Received authentication agent forwarding request.");
1745 auth_input_request_forwarding(pw);
1746 break;
1747
1748 case SSH_CMSG_PORT_FORWARD_REQUEST:
1749 if (no_port_forwarding_flag)
1750 {
1751 debug("Port forwarding not permitted for this authentication.");
1752 goto fail;
1753 }
1754 debug("Received TCP/IP port forwarding request.");
1755 channel_input_port_forward_request(pw->pw_uid == 0);
1756 break;
1757
1758 case SSH_CMSG_EXEC_SHELL:
1759 /* Set interactive/non-interactive mode. */
1760 packet_set_interactive(have_pty || display != NULL,
1761 options.keepalives);
1762
1763 if (forced_command != NULL)
1764 goto do_forced_command;
1765 debug("Forking shell.");
1766 packet_integrity_check(plen, 0, type);
1767 if (have_pty)
1768 do_exec_pty(NULL, ptyfd, ttyfd, ttyname, pw, term, display, proto,
1769 data);
1770 else
1771 do_exec_no_pty(NULL, pw, display, proto, data);
1772 return;
1773
1774 case SSH_CMSG_EXEC_CMD:
1775 /* Set interactive/non-interactive mode. */
1776 packet_set_interactive(have_pty || display != NULL,
1777 options.keepalives);
1778
1779 if (forced_command != NULL)
1780 goto do_forced_command;
1781 /* Get command from the packet. */
1782 {
1783 int dlen;
1784 command = packet_get_string(&dlen);
1785 debug("Executing command '%.500s'", command);
1786 packet_integrity_check(plen, 4 + dlen, type);
1787 }
1788 if (have_pty)
1789 do_exec_pty(command, ptyfd, ttyfd, ttyname, pw, term, display,
1790 proto, data);
1791 else
1792 do_exec_no_pty(command, pw, display, proto, data);
1793 xfree(command);
1794 return;
1795
1796 case SSH_CMSG_MAX_PACKET_SIZE:
1797 debug("The server does not support limiting packet size.");
1798 goto fail;
1799
1800 default:
1801 /* Any unknown messages in this phase are ignored, and a failure
1802 message is returned. */
1803 log("Unknown packet type received after authentication: %d", type);
1804 goto fail;
1805 }
1806
1807 /* The request was successfully processed. */
1808 packet_start(SSH_SMSG_SUCCESS);
1809 packet_send();
1810 packet_write_wait();
1811
1812 /* Enable compression now that we have replied if appropriate. */
1813 if (enable_compression_after_reply)
1814 {
1815 enable_compression_after_reply = 0;
1816 packet_start_compression(compression_level);
1817 }
1818
1819 continue;
1820
1821 fail:
1822 /* The request failed. */
1823 packet_start(SSH_SMSG_FAILURE);
1824 packet_send();
1825 packet_write_wait();
1826 continue;
1827
1828 do_forced_command:
1829 /* There is a forced command specified for this login. Execute it. */
1830 debug("Executing forced command: %.900s", forced_command);
1831 if (have_pty)
1832 do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display,
1833 proto, data);
1834 else
1835 do_exec_no_pty(forced_command, pw, display, proto, data);
1836 return;
1837 }
1838}
1839
1840/* This is called to fork and execute a command when we have no tty. This
1841 will call do_child from the child, and server_loop from the parent after
1842 setting up file descriptors and such. */
1843
1844void do_exec_no_pty(const char *command, struct passwd *pw,
1845 const char *display, const char *auth_proto,
1846 const char *auth_data)
1847{
1848 int pid;
1849
1850#ifdef USE_PIPES
1851 int pin[2], pout[2], perr[2];
1852 /* Allocate pipes for communicating with the program. */
1853 if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
1854 packet_disconnect("Could not create pipes: %.100s",
1855 strerror(errno));
1856#else /* USE_PIPES */
1857 int inout[2], err[2];
1858 /* Uses socket pairs to communicate with the program. */
1859 if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
1860 socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
1861 packet_disconnect("Could not create socket pairs: %.100s",
1862 strerror(errno));
1863#endif /* USE_PIPES */
1864
1865 setproctitle("%s@notty", pw->pw_name);
1866
1867 /* Fork the child. */
1868 if ((pid = fork()) == 0)
1869 {
1870 /* Child. Reinitialize the log since the pid has changed. */
Damien Miller5ce662a1999-11-11 17:57:39 +11001871 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001872
1873 /* Create a new session and process group since the 4.4BSD setlogin()
1874 affects the entire process group. */
1875 if (setsid() < 0)
1876 error("setsid failed: %.100s", strerror(errno));
1877
1878#ifdef USE_PIPES
1879 /* Redirect stdin. We close the parent side of the socket pair,
1880 and make the child side the standard input. */
1881 close(pin[1]);
1882 if (dup2(pin[0], 0) < 0)
1883 perror("dup2 stdin");
1884 close(pin[0]);
1885
1886 /* Redirect stdout. */
1887 close(pout[0]);
1888 if (dup2(pout[1], 1) < 0)
1889 perror("dup2 stdout");
1890 close(pout[1]);
1891
1892 /* Redirect stderr. */
1893 close(perr[0]);
1894 if (dup2(perr[1], 2) < 0)
1895 perror("dup2 stderr");
1896 close(perr[1]);
1897#else /* USE_PIPES */
1898 /* Redirect stdin, stdout, and stderr. Stdin and stdout will use the
1899 same socket, as some programs (particularly rdist) seem to depend
1900 on it. */
1901 close(inout[1]);
1902 close(err[1]);
1903 if (dup2(inout[0], 0) < 0) /* stdin */
1904 perror("dup2 stdin");
1905 if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */
1906 perror("dup2 stdout");
1907 if (dup2(err[0], 2) < 0) /* stderr */
1908 perror("dup2 stderr");
1909#endif /* USE_PIPES */
1910
1911 /* Do processing for the child (exec command etc). */
1912 do_child(command, pw, NULL, display, auth_proto, auth_data, NULL);
1913 /*NOTREACHED*/
1914 }
1915 if (pid < 0)
1916 packet_disconnect("fork failed: %.100s", strerror(errno));
1917#ifdef USE_PIPES
1918 /* We are the parent. Close the child sides of the pipes. */
1919 close(pin[0]);
1920 close(pout[1]);
1921 close(perr[1]);
1922
1923 /* Enter the interactive session. */
1924 server_loop(pid, pin[1], pout[0], perr[0]);
1925 /* server_loop has closed pin[1], pout[1], and perr[1]. */
1926#else /* USE_PIPES */
1927 /* We are the parent. Close the child sides of the socket pairs. */
1928 close(inout[0]);
1929 close(err[0]);
1930
1931 /* Enter the interactive session. Note: server_loop must be able to handle
1932 the case that fdin and fdout are the same. */
1933 server_loop(pid, inout[1], inout[1], err[1]);
1934 /* server_loop has closed inout[1] and err[1]. */
1935#endif /* USE_PIPES */
1936}
1937
1938struct pty_cleanup_context
1939{
1940 const char *ttyname;
1941 int pid;
1942};
1943
1944/* Function to perform cleanup if we get aborted abnormally (e.g., due to a
1945 dropped connection). */
1946
1947void pty_cleanup_proc(void *context)
1948{
1949 struct pty_cleanup_context *cu = context;
1950
1951 debug("pty_cleanup_proc called");
1952
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001953 /* Record that the user has logged out. */
1954 record_logout(cu->pid, cu->ttyname);
1955
1956 /* Release the pseudo-tty. */
1957 pty_release(cu->ttyname);
1958}
1959
1960/* This is called to fork and execute a command when we have a tty. This
1961 will call do_child from the child, and server_loop from the parent after
1962 setting up file descriptors, controlling tty, updating wtmp, utmp,
1963 lastlog, and other such operations. */
1964
1965void do_exec_pty(const char *command, int ptyfd, int ttyfd,
1966 const char *ttyname, struct passwd *pw, const char *term,
1967 const char *display, const char *auth_proto,
1968 const char *auth_data)
1969{
1970 int pid, fdout;
1971 const char *hostname;
1972 time_t last_login_time;
1973 char buf[100], *time_string;
1974 FILE *f;
1975 char line[256];
1976 struct stat st;
1977 int quiet_login;
1978 struct sockaddr_in from;
1979 int fromlen;
1980 struct pty_cleanup_context cleanup_context;
1981
1982 /* Get remote host name. */
1983 hostname = get_canonical_hostname();
1984
1985 /* Get the time when the user last logged in. Buf will be set to contain
1986 the hostname the last login was from. */
1987 if(!options.use_login) {
1988 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
1989 buf, sizeof(buf));
1990 }
1991
1992 setproctitle("%s@%s", pw->pw_name, strrchr(ttyname, '/') + 1);
1993
1994 /* Fork the child. */
1995 if ((pid = fork()) == 0)
1996 {
1997 pid = getpid();
1998
1999 /* Child. Reinitialize the log because the pid has changed. */
Damien Miller5ce662a1999-11-11 17:57:39 +11002000 log_init(av0, options.log_level, options.log_facility, log_stderr);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002001
2002 /* Close the master side of the pseudo tty. */
2003 close(ptyfd);
2004
2005 /* Make the pseudo tty our controlling tty. */
2006 pty_make_controlling_tty(&ttyfd, ttyname);
2007
2008 /* Redirect stdin from the pseudo tty. */
2009 if (dup2(ttyfd, fileno(stdin)) < 0)
2010 error("dup2 stdin failed: %.100s", strerror(errno));
2011
2012 /* Redirect stdout to the pseudo tty. */
2013 if (dup2(ttyfd, fileno(stdout)) < 0)
2014 error("dup2 stdin failed: %.100s", strerror(errno));
2015
2016 /* Redirect stderr to the pseudo tty. */
2017 if (dup2(ttyfd, fileno(stderr)) < 0)
2018 error("dup2 stdin failed: %.100s", strerror(errno));
2019
2020 /* Close the extra descriptor for the pseudo tty. */
2021 close(ttyfd);
2022
2023 /* Get IP address of client. This is needed because we want to record
2024 where the user logged in from. If the connection is not a socket,
2025 let the ip address be 0.0.0.0. */
2026 memset(&from, 0, sizeof(from));
2027 if (packet_get_connection_in() == packet_get_connection_out())
2028 {
2029 fromlen = sizeof(from);
2030 if (getpeername(packet_get_connection_in(),
Damien Miller2ccf6611999-11-15 15:25:10 +11002031 (struct sockaddr *)&from, &fromlen) < 0) {
2032 debug("getpeername: %.100s", strerror(errno));
2033 fatal_cleanup();
2034 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002035 }
2036
2037 /* Record that there was a login on that terminal. */
2038 record_login(pid, ttyname, pw->pw_name, pw->pw_uid, hostname,
2039 &from);
2040
2041 /* Check if .hushlogin exists. */
2042 snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
2043 quiet_login = stat(line, &st) >= 0;
Damien Miller356a0b01999-11-08 15:30:59 +11002044
2045#ifdef HAVE_LIBPAM
2046 /* output the results of the pamconv() */
2047 if (!quiet_login && pamconv_msg != NULL)
2048 fprintf(stderr, pamconv_msg);
2049#endif
2050
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002051 /* If the user has logged in before, display the time of last login.
2052 However, don't display anything extra if a command has been
2053 specified (so that ssh can be used to execute commands on a remote
2054 machine without users knowing they are going to another machine).
2055 Login(1) will do this for us as well, so check if login(1) is used */
2056 if (command == NULL && last_login_time != 0 && !quiet_login &&
2057 !options.use_login)
2058 {
2059 /* Convert the date to a string. */
2060 time_string = ctime(&last_login_time);
2061 /* Remove the trailing newline. */
2062 if (strchr(time_string, '\n'))
2063 *strchr(time_string, '\n') = 0;
2064 /* Display the last login time. Host if displayed if known. */
2065 if (strcmp(buf, "") == 0)
2066 printf("Last login: %s\r\n", time_string);
2067 else
2068 printf("Last login: %s from %s\r\n", time_string, buf);
2069 }
2070
2071 /* Print /etc/motd unless a command was specified or printing it was
2072 disabled in server options or login(1) will be used. Note that
2073 some machines appear to print it in /etc/profile or similar. */
2074 if (command == NULL && options.print_motd && !quiet_login &&
2075 !options.use_login)
2076 {
2077 /* Print /etc/motd if it exists. */
2078 f = fopen("/etc/motd", "r");
2079 if (f)
2080 {
2081 while (fgets(line, sizeof(line), f))
2082 fputs(line, stdout);
2083 fclose(f);
2084 }
2085 }
2086
2087 /* Do common processing for the child, such as execing the command. */
2088 do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
2089 /*NOTREACHED*/
2090 }
2091 if (pid < 0)
2092 packet_disconnect("fork failed: %.100s", strerror(errno));
2093 /* Parent. Close the slave side of the pseudo tty. */
2094 close(ttyfd);
2095
2096 /* Create another descriptor of the pty master side for use as the standard
2097 input. We could use the original descriptor, but this simplifies code
2098 in server_loop. The descriptor is bidirectional. */
2099 fdout = dup(ptyfd);
2100 if (fdout < 0)
2101 packet_disconnect("dup failed: %.100s", strerror(errno));
2102
2103 /* Add a cleanup function to clear the utmp entry and record logout time
2104 in case we call fatal() (e.g., the connection gets closed). */
2105 cleanup_context.pid = pid;
2106 cleanup_context.ttyname = ttyname;
2107 fatal_add_cleanup(pty_cleanup_proc, (void *)&cleanup_context);
2108
2109 /* Enter interactive session. */
2110 server_loop(pid, ptyfd, fdout, -1);
2111 /* server_loop has not closed ptyfd and fdout. */
2112
2113 /* Cancel the cleanup function. */
2114 fatal_remove_cleanup(pty_cleanup_proc, (void *)&cleanup_context);
2115
2116 /* Record that the user has logged out. */
2117 record_logout(pid, ttyname);
2118
2119 /* Release the pseudo-tty. */
2120 pty_release(ttyname);
2121
2122 /* Close the server side of the socket pairs. We must do this after the
2123 pty cleanup, so that another process doesn't get this pty while we're
2124 still cleaning up. */
2125 close(ptyfd);
2126 close(fdout);
2127}
2128
2129/* Sets the value of the given variable in the environment. If the variable
2130 already exists, its value is overriden. */
2131
2132void child_set_env(char ***envp, unsigned int *envsizep, const char *name,
2133 const char *value)
2134{
2135 unsigned int i, namelen;
2136 char **env;
2137
2138 /* Find the slot where the value should be stored. If the variable already
2139 exists, we reuse the slot; otherwise we append a new slot at the end
2140 of the array, expanding if necessary. */
2141 env = *envp;
2142 namelen = strlen(name);
2143 for (i = 0; env[i]; i++)
2144 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
2145 break;
2146 if (env[i])
2147 {
2148 /* Name already exists. Reuse the slot. */
2149 xfree(env[i]);
2150 }
2151 else
2152 {
2153 /* New variable. Expand the array if necessary. */
2154 if (i >= (*envsizep) - 1)
2155 {
2156 (*envsizep) += 50;
2157 env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
2158 }
2159
2160 /* Need to set the NULL pointer at end of array beyond the new
2161 slot. */
2162 env[i + 1] = NULL;
2163 }
2164
2165 /* Allocate space and format the variable in the appropriate slot. */
2166 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
2167 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
2168}
2169
2170/* Reads environment variables from the given file and adds/overrides them
2171 into the environment. If the file does not exist, this does nothing.
2172 Otherwise, it must consist of empty lines, comments (line starts with '#')
2173 and assignments of the form name=value. No other forms are allowed. */
2174
2175void read_environment_file(char ***env, unsigned int *envsize,
2176 const char *filename)
2177{
2178 FILE *f;
2179 char buf[4096];
2180 char *cp, *value;
2181
2182 /* Open the environment file. */
2183 f = fopen(filename, "r");
2184 if (!f)
2185 return; /* Not found. */
2186
2187 /* Process each line. */
2188 while (fgets(buf, sizeof(buf), f))
2189 {
2190 /* Skip leading whitespace. */
2191 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
2192 ;
2193
2194 /* Ignore empty and comment lines. */
2195 if (!*cp || *cp == '#' || *cp == '\n')
2196 continue;
2197
2198 /* Remove newline. */
2199 if (strchr(cp, '\n'))
2200 *strchr(cp, '\n') = '\0';
2201
2202 /* Find the equals sign. Its lack indicates badly formatted line. */
2203 value = strchr(cp, '=');
2204 if (value == NULL)
2205 {
2206 fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
2207 continue;
2208 }
2209
2210 /* Replace the equals sign by nul, and advance value to the value
2211 string. */
2212 *value = '\0';
2213 value++;
2214
2215 /* Set the value in environment. */
2216 child_set_env(env, envsize, cp, value);
2217 }
2218
2219 fclose(f);
2220}
2221
2222/* Performs common processing for the child, such as setting up the
2223 environment, closing extra file descriptors, setting the user and group
2224 ids, and executing the command or shell. */
2225
2226void do_child(const char *command, struct passwd *pw, const char *term,
2227 const char *display, const char *auth_proto,
2228 const char *auth_data, const char *ttyname)
2229{
2230 const char *shell, *cp = NULL;
2231 char buf[256];
2232 FILE *f;
2233 unsigned int envsize, i;
2234 char **env;
2235 extern char **environ;
2236 struct stat st;
2237 char *argv[10];
2238
Damien Miller356a0b01999-11-08 15:30:59 +11002239#ifndef HAVE_LIBPAM /* pam_nologin handles this */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002240 /* Check /etc/nologin. */
2241 f = fopen("/etc/nologin", "r");
2242 if (f)
2243 { /* /etc/nologin exists. Print its contents and exit. */
2244 while (fgets(buf, sizeof(buf), f))
2245 fputs(buf, stderr);
2246 fclose(f);
2247 if (pw->pw_uid != 0)
2248 exit(254);
2249 }
Damien Miller776af5d1999-11-12 08:49:09 +11002250#endif /* HAVE_LIBPAM */
2251
2252#ifdef HAVE_SETLOGIN
2253 /* Set login name in the kernel. */
2254 if (setlogin(pw->pw_name) < 0)
2255 error("setlogin failed: %s", strerror(errno));
2256#endif /* HAVE_SETLOGIN */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002257
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002258 /* Set uid, gid, and groups. */
2259 /* Login(1) does this as well, and it needs uid 0 for the "-h" switch,
2260 so we let login(1) to this for us. */
2261 if(!options.use_login) {
2262 if (getuid() == 0 || geteuid() == 0)
2263 {
2264 if (setgid(pw->pw_gid) < 0)
2265 {
2266 perror("setgid");
2267 exit(1);
2268 }
2269 /* Initialize the group list. */
2270 if (initgroups(pw->pw_name, pw->pw_gid) < 0)
2271 {
2272 perror("initgroups");
2273 exit(1);
2274 }
2275 endgrent();
2276
2277 /* Permanently switch to the desired uid. */
2278 permanently_set_uid(pw->pw_uid);
2279 }
2280
2281 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
2282 fatal("Failed to set uids to %d.", (int)pw->pw_uid);
2283 }
2284
2285 /* Get the shell from the password data. An empty shell field is legal,
2286 and means /bin/sh. */
2287 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
2288
2289#ifdef AFS
2290 /* Try to get AFS tokens for the local cell. */
2291 if (k_hasafs()) {
2292 char cell[64];
2293
2294 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
2295 krb_afslog(cell, 0);
2296
2297 krb_afslog(0, 0);
2298 }
2299#endif /* AFS */
2300
2301 /* Initialize the environment. In the first part we allocate space for
2302 all environment variables. */
2303 envsize = 100;
2304 env = xmalloc(envsize * sizeof(char *));
2305 env[0] = NULL;
2306
2307 if(!options.use_login) {
2308 /* Set basic environment. */
2309 child_set_env(&env, &envsize, "USER", pw->pw_name);
2310 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
2311 child_set_env(&env, &envsize, "HOME", pw->pw_dir);
2312 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
2313
2314 snprintf(buf, sizeof buf, "%.200s/%.50s",
2315 _PATH_MAILDIR, pw->pw_name);
2316 child_set_env(&env, &envsize, "MAIL", buf);
2317
2318 /* Normal systems set SHELL by default. */
2319 child_set_env(&env, &envsize, "SHELL", shell);
2320 }
2321
2322 /* Let it inherit timezone if we have one. */
2323 if (getenv("TZ"))
2324 child_set_env(&env, &envsize, "TZ", getenv("TZ"));
2325
2326 /* Set custom environment options from RSA authentication. */
2327 while (custom_environment)
2328 {
2329 struct envstring *ce = custom_environment;
2330 char *s = ce->s;
2331 int i;
2332 for (i = 0; s[i] != '=' && s[i]; i++)
2333 ;
2334 if (s[i] == '=')
2335 {
2336 s[i] = 0;
2337 child_set_env(&env, &envsize, s, s + i + 1);
2338 }
2339 custom_environment = ce->next;
2340 xfree(ce->s);
2341 xfree(ce);
2342 }
2343
2344 /* Set SSH_CLIENT. */
2345 snprintf(buf, sizeof buf, "%.50s %d %d",
2346 get_remote_ipaddr(), get_remote_port(), options.port);
2347 child_set_env(&env, &envsize, "SSH_CLIENT", buf);
2348
2349 /* Set SSH_TTY if we have a pty. */
2350 if (ttyname)
2351 child_set_env(&env, &envsize, "SSH_TTY", ttyname);
2352
2353 /* Set TERM if we have a pty. */
2354 if (term)
2355 child_set_env(&env, &envsize, "TERM", term);
2356
2357 /* Set DISPLAY if we have one. */
2358 if (display)
2359 child_set_env(&env, &envsize, "DISPLAY", display);
2360
2361#ifdef KRB4
Damien Miller5ce662a1999-11-11 17:57:39 +11002362 {
Damien Miller776af5d1999-11-12 08:49:09 +11002363 extern char *ticket;
2364
2365 if (ticket)
2366 child_set_env(&env, &envsize, "KRBTKFILE", ticket);
Damien Miller5ce662a1999-11-11 17:57:39 +11002367 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002368#endif /* KRB4 */
2369
Damien Miller94388161999-10-29 09:57:31 +10002370#ifdef HAVE_LIBPAM
2371 /* Pull in any environment variables that may have been set by PAM. */
2372 {
2373 char *equal_sign, var_name[256], var_val[256];
2374 long this_var;
Damien Miller5eeedae1999-10-29 10:21:15 +10002375 char **pam_env = pam_getenvlist((pam_handle_t *)pamh);
Damien Miller94388161999-10-29 09:57:31 +10002376 for(this_var = 0; pam_env && pam_env[this_var]; this_var++)
2377 {
Damien Millerd0562b31999-10-29 13:09:40 +10002378 if(strlen(pam_env[this_var]) < (sizeof(var_name) - 1))
Damien Miller94388161999-10-29 09:57:31 +10002379 if((equal_sign = strstr(pam_env[this_var], "=")) != NULL)
2380 {
2381 memset(var_name, 0, sizeof(var_name));
2382 memset(var_val, 0, sizeof(var_val));
2383 strncpy(var_name, pam_env[this_var],
2384 equal_sign - pam_env[this_var]);
2385 strcpy(var_val, equal_sign + 1);
2386 child_set_env(&env, &envsize, var_name, var_val);
2387 }
2388 }
2389 }
2390#endif /* HAVE_LIBPAM */
2391
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002392 /* Set XAUTHORITY to always be a local file. */
2393 if (xauthfile)
2394 child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
2395
2396 /* Set variable for forwarded authentication connection, if we have one. */
2397 if (auth_get_socket_name() != NULL)
2398 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
2399 auth_get_socket_name());
Damien Miller776af5d1999-11-12 08:49:09 +11002400
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002401 /* Read $HOME/.ssh/environment. */
2402 if(!options.use_login) {
2403 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);
2404 read_environment_file(&env, &envsize, buf);
2405 }
2406
2407 /* If debugging, dump the environment to stderr. */
2408 if (debug_flag)
2409 {
2410 fprintf(stderr, "Environment:\n");
2411 for (i = 0; env[i]; i++)
2412 fprintf(stderr, " %.200s\n", env[i]);
2413 }
2414
2415 /* Close the connection descriptors; note that this is the child, and the
2416 server will still have the socket open, and it is important that we
2417 do not shutdown it. Note that the descriptors cannot be closed before
2418 building the environment, as we call get_remote_ipaddr there. */
2419 if (packet_get_connection_in() == packet_get_connection_out())
2420 close(packet_get_connection_in());
2421 else
2422 {
2423 close(packet_get_connection_in());
2424 close(packet_get_connection_out());
2425 }
2426 /* Close all descriptors related to channels. They will still remain
2427 open in the parent. */
2428 channel_close_all();
2429
2430 /* Close any extra file descriptors. Note that there may still be
2431 descriptors left by system functions. They will be closed later. */
2432 endpwent();
2433 endhostent();
2434
2435 /* Close any extra open file descriptors so that we don\'t have them
2436 hanging around in clients. Note that we want to do this after
2437 initgroups, because at least on Solaris 2.3 it leaves file descriptors
2438 open. */
2439 for (i = 3; i < 64; i++)
2440 close(i);
2441
2442 /* Change current directory to the user\'s home directory. */
2443 if (chdir(pw->pw_dir) < 0)
2444 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
2445 pw->pw_dir, strerror(errno));
2446
2447 /* Must take new environment into use so that .ssh/rc, /etc/sshrc and
2448 xauth are run in the proper environment. */
2449 environ = env;
2450
2451 /* Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
2452 in this order). */
2453 if(!options.use_login) {
2454 if (stat(SSH_USER_RC, &st) >= 0)
2455 {
2456 if (debug_flag)
2457 fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);
2458
2459 f = popen("/bin/sh " SSH_USER_RC, "w");
2460 if (f)
2461 {
2462 if (auth_proto != NULL && auth_data != NULL)
2463 fprintf(f, "%s %s\n", auth_proto, auth_data);
2464 pclose(f);
2465 }
2466 else
2467 fprintf(stderr, "Could not run %s\n", SSH_USER_RC);
2468 }
2469 else
2470 if (stat(SSH_SYSTEM_RC, &st) >= 0)
2471 {
2472 if (debug_flag)
2473 fprintf(stderr, "Running /bin/sh %s\n", SSH_SYSTEM_RC);
2474
2475 f = popen("/bin/sh " SSH_SYSTEM_RC, "w");
2476 if (f)
2477 {
2478 if (auth_proto != NULL && auth_data != NULL)
2479 fprintf(f, "%s %s\n", auth_proto, auth_data);
2480 pclose(f);
2481 }
2482 else
2483 fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC);
2484 }
2485#ifdef XAUTH_PATH
2486 else
2487 {
2488 /* Add authority data to .Xauthority if appropriate. */
2489 if (auth_proto != NULL && auth_data != NULL)
2490 {
2491 if (debug_flag)
2492 fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n",
2493 XAUTH_PATH, display, auth_proto, auth_data);
2494
2495 f = popen(XAUTH_PATH " -q -", "w");
2496 if (f)
2497 {
2498 fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data);
2499 fclose(f);
2500 }
2501 else
2502 fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH);
2503 }
2504 }
2505#endif /* XAUTH_PATH */
2506
2507 /* Get the last component of the shell name. */
2508 cp = strrchr(shell, '/');
2509 if (cp)
2510 cp++;
2511 else
2512 cp = shell;
2513 }
2514
2515 /* If we have no command, execute the shell. In this case, the shell name
2516 to be passed in argv[0] is preceded by '-' to indicate that this is
2517 a login shell. */
2518 if (!command)
2519 {
2520 if(!options.use_login) {
2521 char buf[256];
2522
2523 /* Check for mail if we have a tty and it was enabled in server options. */
2524 if (ttyname && options.check_mail) {
2525 char *mailbox;
2526 struct stat mailstat;
2527 mailbox = getenv("MAIL");
2528 if(mailbox != NULL) {
2529 if(stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0) {
2530 printf("No mail.\n");
2531 } else if(mailstat.st_mtime < mailstat.st_atime) {
2532 printf("You have mail.\n");
2533 } else {
2534 printf("You have new mail.\n");
2535 }
2536 }
2537 }
2538 /* Start the shell. Set initial character to '-'. */
2539 buf[0] = '-';
2540 strncpy(buf + 1, cp, sizeof(buf) - 1);
2541 buf[sizeof(buf) - 1] = 0;
2542 /* Execute the shell. */
2543 argv[0] = buf;
2544 argv[1] = NULL;
2545 execve(shell, argv, env);
2546 /* Executing the shell failed. */
2547 perror(shell);
2548 exit(1);
2549
2550 } else {
2551 /* Launch login(1). */
2552
Damien Miller356a0b01999-11-08 15:30:59 +11002553 execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL);
Damien Millerd4a8b7e1999-10-27 13:42:43 +10002554
2555 /* Login couldn't be executed, die. */
2556
2557 perror("login");
2558 exit(1);
2559 }
2560 }
2561
2562 /* Execute the command using the user's shell. This uses the -c option
2563 to execute the command. */
2564 argv[0] = (char *)cp;
2565 argv[1] = "-c";
2566 argv[2] = (char *)command;
2567 argv[3] = NULL;
2568 execve(shell, argv, env);
2569 perror(shell);
2570 exit(1);
2571}