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