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.128 2003/09/29 20:19:57 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_rsa_authentication = -1; 63 options->hostbased_authentication = -1; 64 options->hostbased_uses_name_from_packet_only = -1; 65 options->rsa_authentication = -1; 66 options->pubkey_authentication = -1; 67 options->kerberos_authentication = -1; 68 options->kerberos_or_local_passwd = -1; 69 options->kerberos_ticket_cleanup = -1; 70 options->gss_authentication=-1; 71 options->gss_cleanup_creds = -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_rsa_authentication == -1) 159 options->rhosts_rsa_authentication = 0; 160 if (options->hostbased_authentication == -1) 161 options->hostbased_authentication = 0; 162 if (options->hostbased_uses_name_from_packet_only == -1) 163 options->hostbased_uses_name_from_packet_only = 0; 164 if (options->rsa_authentication == -1) 165 options->rsa_authentication = 1; 166 if (options->pubkey_authentication == -1) 167 options->pubkey_authentication = 1; 168 if (options->kerberos_authentication == -1) 169 options->kerberos_authentication = 0; 170 if (options->kerberos_or_local_passwd == -1) 171 options->kerberos_or_local_passwd = 1; 172 if (options->kerberos_ticket_cleanup == -1) 173 options->kerberos_ticket_cleanup = 1; 174 if (options->gss_authentication == -1) 175 options->gss_authentication = 0; 176 if (options->gss_cleanup_creds == -1) 177 options->gss_cleanup_creds = 1; 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 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 sGssAuthentication, sGssCleanupCreds, 243 sUsePrivilegeSeparation, 244 sDeprecated, sUnsupported 245 } ServerOpCodes; 246 247 /* Textual representation of the tokens. */ 248 static struct { 249 const char *name; 250 ServerOpCodes opcode; 251 } keywords[] = { 252 { "port", sPort }, 253 { "hostkey", sHostKeyFile }, 254 { "hostdsakey", sHostKeyFile }, /* alias */ 255 { "pidfile", sPidFile }, 256 { "serverkeybits", sServerKeyBits }, 257 { "logingracetime", sLoginGraceTime }, 258 { "keyregenerationinterval", sKeyRegenerationTime }, 259 { "permitrootlogin", sPermitRootLogin }, 260 { "syslogfacility", sLogFacility }, 261 { "loglevel", sLogLevel }, 262 { "rhostsauthentication", sDeprecated }, 263 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 264 { "hostbasedauthentication", sHostbasedAuthentication }, 265 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, 266 { "rsaauthentication", sRSAAuthentication }, 267 { "pubkeyauthentication", sPubkeyAuthentication }, 268 { "dsaauthentication", sPubkeyAuthentication }, /* alias */ 269 #ifdef KRB5 270 { "kerberosauthentication", sKerberosAuthentication }, 271 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, 272 { "kerberosticketcleanup", sKerberosTicketCleanup }, 273 #else 274 { "kerberosauthentication", sUnsupported }, 275 { "kerberosorlocalpasswd", sUnsupported }, 276 { "kerberosticketcleanup", sUnsupported }, 277 #endif 278 { "kerberostgtpassing", sUnsupported }, 279 { "afstokenpassing", sUnsupported }, 280 #ifdef GSSAPI 281 { "gssapiauthentication", sGssAuthentication }, 282 { "gssapicleanupcredentials", sGssCleanupCreds }, 283 #else 284 { "gssapiauthentication", sUnsupported }, 285 { "gssapicleanupcredentials", sUnsupported }, 286 #endif 287 { "passwordauthentication", sPasswordAuthentication }, 288 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, 289 { "challengeresponseauthentication", sChallengeResponseAuthentication }, 290 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */ 291 { "checkmail", sDeprecated }, 292 { "listenaddress", sListenAddress }, 293 { "printmotd", sPrintMotd }, 294 { "printlastlog", sPrintLastLog }, 295 { "ignorerhosts", sIgnoreRhosts }, 296 { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, 297 { "x11forwarding", sX11Forwarding }, 298 { "x11displayoffset", sX11DisplayOffset }, 299 { "x11uselocalhost", sX11UseLocalhost }, 300 { "xauthlocation", sXAuthLocation }, 301 { "strictmodes", sStrictModes }, 302 { "permitemptypasswords", sEmptyPasswd }, 303 { "permituserenvironment", sPermitUserEnvironment }, 304 { "uselogin", sUseLogin }, 305 { "compression", sCompression }, 306 { "keepalive", sKeepAlives }, 307 { "allowtcpforwarding", sAllowTcpForwarding }, 308 { "allowusers", sAllowUsers }, 309 { "denyusers", sDenyUsers }, 310 { "allowgroups", sAllowGroups }, 311 { "denygroups", sDenyGroups }, 312 { "ciphers", sCiphers }, 313 { "macs", sMacs }, 314 { "protocol", sProtocol }, 315 { "gatewayports", sGatewayPorts }, 316 { "subsystem", sSubsystem }, 317 { "maxstartups", sMaxStartups }, 318 { "banner", sBanner }, 319 { "usedns", sUseDNS }, 320 { "verifyreversemapping", sDeprecated }, 321 { "reversemappingcheck", sDeprecated }, 322 { "clientaliveinterval", sClientAliveInterval }, 323 { "clientalivecountmax", sClientAliveCountMax }, 324 { "authorizedkeysfile", sAuthorizedKeysFile }, 325 { "authorizedkeysfile2", sAuthorizedKeysFile2 }, 326 { "useprivilegeseparation", sUsePrivilegeSeparation}, 327 { NULL, sBadOption } 328 }; 329 330 /* 331 * Returns the number of the token pointed to by cp or sBadOption. 332 */ 333 334 static ServerOpCodes 335 parse_token(const char *cp, const char *filename, 336 int linenum) 337 { 338 u_int i; 339 340 for (i = 0; keywords[i].name; i++) 341 if (strcasecmp(cp, keywords[i].name) == 0) 342 return keywords[i].opcode; 343 344 error("%s: line %d: Bad configuration option: %s", 345 filename, linenum, cp); 346 return sBadOption; 347 } 348 349 static void 350 add_listen_addr(ServerOptions *options, char *addr, u_short port) 351 { 352 int i; 353 354 if (options->num_ports == 0) 355 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 356 if (port == 0) 357 for (i = 0; i < options->num_ports; i++) 358 add_one_listen_addr(options, addr, options->ports[i]); 359 else 360 add_one_listen_addr(options, addr, port); 361 } 362 363 static void 364 add_one_listen_addr(ServerOptions *options, char *addr, u_short port) 365 { 366 struct addrinfo hints, *ai, *aitop; 367 char strport[NI_MAXSERV]; 368 int gaierr; 369 370 memset(&hints, 0, sizeof(hints)); 371 hints.ai_family = IPv4or6; 372 hints.ai_socktype = SOCK_STREAM; 373 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 374 snprintf(strport, sizeof strport, "%u", port); 375 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 376 fatal("bad addr or host: %s (%s)", 377 addr ? addr : "<NULL>", 378 gai_strerror(gaierr)); 379 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 380 ; 381 ai->ai_next = options->listen_addrs; 382 options->listen_addrs = aitop; 383 } 384 385 int 386 process_server_config_line(ServerOptions *options, char *line, 387 const char *filename, int linenum) 388 { 389 char *cp, **charptr, *arg, *p; 390 int *intptr, value, i, n; 391 ServerOpCodes opcode; 392 393 cp = line; 394 arg = strdelim(&cp); 395 /* Ignore leading whitespace */ 396 if (*arg == '\0') 397 arg = strdelim(&cp); 398 if (!arg || !*arg || *arg == '#') 399 return 0; 400 intptr = NULL; 401 charptr = NULL; 402 opcode = parse_token(arg, filename, linenum); 403 switch (opcode) { 404 case sBadOption: 405 return -1; 406 case sPort: 407 /* ignore ports from configfile if cmdline specifies ports */ 408 if (options->ports_from_cmdline) 409 return 0; 410 if (options->listen_addrs != NULL) 411 fatal("%s line %d: ports must be specified before " 412 "ListenAddress.", filename, linenum); 413 if (options->num_ports >= MAX_PORTS) 414 fatal("%s line %d: too many ports.", 415 filename, linenum); 416 arg = strdelim(&cp); 417 if (!arg || *arg == '\0') 418 fatal("%s line %d: missing port number.", 419 filename, linenum); 420 options->ports[options->num_ports++] = a2port(arg); 421 if (options->ports[options->num_ports-1] == 0) 422 fatal("%s line %d: Badly formatted port number.", 423 filename, linenum); 424 break; 425 426 case sServerKeyBits: 427 intptr = &options->server_key_bits; 428 parse_int: 429 arg = strdelim(&cp); 430 if (!arg || *arg == '\0') 431 fatal("%s line %d: missing integer value.", 432 filename, linenum); 433 value = atoi(arg); 434 if (*intptr == -1) 435 *intptr = value; 436 break; 437 438 case sLoginGraceTime: 439 intptr = &options->login_grace_time; 440 parse_time: 441 arg = strdelim(&cp); 442 if (!arg || *arg == '\0') 443 fatal("%s line %d: missing time value.", 444 filename, linenum); 445 if ((value = convtime(arg)) == -1) 446 fatal("%s line %d: invalid time value.", 447 filename, linenum); 448 if (*intptr == -1) 449 *intptr = value; 450 break; 451 452 case sKeyRegenerationTime: 453 intptr = &options->key_regeneration_time; 454 goto parse_time; 455 456 case sListenAddress: 457 arg = strdelim(&cp); 458 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) 459 fatal("%s line %d: missing inet addr.", 460 filename, linenum); 461 if (*arg == '[') { 462 if ((p = strchr(arg, ']')) == NULL) 463 fatal("%s line %d: bad ipv6 inet addr usage.", 464 filename, linenum); 465 arg++; 466 memmove(p, p+1, strlen(p+1)+1); 467 } else if (((p = strchr(arg, ':')) == NULL) || 468 (strchr(p+1, ':') != NULL)) { 469 add_listen_addr(options, arg, 0); 470 break; 471 } 472 if (*p == ':') { 473 u_short port; 474 475 p++; 476 if (*p == '\0') 477 fatal("%s line %d: bad inet addr:port usage.", 478 filename, linenum); 479 else { 480 *(p-1) = '\0'; 481 if ((port = a2port(p)) == 0) 482 fatal("%s line %d: bad port number.", 483 filename, linenum); 484 add_listen_addr(options, arg, port); 485 } 486 } else if (*p == '\0') 487 add_listen_addr(options, arg, 0); 488 else 489 fatal("%s line %d: bad inet addr usage.", 490 filename, linenum); 491 break; 492 493 case sHostKeyFile: 494 intptr = &options->num_host_key_files; 495 if (*intptr >= MAX_HOSTKEYS) 496 fatal("%s line %d: too many host keys specified (max %d).", 497 filename, linenum, MAX_HOSTKEYS); 498 charptr = &options->host_key_files[*intptr]; 499 parse_filename: 500 arg = strdelim(&cp); 501 if (!arg || *arg == '\0') 502 fatal("%s line %d: missing file name.", 503 filename, linenum); 504 if (*charptr == NULL) { 505 *charptr = tilde_expand_filename(arg, getuid()); 506 /* increase optional counter */ 507 if (intptr != NULL) 508 *intptr = *intptr + 1; 509 } 510 break; 511 512 case sPidFile: 513 charptr = &options->pid_file; 514 goto parse_filename; 515 516 case sPermitRootLogin: 517 intptr = &options->permit_root_login; 518 arg = strdelim(&cp); 519 if (!arg || *arg == '\0') 520 fatal("%s line %d: missing yes/" 521 "without-password/forced-commands-only/no " 522 "argument.", filename, linenum); 523 value = 0; /* silence compiler */ 524 if (strcmp(arg, "without-password") == 0) 525 value = PERMIT_NO_PASSWD; 526 else if (strcmp(arg, "forced-commands-only") == 0) 527 value = PERMIT_FORCED_ONLY; 528 else if (strcmp(arg, "yes") == 0) 529 value = PERMIT_YES; 530 else if (strcmp(arg, "no") == 0) 531 value = PERMIT_NO; 532 else 533 fatal("%s line %d: Bad yes/" 534 "without-password/forced-commands-only/no " 535 "argument: %s", filename, linenum, arg); 536 if (*intptr == -1) 537 *intptr = value; 538 break; 539 540 case sIgnoreRhosts: 541 intptr = &options->ignore_rhosts; 542 parse_flag: 543 arg = strdelim(&cp); 544 if (!arg || *arg == '\0') 545 fatal("%s line %d: missing yes/no argument.", 546 filename, linenum); 547 value = 0; /* silence compiler */ 548 if (strcmp(arg, "yes") == 0) 549 value = 1; 550 else if (strcmp(arg, "no") == 0) 551 value = 0; 552 else 553 fatal("%s line %d: Bad yes/no argument: %s", 554 filename, linenum, arg); 555 if (*intptr == -1) 556 *intptr = value; 557 break; 558 559 case sIgnoreUserKnownHosts: 560 intptr = &options->ignore_user_known_hosts; 561 goto parse_flag; 562 563 case sRhostsRSAAuthentication: 564 intptr = &options->rhosts_rsa_authentication; 565 goto parse_flag; 566 567 case sHostbasedAuthentication: 568 intptr = &options->hostbased_authentication; 569 goto parse_flag; 570 571 case sHostbasedUsesNameFromPacketOnly: 572 intptr = &options->hostbased_uses_name_from_packet_only; 573 goto parse_flag; 574 575 case sRSAAuthentication: 576 intptr = &options->rsa_authentication; 577 goto parse_flag; 578 579 case sPubkeyAuthentication: 580 intptr = &options->pubkey_authentication; 581 goto parse_flag; 582 583 case sKerberosAuthentication: 584 intptr = &options->kerberos_authentication; 585 goto parse_flag; 586 587 case sKerberosOrLocalPasswd: 588 intptr = &options->kerberos_or_local_passwd; 589 goto parse_flag; 590 591 case sKerberosTicketCleanup: 592 intptr = &options->kerberos_ticket_cleanup; 593 goto parse_flag; 594 595 case sGssAuthentication: 596 intptr = &options->gss_authentication; 597 goto parse_flag; 598 599 case sGssCleanupCreds: 600 intptr = &options->gss_cleanup_creds; 601 goto parse_flag; 602 603 case sPasswordAuthentication: 604 intptr = &options->password_authentication; 605 goto parse_flag; 606 607 case sKbdInteractiveAuthentication: 608 intptr = &options->kbd_interactive_authentication; 609 goto parse_flag; 610 611 case sChallengeResponseAuthentication: 612 intptr = &options->challenge_response_authentication; 613 goto parse_flag; 614 615 case sPrintMotd: 616 intptr = &options->print_motd; 617 goto parse_flag; 618 619 case sPrintLastLog: 620 intptr = &options->print_lastlog; 621 goto parse_flag; 622 623 case sX11Forwarding: 624 intptr = &options->x11_forwarding; 625 goto parse_flag; 626 627 case sX11DisplayOffset: 628 intptr = &options->x11_display_offset; 629 goto parse_int; 630 631 case sX11UseLocalhost: 632 intptr = &options->x11_use_localhost; 633 goto parse_flag; 634 635 case sXAuthLocation: 636 charptr = &options->xauth_location; 637 goto parse_filename; 638 639 case sStrictModes: 640 intptr = &options->strict_modes; 641 goto parse_flag; 642 643 case sKeepAlives: 644 intptr = &options->keepalives; 645 goto parse_flag; 646 647 case sEmptyPasswd: 648 intptr = &options->permit_empty_passwd; 649 goto parse_flag; 650 651 case sPermitUserEnvironment: 652 intptr = &options->permit_user_env; 653 goto parse_flag; 654 655 case sUseLogin: 656 intptr = &options->use_login; 657 goto parse_flag; 658 659 case sCompression: 660 intptr = &options->compression; 661 goto parse_flag; 662 663 case sGatewayPorts: 664 intptr = &options->gateway_ports; 665 goto parse_flag; 666 667 case sUseDNS: 668 intptr = &options->use_dns; 669 goto parse_flag; 670 671 case sLogFacility: 672 intptr = (int *) &options->log_facility; 673 arg = strdelim(&cp); 674 value = log_facility_number(arg); 675 if (value == SYSLOG_FACILITY_NOT_SET) 676 fatal("%.200s line %d: unsupported log facility '%s'", 677 filename, linenum, arg ? arg : "<NONE>"); 678 if (*intptr == -1) 679 *intptr = (SyslogFacility) value; 680 break; 681 682 case sLogLevel: 683 intptr = (int *) &options->log_level; 684 arg = strdelim(&cp); 685 value = log_level_number(arg); 686 if (value == SYSLOG_LEVEL_NOT_SET) 687 fatal("%.200s line %d: unsupported log level '%s'", 688 filename, linenum, arg ? arg : "<NONE>"); 689 if (*intptr == -1) 690 *intptr = (LogLevel) value; 691 break; 692 693 case sAllowTcpForwarding: 694 intptr = &options->allow_tcp_forwarding; 695 goto parse_flag; 696 697 case sUsePrivilegeSeparation: 698 intptr = &use_privsep; 699 goto parse_flag; 700 701 case sAllowUsers: 702 while ((arg = strdelim(&cp)) && *arg != '\0') { 703 if (options->num_allow_users >= MAX_ALLOW_USERS) 704 fatal("%s line %d: too many allow users.", 705 filename, linenum); 706 options->allow_users[options->num_allow_users++] = 707 xstrdup(arg); 708 } 709 break; 710 711 case sDenyUsers: 712 while ((arg = strdelim(&cp)) && *arg != '\0') { 713 if (options->num_deny_users >= MAX_DENY_USERS) 714 fatal( "%s line %d: too many deny users.", 715 filename, linenum); 716 options->deny_users[options->num_deny_users++] = 717 xstrdup(arg); 718 } 719 break; 720 721 case sAllowGroups: 722 while ((arg = strdelim(&cp)) && *arg != '\0') { 723 if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 724 fatal("%s line %d: too many allow groups.", 725 filename, linenum); 726 options->allow_groups[options->num_allow_groups++] = 727 xstrdup(arg); 728 } 729 break; 730 731 case sDenyGroups: 732 while ((arg = strdelim(&cp)) && *arg != '\0') { 733 if (options->num_deny_groups >= MAX_DENY_GROUPS) 734 fatal("%s line %d: too many deny groups.", 735 filename, linenum); 736 options->deny_groups[options->num_deny_groups++] = xstrdup(arg); 737 } 738 break; 739 740 case sCiphers: 741 arg = strdelim(&cp); 742 if (!arg || *arg == '\0') 743 fatal("%s line %d: Missing argument.", filename, linenum); 744 if (!ciphers_valid(arg)) 745 fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 746 filename, linenum, arg ? arg : "<NONE>"); 747 if (options->ciphers == NULL) 748 options->ciphers = xstrdup(arg); 749 break; 750 751 case sMacs: 752 arg = strdelim(&cp); 753 if (!arg || *arg == '\0') 754 fatal("%s line %d: Missing argument.", filename, linenum); 755 if (!mac_valid(arg)) 756 fatal("%s line %d: Bad SSH2 mac spec '%s'.", 757 filename, linenum, arg ? arg : "<NONE>"); 758 if (options->macs == NULL) 759 options->macs = xstrdup(arg); 760 break; 761 762 case sProtocol: 763 intptr = &options->protocol; 764 arg = strdelim(&cp); 765 if (!arg || *arg == '\0') 766 fatal("%s line %d: Missing argument.", filename, linenum); 767 value = proto_spec(arg); 768 if (value == SSH_PROTO_UNKNOWN) 769 fatal("%s line %d: Bad protocol spec '%s'.", 770 filename, linenum, arg ? arg : "<NONE>"); 771 if (*intptr == SSH_PROTO_UNKNOWN) 772 *intptr = value; 773 break; 774 775 case sSubsystem: 776 if (options->num_subsystems >= MAX_SUBSYSTEMS) { 777 fatal("%s line %d: too many subsystems defined.", 778 filename, linenum); 779 } 780 arg = strdelim(&cp); 781 if (!arg || *arg == '\0') 782 fatal("%s line %d: Missing subsystem name.", 783 filename, linenum); 784 for (i = 0; i < options->num_subsystems; i++) 785 if (strcmp(arg, options->subsystem_name[i]) == 0) 786 fatal("%s line %d: Subsystem '%s' already defined.", 787 filename, linenum, arg); 788 options->subsystem_name[options->num_subsystems] = xstrdup(arg); 789 arg = strdelim(&cp); 790 if (!arg || *arg == '\0') 791 fatal("%s line %d: Missing subsystem command.", 792 filename, linenum); 793 options->subsystem_command[options->num_subsystems] = xstrdup(arg); 794 options->num_subsystems++; 795 break; 796 797 case sMaxStartups: 798 arg = strdelim(&cp); 799 if (!arg || *arg == '\0') 800 fatal("%s line %d: Missing MaxStartups spec.", 801 filename, linenum); 802 if ((n = sscanf(arg, "%d:%d:%d", 803 &options->max_startups_begin, 804 &options->max_startups_rate, 805 &options->max_startups)) == 3) { 806 if (options->max_startups_begin > 807 options->max_startups || 808 options->max_startups_rate > 100 || 809 options->max_startups_rate < 1) 810 fatal("%s line %d: Illegal MaxStartups spec.", 811 filename, linenum); 812 } else if (n != 1) 813 fatal("%s line %d: Illegal MaxStartups spec.", 814 filename, linenum); 815 else 816 options->max_startups = options->max_startups_begin; 817 break; 818 819 case sBanner: 820 charptr = &options->banner; 821 goto parse_filename; 822 /* 823 * These options can contain %X options expanded at 824 * connect time, so that you can specify paths like: 825 * 826 * AuthorizedKeysFile /etc/ssh_keys/%u 827 */ 828 case sAuthorizedKeysFile: 829 case sAuthorizedKeysFile2: 830 charptr = (opcode == sAuthorizedKeysFile ) ? 831 &options->authorized_keys_file : 832 &options->authorized_keys_file2; 833 goto parse_filename; 834 835 case sClientAliveInterval: 836 intptr = &options->client_alive_interval; 837 goto parse_time; 838 839 case sClientAliveCountMax: 840 intptr = &options->client_alive_count_max; 841 goto parse_int; 842 843 case sDeprecated: 844 logit("%s line %d: Deprecated option %s", 845 filename, linenum, arg); 846 while (arg) 847 arg = strdelim(&cp); 848 break; 849 850 case sUnsupported: 851 logit("%s line %d: Unsupported option %s", 852 filename, linenum, arg); 853 while (arg) 854 arg = strdelim(&cp); 855 break; 856 857 default: 858 fatal("%s line %d: Missing handler for opcode %s (%d)", 859 filename, linenum, arg, opcode); 860 } 861 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 862 fatal("%s line %d: garbage at end of line; \"%.200s\".", 863 filename, linenum, arg); 864 return 0; 865 } 866 867 /* Reads the server configuration file. */ 868 869 void 870 read_server_config(ServerOptions *options, const char *filename) 871 { 872 int linenum, bad_options = 0; 873 char line[1024]; 874 FILE *f; 875 876 debug2("read_server_config: filename %s", filename); 877 f = fopen(filename, "r"); 878 if (!f) { 879 perror(filename); 880 exit(1); 881 } 882 linenum = 0; 883 while (fgets(line, sizeof(line), f)) { 884 /* Update line number counter. */ 885 linenum++; 886 if (process_server_config_line(options, line, filename, linenum) != 0) 887 bad_options++; 888 } 889 fclose(f); 890 if (bad_options > 0) 891 fatal("%s: terminating, %d bad configuration options", 892 filename, bad_options); 893 } 894