2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
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".
13 RCSID("$OpenBSD: servconf.c,v 1.137 2004/08/13 11:09:24 dtucker Exp $");
20 #include "pathnames.h"
26 static void add_listen_addr(ServerOptions *, char *, u_short);
27 static void add_one_listen_addr(ServerOptions *, char *, u_short);
29 /* AF_UNSPEC or AF_INET or AF_INET6 */
31 /* Use of privilege separation or not */
32 extern int use_privsep;
34 /* Initializes the server options to their default values. */
37 initialize_server_options(ServerOptions *options)
39 memset(options, 0, sizeof(*options));
41 /* Portable-specific options */
42 options->use_pam = -1;
44 /* Standard Options */
45 options->num_ports = 0;
46 options->ports_from_cmdline = 0;
47 options->listen_addrs = NULL;
48 options->num_host_key_files = 0;
49 options->pid_file = NULL;
50 options->server_key_bits = -1;
51 options->login_grace_time = -1;
52 options->key_regeneration_time = -1;
53 options->permit_root_login = PERMIT_NOT_SET;
54 options->ignore_rhosts = -1;
55 options->ignore_user_known_hosts = -1;
56 options->print_motd = -1;
57 options->print_lastlog = -1;
58 options->x11_forwarding = -1;
59 options->x11_display_offset = -1;
60 options->x11_use_localhost = -1;
61 options->xauth_location = NULL;
62 options->strict_modes = -1;
63 options->tcp_keep_alive = -1;
64 options->log_facility = SYSLOG_FACILITY_NOT_SET;
65 options->log_level = SYSLOG_LEVEL_NOT_SET;
66 options->rhosts_rsa_authentication = -1;
67 options->hostbased_authentication = -1;
68 options->hostbased_uses_name_from_packet_only = -1;
69 options->rsa_authentication = -1;
70 options->pubkey_authentication = -1;
71 options->kerberos_authentication = -1;
72 options->kerberos_or_local_passwd = -1;
73 options->kerberos_ticket_cleanup = -1;
74 options->kerberos_get_afs_token = -1;
75 options->gss_authentication=-1;
76 options->gss_cleanup_creds = -1;
77 options->password_authentication = -1;
78 options->kbd_interactive_authentication = -1;
79 options->challenge_response_authentication = -1;
80 options->permit_empty_passwd = -1;
81 options->permit_user_env = -1;
82 options->use_login = -1;
83 options->compression = -1;
84 options->allow_tcp_forwarding = -1;
85 options->num_allow_users = 0;
86 options->num_deny_users = 0;
87 options->num_allow_groups = 0;
88 options->num_deny_groups = 0;
89 options->ciphers = NULL;
91 options->protocol = SSH_PROTO_UNKNOWN;
92 options->gateway_ports = -1;
93 options->num_subsystems = 0;
94 options->max_startups_begin = -1;
95 options->max_startups_rate = -1;
96 options->max_startups = -1;
97 options->max_authtries = -1;
98 options->banner = NULL;
99 options->use_dns = -1;
100 options->client_alive_interval = -1;
101 options->client_alive_count_max = -1;
102 options->authorized_keys_file = NULL;
103 options->authorized_keys_file2 = NULL;
104 options->num_accept_env = 0;
106 /* Needs to be accessable in many places */
111 fill_default_server_options(ServerOptions *options)
113 /* Portable-specific options */
114 if (options->use_pam == -1)
115 options->use_pam = 0;
117 /* Standard Options */
118 if (options->protocol == SSH_PROTO_UNKNOWN)
119 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
120 if (options->num_host_key_files == 0) {
121 /* fill default hostkeys for protocols */
122 if (options->protocol & SSH_PROTO_1)
123 options->host_key_files[options->num_host_key_files++] =
125 if (options->protocol & SSH_PROTO_2) {
126 options->host_key_files[options->num_host_key_files++] =
127 _PATH_HOST_RSA_KEY_FILE;
128 options->host_key_files[options->num_host_key_files++] =
129 _PATH_HOST_DSA_KEY_FILE;
132 if (options->num_ports == 0)
133 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
134 if (options->listen_addrs == NULL)
135 add_listen_addr(options, NULL, 0);
136 if (options->pid_file == NULL)
137 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
138 if (options->server_key_bits == -1)
139 options->server_key_bits = 768;
140 if (options->login_grace_time == -1)
141 options->login_grace_time = 120;
142 if (options->key_regeneration_time == -1)
143 options->key_regeneration_time = 3600;
144 if (options->permit_root_login == PERMIT_NOT_SET)
145 options->permit_root_login = PERMIT_YES;
146 if (options->ignore_rhosts == -1)
147 options->ignore_rhosts = 1;
148 if (options->ignore_user_known_hosts == -1)
149 options->ignore_user_known_hosts = 0;
150 if (options->print_motd == -1)
151 options->print_motd = 1;
152 if (options->print_lastlog == -1)
153 options->print_lastlog = 1;
154 if (options->x11_forwarding == -1)
155 options->x11_forwarding = 0;
156 if (options->x11_display_offset == -1)
157 options->x11_display_offset = 10;
158 if (options->x11_use_localhost == -1)
159 options->x11_use_localhost = 1;
160 if (options->xauth_location == NULL)
161 options->xauth_location = _PATH_XAUTH;
162 if (options->strict_modes == -1)
163 options->strict_modes = 1;
164 if (options->tcp_keep_alive == -1)
165 options->tcp_keep_alive = 1;
166 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
167 options->log_facility = SYSLOG_FACILITY_AUTH;
168 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
169 options->log_level = SYSLOG_LEVEL_INFO;
170 if (options->rhosts_rsa_authentication == -1)
171 options->rhosts_rsa_authentication = 0;
172 if (options->hostbased_authentication == -1)
173 options->hostbased_authentication = 0;
174 if (options->hostbased_uses_name_from_packet_only == -1)
175 options->hostbased_uses_name_from_packet_only = 0;
176 if (options->rsa_authentication == -1)
177 options->rsa_authentication = 1;
178 if (options->pubkey_authentication == -1)
179 options->pubkey_authentication = 1;
180 if (options->kerberos_authentication == -1)
181 options->kerberos_authentication = 0;
182 if (options->kerberos_or_local_passwd == -1)
183 options->kerberos_or_local_passwd = 1;
184 if (options->kerberos_ticket_cleanup == -1)
185 options->kerberos_ticket_cleanup = 1;
186 if (options->kerberos_get_afs_token == -1)
187 options->kerberos_get_afs_token = 0;
188 if (options->gss_authentication == -1)
189 options->gss_authentication = 0;
190 if (options->gss_cleanup_creds == -1)
191 options->gss_cleanup_creds = 1;
192 if (options->password_authentication == -1)
193 options->password_authentication = 1;
194 if (options->kbd_interactive_authentication == -1)
195 options->kbd_interactive_authentication = 0;
196 if (options->challenge_response_authentication == -1)
197 options->challenge_response_authentication = 1;
198 if (options->permit_empty_passwd == -1)
199 options->permit_empty_passwd = 0;
200 if (options->permit_user_env == -1)
201 options->permit_user_env = 0;
202 if (options->use_login == -1)
203 options->use_login = 0;
204 if (options->compression == -1)
205 options->compression = 1;
206 if (options->allow_tcp_forwarding == -1)
207 options->allow_tcp_forwarding = 1;
208 if (options->gateway_ports == -1)
209 options->gateway_ports = 0;
210 if (options->max_startups == -1)
211 options->max_startups = 10;
212 if (options->max_startups_rate == -1)
213 options->max_startups_rate = 100; /* 100% */
214 if (options->max_startups_begin == -1)
215 options->max_startups_begin = options->max_startups;
216 if (options->max_authtries == -1)
217 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
218 if (options->use_dns == -1)
219 options->use_dns = 1;
220 if (options->client_alive_interval == -1)
221 options->client_alive_interval = 0;
222 if (options->client_alive_count_max == -1)
223 options->client_alive_count_max = 3;
224 if (options->authorized_keys_file2 == NULL) {
225 /* authorized_keys_file2 falls back to authorized_keys_file */
226 if (options->authorized_keys_file != NULL)
227 options->authorized_keys_file2 = options->authorized_keys_file;
229 options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
231 if (options->authorized_keys_file == NULL)
232 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
234 /* Turn privilege separation on by default */
235 if (use_privsep == -1)
239 if (use_privsep && options->compression == 1) {
240 error("This platform does not support both privilege "
241 "separation and compression");
242 error("Compression disabled");
243 options->compression = 0;
249 /* Keyword tokens. */
251 sBadOption, /* == unknown option */
252 /* Portable-specific options */
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,
269 sMaxStartups, sMaxAuthTries,
270 sBanner, sUseDNS, sHostbasedAuthentication,
271 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
272 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
273 sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
274 sUsePrivilegeSeparation,
275 sDeprecated, sUnsupported
278 /* Textual representation of the tokens. */
281 ServerOpCodes opcode;
283 /* Portable-specific options */
285 { "usepam", sUsePAM },
287 { "usepam", sUnsupported },
289 { "pamauthenticationviakbdint", sDeprecated },
290 /* Standard Options */
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 */
309 { "kerberosauthentication", sKerberosAuthentication },
310 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
311 { "kerberosticketcleanup", sKerberosTicketCleanup },
313 { "kerberosgetafstoken", sKerberosGetAFSToken },
315 { "kerberosgetafstoken", sUnsupported },
318 { "kerberosauthentication", sUnsupported },
319 { "kerberosorlocalpasswd", sUnsupported },
320 { "kerberosticketcleanup", sUnsupported },
321 { "kerberosgetafstoken", sUnsupported },
323 { "kerberostgtpassing", sUnsupported },
324 { "afstokenpassing", sUnsupported },
326 { "gssapiauthentication", sGssAuthentication },
327 { "gssapicleanupcredentials", sGssCleanupCreds },
329 { "gssapiauthentication", sUnsupported },
330 { "gssapicleanupcredentials", sUnsupported },
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 },
360 { "protocol", sProtocol },
361 { "gatewayports", sGatewayPorts },
362 { "subsystem", sSubsystem },
363 { "maxstartups", sMaxStartups },
364 { "maxauthtries", sMaxAuthTries },
365 { "banner", sBanner },
366 { "usedns", sUseDNS },
367 { "verifyreversemapping", sDeprecated },
368 { "reversemappingcheck", sDeprecated },
369 { "clientaliveinterval", sClientAliveInterval },
370 { "clientalivecountmax", sClientAliveCountMax },
371 { "authorizedkeysfile", sAuthorizedKeysFile },
372 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
373 { "useprivilegeseparation", sUsePrivilegeSeparation},
374 { "acceptenv", sAcceptEnv },
379 * Returns the number of the token pointed to by cp or sBadOption.
383 parse_token(const char *cp, const char *filename,
388 for (i = 0; keywords[i].name; i++)
389 if (strcasecmp(cp, keywords[i].name) == 0)
390 return keywords[i].opcode;
392 error("%s: line %d: Bad configuration option: %s",
393 filename, linenum, cp);
398 add_listen_addr(ServerOptions *options, char *addr, u_short port)
402 if (options->num_ports == 0)
403 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
405 for (i = 0; i < options->num_ports; i++)
406 add_one_listen_addr(options, addr, options->ports[i]);
408 add_one_listen_addr(options, addr, port);
412 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
414 struct addrinfo hints, *ai, *aitop;
415 char strport[NI_MAXSERV];
418 memset(&hints, 0, sizeof(hints));
419 hints.ai_family = IPv4or6;
420 hints.ai_socktype = SOCK_STREAM;
421 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
422 snprintf(strport, sizeof strport, "%u", port);
423 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
424 fatal("bad addr or host: %s (%s)",
425 addr ? addr : "<NULL>",
426 gai_strerror(gaierr));
427 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
429 ai->ai_next = options->listen_addrs;
430 options->listen_addrs = aitop;
434 process_server_config_line(ServerOptions *options, char *line,
435 const char *filename, int linenum)
437 char *cp, **charptr, *arg, *p;
438 int *intptr, value, i, n;
439 ServerOpCodes opcode;
443 /* Ignore leading whitespace */
446 if (!arg || !*arg || *arg == '#')
450 opcode = parse_token(arg, filename, linenum);
452 /* Portable-specific options */
454 intptr = &options->use_pam;
457 /* Standard Options */
461 /* ignore ports from configfile if cmdline specifies ports */
462 if (options->ports_from_cmdline)
464 if (options->listen_addrs != NULL)
465 fatal("%s line %d: ports must be specified before "
466 "ListenAddress.", filename, linenum);
467 if (options->num_ports >= MAX_PORTS)
468 fatal("%s line %d: too many ports.",
471 if (!arg || *arg == '\0')
472 fatal("%s line %d: missing port number.",
474 options->ports[options->num_ports++] = a2port(arg);
475 if (options->ports[options->num_ports-1] == 0)
476 fatal("%s line %d: Badly formatted port number.",
481 intptr = &options->server_key_bits;
484 if (!arg || *arg == '\0')
485 fatal("%s line %d: missing integer value.",
492 case sLoginGraceTime:
493 intptr = &options->login_grace_time;
496 if (!arg || *arg == '\0')
497 fatal("%s line %d: missing time value.",
499 if ((value = convtime(arg)) == -1)
500 fatal("%s line %d: invalid time value.",
506 case sKeyRegenerationTime:
507 intptr = &options->key_regeneration_time;
512 if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
513 fatal("%s line %d: missing inet addr.",
516 if ((p = strchr(arg, ']')) == NULL)
517 fatal("%s line %d: bad ipv6 inet addr usage.",
520 memmove(p, p+1, strlen(p+1)+1);
521 } else if (((p = strchr(arg, ':')) == NULL) ||
522 (strchr(p+1, ':') != NULL)) {
523 add_listen_addr(options, arg, 0);
531 fatal("%s line %d: bad inet addr:port usage.",
535 if ((port = a2port(p)) == 0)
536 fatal("%s line %d: bad port number.",
538 add_listen_addr(options, arg, port);
540 } else if (*p == '\0')
541 add_listen_addr(options, arg, 0);
543 fatal("%s line %d: bad inet addr usage.",
548 intptr = &options->num_host_key_files;
549 if (*intptr >= MAX_HOSTKEYS)
550 fatal("%s line %d: too many host keys specified (max %d).",
551 filename, linenum, MAX_HOSTKEYS);
552 charptr = &options->host_key_files[*intptr];
555 if (!arg || *arg == '\0')
556 fatal("%s line %d: missing file name.",
558 if (*charptr == NULL) {
559 *charptr = tilde_expand_filename(arg, getuid());
560 /* increase optional counter */
562 *intptr = *intptr + 1;
567 charptr = &options->pid_file;
570 case sPermitRootLogin:
571 intptr = &options->permit_root_login;
573 if (!arg || *arg == '\0')
574 fatal("%s line %d: missing yes/"
575 "without-password/forced-commands-only/no "
576 "argument.", filename, linenum);
577 value = 0; /* silence compiler */
578 if (strcmp(arg, "without-password") == 0)
579 value = PERMIT_NO_PASSWD;
580 else if (strcmp(arg, "forced-commands-only") == 0)
581 value = PERMIT_FORCED_ONLY;
582 else if (strcmp(arg, "yes") == 0)
584 else if (strcmp(arg, "no") == 0)
587 fatal("%s line %d: Bad yes/"
588 "without-password/forced-commands-only/no "
589 "argument: %s", filename, linenum, arg);
595 intptr = &options->ignore_rhosts;
598 if (!arg || *arg == '\0')
599 fatal("%s line %d: missing yes/no argument.",
601 value = 0; /* silence compiler */
602 if (strcmp(arg, "yes") == 0)
604 else if (strcmp(arg, "no") == 0)
607 fatal("%s line %d: Bad yes/no argument: %s",
608 filename, linenum, arg);
613 case sIgnoreUserKnownHosts:
614 intptr = &options->ignore_user_known_hosts;
617 case sRhostsRSAAuthentication:
618 intptr = &options->rhosts_rsa_authentication;
621 case sHostbasedAuthentication:
622 intptr = &options->hostbased_authentication;
625 case sHostbasedUsesNameFromPacketOnly:
626 intptr = &options->hostbased_uses_name_from_packet_only;
629 case sRSAAuthentication:
630 intptr = &options->rsa_authentication;
633 case sPubkeyAuthentication:
634 intptr = &options->pubkey_authentication;
637 case sKerberosAuthentication:
638 intptr = &options->kerberos_authentication;
641 case sKerberosOrLocalPasswd:
642 intptr = &options->kerberos_or_local_passwd;
645 case sKerberosTicketCleanup:
646 intptr = &options->kerberos_ticket_cleanup;
649 case sKerberosGetAFSToken:
650 intptr = &options->kerberos_get_afs_token;
653 case sGssAuthentication:
654 intptr = &options->gss_authentication;
657 case sGssCleanupCreds:
658 intptr = &options->gss_cleanup_creds;
661 case sPasswordAuthentication:
662 intptr = &options->password_authentication;
665 case sKbdInteractiveAuthentication:
666 intptr = &options->kbd_interactive_authentication;
669 case sChallengeResponseAuthentication:
670 intptr = &options->challenge_response_authentication;
674 intptr = &options->print_motd;
678 intptr = &options->print_lastlog;
682 intptr = &options->x11_forwarding;
685 case sX11DisplayOffset:
686 intptr = &options->x11_display_offset;
689 case sX11UseLocalhost:
690 intptr = &options->x11_use_localhost;
694 charptr = &options->xauth_location;
698 intptr = &options->strict_modes;
702 intptr = &options->tcp_keep_alive;
706 intptr = &options->permit_empty_passwd;
709 case sPermitUserEnvironment:
710 intptr = &options->permit_user_env;
714 intptr = &options->use_login;
718 intptr = &options->compression;
722 intptr = &options->gateway_ports;
726 intptr = &options->use_dns;
730 intptr = (int *) &options->log_facility;
732 value = log_facility_number(arg);
733 if (value == SYSLOG_FACILITY_NOT_SET)
734 fatal("%.200s line %d: unsupported log facility '%s'",
735 filename, linenum, arg ? arg : "<NONE>");
737 *intptr = (SyslogFacility) value;
741 intptr = (int *) &options->log_level;
743 value = log_level_number(arg);
744 if (value == SYSLOG_LEVEL_NOT_SET)
745 fatal("%.200s line %d: unsupported log level '%s'",
746 filename, linenum, arg ? arg : "<NONE>");
748 *intptr = (LogLevel) value;
751 case sAllowTcpForwarding:
752 intptr = &options->allow_tcp_forwarding;
755 case sUsePrivilegeSeparation:
756 intptr = &use_privsep;
760 while ((arg = strdelim(&cp)) && *arg != '\0') {
761 if (options->num_allow_users >= MAX_ALLOW_USERS)
762 fatal("%s line %d: too many allow users.",
764 options->allow_users[options->num_allow_users++] =
770 while ((arg = strdelim(&cp)) && *arg != '\0') {
771 if (options->num_deny_users >= MAX_DENY_USERS)
772 fatal( "%s line %d: too many deny users.",
774 options->deny_users[options->num_deny_users++] =
780 while ((arg = strdelim(&cp)) && *arg != '\0') {
781 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
782 fatal("%s line %d: too many allow groups.",
784 options->allow_groups[options->num_allow_groups++] =
790 while ((arg = strdelim(&cp)) && *arg != '\0') {
791 if (options->num_deny_groups >= MAX_DENY_GROUPS)
792 fatal("%s line %d: too many deny groups.",
794 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
800 if (!arg || *arg == '\0')
801 fatal("%s line %d: Missing argument.", filename, linenum);
802 if (!ciphers_valid(arg))
803 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
804 filename, linenum, arg ? arg : "<NONE>");
805 if (options->ciphers == NULL)
806 options->ciphers = xstrdup(arg);
811 if (!arg || *arg == '\0')
812 fatal("%s line %d: Missing argument.", filename, linenum);
814 fatal("%s line %d: Bad SSH2 mac spec '%s'.",
815 filename, linenum, arg ? arg : "<NONE>");
816 if (options->macs == NULL)
817 options->macs = xstrdup(arg);
821 intptr = &options->protocol;
823 if (!arg || *arg == '\0')
824 fatal("%s line %d: Missing argument.", filename, linenum);
825 value = proto_spec(arg);
826 if (value == SSH_PROTO_UNKNOWN)
827 fatal("%s line %d: Bad protocol spec '%s'.",
828 filename, linenum, arg ? arg : "<NONE>");
829 if (*intptr == SSH_PROTO_UNKNOWN)
834 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
835 fatal("%s line %d: too many subsystems defined.",
839 if (!arg || *arg == '\0')
840 fatal("%s line %d: Missing subsystem name.",
842 for (i = 0; i < options->num_subsystems; i++)
843 if (strcmp(arg, options->subsystem_name[i]) == 0)
844 fatal("%s line %d: Subsystem '%s' already defined.",
845 filename, linenum, arg);
846 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
848 if (!arg || *arg == '\0')
849 fatal("%s line %d: Missing subsystem command.",
851 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
852 options->num_subsystems++;
857 if (!arg || *arg == '\0')
858 fatal("%s line %d: Missing MaxStartups spec.",
860 if ((n = sscanf(arg, "%d:%d:%d",
861 &options->max_startups_begin,
862 &options->max_startups_rate,
863 &options->max_startups)) == 3) {
864 if (options->max_startups_begin >
865 options->max_startups ||
866 options->max_startups_rate > 100 ||
867 options->max_startups_rate < 1)
868 fatal("%s line %d: Illegal MaxStartups spec.",
871 fatal("%s line %d: Illegal MaxStartups spec.",
874 options->max_startups = options->max_startups_begin;
878 intptr = &options->max_authtries;
882 charptr = &options->banner;
885 * These options can contain %X options expanded at
886 * connect time, so that you can specify paths like:
888 * AuthorizedKeysFile /etc/ssh_keys/%u
890 case sAuthorizedKeysFile:
891 case sAuthorizedKeysFile2:
892 charptr = (opcode == sAuthorizedKeysFile ) ?
893 &options->authorized_keys_file :
894 &options->authorized_keys_file2;
897 case sClientAliveInterval:
898 intptr = &options->client_alive_interval;
901 case sClientAliveCountMax:
902 intptr = &options->client_alive_count_max;
906 while ((arg = strdelim(&cp)) && *arg != '\0') {
907 if (strchr(arg, '=') != NULL)
908 fatal("%s line %d: Invalid environment name.",
910 if (options->num_accept_env >= MAX_ACCEPT_ENV)
911 fatal("%s line %d: too many allow env.",
913 options->accept_env[options->num_accept_env++] =
919 logit("%s line %d: Deprecated option %s",
920 filename, linenum, arg);
926 logit("%s line %d: Unsupported option %s",
927 filename, linenum, arg);
933 fatal("%s line %d: Missing handler for opcode %s (%d)",
934 filename, linenum, arg, opcode);
936 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
937 fatal("%s line %d: garbage at end of line; \"%.200s\".",
938 filename, linenum, arg);
942 /* Reads the server configuration file. */
945 load_server_config(const char *filename, Buffer *conf)
947 char line[1024], *cp;
950 debug2("%s: filename %s", __func__, filename);
951 if ((f = fopen(filename, "r")) == NULL) {
956 while (fgets(line, sizeof(line), f)) {
958 * Trim out comments and strip whitespace
959 * NB - preserve newlines, they are needed to reproduce
960 * line numbers later for error messages
962 if ((cp = strchr(line, '#')) != NULL)
964 cp = line + strspn(line, " \t\r");
966 buffer_append(conf, cp, strlen(cp));
968 buffer_append(conf, "\0", 1);
970 debug2("%s: done config len = %d", __func__, buffer_len(conf));
974 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
976 int linenum, bad_options = 0;
977 char *cp, *obuf, *cbuf;
979 debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
981 obuf = cbuf = xstrdup(buffer_ptr(conf));
983 while((cp = strsep(&cbuf, "\n")) != NULL) {
984 if (process_server_config_line(options, cp, filename,
990 fatal("%s: terminating, %d bad configuration options",
991 filename, bad_options);