servconf.c revision 126277
150479Speter/* 2327Sjkh * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3327Sjkh * All rights reserved 4228990Suqs * 5327Sjkh * As far as I am concerned, the code I have written for this software 6327Sjkh * can be used freely for any purpose. Any derived versions of this 7327Sjkh * software must be clearly marked as such, and if the derived work is 8327Sjkh * incompatible with the protocol description in the RFC file, it must be 9327Sjkh * called by a name other than "ssh" or "Secure Shell". 10327Sjkh */ 11327Sjkh 12327Sjkh#include "includes.h" 13327SjkhRCSID("$OpenBSD: servconf.c,v 1.130 2003/12/23 16:12:10 jakob Exp $"); 14327SjkhRCSID("$FreeBSD: head/crypto/openssh/servconf.c 126277 2004-02-26 10:52:33Z des $"); 15327Sjkh 16327Sjkh#include "ssh.h" 17327Sjkh#include "log.h" 18327Sjkh#include "servconf.h" 19327Sjkh#include "xmalloc.h" 20327Sjkh#include "compat.h" 21327Sjkh#include "pathnames.h" 22327Sjkh#include "tildexpand.h" 23327Sjkh#include "misc.h" 24327Sjkh#include "cipher.h" 25327Sjkh#include "kex.h" 26327Sjkh#include "mac.h" 2762154Sdes 2862154Sdesstatic void add_listen_addr(ServerOptions *, char *, u_short); 2962154Sdesstatic void add_one_listen_addr(ServerOptions *, char *, u_short); 3083663Ssobomax 31206043Sflz/* AF_UNSPEC or AF_INET or AF_INET6 */ 3262154Sdesextern int IPv4or6; 3362154Sdes/* Use of privilege separation or not */ 3462154Sdesextern int use_privsep; 35327Sjkh 36327Sjkh/* Initializes the server options to their default values. */ 37327Sjkh 38327Sjkhvoid 39327Sjkhinitialize_server_options(ServerOptions *options) 40327Sjkh{ 41327Sjkh memset(options, 0, sizeof(*options)); 42327Sjkh 43327Sjkh /* Portable-specific options */ 44327Sjkh options->use_pam = -1; 45327Sjkh 46327Sjkh /* Standard Options */ 47327Sjkh options->num_ports = 0; 48327Sjkh options->ports_from_cmdline = 0; 49327Sjkh options->listen_addrs = NULL; 50327Sjkh options->num_host_key_files = 0; 51327Sjkh options->pid_file = NULL; 521338Sjkh options->server_key_bits = -1; 531338Sjkh options->login_grace_time = -1; 541338Sjkh options->key_regeneration_time = -1; 55206043Sflz options->permit_root_login = PERMIT_NOT_SET; 56206043Sflz options->ignore_rhosts = -1; 57206043Sflz options->ignore_user_known_hosts = -1; 58206043Sflz options->print_motd = -1; 59206043Sflz options->print_lastlog = -1; 60327Sjkh options->x11_forwarding = -1; 61131285Seik options->x11_display_offset = -1; 62327Sjkh options->x11_use_localhost = -1; 63327Sjkh options->xauth_location = NULL; 64131285Seik options->strict_modes = -1; 65327Sjkh options->tcp_keep_alive = -1; 66173514Skrion options->log_facility = SYSLOG_FACILITY_NOT_SET; 67173514Skrion options->log_level = SYSLOG_LEVEL_NOT_SET; 68173514Skrion options->rhosts_rsa_authentication = -1; 69173514Skrion options->hostbased_authentication = -1; 70173514Skrion options->hostbased_uses_name_from_packet_only = -1; 71173514Skrion options->rsa_authentication = -1; 72173514Skrion options->pubkey_authentication = -1; 737937Sjkh options->kerberos_authentication = -1; 7481049Ssobomax options->kerberos_or_local_passwd = -1; 757937Sjkh options->kerberos_ticket_cleanup = -1; 7681049Ssobomax options->kerberos_get_afs_token = -1; 7781049Ssobomax options->gss_authentication=-1; 7881049Ssobomax options->gss_cleanup_creds = -1; 79327Sjkh options->password_authentication = -1; 80327Sjkh options->kbd_interactive_authentication = -1; 8117338Sjkh options->challenge_response_authentication = -1; 8217338Sjkh options->permit_empty_passwd = -1; 8317338Sjkh options->permit_user_env = -1; 8417338Sjkh options->use_login = -1; 8541866Sjkh options->compression = -1; 8617338Sjkh options->allow_tcp_forwarding = -1; 8741866Sjkh options->num_allow_users = 0; 8817338Sjkh options->num_deny_users = 0; 894996Sjkh options->num_allow_groups = 0; 9017338Sjkh options->num_deny_groups = 0; 9117338Sjkh options->ciphers = NULL; 92327Sjkh options->macs = NULL; 9317338Sjkh options->protocol = SSH_PROTO_UNKNOWN; 94327Sjkh options->gateway_ports = -1; 951550Sasami options->num_subsystems = 0; 961550Sasami options->max_startups_begin = -1; 97479Sjkh options->max_startups_rate = -1; 98103149Ssobomax options->max_startups = -1; 99196766Sflz options->banner = NULL; 100196766Sflz options->use_dns = -1; 101103149Ssobomax options->client_alive_interval = -1; 102245828Sbapt options->client_alive_count_max = -1; 103103149Ssobomax options->authorized_keys_file = NULL; 104103149Ssobomax options->authorized_keys_file2 = NULL; 105103149Ssobomax 106103149Ssobomax /* Needs to be accessable in many places */ 10784750Ssobomax use_privsep = -1; 10884750Ssobomax} 10984750Ssobomax 11084750Ssobomaxvoid 111327Sjkhfill_default_server_options(ServerOptions *options) 112327Sjkh{ 11317338Sjkh /* Portable-specific options */ 11417338Sjkh if (options->use_pam == -1) 115157809Skrion options->use_pam = 1; 116147381Skrion 117147381Skrion /* Standard Options */ 118327Sjkh if (options->protocol == SSH_PROTO_UNKNOWN) 119327Sjkh options->protocol = SSH_PROTO_2; 120327Sjkh if (options->num_host_key_files == 0) { 12173134Ssobomax /* fill default hostkeys for protocols */ 122131275Seik if (options->protocol & SSH_PROTO_1) 12373134Ssobomax options->host_key_files[options->num_host_key_files++] = 12473134Ssobomax _PATH_HOST_KEY_FILE; 12573134Ssobomax if (options->protocol & SSH_PROTO_2) { 126327Sjkh options->host_key_files[options->num_host_key_files++] = 127327Sjkh _PATH_HOST_DSA_KEY_FILE; 128327Sjkh } 129327Sjkh } 130327Sjkh if (options->num_ports == 0) 131327Sjkh options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 132327Sjkh if (options->listen_addrs == NULL) 133327Sjkh add_listen_addr(options, NULL, 0); 134327Sjkh if (options->pid_file == NULL) 135327Sjkh options->pid_file = _PATH_SSH_DAEMON_PID_FILE; 136327Sjkh if (options->server_key_bits == -1) 137327Sjkh options->server_key_bits = 768; 138327Sjkh if (options->login_grace_time == -1) 139131280Seik options->login_grace_time = 120; 140131280Seik if (options->key_regeneration_time == -1) 14184750Ssobomax options->key_regeneration_time = 3600; 142327Sjkh if (options->permit_root_login == PERMIT_NOT_SET) 143327Sjkh options->permit_root_login = PERMIT_NO; 144327Sjkh if (options->ignore_rhosts == -1) 14583663Ssobomax options->ignore_rhosts = 1; 14683663Ssobomax if (options->ignore_user_known_hosts == -1) 14783663Ssobomax options->ignore_user_known_hosts = 0; 14883663Ssobomax if (options->print_motd == -1) 14983663Ssobomax options->print_motd = 1; 150157809Skrion if (options->print_lastlog == -1) 151327Sjkh options->print_lastlog = 1; 152327Sjkh if (options->x11_forwarding == -1) 153327Sjkh options->x11_forwarding = 1; 15474699Ssobomax if (options->x11_display_offset == -1) 155327Sjkh options->x11_display_offset = 10; 156194497Sbrian if (options->x11_use_localhost == -1) 157383Sjkh options->x11_use_localhost = 1; 158194497Sbrian if (options->xauth_location == NULL) 15984745Ssobomax options->xauth_location = _PATH_XAUTH; 160241830Seadler if (options->strict_modes == -1) 161327Sjkh options->strict_modes = 1; 162327Sjkh if (options->tcp_keep_alive == -1) 163327Sjkh options->tcp_keep_alive = 1; 16484745Ssobomax if (options->log_facility == SYSLOG_FACILITY_NOT_SET) 165115325Slioux options->log_facility = SYSLOG_FACILITY_AUTH; 16684745Ssobomax if (options->log_level == SYSLOG_LEVEL_NOT_SET) 167327Sjkh options->log_level = SYSLOG_LEVEL_INFO; 168327Sjkh if (options->rhosts_rsa_authentication == -1) 16984745Ssobomax options->rhosts_rsa_authentication = 0; 17074699Ssobomax if (options->hostbased_authentication == -1) 171327Sjkh options->hostbased_authentication = 0; 172327Sjkh if (options->hostbased_uses_name_from_packet_only == -1) 17384745Ssobomax options->hostbased_uses_name_from_packet_only = 0; 17484745Ssobomax if (options->rsa_authentication == -1) 17584745Ssobomax options->rsa_authentication = 1; 17684745Ssobomax if (options->pubkey_authentication == -1) 177167972Snjl options->pubkey_authentication = 1; 17884745Ssobomax if (options->kerberos_authentication == -1) 17984745Ssobomax options->kerberos_authentication = 0; 18084745Ssobomax if (options->kerberos_or_local_passwd == -1) 181194497Sbrian options->kerberos_or_local_passwd = 1; 18284745Ssobomax if (options->kerberos_ticket_cleanup == -1) 18384745Ssobomax options->kerberos_ticket_cleanup = 1; 18484745Ssobomax if (options->kerberos_get_afs_token == -1) 18584745Ssobomax options->kerberos_get_afs_token = 0; 18684745Ssobomax if (options->gss_authentication == -1) 18784745Ssobomax options->gss_authentication = 0; 18884745Ssobomax if (options->gss_cleanup_creds == -1) 18984745Ssobomax options->gss_cleanup_creds = 1; 190108778Sjkh if (options->password_authentication == -1) 191327Sjkh#ifdef USE_PAM 192327Sjkh options->password_authentication = 0; 193327Sjkh#else 194327Sjkh options->password_authentication = 1; 195327Sjkh#endif 196327Sjkh if (options->kbd_interactive_authentication == -1) 197327Sjkh options->kbd_interactive_authentication = 0; 198327Sjkh if (options->challenge_response_authentication == -1) 199327Sjkh options->challenge_response_authentication = 1; 200327Sjkh if (options->permit_empty_passwd == -1) 2011547Sjkh options->permit_empty_passwd = 0; 20284745Ssobomax if (options->permit_user_env == -1) 20384745Ssobomax options->permit_user_env = 0; 204327Sjkh if (options->use_login == -1) 205327Sjkh options->use_login = 0; 206327Sjkh if (options->compression == -1) 20784745Ssobomax options->compression = 1; 20884745Ssobomax if (options->allow_tcp_forwarding == -1) 20984745Ssobomax options->allow_tcp_forwarding = 1; 210327Sjkh if (options->gateway_ports == -1) 211327Sjkh options->gateway_ports = 0; 21284745Ssobomax if (options->max_startups == -1) 2134996Sjkh options->max_startups = 10; 21484745Ssobomax if (options->max_startups_rate == -1) 215327Sjkh options->max_startups_rate = 100; /* 100% */ 216327Sjkh if (options->max_startups_begin == -1) 217327Sjkh options->max_startups_begin = options->max_startups; 218103149Ssobomax if (options->use_dns == -1) 219327Sjkh options->use_dns = 1; 22073134Ssobomax if (options->client_alive_interval == -1) 22173134Ssobomax options->client_alive_interval = 0; 22296613Ssobomax if (options->client_alive_count_max == -1) 223178753Spav options->client_alive_count_max = 3; 22496613Ssobomax if (options->authorized_keys_file2 == NULL) { 225131275Seik /* authorized_keys_file2 falls back to authorized_keys_file */ 22673134Ssobomax if (options->authorized_keys_file != NULL) 22774295Ssobomax options->authorized_keys_file2 = options->authorized_keys_file; 22874295Ssobomax else 22984745Ssobomax options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2; 23083663Ssobomax } 23174295Ssobomax if (options->authorized_keys_file == NULL) 23284750Ssobomax options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; 23384750Ssobomax 23498766Smarkm /* Turn privilege separation on by default */ 23584750Ssobomax if (use_privsep == -1) 236327Sjkh use_privsep = 1; 237136643Sobrien 238327Sjkh#ifndef HAVE_MMAP 23917338Sjkh if (use_privsep && options->compression == 1) { 2401338Sjkh error("This platform does not support both privilege " 241159554Sobrien "separation and compression"); 242327Sjkh error("Compression disabled"); 243327Sjkh options->compression = 0; 244 } 245#endif 246 247} 248 249/* Keyword tokens. */ 250typedef enum { 251 sBadOption, /* == unknown option */ 252 /* Portable-specific options */ 253 sUsePAM, 254 /* Standard Options */ 255 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 256 sPermitRootLogin, sLogFacility, sLogLevel, 257 sRhostsRSAAuthentication, sRSAAuthentication, 258 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 259 sKerberosGetAFSToken, 260 sKerberosTgtPassing, sChallengeResponseAuthentication, 261 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, 262 sPrintMotd, sPrintLastLog, sIgnoreRhosts, 263 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 264 sStrictModes, sEmptyPasswd, sTCPKeepAlive, 265 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 266 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 267 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 268 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, 269 sBanner, sUseDNS, sHostbasedAuthentication, 270 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 271 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 272 sGssAuthentication, sGssCleanupCreds, 273 sUsePrivilegeSeparation, 274 sVersionAddendum, 275 sDeprecated, sUnsupported 276} ServerOpCodes; 277 278/* Textual representation of the tokens. */ 279static struct { 280 const char *name; 281 ServerOpCodes opcode; 282} keywords[] = { 283 /* Portable-specific options */ 284#ifdef USE_PAM 285 { "usepam", sUsePAM }, 286#else 287 { "usepam", sUnsupported }, 288#endif 289 { "pamauthenticationviakbdint", sDeprecated }, 290 /* Standard Options */ 291 { "port", sPort }, 292 { "hostkey", sHostKeyFile }, 293 { "hostdsakey", sHostKeyFile }, /* alias */ 294 { "pidfile", sPidFile }, 295 { "serverkeybits", sServerKeyBits }, 296 { "logingracetime", sLoginGraceTime }, 297 { "keyregenerationinterval", sKeyRegenerationTime }, 298 { "permitrootlogin", sPermitRootLogin }, 299 { "syslogfacility", sLogFacility }, 300 { "loglevel", sLogLevel }, 301 { "rhostsauthentication", sDeprecated }, 302 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 303 { "hostbasedauthentication", sHostbasedAuthentication }, 304 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, 305 { "rsaauthentication", sRSAAuthentication }, 306 { "pubkeyauthentication", sPubkeyAuthentication }, 307 { "dsaauthentication", sPubkeyAuthentication }, /* alias */ 308#ifdef KRB5 309 { "kerberosauthentication", sKerberosAuthentication }, 310 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, 311 { "kerberosticketcleanup", sKerberosTicketCleanup }, 312#ifdef USE_AFS 313 { "kerberosgetafstoken", sKerberosGetAFSToken }, 314#else 315 { "kerberosgetafstoken", sUnsupported }, 316#endif 317#else 318 { "kerberosauthentication", sUnsupported }, 319 { "kerberosorlocalpasswd", sUnsupported }, 320 { "kerberosticketcleanup", sUnsupported }, 321 { "kerberosgetafstoken", sUnsupported }, 322#endif 323 { "kerberostgtpassing", sUnsupported }, 324 { "afstokenpassing", sUnsupported }, 325#ifdef GSSAPI 326 { "gssapiauthentication", sGssAuthentication }, 327 { "gssapicleanupcredentials", sGssCleanupCreds }, 328#else 329 { "gssapiauthentication", sUnsupported }, 330 { "gssapicleanupcredentials", sUnsupported }, 331#endif 332 { "passwordauthentication", sPasswordAuthentication }, 333 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, 334 { "challengeresponseauthentication", sChallengeResponseAuthentication }, 335 { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */ 336 { "checkmail", sDeprecated }, 337 { "listenaddress", sListenAddress }, 338 { "printmotd", sPrintMotd }, 339 { "printlastlog", sPrintLastLog }, 340 { "ignorerhosts", sIgnoreRhosts }, 341 { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, 342 { "x11forwarding", sX11Forwarding }, 343 { "x11displayoffset", sX11DisplayOffset }, 344 { "x11uselocalhost", sX11UseLocalhost }, 345 { "xauthlocation", sXAuthLocation }, 346 { "strictmodes", sStrictModes }, 347 { "permitemptypasswords", sEmptyPasswd }, 348 { "permituserenvironment", sPermitUserEnvironment }, 349 { "uselogin", sUseLogin }, 350 { "compression", sCompression }, 351 { "tcpkeepalive", sTCPKeepAlive }, 352 { "keepalive", sTCPKeepAlive }, /* obsolete alias */ 353 { "allowtcpforwarding", sAllowTcpForwarding }, 354 { "allowusers", sAllowUsers }, 355 { "denyusers", sDenyUsers }, 356 { "allowgroups", sAllowGroups }, 357 { "denygroups", sDenyGroups }, 358 { "ciphers", sCiphers }, 359 { "macs", sMacs }, 360 { "protocol", sProtocol }, 361 { "gatewayports", sGatewayPorts }, 362 { "subsystem", sSubsystem }, 363 { "maxstartups", sMaxStartups }, 364 { "banner", sBanner }, 365 { "usedns", sUseDNS }, 366 { "verifyreversemapping", sDeprecated }, 367 { "reversemappingcheck", sDeprecated }, 368 { "clientaliveinterval", sClientAliveInterval }, 369 { "clientalivecountmax", sClientAliveCountMax }, 370 { "authorizedkeysfile", sAuthorizedKeysFile }, 371 { "authorizedkeysfile2", sAuthorizedKeysFile2 }, 372 { "useprivilegeseparation", sUsePrivilegeSeparation}, 373 { "versionaddendum", sVersionAddendum }, 374 { NULL, sBadOption } 375}; 376 377/* 378 * Returns the number of the token pointed to by cp or sBadOption. 379 */ 380 381static ServerOpCodes 382parse_token(const char *cp, const char *filename, 383 int linenum) 384{ 385 u_int i; 386 387 for (i = 0; keywords[i].name; i++) 388 if (strcasecmp(cp, keywords[i].name) == 0) 389 return keywords[i].opcode; 390 391 error("%s: line %d: Bad configuration option: %s", 392 filename, linenum, cp); 393 return sBadOption; 394} 395 396static void 397add_listen_addr(ServerOptions *options, char *addr, u_short port) 398{ 399 int i; 400 401 if (options->num_ports == 0) 402 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 403 if (port == 0) 404 for (i = 0; i < options->num_ports; i++) 405 add_one_listen_addr(options, addr, options->ports[i]); 406 else 407 add_one_listen_addr(options, addr, port); 408} 409 410static void 411add_one_listen_addr(ServerOptions *options, char *addr, u_short port) 412{ 413 struct addrinfo hints, *ai, *aitop; 414 char strport[NI_MAXSERV]; 415 int gaierr; 416 417 memset(&hints, 0, sizeof(hints)); 418 hints.ai_family = IPv4or6; 419 hints.ai_socktype = SOCK_STREAM; 420 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; 421 snprintf(strport, sizeof strport, "%u", port); 422 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 423 fatal("bad addr or host: %s (%s)", 424 addr ? addr : "<NULL>", 425 gai_strerror(gaierr)); 426 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 427 ; 428 ai->ai_next = options->listen_addrs; 429 options->listen_addrs = aitop; 430} 431 432int 433process_server_config_line(ServerOptions *options, char *line, 434 const char *filename, int linenum) 435{ 436 char *cp, **charptr, *arg, *p; 437 int *intptr, value, i, n; 438 ServerOpCodes opcode; 439 440 cp = line; 441 arg = strdelim(&cp); 442 /* Ignore leading whitespace */ 443 if (*arg == '\0') 444 arg = strdelim(&cp); 445 if (!arg || !*arg || *arg == '#') 446 return 0; 447 intptr = NULL; 448 charptr = NULL; 449 opcode = parse_token(arg, filename, linenum); 450 switch (opcode) { 451 /* Portable-specific options */ 452 case sUsePAM: 453 intptr = &options->use_pam; 454 goto parse_flag; 455 456 /* Standard Options */ 457 case sBadOption: 458 return -1; 459 case sPort: 460 /* ignore ports from configfile if cmdline specifies ports */ 461 if (options->ports_from_cmdline) 462 return 0; 463 if (options->listen_addrs != NULL) 464 fatal("%s line %d: ports must be specified before " 465 "ListenAddress.", filename, linenum); 466 if (options->num_ports >= MAX_PORTS) 467 fatal("%s line %d: too many ports.", 468 filename, linenum); 469 arg = strdelim(&cp); 470 if (!arg || *arg == '\0') 471 fatal("%s line %d: missing port number.", 472 filename, linenum); 473 options->ports[options->num_ports++] = a2port(arg); 474 if (options->ports[options->num_ports-1] == 0) 475 fatal("%s line %d: Badly formatted port number.", 476 filename, linenum); 477 break; 478 479 case sServerKeyBits: 480 intptr = &options->server_key_bits; 481parse_int: 482 arg = strdelim(&cp); 483 if (!arg || *arg == '\0') 484 fatal("%s line %d: missing integer value.", 485 filename, linenum); 486 value = atoi(arg); 487 if (*intptr == -1) 488 *intptr = value; 489 break; 490 491 case sLoginGraceTime: 492 intptr = &options->login_grace_time; 493parse_time: 494 arg = strdelim(&cp); 495 if (!arg || *arg == '\0') 496 fatal("%s line %d: missing time value.", 497 filename, linenum); 498 if ((value = convtime(arg)) == -1) 499 fatal("%s line %d: invalid time value.", 500 filename, linenum); 501 if (*intptr == -1) 502 *intptr = value; 503 break; 504 505 case sKeyRegenerationTime: 506 intptr = &options->key_regeneration_time; 507 goto parse_time; 508 509 case sListenAddress: 510 arg = strdelim(&cp); 511 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) 512 fatal("%s line %d: missing inet addr.", 513 filename, linenum); 514 if (*arg == '[') { 515 if ((p = strchr(arg, ']')) == NULL) 516 fatal("%s line %d: bad ipv6 inet addr usage.", 517 filename, linenum); 518 arg++; 519 memmove(p, p+1, strlen(p+1)+1); 520 } else if (((p = strchr(arg, ':')) == NULL) || 521 (strchr(p+1, ':') != NULL)) { 522 add_listen_addr(options, arg, 0); 523 break; 524 } 525 if (*p == ':') { 526 u_short port; 527 528 p++; 529 if (*p == '\0') 530 fatal("%s line %d: bad inet addr:port usage.", 531 filename, linenum); 532 else { 533 *(p-1) = '\0'; 534 if ((port = a2port(p)) == 0) 535 fatal("%s line %d: bad port number.", 536 filename, linenum); 537 add_listen_addr(options, arg, port); 538 } 539 } else if (*p == '\0') 540 add_listen_addr(options, arg, 0); 541 else 542 fatal("%s line %d: bad inet addr usage.", 543 filename, linenum); 544 break; 545 546 case sHostKeyFile: 547 intptr = &options->num_host_key_files; 548 if (*intptr >= MAX_HOSTKEYS) 549 fatal("%s line %d: too many host keys specified (max %d).", 550 filename, linenum, MAX_HOSTKEYS); 551 charptr = &options->host_key_files[*intptr]; 552parse_filename: 553 arg = strdelim(&cp); 554 if (!arg || *arg == '\0') 555 fatal("%s line %d: missing file name.", 556 filename, linenum); 557 if (*charptr == NULL) { 558 *charptr = tilde_expand_filename(arg, getuid()); 559 /* increase optional counter */ 560 if (intptr != NULL) 561 *intptr = *intptr + 1; 562 } 563 break; 564 565 case sPidFile: 566 charptr = &options->pid_file; 567 goto parse_filename; 568 569 case sPermitRootLogin: 570 intptr = &options->permit_root_login; 571 arg = strdelim(&cp); 572 if (!arg || *arg == '\0') 573 fatal("%s line %d: missing yes/" 574 "without-password/forced-commands-only/no " 575 "argument.", filename, linenum); 576 value = 0; /* silence compiler */ 577 if (strcmp(arg, "without-password") == 0) 578 value = PERMIT_NO_PASSWD; 579 else if (strcmp(arg, "forced-commands-only") == 0) 580 value = PERMIT_FORCED_ONLY; 581 else if (strcmp(arg, "yes") == 0) 582 value = PERMIT_YES; 583 else if (strcmp(arg, "no") == 0) 584 value = PERMIT_NO; 585 else 586 fatal("%s line %d: Bad yes/" 587 "without-password/forced-commands-only/no " 588 "argument: %s", filename, linenum, arg); 589 if (*intptr == -1) 590 *intptr = value; 591 break; 592 593 case sIgnoreRhosts: 594 intptr = &options->ignore_rhosts; 595parse_flag: 596 arg = strdelim(&cp); 597 if (!arg || *arg == '\0') 598 fatal("%s line %d: missing yes/no argument.", 599 filename, linenum); 600 value = 0; /* silence compiler */ 601 if (strcmp(arg, "yes") == 0) 602 value = 1; 603 else if (strcmp(arg, "no") == 0) 604 value = 0; 605 else 606 fatal("%s line %d: Bad yes/no argument: %s", 607 filename, linenum, arg); 608 if (*intptr == -1) 609 *intptr = value; 610 break; 611 612 case sIgnoreUserKnownHosts: 613 intptr = &options->ignore_user_known_hosts; 614 goto parse_flag; 615 616 case sRhostsRSAAuthentication: 617 intptr = &options->rhosts_rsa_authentication; 618 goto parse_flag; 619 620 case sHostbasedAuthentication: 621 intptr = &options->hostbased_authentication; 622 goto parse_flag; 623 624 case sHostbasedUsesNameFromPacketOnly: 625 intptr = &options->hostbased_uses_name_from_packet_only; 626 goto parse_flag; 627 628 case sRSAAuthentication: 629 intptr = &options->rsa_authentication; 630 goto parse_flag; 631 632 case sPubkeyAuthentication: 633 intptr = &options->pubkey_authentication; 634 goto parse_flag; 635 636 case sKerberosAuthentication: 637 intptr = &options->kerberos_authentication; 638 goto parse_flag; 639 640 case sKerberosOrLocalPasswd: 641 intptr = &options->kerberos_or_local_passwd; 642 goto parse_flag; 643 644 case sKerberosTicketCleanup: 645 intptr = &options->kerberos_ticket_cleanup; 646 goto parse_flag; 647 648 case sKerberosGetAFSToken: 649 intptr = &options->kerberos_get_afs_token; 650 goto parse_flag; 651 652 case sGssAuthentication: 653 intptr = &options->gss_authentication; 654 goto parse_flag; 655 656 case sGssCleanupCreds: 657 intptr = &options->gss_cleanup_creds; 658 goto parse_flag; 659 660 case sPasswordAuthentication: 661 intptr = &options->password_authentication; 662 goto parse_flag; 663 664 case sKbdInteractiveAuthentication: 665 intptr = &options->kbd_interactive_authentication; 666 goto parse_flag; 667 668 case sChallengeResponseAuthentication: 669 intptr = &options->challenge_response_authentication; 670 goto parse_flag; 671 672 case sPrintMotd: 673 intptr = &options->print_motd; 674 goto parse_flag; 675 676 case sPrintLastLog: 677 intptr = &options->print_lastlog; 678 goto parse_flag; 679 680 case sX11Forwarding: 681 intptr = &options->x11_forwarding; 682 goto parse_flag; 683 684 case sX11DisplayOffset: 685 intptr = &options->x11_display_offset; 686 goto parse_int; 687 688 case sX11UseLocalhost: 689 intptr = &options->x11_use_localhost; 690 goto parse_flag; 691 692 case sXAuthLocation: 693 charptr = &options->xauth_location; 694 goto parse_filename; 695 696 case sStrictModes: 697 intptr = &options->strict_modes; 698 goto parse_flag; 699 700 case sTCPKeepAlive: 701 intptr = &options->tcp_keep_alive; 702 goto parse_flag; 703 704 case sEmptyPasswd: 705 intptr = &options->permit_empty_passwd; 706 goto parse_flag; 707 708 case sPermitUserEnvironment: 709 intptr = &options->permit_user_env; 710 goto parse_flag; 711 712 case sUseLogin: 713 intptr = &options->use_login; 714 goto parse_flag; 715 716 case sCompression: 717 intptr = &options->compression; 718 goto parse_flag; 719 720 case sGatewayPorts: 721 intptr = &options->gateway_ports; 722 goto parse_flag; 723 724 case sUseDNS: 725 intptr = &options->use_dns; 726 goto parse_flag; 727 728 case sLogFacility: 729 intptr = (int *) &options->log_facility; 730 arg = strdelim(&cp); 731 value = log_facility_number(arg); 732 if (value == SYSLOG_FACILITY_NOT_SET) 733 fatal("%.200s line %d: unsupported log facility '%s'", 734 filename, linenum, arg ? arg : "<NONE>"); 735 if (*intptr == -1) 736 *intptr = (SyslogFacility) value; 737 break; 738 739 case sLogLevel: 740 intptr = (int *) &options->log_level; 741 arg = strdelim(&cp); 742 value = log_level_number(arg); 743 if (value == SYSLOG_LEVEL_NOT_SET) 744 fatal("%.200s line %d: unsupported log level '%s'", 745 filename, linenum, arg ? arg : "<NONE>"); 746 if (*intptr == -1) 747 *intptr = (LogLevel) value; 748 break; 749 750 case sAllowTcpForwarding: 751 intptr = &options->allow_tcp_forwarding; 752 goto parse_flag; 753 754 case sUsePrivilegeSeparation: 755 intptr = &use_privsep; 756 goto parse_flag; 757 758 case sAllowUsers: 759 while ((arg = strdelim(&cp)) && *arg != '\0') { 760 if (options->num_allow_users >= MAX_ALLOW_USERS) 761 fatal("%s line %d: too many allow users.", 762 filename, linenum); 763 options->allow_users[options->num_allow_users++] = 764 xstrdup(arg); 765 } 766 break; 767 768 case sDenyUsers: 769 while ((arg = strdelim(&cp)) && *arg != '\0') { 770 if (options->num_deny_users >= MAX_DENY_USERS) 771 fatal( "%s line %d: too many deny users.", 772 filename, linenum); 773 options->deny_users[options->num_deny_users++] = 774 xstrdup(arg); 775 } 776 break; 777 778 case sAllowGroups: 779 while ((arg = strdelim(&cp)) && *arg != '\0') { 780 if (options->num_allow_groups >= MAX_ALLOW_GROUPS) 781 fatal("%s line %d: too many allow groups.", 782 filename, linenum); 783 options->allow_groups[options->num_allow_groups++] = 784 xstrdup(arg); 785 } 786 break; 787 788 case sDenyGroups: 789 while ((arg = strdelim(&cp)) && *arg != '\0') { 790 if (options->num_deny_groups >= MAX_DENY_GROUPS) 791 fatal("%s line %d: too many deny groups.", 792 filename, linenum); 793 options->deny_groups[options->num_deny_groups++] = xstrdup(arg); 794 } 795 break; 796 797 case sCiphers: 798 arg = strdelim(&cp); 799 if (!arg || *arg == '\0') 800 fatal("%s line %d: Missing argument.", filename, linenum); 801 if (!ciphers_valid(arg)) 802 fatal("%s line %d: Bad SSH2 cipher spec '%s'.", 803 filename, linenum, arg ? arg : "<NONE>"); 804 if (options->ciphers == NULL) 805 options->ciphers = xstrdup(arg); 806 break; 807 808 case sMacs: 809 arg = strdelim(&cp); 810 if (!arg || *arg == '\0') 811 fatal("%s line %d: Missing argument.", filename, linenum); 812 if (!mac_valid(arg)) 813 fatal("%s line %d: Bad SSH2 mac spec '%s'.", 814 filename, linenum, arg ? arg : "<NONE>"); 815 if (options->macs == NULL) 816 options->macs = xstrdup(arg); 817 break; 818 819 case sProtocol: 820 intptr = &options->protocol; 821 arg = strdelim(&cp); 822 if (!arg || *arg == '\0') 823 fatal("%s line %d: Missing argument.", filename, linenum); 824 value = proto_spec(arg); 825 if (value == SSH_PROTO_UNKNOWN) 826 fatal("%s line %d: Bad protocol spec '%s'.", 827 filename, linenum, arg ? arg : "<NONE>"); 828 if (*intptr == SSH_PROTO_UNKNOWN) 829 *intptr = value; 830 break; 831 832 case sSubsystem: 833 if (options->num_subsystems >= MAX_SUBSYSTEMS) { 834 fatal("%s line %d: too many subsystems defined.", 835 filename, linenum); 836 } 837 arg = strdelim(&cp); 838 if (!arg || *arg == '\0') 839 fatal("%s line %d: Missing subsystem name.", 840 filename, linenum); 841 for (i = 0; i < options->num_subsystems; i++) 842 if (strcmp(arg, options->subsystem_name[i]) == 0) 843 fatal("%s line %d: Subsystem '%s' already defined.", 844 filename, linenum, arg); 845 options->subsystem_name[options->num_subsystems] = xstrdup(arg); 846 arg = strdelim(&cp); 847 if (!arg || *arg == '\0') 848 fatal("%s line %d: Missing subsystem command.", 849 filename, linenum); 850 options->subsystem_command[options->num_subsystems] = xstrdup(arg); 851 options->num_subsystems++; 852 break; 853 854 case sMaxStartups: 855 arg = strdelim(&cp); 856 if (!arg || *arg == '\0') 857 fatal("%s line %d: Missing MaxStartups spec.", 858 filename, linenum); 859 if ((n = sscanf(arg, "%d:%d:%d", 860 &options->max_startups_begin, 861 &options->max_startups_rate, 862 &options->max_startups)) == 3) { 863 if (options->max_startups_begin > 864 options->max_startups || 865 options->max_startups_rate > 100 || 866 options->max_startups_rate < 1) 867 fatal("%s line %d: Illegal MaxStartups spec.", 868 filename, linenum); 869 } else if (n != 1) 870 fatal("%s line %d: Illegal MaxStartups spec.", 871 filename, linenum); 872 else 873 options->max_startups = options->max_startups_begin; 874 break; 875 876 case sBanner: 877 charptr = &options->banner; 878 goto parse_filename; 879 /* 880 * These options can contain %X options expanded at 881 * connect time, so that you can specify paths like: 882 * 883 * AuthorizedKeysFile /etc/ssh_keys/%u 884 */ 885 case sAuthorizedKeysFile: 886 case sAuthorizedKeysFile2: 887 charptr = (opcode == sAuthorizedKeysFile ) ? 888 &options->authorized_keys_file : 889 &options->authorized_keys_file2; 890 goto parse_filename; 891 892 case sClientAliveInterval: 893 intptr = &options->client_alive_interval; 894 goto parse_time; 895 896 case sClientAliveCountMax: 897 intptr = &options->client_alive_count_max; 898 goto parse_int; 899 900 case sVersionAddendum: 901 ssh_version_set_addendum(strtok(cp, "\n")); 902 do { 903 arg = strdelim(&cp); 904 } while (arg != NULL && *arg != '\0'); 905 break; 906 907 case sDeprecated: 908 logit("%s line %d: Deprecated option %s", 909 filename, linenum, arg); 910 while (arg) 911 arg = strdelim(&cp); 912 break; 913 914 case sUnsupported: 915 logit("%s line %d: Unsupported option %s", 916 filename, linenum, arg); 917 while (arg) 918 arg = strdelim(&cp); 919 break; 920 921 default: 922 fatal("%s line %d: Missing handler for opcode %s (%d)", 923 filename, linenum, arg, opcode); 924 } 925 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') 926 fatal("%s line %d: garbage at end of line; \"%.200s\".", 927 filename, linenum, arg); 928 return 0; 929} 930 931/* Reads the server configuration file. */ 932 933void 934read_server_config(ServerOptions *options, const char *filename) 935{ 936 int linenum, bad_options = 0; 937 char line[1024]; 938 FILE *f; 939 940 debug2("read_server_config: filename %s", filename); 941 f = fopen(filename, "r"); 942 if (!f) { 943 perror(filename); 944 exit(1); 945 } 946 linenum = 0; 947 while (fgets(line, sizeof(line), f)) { 948 /* Update line number counter. */ 949 linenum++; 950 if (process_server_config_line(options, line, filename, linenum) != 0) 951 bad_options++; 952 } 953 fclose(f); 954 if (bad_options > 0) 955 fatal("%s: terminating, %d bad configuration options", 956 filename, bad_options); 957} 958