summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2006-08-19 00:31:39 +1000
committerDamien Miller <djm@mindrot.org>2006-08-19 00:31:39 +1000
commita1f6840a4fa1fd48ecbf5a3ebb2c3b18f3a6c587 (patch)
tree8e43bc8778518252c8ebba8fb11764d8f1927a50
parent565ca3f60058f22d083572930833aaff2292ac20 (diff)
- djm@cvs.openbsd.org 2006/08/16 11:47:15
[sshd.c] factor inetd connection, TCP listen and main TCP accept loop out of main() into separate functions to improve readability; ok markus@
-rw-r--r--ChangeLog6
-rw-r--r--sshd.c637
2 files changed, 337 insertions, 306 deletions
diff --git a/ChangeLog b/ChangeLog
index 328f0c116..34aad31f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,10 @@
18 [servconf.c servconf.h sshd_config.5] 18 [servconf.c servconf.h sshd_config.5]
19 Add ability to match groups to Match keyword in sshd_config. Feedback 19 Add ability to match groups to Match keyword in sshd_config. Feedback
20 djm@, stevesk@, ok stevesk@. 20 djm@, stevesk@, ok stevesk@.
21 - djm@cvs.openbsd.org 2006/08/16 11:47:15
22 [sshd.c]
23 factor inetd connection, TCP listen and main TCP accept loop out of
24 main() into separate functions to improve readability; ok markus@
21 25
2220060817 2620060817
23 - (dtucker) [openbsd-compat/fake-rfc2553.c openbsd-compat/setproctitle.c] 27 - (dtucker) [openbsd-compat/fake-rfc2553.c openbsd-compat/setproctitle.c]
@@ -5239,4 +5243,4 @@
5239 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 5243 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
5240 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 5244 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
5241 5245
5242$Id: ChangeLog,v 1.4489 2006/08/18 14:23:15 djm Exp $ 5246$Id: ChangeLog,v 1.4490 2006/08/18 14:31:39 djm Exp $
diff --git a/sshd.c b/sshd.c
index ca418e36f..7065d471b 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.344 2006/08/05 07:52:52 dtucker Exp $ */ 1/* $OpenBSD: sshd.c,v 1.345 2006/08/16 11:47:15 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -905,6 +905,322 @@ recv_rexec_state(int fd, Buffer *conf)
905 debug3("%s: done", __func__); 905 debug3("%s: done", __func__);
906} 906}
907 907
908/* Accept a connection from inetd */
909static void
910server_accept_inetd(int *sock_in, int *sock_out)
911{
912 int fd;
913
914 startup_pipe = -1;
915 if (rexeced_flag) {
916 close(REEXEC_CONFIG_PASS_FD);
917 *sock_in = *sock_out = dup(STDIN_FILENO);
918 if (!debug_flag) {
919 startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
920 close(REEXEC_STARTUP_PIPE_FD);
921 }
922 } else {
923 *sock_in = dup(STDIN_FILENO);
924 *sock_out = dup(STDOUT_FILENO);
925 }
926 /*
927 * We intentionally do not close the descriptors 0, 1, and 2
928 * as our code for setting the descriptors won't work if
929 * ttyfd happens to be one of those.
930 */
931 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
932 dup2(fd, STDIN_FILENO);
933 dup2(fd, STDOUT_FILENO);
934 if (fd > STDOUT_FILENO)
935 close(fd);
936 }
937 debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out);
938}
939
940/*
941 * Listen for TCP connections
942 */
943static void
944server_listen(void)
945{
946 int ret, listen_sock, on = 1;
947 struct addrinfo *ai;
948 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
949
950 for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
951 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
952 continue;
953 if (num_listen_socks >= MAX_LISTEN_SOCKS)
954 fatal("Too many listen sockets. "
955 "Enlarge MAX_LISTEN_SOCKS");
956 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
957 ntop, sizeof(ntop), strport, sizeof(strport),
958 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
959 error("getnameinfo failed: %.100s",
960 (ret != EAI_SYSTEM) ? gai_strerror(ret) :
961 strerror(errno));
962 continue;
963 }
964 /* Create socket for listening. */
965 listen_sock = socket(ai->ai_family, ai->ai_socktype,
966 ai->ai_protocol);
967 if (listen_sock < 0) {
968 /* kernel may not support ipv6 */
969 verbose("socket: %.100s", strerror(errno));
970 continue;
971 }
972 if (set_nonblock(listen_sock) == -1) {
973 close(listen_sock);
974 continue;
975 }
976 /*
977 * Set socket options.
978 * Allow local port reuse in TIME_WAIT.
979 */
980 if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
981 &on, sizeof(on)) == -1)
982 error("setsockopt SO_REUSEADDR: %s", strerror(errno));
983
984 debug("Bind to port %s on %s.", strport, ntop);
985
986 /* Bind the socket to the desired port. */
987 if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
988 error("Bind to port %s on %s failed: %.200s.",
989 strport, ntop, strerror(errno));
990 close(listen_sock);
991 continue;
992 }
993 listen_socks[num_listen_socks] = listen_sock;
994 num_listen_socks++;
995
996 /* Start listening on the port. */
997 if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
998 fatal("listen on [%s]:%s: %.100s",
999 ntop, strport, strerror(errno));
1000 logit("Server listening on %s port %s.", ntop, strport);
1001 }
1002 freeaddrinfo(options.listen_addrs);
1003
1004 if (!num_listen_socks)
1005 fatal("Cannot bind any address.");
1006}
1007
1008/*
1009 * The main TCP accept loop. Note that, for the non-debug case, returns
1010 * from this function are in a forked subprocess.
1011 */
1012static void
1013server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1014{
1015 fd_set *fdset;
1016 int i, j, ret, maxfd;
1017 int key_used = 0, startups = 0;
1018 int startup_p[2] = { -1 , -1 };
1019 struct sockaddr_storage from;
1020 socklen_t fromlen;
1021 pid_t pid;
1022
1023 /* setup fd set for accept */
1024 fdset = NULL;
1025 maxfd = 0;
1026 for (i = 0; i < num_listen_socks; i++)
1027 if (listen_socks[i] > maxfd)
1028 maxfd = listen_socks[i];
1029 /* pipes connected to unauthenticated childs */
1030 startup_pipes = xcalloc(options.max_startups, sizeof(int));
1031 for (i = 0; i < options.max_startups; i++)
1032 startup_pipes[i] = -1;
1033
1034 /*
1035 * Stay listening for connections until the system crashes or
1036 * the daemon is killed with a signal.
1037 */
1038 for (;;) {
1039 if (received_sighup)
1040 sighup_restart();
1041 if (fdset != NULL)
1042 xfree(fdset);
1043 fdset = (fd_set *)xcalloc(howmany(maxfd + 1, NFDBITS),
1044 sizeof(fd_mask));
1045
1046 for (i = 0; i < num_listen_socks; i++)
1047 FD_SET(listen_socks[i], fdset);
1048 for (i = 0; i < options.max_startups; i++)
1049 if (startup_pipes[i] != -1)
1050 FD_SET(startup_pipes[i], fdset);
1051
1052 /* Wait in select until there is a connection. */
1053 ret = select(maxfd+1, fdset, NULL, NULL, NULL);
1054 if (ret < 0 && errno != EINTR)
1055 error("select: %.100s", strerror(errno));
1056 if (received_sigterm) {
1057 logit("Received signal %d; terminating.",
1058 (int) received_sigterm);
1059 close_listen_socks();
1060 unlink(options.pid_file);
1061 exit(255);
1062 }
1063 if (key_used && key_do_regen) {
1064 generate_ephemeral_server_key();
1065 key_used = 0;
1066 key_do_regen = 0;
1067 }
1068 if (ret < 0)
1069 continue;
1070
1071 for (i = 0; i < options.max_startups; i++)
1072 if (startup_pipes[i] != -1 &&
1073 FD_ISSET(startup_pipes[i], fdset)) {
1074 /*
1075 * the read end of the pipe is ready
1076 * if the child has closed the pipe
1077 * after successful authentication
1078 * or if the child has died
1079 */
1080 close(startup_pipes[i]);
1081 startup_pipes[i] = -1;
1082 startups--;
1083 }
1084 for (i = 0; i < num_listen_socks; i++) {
1085 if (!FD_ISSET(listen_socks[i], fdset))
1086 continue;
1087 fromlen = sizeof(from);
1088 *newsock = accept(listen_socks[i],
1089 (struct sockaddr *)&from, &fromlen);
1090 if (*newsock < 0) {
1091 if (errno != EINTR && errno != EWOULDBLOCK)
1092 error("accept: %.100s", strerror(errno));
1093 continue;
1094 }
1095 if (unset_nonblock(*newsock) == -1) {
1096 close(*newsock);
1097 continue;
1098 }
1099 if (drop_connection(startups) == 1) {
1100 debug("drop connection #%d", startups);
1101 close(*newsock);
1102 continue;
1103 }
1104 if (pipe(startup_p) == -1) {
1105 close(*newsock);
1106 continue;
1107 }
1108
1109 if (rexec_flag && socketpair(AF_UNIX,
1110 SOCK_STREAM, 0, config_s) == -1) {
1111 error("reexec socketpair: %s",
1112 strerror(errno));
1113 close(*newsock);
1114 close(startup_p[0]);
1115 close(startup_p[1]);
1116 continue;
1117 }
1118
1119 for (j = 0; j < options.max_startups; j++)
1120 if (startup_pipes[j] == -1) {
1121 startup_pipes[j] = startup_p[0];
1122 if (maxfd < startup_p[0])
1123 maxfd = startup_p[0];
1124 startups++;
1125 break;
1126 }
1127
1128 /*
1129 * Got connection. Fork a child to handle it, unless
1130 * we are in debugging mode.
1131 */
1132 if (debug_flag) {
1133 /*
1134 * In debugging mode. Close the listening
1135 * socket, and start processing the
1136 * connection without forking.
1137 */
1138 debug("Server will not fork when running in debugging mode.");
1139 close_listen_socks();
1140 *sock_in = *newsock;
1141 *sock_out = *newsock;
1142 close(startup_p[0]);
1143 close(startup_p[1]);
1144 startup_pipe = -1;
1145 pid = getpid();
1146 if (rexec_flag) {
1147 send_rexec_state(config_s[0],
1148 &cfg);
1149 close(config_s[0]);
1150 }
1151 break;
1152 }
1153
1154 /*
1155 * Normal production daemon. Fork, and have
1156 * the child process the connection. The
1157 * parent continues listening.
1158 */
1159 if ((pid = fork()) == 0) {
1160 /*
1161 * Child. Close the listening and
1162 * max_startup sockets. Start using
1163 * the accepted socket. Reinitialize
1164 * logging (since our pid has changed).
1165 * We break out of the loop to handle
1166 * the connection.
1167 */
1168 startup_pipe = startup_p[1];
1169 close_startup_pipes();
1170 close_listen_socks();
1171 *sock_in = *newsock;
1172 *sock_out = *newsock;
1173 log_init(__progname,
1174 options.log_level,
1175 options.log_facility,
1176 log_stderr);
1177 if (rexec_flag)
1178 close(config_s[0]);
1179 break;
1180 }
1181
1182 /* Parent. Stay in the loop. */
1183 if (pid < 0)
1184 error("fork: %.100s", strerror(errno));
1185 else
1186 debug("Forked child %ld.", (long)pid);
1187
1188 close(startup_p[1]);
1189
1190 if (rexec_flag) {
1191 send_rexec_state(config_s[0], &cfg);
1192 close(config_s[0]);
1193 close(config_s[1]);
1194 }
1195
1196 /*
1197 * Mark that the key has been used (it
1198 * was "given" to the child).
1199 */
1200 if ((options.protocol & SSH_PROTO_1) &&
1201 key_used == 0) {
1202 /* Schedule server key regeneration alarm. */
1203 signal(SIGALRM, key_regeneration_alarm);
1204 alarm(options.key_regeneration_time);
1205 key_used = 1;
1206 }
1207
1208 close(*newsock);
1209
1210 /*
1211 * Ensure that our random state differs
1212 * from that of the child
1213 */
1214 arc4random_stir();
1215 }
1216
1217 /* child process check (or debug mode) */
1218 if (num_listen_socks < 0)
1219 break;
1220 }
1221}
1222
1223
908/* 1224/*
909 * Main program for the daemon. 1225 * Main program for the daemon.
910 */ 1226 */
@@ -913,24 +1229,14 @@ main(int ac, char **av)
913{ 1229{
914 extern char *optarg; 1230 extern char *optarg;
915 extern int optind; 1231 extern int optind;
916 int opt, j, i, on = 1; 1232 int opt, i, on = 1;
917 int sock_in = -1, sock_out = -1, newsock = -1; 1233 int sock_in = -1, sock_out = -1, newsock = -1;
918 pid_t pid;
919 socklen_t fromlen;
920 fd_set *fdset;
921 struct sockaddr_storage from;
922 const char *remote_ip; 1234 const char *remote_ip;
923 int remote_port; 1235 int remote_port;
924 FILE *f;
925 struct addrinfo *ai;
926 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
927 char *line; 1236 char *line;
928 int listen_sock, maxfd; 1237 int config_s[2] = { -1 , -1 };
929 int startup_p[2] = { -1 , -1 }, config_s[2] = { -1 , -1 };
930 int startups = 0;
931 Key *key; 1238 Key *key;
932 Authctxt *authctxt; 1239 Authctxt *authctxt;
933 int ret, key_used = 0;
934 1240
935#ifdef HAVE_SECUREWARE 1241#ifdef HAVE_SECUREWARE
936 (void)set_auth_parameters(ac, av); 1242 (void)set_auth_parameters(ac, av);
@@ -1278,121 +1584,31 @@ main(int ac, char **av)
1278 /* ignore SIGPIPE */ 1584 /* ignore SIGPIPE */
1279 signal(SIGPIPE, SIG_IGN); 1585 signal(SIGPIPE, SIG_IGN);
1280 1586
1281 /* Start listening for a socket, unless started from inetd. */ 1587 /* Get a connection, either from inetd or a listening TCP socket */
1282 if (inetd_flag) { 1588 if (inetd_flag) {
1283 int fd; 1589 server_accept_inetd(&sock_in, &sock_out);
1284 1590
1285 startup_pipe = -1;
1286 if (rexeced_flag) {
1287 close(REEXEC_CONFIG_PASS_FD);
1288 sock_in = sock_out = dup(STDIN_FILENO);
1289 if (!debug_flag) {
1290 startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
1291 close(REEXEC_STARTUP_PIPE_FD);
1292 }
1293 } else {
1294 sock_in = dup(STDIN_FILENO);
1295 sock_out = dup(STDOUT_FILENO);
1296 }
1297 /*
1298 * We intentionally do not close the descriptors 0, 1, and 2
1299 * as our code for setting the descriptors won't work if
1300 * ttyfd happens to be one of those.
1301 */
1302 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
1303 dup2(fd, STDIN_FILENO);
1304 dup2(fd, STDOUT_FILENO);
1305 if (fd > STDOUT_FILENO)
1306 close(fd);
1307 }
1308 debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);
1309 if ((options.protocol & SSH_PROTO_1) && 1591 if ((options.protocol & SSH_PROTO_1) &&
1310 sensitive_data.server_key == NULL) 1592 sensitive_data.server_key == NULL)
1311 generate_ephemeral_server_key(); 1593 generate_ephemeral_server_key();
1312 } else { 1594 } else {
1313 for (ai = options.listen_addrs; ai; ai = ai->ai_next) { 1595 server_listen();
1314 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1315 continue;
1316 if (num_listen_socks >= MAX_LISTEN_SOCKS)
1317 fatal("Too many listen sockets. "
1318 "Enlarge MAX_LISTEN_SOCKS");
1319 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
1320 ntop, sizeof(ntop), strport, sizeof(strport),
1321 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1322 error("getnameinfo failed: %.100s",
1323 (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1324 strerror(errno));
1325 continue;
1326 }
1327 /* Create socket for listening. */
1328 listen_sock = socket(ai->ai_family, ai->ai_socktype,
1329 ai->ai_protocol);
1330 if (listen_sock < 0) {
1331 /* kernel may not support ipv6 */
1332 verbose("socket: %.100s", strerror(errno));
1333 continue;
1334 }
1335 if (set_nonblock(listen_sock) == -1) {
1336 close(listen_sock);
1337 continue;
1338 }
1339 /*
1340 * Set socket options.
1341 * Allow local port reuse in TIME_WAIT.
1342 */
1343 if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
1344 &on, sizeof(on)) == -1)
1345 error("setsockopt SO_REUSEADDR: %s", strerror(errno));
1346
1347 debug("Bind to port %s on %s.", strport, ntop);
1348
1349 /* Bind the socket to the desired port. */
1350 if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1351 if (!ai->ai_next)
1352 error("Bind to port %s on %s failed: %.200s.",
1353 strport, ntop, strerror(errno));
1354 close(listen_sock);
1355 continue;
1356 }
1357 listen_socks[num_listen_socks] = listen_sock;
1358 num_listen_socks++;
1359
1360 /* Start listening on the port. */
1361 if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
1362 fatal("listen on [%s]:%s: %.100s",
1363 ntop, strport, strerror(errno));
1364 logit("Server listening on %s port %s.", ntop, strport);
1365 }
1366 freeaddrinfo(options.listen_addrs);
1367
1368 if (!num_listen_socks)
1369 fatal("Cannot bind any address.");
1370 1596
1371 if (options.protocol & SSH_PROTO_1) 1597 if (options.protocol & SSH_PROTO_1)
1372 generate_ephemeral_server_key(); 1598 generate_ephemeral_server_key();
1373 1599
1374 /*
1375 * Arrange to restart on SIGHUP. The handler needs
1376 * listen_sock.
1377 */
1378 signal(SIGHUP, sighup_handler); 1600 signal(SIGHUP, sighup_handler);
1379 1601 signal(SIGCHLD, main_sigchld_handler);
1380 signal(SIGTERM, sigterm_handler); 1602 signal(SIGTERM, sigterm_handler);
1381 signal(SIGQUIT, sigterm_handler); 1603 signal(SIGQUIT, sigterm_handler);
1382 1604
1383 /* Arrange SIGCHLD to be caught. */ 1605 /*
1384 signal(SIGCHLD, main_sigchld_handler); 1606 * Write out the pid file after the sigterm handler
1385 1607 * is setup and the listen sockets are bound
1386 /* Write out the pid file after the sigterm handler is setup */ 1608 */
1387 if (!debug_flag) { 1609 if (!debug_flag) {
1388 /* 1610 FILE *f = fopen(options.pid_file, "w");
1389 * Record our pid in /var/run/sshd.pid to make it 1611
1390 * easier to kill the correct sshd. We don't want to
1391 * do this before the bind above because the bind will
1392 * fail if there already is a daemon, and this will
1393 * overwrite any old pid in the file.
1394 */
1395 f = fopen(options.pid_file, "wb");
1396 if (f == NULL) { 1612 if (f == NULL) {
1397 error("Couldn't create pid file \"%s\": %s", 1613 error("Couldn't create pid file \"%s\": %s",
1398 options.pid_file, strerror(errno)); 1614 options.pid_file, strerror(errno));
@@ -1402,198 +1618,9 @@ main(int ac, char **av)
1402 } 1618 }
1403 } 1619 }
1404 1620
1405 /* setup fd set for listen */ 1621 /* Accept a connection and return in a forked child */
1406 fdset = NULL; 1622 server_accept_loop(&sock_in, &sock_out,
1407 maxfd = 0; 1623 &newsock, config_s);
1408 for (i = 0; i < num_listen_socks; i++)
1409 if (listen_socks[i] > maxfd)
1410 maxfd = listen_socks[i];
1411 /* pipes connected to unauthenticated childs */
1412 startup_pipes = xcalloc(options.max_startups, sizeof(int));
1413 for (i = 0; i < options.max_startups; i++)
1414 startup_pipes[i] = -1;
1415
1416 /*
1417 * Stay listening for connections until the system crashes or
1418 * the daemon is killed with a signal.
1419 */
1420 for (;;) {
1421 if (received_sighup)
1422 sighup_restart();
1423 if (fdset != NULL)
1424 xfree(fdset);
1425 fdset = (fd_set *)xcalloc(howmany(maxfd + 1, NFDBITS),
1426 sizeof(fd_mask));
1427
1428 for (i = 0; i < num_listen_socks; i++)
1429 FD_SET(listen_socks[i], fdset);
1430 for (i = 0; i < options.max_startups; i++)
1431 if (startup_pipes[i] != -1)
1432 FD_SET(startup_pipes[i], fdset);
1433
1434 /* Wait in select until there is a connection. */
1435 ret = select(maxfd+1, fdset, NULL, NULL, NULL);
1436 if (ret < 0 && errno != EINTR)
1437 error("select: %.100s", strerror(errno));
1438 if (received_sigterm) {
1439 logit("Received signal %d; terminating.",
1440 (int) received_sigterm);
1441 close_listen_socks();
1442 unlink(options.pid_file);
1443 exit(255);
1444 }
1445 if (key_used && key_do_regen) {
1446 generate_ephemeral_server_key();
1447 key_used = 0;
1448 key_do_regen = 0;
1449 }
1450 if (ret < 0)
1451 continue;
1452
1453 for (i = 0; i < options.max_startups; i++)
1454 if (startup_pipes[i] != -1 &&
1455 FD_ISSET(startup_pipes[i], fdset)) {
1456 /*
1457 * the read end of the pipe is ready
1458 * if the child has closed the pipe
1459 * after successful authentication
1460 * or if the child has died
1461 */
1462 close(startup_pipes[i]);
1463 startup_pipes[i] = -1;
1464 startups--;
1465 }
1466 for (i = 0; i < num_listen_socks; i++) {
1467 if (!FD_ISSET(listen_socks[i], fdset))
1468 continue;
1469 fromlen = sizeof(from);
1470 newsock = accept(listen_socks[i],
1471 (struct sockaddr *)&from, &fromlen);
1472 if (newsock < 0) {
1473 if (errno != EINTR && errno != EWOULDBLOCK)
1474 error("accept: %.100s", strerror(errno));
1475 continue;
1476 }
1477 if (unset_nonblock(newsock) == -1) {
1478 close(newsock);
1479 continue;
1480 }
1481 if (drop_connection(startups) == 1) {
1482 debug("drop connection #%d", startups);
1483 close(newsock);
1484 continue;
1485 }
1486 if (pipe(startup_p) == -1) {
1487 close(newsock);
1488 continue;
1489 }
1490
1491 if (rexec_flag && socketpair(AF_UNIX,
1492 SOCK_STREAM, 0, config_s) == -1) {
1493 error("reexec socketpair: %s",
1494 strerror(errno));
1495 close(newsock);
1496 close(startup_p[0]);
1497 close(startup_p[1]);
1498 continue;
1499 }
1500
1501 for (j = 0; j < options.max_startups; j++)
1502 if (startup_pipes[j] == -1) {
1503 startup_pipes[j] = startup_p[0];
1504 if (maxfd < startup_p[0])
1505 maxfd = startup_p[0];
1506 startups++;
1507 break;
1508 }
1509
1510 /*
1511 * Got connection. Fork a child to handle it, unless
1512 * we are in debugging mode.
1513 */
1514 if (debug_flag) {
1515 /*
1516 * In debugging mode. Close the listening
1517 * socket, and start processing the
1518 * connection without forking.
1519 */
1520 debug("Server will not fork when running in debugging mode.");
1521 close_listen_socks();
1522 sock_in = newsock;
1523 sock_out = newsock;
1524 close(startup_p[0]);
1525 close(startup_p[1]);
1526 startup_pipe = -1;
1527 pid = getpid();
1528 if (rexec_flag) {
1529 send_rexec_state(config_s[0],
1530 &cfg);
1531 close(config_s[0]);
1532 }
1533 break;
1534 } else {
1535 /*
1536 * Normal production daemon. Fork, and have
1537 * the child process the connection. The
1538 * parent continues listening.
1539 */
1540 if ((pid = fork()) == 0) {
1541 /*
1542 * Child. Close the listening and
1543 * max_startup sockets. Start using
1544 * the accepted socket. Reinitialize
1545 * logging (since our pid has changed).
1546 * We break out of the loop to handle
1547 * the connection.
1548 */
1549 startup_pipe = startup_p[1];
1550 close_startup_pipes();
1551 close_listen_socks();
1552 sock_in = newsock;
1553 sock_out = newsock;
1554 log_init(__progname,
1555 options.log_level,
1556 options.log_facility,
1557 log_stderr);
1558 if (rexec_flag)
1559 close(config_s[0]);
1560 break;
1561 }
1562 }
1563
1564 /* Parent. Stay in the loop. */
1565 if (pid < 0)
1566 error("fork: %.100s", strerror(errno));
1567 else
1568 debug("Forked child %ld.", (long)pid);
1569
1570 close(startup_p[1]);
1571
1572 if (rexec_flag) {
1573 send_rexec_state(config_s[0], &cfg);
1574 close(config_s[0]);
1575 close(config_s[1]);
1576 }
1577
1578 /*
1579 * Mark that the key has been used (it
1580 * was "given" to the child).
1581 */
1582 if ((options.protocol & SSH_PROTO_1) &&
1583 key_used == 0) {
1584 /* Schedule server key regeneration alarm. */
1585 signal(SIGALRM, key_regeneration_alarm);
1586 alarm(options.key_regeneration_time);
1587 key_used = 1;
1588 }
1589
1590 arc4random_stir();
1591 close(newsock);
1592 }
1593 /* child process check (or debug mode) */
1594 if (num_listen_socks < 0)
1595 break;
1596 }
1597 } 1624 }
1598 1625
1599 /* This is the child processing a new connection. */ 1626 /* This is the child processing a new connection. */