1 /* 2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * All rights reserved 4 * 5 * As far as I am concerned, the code I have written for this software 6 * can be used freely for any purpose. Any derived versions of this 7 * software must be clearly marked as such, and if the derived work is 8 * incompatible with the protocol description in the RFC file, it must be 9 * called by a name other than "ssh" or "Secure Shell". 10 */ 11 12 #include "includes.h" 13 RCSID("$OpenBSD: servconf.c,v 1.123 2003/07/22 13:35:22 markus Exp $"); 14 15 #include "ssh.h" 16 #include "log.h" 17 #include "servconf.h" 18 #include "xmalloc.h" 19 #include "compat.h" 20 #include "pathnames.h" 21 #include "tildexpand.h" 22 #include "misc.h" 23 #include "cipher.h" 24 #include "kex.h" 25 #include "mac.h" 26 27 static void add_listen_addr(ServerOptions *, char *, u_short); 28 static void add_one_listen_addr(ServerOptions *, char *, u_short); 29 30 /* AF_UNSPEC or AF_INET or AF_INET6 */ 31 extern int IPv4or6; 32 /* Use of privilege separation or not */ 33 extern int use_privsep; 34 35 /* Initializes the server options to their default values. */ 36 37 void 38 initialize_server_options(ServerOptions *options) 39 { 40 memset(options, 0, sizeof(*options)); 41 options->num_ports = 0; 42 options->ports_from_cmdline = 0; 43 options->listen_addrs = NULL; 44 options->num_host_key_files = 0; 45 options->pid_file = NULL; 46 options->server_key_bits = -1; 47 options->login_grace_time = -1; 48 options->key_regeneration_time = -1; 49 options->permit_root_login = PERMIT_NOT_SET; 50 options->ignore_rhosts = -1; 51 options->ignore_user_known_hosts = -1; 52 options->print_motd = -1; 53 options->print_lastlog = -1; 54 options->x11_forwarding = -1; 55 options->x11_display_offset = -1; 56 options->x11_use_localhost = -1; 57 options->xauth_location = NULL; 58 options->strict_modes = -1; 59 options->keepalives = -1; 60 options->log_facility = SYSLOG_FACILITY_NOT_SET; 61 options->log_level = SYSLOG_LEVEL_NOT_SET; 62 options->rhosts_authentication = -1; 63 options->rhosts_rsa_authentication = -1; 64 options->hostbased_authentication = -1; 65 options->hostbased_uses_name_from_packet_only = -1; 66 options->rsa_authentication = -1; 67 options->pubkey_authentication = -1; 68 options->kerberos_authentication = -1; 69 options->kerberos_or_local_passwd = -1; 70 options->kerberos_ticket_cleanup = -1; 71 options->kerberos_tgt_passing = -1; 72 options->password_authentication = -1; 73 options->kbd_interactive_authentication = -1; 74 options->challenge_response_authentication = -1; 75 options->permit_empty_passwd = -1; 76 options->permit_user_env = -1; 77 options->use_login = -1; 78 options->compression = -1; 79 options->allow_tcp_forwarding = -1; 80 options->num_allow_users = 0; 81 options->num_deny_users = 0; 82 options->num_allow_groups = 0; 83 options->num_deny_groups = 0; 84 options->ciphers = NULL; 85 options->macs = NULL; 86 options->protocol = SSH_PROTO_UNKNOWN; 87 options->gateway_ports = -1; 88 options->num_subsystems = 0; 89 options->max_startups_begin = -1; 90 options->max_startups_rate = -1; 91 options->max_startups = -1; 92 options->banner = NULL; 93 options->use_dns = -1; 94 options->client_alive_interval = -1; 95 options->client_alive_count_max = -1; 96 options->authorized_keys_file = NULL; 97 options->authorized_keys_file2 = NULL; 98 99 /* Needs to be accessable in many places */ 100 use_privsep = -1; 101 } 102 103 void 104 fill_default_server_options(ServerOptions *options) 105 { 106 if (options->protocol == SSH_PROTO_UNKNOWN) 107 options->protocol = SSH_PROTO_1|SSH_PROTO_2; 108 if (options->num_host_key_files == 0) { 109 /* fill default hostkeys for protocols */ 110 if (options->protocol & SSH_PROTO_1) 111 options->host_key_files[options->num_host_key_files++] = 112 _PATH_HOST_KEY_FILE; 113 if (options->protocol & SSH_PROTO_2) { 114 options->host_key_files[options->num_host_key_files++] = 115 _PATH_HOST_RSA_KEY_FILE; 116 options->host_key_files[options->num_host_key_files++] = 117 _PATH_HOST_DSA_KEY_FILE; 118 } 119 } 120 if (options->num_ports == 0) 121 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 122 if (options->listen_addrs == NULL) 123 add_listen_addr(options, NULL, 0); 124 if (options->pid_file == NULL) 125 options->pid_file = _PATH_SSH_DAEMON_PID_FILE; 126 if (options->server_key_bits == -1) 127 options->server_key_bits = 768; 128 if (options->login_grace_time == -1) 129 options->login_grace_time = 120; 130 if (options->key_regeneration_time == -1) 131 options->key_regeneration_time = 3600; 132 if (options->permit_root_login == PERMIT_NOT_SET) 133 options->permit_root_login = PERMIT_YES; 134 if (options->ignore_rhosts == -1) 135 options->ignore_rhosts = 1; 136 if (options->ignore_user_known_hosts == -1) 137 options->ignore_user_known_hosts = 0; 138 if (options->print_motd == -1) 139 options->print_motd = 1; 140 if (options->print_lastlog == -1) 141 options->print_lastlog = 1; 142 if (options->x11_forwarding == -1) 143 options->x11_forwarding = 0; 144 if (options->x11_display_offset == -1) 145 options->x11_display_offset = 10; 146 if (options->x11_use_localhost == -1) 147 options->x11_use_localhost = 1; 148 if (options->xauth_location == NULL) 149 options->xauth_location = _PATH_XAUTH; 150 if (options->strict_modes == -1) 151 options->strict_modes = 1; 152 if (options->keepalives == -1) 153 options->keepalives = 1; 154 if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 155 options->log_facility = SYSLOG_FACILITY_AUTH; 156 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 157 options->log_level = SYSLOG_LEVEL_INFO; 158 if (options->rhosts_authentication == -1) 159 options->rhosts_authentication = 0; 160 if (options->rhosts_rsa_authentication == -1) 161 options->rhosts_rsa_authentication = 0; 162 if (options->hostbased_authentication == -1) 163 options->hostbased_authentication = 0; 164 if (options->hostbased_uses_name_from_packet_only == -1) 165 options->hostbased_uses_name_from_packet_only = 0; 166 if (options->rsa_authentication == -1) 167 options->rsa_authentication = 1; 168 if (options->pubkey_authentication == -1) 169 options->pubkey_authentication = 1; 170 if (options->kerberos_authentication == -1) 171 options->kerberos_authentication = 0; 172 if (options->kerberos_or_local_passwd == -1) 173 options->kerberos_or_local_passwd = 1; 174 if (options->kerberos_ticket_cleanup == -1) 175 options->kerberos_ticket_cleanup = 1; 176 if (options->kerberos_tgt_passing == -1) 177 options->kerberos_tgt_passing = 0; 178 if (options->password_authentication == -1) 179 options->password_authentication = 1; 180 if (options->kbd_interactive_authentication == -1) 181 options->kbd_interactive_authentication = 0; 182 if (options->challenge_response_authentication == -1) 183 options->challenge_response_authentication = 1; 184 if (options->permit_empty_passwd == -1) 185 options->permit_empty_passwd = 0; 186 if (options->permit_user_env == -1) 187 options->permit_user_env = 0; 188 if (options->use_login == -1) 189 options->use_login = 0; 190 if (options->compression == -1) 191 options->compression = 1; 192 if (options->allow_tcp_forwarding == -1) 193 options->allow_tcp_forwarding = 1; 194 if (options->gateway_ports == -1) 195 options->gateway_ports = 0; 196 if (options->max_startups == -1) 197 options->max_startups = 10; 198 if (options->max_startups_rate == -1) 199 options->max_startups_rate = 100; /* 100% */ 200 if (options->max_startups_begin == -1) 201 options->max_startups_begin = options->max_startups; 202 if (options->use_dns == -1) 203 options->use_dns = 1; 204 if (options->client_alive_interval == -1) 205 options->client_alive_interval = 0; 206 if (options->client_alive_count_max == -1) 207 options->client_alive_count_max = 3; 208 if (options->authorized_keys_file2 == NULL) { 209 /* authorized_keys_file2 falls back to authorized_keys_file */ 210 if (options->authorized_keys_file != NULL) 211 options->authorized_keys_file2 = options->authorized_keys_file; 212 else 213 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2; 214 } 215 if (options->authorized_keys_file == NULL) 216 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; 217 218 /* Turn privilege separation on by default */ 219 if (use_privsep == -1) 220 use_privsep = 1; 221 } 222 223 /* Keyword tokens. */ 224 typedef enum { 225 sBadOption, /* == unknown option */ 226 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 227 sPermitRootLogin, sLogFacility, sLogLevel, 228 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, 229 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 230 sKerberosTgtPassing, sChallengeResponseAuthentication, 231 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, 232 sPrintMotd, sPrintLastLog, sIgnoreRhosts, 233 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 234 sStrictModes, sEmptyPasswd, sKeepAlives, 235 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 236 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 237 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 238 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, 239 sBanner, sUseDNS, sHostbasedAuthentication, 240 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 241 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 242 sUsePrivilegeSeparation, 243 sDeprecated, sUnsupported 244 } ServerOpCodes; 245 246 /* Textual representation of the tokens. */ 247 static struct { 248 const char *name; 249 ServerOpCodes opcode; 250 } keywords[] = { 251 { "port", sPort }, 252 { "hostkey", sHostKeyFile }, 253 { "hostdsakey", sHostKeyFile }, /* alias */ 254 { "pidfile", sPidFile }, 255 { "serverkeybits", sServerKeyBits }, 256 { "logingracetime", sLoginGraceTime }, 257 { "keyregenerationinterval", sKeyRegenerationTime }, 258 { "permitrootlogin", sPermitRootLogin }, 259 { "syslogfacility", sLogFacility }, 260 { "loglevel", sLogLevel }, 261 { "rhostsauthentication", sRhostsAuthentication }, 262 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 263 { "hostbasedauthentication", sHostbasedAuthentication }, 264 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, 265 { "rsaauthentication", sRSAAuthentication }, 266 { "pubkeyauthentication", sPubkeyAuthentication }, 267 { "dsaauthentication", sPubkeyAuthentication }, /* alias */ 268 #ifdef KRB5 269 { "kerberosauthentication", sKerberosAuthentication }, 270 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, 271 { "kerberosticketcleanup", sKerberosTicketCleanup }, 272 { "kerberostgtpassing", sKerberosTgtPassing }, 273 #else 274 { "kerberosauthentication", sUnsupported }, 275 { "kerberosorlocalpasswd", sUnsupported }, 276 { "kerberosticketcleanup", sUnsupported }, 277 { "kerberostgtpassing", sUnsupported }, 278 #endif 279 { "afstokenpassing", sUnsupported }, 280 { "passwordauthentication", sPasswordAuthentication }, 281 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, 282 { "challengeresponseauthentication", sChallengeResponseAuthentication }, 283 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */ 284 { "checkmail", sDeprecated }, 285 { "listenaddress", sListenAddress }, 286 { "printmotd", sPrintMotd }, 287 { "printlastlog", sPrintLastLog }, 288 { "ignorerhosts", sIgnoreRhosts }, 289 { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, 290 { "x11forwarding", sX11Forwarding }, 291 { "x11displayoffset", sX11DisplayOffset }, 292 { "x11uselocalhost", sX11UseLocalhost }, 293 { "xauthlocation", sXAuthLocation }, 294 { "strictmodes", sStrictModes }, 295 { "permitemptypasswords", sEmptyPasswd }, 296 { "permituserenvironment", sPermitUserEnvironment }, 297 { "uselogin", sUseLogin }, 298 { "compression", sCompression }, 299 { "keepalive", sKeepAlives }, 300 { "allowtcpforwarding", sAllowTcpForwarding }, 301 { "allowusers", sAllowUsers }, 302 { "denyusers", sDenyUsers }, 303 { "allowgroups", sAllowGroups }, 304 { "denygroups", sDenyGroups }, 305 { "ciphers", sCiphers }, 306 { "macs", sMacs }, 307 { "protocol", sProtocol }, 308 { "gatewayports", sGatewayPorts }, 309 { "subsystem", sSubsystem }, 310 { "maxstartups", sMaxStartups }, 311 { "banner", sBanner }, 312 { "usedns", sUseDNS }, 313 { "verifyreversemapping", sDeprecated }, 314 { "reversemappingcheck", sDeprecated }, 315 { "clientaliveinterval", sClientAliveInterval }, 316 { "clientalivecountmax", sClientAliveCountMax }, 317 { "authorizedkeysfile", sAuthorizedKeysFile }, 318 { "authorizedkeysfile2", sAuthorizedKeysFile2 }, 319 { "useprivilegeseparation", sUsePrivilegeSeparation}, 320 { NULL, sBadOption } 321 }; 322 323 /* 324 * Returns the number of the token pointed to by cp or sBadOption. 325 */ 326 327 static ServerOpCodes 328 parse_token(const char *cp, const char *filename, 329 int linenum) 330 { 331 u_int i; 332 333 for (i = 0; keywords[i].name; i++) 334 if (strcasecmp(cp, keywords[i].name) == 0) 335 return keywords[i].opcode; 336 337 error("%s: line %d: Bad configuration option: %s", 338 filename, linenum, cp); 339 return sBadOption; 340 } 341 342 static void 343 add_listen_addr(ServerOptions *options, char *addr, u_short port) 344 { 345 int i; 346 347 if (options->num_ports == 0) 348 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 349 if (port == 0) 350 for (i = 0; i < options->num_ports; i++) 351 add_one_listen_addr(options, addr, options->ports[i]); 352 else 353 add_one_listen_addr(options, addr, port); 354 } 355 356 static void 357 add_one_listen_addr(ServerOptions *options, char *addr, u_short port) 358 { 359 struct addrinfo hints, *ai, *aitop; 360 char strport[NI_MAXSERV]; 361 int gaierr; 362 363 memset(&hints, 0, sizeof(hints)); 364 hints.ai_family = IPv4or6; 365 hints.ai_socktype = SOCK_STREAM; 366 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 367 snprintf(strport, sizeof strport, "%u", port); 368 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 369 fatal("bad addr or host: %s (%s)", 370 addr ? addr : "<NULL>", 371 gai_strerror(gaierr)); 372 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 373 ; 374 ai->ai_next = options->listen_addrs; 375 options->listen_addrs = aitop; 376 } 377 378 int 379 process_server_config_line(ServerOptions *options, char *line, 380 const char *filename, int linenum) 381 { 382 char *cp, **charptr, *arg, *p; 383 int *intptr, value, i, n; 384 ServerOpCodes opcode; 385 386 cp = line; 387 arg = strdelim(&cp); 388 /* Ignore leading whitespace */ 389 if (*arg == '\0') 390 arg = strdelim(&cp); 391 if (!arg || !*arg || *arg == '#') 392 return 0; 393 intptr = NULL; 394 charptr = NULL; 395 opcode = parse_token(arg, filename, linenum); 396 switch (opcode) { 397 case sBadOption: 398 return -1; 399 case sPort: 400 /* ignore ports from configfile if cmdline specifies ports */ 401 if (options->ports_from_cmdline) 402 return 0; 403 if (options->listen_addrs != NULL) 404 fatal("%s line %d: ports must be specified before " 405 "ListenAddress.", filename, linenum); 406 if (options->num_ports >= MAX_PORTS) 407 fatal("%s line %d: too many ports.", 408 filename, linenum); 409 arg = strdelim(&cp); 410 if (!arg || *arg == '\0') 411 fatal("%s line %d: missing port number.", 412 filename, linenum); 413 options->ports[options->num_ports++] = a2port(arg); 414 if (options->ports[options->num_ports-1] == 0) 415 fatal("%s line %d: Badly formatted port number.", 416 filename, linenum); 417 break; 418 419 case sServerKeyBits: 420 intptr = &options->server_key_bits; 421 parse_int: 422 arg = strdelim(&cp); 423 if (!arg || *arg == '\0') 424 fatal("%s line %d: missing integer value.", 425 filename, linenum); 426 value = atoi(arg); 427 if (*intptr == -1) 428 *intptr = value; 429 break; 430 431 case sLoginGraceTime: 432 intptr = &options->login_grace_time; 433 parse_time: 434 arg = strdelim(&cp); 435 if (!arg || *arg == '\0') 436 fatal("%s line %d: missing time value.", 437 filename, linenum); 438 if ((value = convtime(arg)) == -1) 439 fatal("%s line %d: invalid time value.", 440 filename, linenum); 441 if (*intptr == -1) 442 *intptr = value; 443 break; 444 445 case sKeyRegenerationTime: 446 intptr = &options->key_regeneration_time; 447 goto parse_time; 448 449 case sListenAddress: 450 arg = strdelim(&cp); 451 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) 452 fatal("%s line %d: missing inet addr.", 453 filename, linenum); 454 if (*arg == '[') { 455 if ((p = strchr(arg, ']')) == NULL) 456 fatal("%s line %d: bad ipv6 inet addr usage.", 457 filename, linenum); 458 arg++; 459 memmove(p, p+1, strlen(p+1)+1); 460 } else if (((p = strchr(arg, ':')) == NULL) || 461 (strchr(p+1, ':') != NULL)) { 462 add_listen_addr(options, arg, 0); 463 break; 464 } 465 if (*p == ':') { 466 u_short port; 467 468 p++; 469 if (*p == '\0') 470 fatal("%s line %d: bad inet addr:port usage.", 471 filename, linenum); 472 else { 473 *(p-1) = '\0'; 474 if ((port = a2port(p)) == 0) 475 fatal("%s line %d: bad port number.", 476 filename, linenum); 477 add_listen_addr(options, arg, port); 478 } 479 } else if (*p == '\0') 480 add_listen_addr(options, arg, 0); 481 else 482 fatal("%s line %d: bad inet addr usage.", 483 filename, linenum); 484 break; 485 486 case sHostKeyFile: 487 intptr = &options->num_host_key_files; 488 if (*intptr >= MAX_HOSTKEYS) 489 fatal("%s line %d: too many host keys specified (max %d).", 490 filename, linenum, MAX_HOSTKEYS); 491 charptr = &options->host_key_files[*intptr]; 492 parse_filename: 493 arg = strdelim(&cp); 494 if (!arg || *arg == '\0') 495 fatal("%s line %d: missing file name.", 496 filename, linenum); 497 if (*charptr == NULL) { 498 *charptr = tilde_expand_filename(arg, getuid()); 499 /* increase optional counter */ 500 if (intptr != NULL) 501 *intptr = *intptr + 1; 502 } 503 break; 504 505 case sPidFile: 506 charptr = &options->pid_file; 507 goto parse_filename; 508 509 case sPermitRootLogin: 510 intptr = &options->permit_root_login; 511 arg = strdelim(&cp); 512 if (!arg || *arg == '\0') 513 fatal("%s line %d: missing yes/" 514 "without-password/forced-commands-only/no " 515 "argument.", filename, linenum); 516 value = 0; /* silence compiler */ 517 if (strcmp(arg, "without-password") == 0) 518 value = PERMIT_NO_PASSWD; 519 else if (strcmp(arg, "forced-commands-only") == 0) 520 value = PERMIT_FORCED_ONLY; 521 else if (strcmp(arg, "yes") == 0) 522 value = PERMIT_YES; 523 else if (strcmp(arg, "no") == 0) 524 value = PERMIT_NO; 525 else 526 fatal("%s line %d: Bad yes/" 527 "without-password/forced-commands-only/no " 528 "argument: %s", filename, linenum, arg); 529 if (*intptr == -1) 530 *intptr = value; 531 break; 532 533 case sIgnoreRhosts: 534 intptr = &options->ignore_rhosts; 535 parse_flag: 536 arg = strdelim(&cp); 537 if (!arg || *arg == '\0') 538 fatal("%s line %d: missing yes/no argument.", 539 filename, linenum); 540 value = 0; /* silence compiler */ 541 if (strcmp(arg, "yes") == 0) 542 value = 1; 543 else if (strcmp(arg, "no") == 0) 544 value = 0; 545 else 546 fatal("%s line %d: Bad yes/no argument: %s", 547 filename, linenum, arg); 548 if (*intptr == -1) 549 *intptr = value; 550 break; 551 552 case sIgnoreUserKnownHosts: 553 intptr = &options->ignore_user_known_hosts; 554 goto parse_flag; 555 556 case sRhostsAuthentication: 557 intptr = &options->rhosts_authentication; 558 goto parse_flag; 559 560 case sRhostsRSAAuthentication: 561 intptr = &options->rhosts_rsa_authentication; 562 goto parse_flag; 563 564 case sHostbasedAuthentication: 565 intptr = &options->hostbased_authentication; 566 goto parse_flag; 567 568 case sHostbasedUsesNameFromPacketOnly: 569 intptr = &options->hostbased_uses_name_from_packet_only; 570 goto parse_flag; 571 572 case sRSAAuthentication: 573 intptr = &options->rsa_authentication; 574 goto parse_flag; 575 576 case sPubkeyAuthentication: 577 intptr = &options->pubkey_authentication; 578 goto parse_flag; 579 580 case sKerberosAuthentication: 581 intptr = &options->kerberos_authentication; 582 goto parse_flag; 583 584 case sKerberosOrLocalPasswd: 585 intptr = &options->kerberos_or_local_passwd; 586 goto parse_flag; 587 588 case sKerberosTicketCleanup: 589 intptr = &options->kerberos_ticket_cleanup; 590 goto parse_flag; 591 592 case sKerberosTgtPassing: 593 intptr = &options->kerberos_tgt_passing; 594 goto parse_flag; 595 596 case sPasswordAuthentication: 597 intptr = &options->password_authentication; 598 goto parse_flag; 599 600 case sKbdInteractiveAuthentication: 601 intptr = &options->kbd_interactive_authentication; 602 goto parse_flag; 603 604 case sChallengeResponseAuthentication: 605 intptr = &options->challenge_response_authentication; 606 goto parse_flag; 607 608 case sPrintMotd: 609 intptr = &options->print_motd; 610 goto parse_flag; 611 612 case sPrintLastLog: 613 intptr = &options->print_lastlog; 614 goto parse_flag; 615 616 case sX11Forwarding: 617 intptr = &options->x11_forwarding; 618 goto parse_flag; 619 620 case sX11DisplayOffset: 621 intptr = &options->x11_display_offset; 622 goto parse_int; 623 624 case sX11UseLocalhost: 625 intptr = &options->x11_use_localhost; 626 goto parse_flag; 627 628 case sXAuthLocation: 629 charptr = &options->xauth_location; 630 goto parse_filename; 631 632 case sStrictModes: 633 intptr = &options->strict_modes; 634 goto parse_flag; 635 636 case sKeepAlives: 637 intptr = &options->keepalives; 638 goto parse_flag; 639 640 case sEmptyPasswd: 641 intptr = &options->permit_empty_passwd; 642 goto parse_flag; 643 644 case sPermitUserEnvironment: 645 intptr = &options->permit_user_env; 646 goto parse_flag; 647 648 case sUseLogin: 649 intptr = &options->use_login; 650 goto parse_flag; 651 652 case sCompression: 653 intptr = &options->compression; 654 goto parse_flag; 655 656 case sGatewayPorts: 657 intptr = &options->gateway_ports; 658 goto parse_flag; 659 660 case sUseDNS: 661 intptr = &options->use_dns; 662 goto parse_flag; 663 664 case sLogFacility: 665 intptr = (int *) &options->log_facility; 666 arg = strdelim(&cp); 667 value = log_facility_number(arg); 668 if (value == SYSLOG_FACILITY_NOT_SET) 669 fatal("%.200s line %d: unsupported log facility '%s'", 670 filename, linenum, arg ? arg : "<NONE>"); 671 if (*intptr == -1) 672 *intptr = (SyslogFacility) value; 673 break; 674 675 case sLogLevel: 676 intptr = (int *) &options->log_level; 677 arg = strdelim(&cp); 678 value = log_level_number(arg); 679 if (value == SYSLOG_LEVEL_NOT_SET) 680 fatal("%.200s line %d: unsupported log level '%s'", 681 filename, linenum, arg ? arg : "<NONE>"); 682 if (*intptr == -1) 683 *intptr = (LogLevel) value; 684 break; 685 686 case sAllowTcpForwarding: 687 intptr = &options->allow_tcp_forwarding; 688 goto parse_flag; 689 690 case sUsePrivilegeSeparation: 691 intptr = &use_privsep; 692 goto parse_flag; 693 694 case sAllowUsers: 695 while ((arg = strdelim(&cp)) && *arg != '\0') { 696 if (options->num_allow_users >= MAX_ALLOW_USERS) 697 fatal("%s line %d: too many allow users.", 698 filename, linenum); 699 options->allow_users[options->num_allow_users++] = 700 xstrdup(arg); 701 } 702 break; 703 704 case sDenyUsers: 705 while ((arg = strdelim(&cp)) && *arg != '\0') { 706 if (options->num_deny_users >= MAX_DENY_USERS) 707 fatal( "%s line %d: too many deny users.", 708 filename, linenum); 709 options->deny_users[options->num_deny_users++] = 710 xstrdup(arg); 711 } 712 break; 713 714 case sAllowGroups: 715 while ((arg = strdelim(&cp)) && *arg != '\0') { 716 if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 717 fatal("%s line %d: too many allow groups.", 718 filename, linenum); 719 options->allow_groups[options->num_allow_groups++] = 720 xstrdup(arg); 721 } 722 break; 723 724 case sDenyGroups: 725 while ((arg = strdelim(&cp)) && *arg != '\0') { 726 if (options->num_deny_groups >= MAX_DENY_GROUPS) 727 fatal("%s line %d: too many deny groups.", 728 filename, linenum); 729 options->deny_groups[options->num_deny_groups++] = xstrdup(arg); 730 } 731 break; 732 733 case sCiphers: 734 arg = strdelim(&cp); 735 if (!arg || *arg == '\0') 736 fatal("%s line %d: Missing argument.", filename, linenum); 737 if (!ciphers_valid(arg)) 738 fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 739 filename, linenum, arg ? arg : "<NONE>"); 740 if (options->ciphers == NULL) 741 options->ciphers = xstrdup(arg); 742 break; 743 744 case sMacs: 745 arg = strdelim(&cp); 746 if (!arg || *arg == '\0') 747 fatal("%s line %d: Missing argument.", filename, linenum); 748 if (!mac_valid(arg)) 749 fatal("%s line %d: Bad SSH2 mac spec '%s'.", 750 filename, linenum, arg ? arg : "<NONE>"); 751 if (options->macs == NULL) 752 options->macs = xstrdup(arg); 753 break; 754 755 case sProtocol: 756 intptr = &options->protocol; 757 arg = strdelim(&cp); 758 if (!arg || *arg == '\0') 759 fatal("%s line %d: Missing argument.", filename, linenum); 760 value = proto_spec(arg); 761 if (value == SSH_PROTO_UNKNOWN) 762 fatal("%s line %d: Bad protocol spec '%s'.", 763 filename, linenum, arg ? arg : "<NONE>"); 764 if (*intptr == SSH_PROTO_UNKNOWN) 765 *intptr = value; 766 break; 767 768 case sSubsystem: 769 if (options->num_subsystems >= MAX_SUBSYSTEMS) { 770 fatal("%s line %d: too many subsystems defined.", 771 filename, linenum); 772 } 773 arg = strdelim(&cp); 774 if (!arg || *arg == '\0') 775 fatal("%s line %d: Missing subsystem name.", 776 filename, linenum); 777 for (i = 0; i < options->num_subsystems; i++) 778 if (strcmp(arg, options->subsystem_name[i]) == 0) 779 fatal("%s line %d: Subsystem '%s' already defined.", 780 filename, linenum, arg); 781 options->subsystem_name[options->num_subsystems] = xstrdup(arg); 782 arg = strdelim(&cp); 783 if (!arg || *arg == '\0') 784 fatal("%s line %d: Missing subsystem command.", 785 filename, linenum); 786 options->subsystem_command[options->num_subsystems] = xstrdup(arg); 787 options->num_subsystems++; 788 break; 789 790 case sMaxStartups: 791 arg = strdelim(&cp); 792 if (!arg || *arg == '\0') 793 fatal("%s line %d: Missing MaxStartups spec.", 794 filename, linenum); 795 if ((n = sscanf(arg, "%d:%d:%d", 796 &options->max_startups_begin, 797 &options->max_startups_rate, 798 &options->max_startups)) == 3) { 799 if (options->max_startups_begin > 800 options->max_startups || 801 options->max_startups_rate > 100 || 802 options->max_startups_rate < 1) 803 fatal("%s line %d: Illegal MaxStartups spec.", 804 filename, linenum); 805 } else if (n != 1) 806 fatal("%s line %d: Illegal MaxStartups spec.", 807 filename, linenum); 808 else 809 options->max_startups = options->max_startups_begin; 810 break; 811 812 case sBanner: 813 charptr = &options->banner; 814 goto parse_filename; 815 /* 816 * These options can contain %X options expanded at 817 * connect time, so that you can specify paths like: 818 * 819 * AuthorizedKeysFile /etc/ssh_keys/%u 820 */ 821 case sAuthorizedKeysFile: 822 case sAuthorizedKeysFile2: 823 charptr = (opcode == sAuthorizedKeysFile ) ? 824 &options->authorized_keys_file : 825 &options->authorized_keys_file2; 826 goto parse_filename; 827 828 case sClientAliveInterval: 829 intptr = &options->client_alive_interval; 830 goto parse_time; 831 832 case sClientAliveCountMax: 833 intptr = &options->client_alive_count_max; 834 goto parse_int; 835 836 case sDeprecated: 837 logit("%s line %d: Deprecated option %s", 838 filename, linenum, arg); 839 while (arg) 840 arg = strdelim(&cp); 841 break; 842 843 case sUnsupported: 844 logit("%s line %d: Unsupported option %s", 845 filename, linenum, arg); 846 while (arg) 847 arg = strdelim(&cp); 848 break; 849 850 default: 851 fatal("%s line %d: Missing handler for opcode %s (%d)", 852 filename, linenum, arg, opcode); 853 } 854 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 855 fatal("%s line %d: garbage at end of line; \"%.200s\".", 856 filename, linenum, arg); 857 return 0; 858 } 859 860 /* Reads the server configuration file. */ 861 862 void 863 read_server_config(ServerOptions *options, const char *filename) 864 { 865 int linenum, bad_options = 0; 866 char line[1024]; 867 FILE *f; 868 869 debug2("read_server_config: filename %s", filename); 870 f = fopen(filename, "r"); 871 if (!f) { 872 perror(filename); 873 exit(1); 874 } 875 linenum = 0; 876 while (fgets(line, sizeof(line), f)) { 877 /* Update line number counter. */ 878 linenum++; 879 if (process_server_config_line(options, line, filename, linenum) != 0) 880 bad_options++; 881 } 882 fclose(f); 883 if (bad_options > 0) 884 fatal("%s: terminating, %d bad configuration options", 885 filename, bad_options); 886 } 887