]> andersk Git - gssapi-openssh.git/blob - openssh/servconf.c
f906e10d193c750e22fdd498d7e72f7e73efdf33
[gssapi-openssh.git] / openssh / servconf.c
1 /* $OpenBSD: servconf.c,v 1.177 2008/02/10 10:54:28 djm Exp $ */
2 /*
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  */
12
13 #include "includes.h"
14
15 #include <sys/types.h>
16 #include <sys/socket.h>
17
18 #include <netdb.h>
19 #include <pwd.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <stdarg.h>
26
27 #include "xmalloc.h"
28 #include "ssh.h"
29 #include "log.h"
30 #include "buffer.h"
31 #include "servconf.h"
32 #include "compat.h"
33 #include "pathnames.h"
34 #include "misc.h"
35 #include "cipher.h"
36 #include "key.h"
37 #include "kex.h"
38 #include "mac.h"
39 #include "match.h"
40 #include "channels.h"
41 #include "groupaccess.h"
42
43 static void add_listen_addr(ServerOptions *, char *, u_short);
44 static void add_one_listen_addr(ServerOptions *, char *, u_short);
45
46 /* Use of privilege separation or not */
47 extern int use_privsep;
48 extern Buffer cfg;
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->use_pam = -1;
59
60         /* Standard Options */
61         options->num_ports = 0;
62         options->ports_from_cmdline = 0;
63         options->listen_addrs = NULL;
64         options->address_family = -1;
65         options->num_host_key_files = 0;
66         options->pid_file = NULL;
67         options->server_key_bits = -1;
68         options->login_grace_time = -1;
69         options->key_regeneration_time = -1;
70         options->permit_root_login = PERMIT_NOT_SET;
71         options->ignore_rhosts = -1;
72         options->ignore_user_known_hosts = -1;
73         options->print_motd = -1;
74         options->print_lastlog = -1;
75         options->x11_forwarding = -1;
76         options->x11_display_offset = -1;
77         options->x11_use_localhost = -1;
78         options->xauth_location = NULL;
79         options->strict_modes = -1;
80         options->tcp_keep_alive = -1;
81         options->log_facility = SYSLOG_FACILITY_NOT_SET;
82         options->log_level = SYSLOG_LEVEL_NOT_SET;
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         options->kerberos_authentication = -1;
89         options->kerberos_or_local_passwd = -1;
90         options->kerberos_ticket_cleanup = -1;
91 #ifdef  SESSION_HOOKS
92         options->session_hooks_allow = -1;
93         options->session_hooks_startup_cmd = NULL;
94         options->session_hooks_shutdown_cmd = NULL;
95 #endif
96         options->kerberos_get_afs_token = -1;
97         options->gss_authentication = -1;
98         options->gss_deleg_creds = -1;
99         options->gss_keyex = -1;
100         options->gss_cleanup_creds = -1;
101         options->gss_strict_acceptor = -1;
102         options->gsi_allow_limited_proxy = -1;
103         options->password_authentication = -1;
104         options->kbd_interactive_authentication = -1;
105         options->challenge_response_authentication = -1;
106         options->permit_empty_passwd = -1;
107         options->permit_user_env = -1;
108         options->use_login = -1;
109         options->compression = -1;
110         options->allow_tcp_forwarding = -1;
111         options->num_allow_users = 0;
112         options->num_deny_users = 0;
113         options->num_allow_groups = 0;
114         options->num_deny_groups = 0;
115         options->ciphers = NULL;
116         options->macs = NULL;
117         options->protocol = SSH_PROTO_UNKNOWN;
118         options->gateway_ports = -1;
119         options->num_subsystems = 0;
120         options->max_startups_begin = -1;
121         options->max_startups_rate = -1;
122         options->max_startups = -1;
123         options->max_authtries = -1;
124         options->banner = NULL;
125         options->use_dns = -1;
126         options->client_alive_interval = -1;
127         options->client_alive_count_max = -1;
128         options->authorized_keys_file = NULL;
129         options->authorized_keys_file2 = NULL;
130         options->num_accept_env = 0;
131         options->permit_tun = -1;
132         options->num_permitted_opens = -1;
133         options->adm_forced_command = NULL;
134         options->chroot_directory = NULL;
135         options->none_enabled = -1;
136         options->tcp_rcv_buf_poll = -1;
137         options->hpn_disabled = -1;
138         options->hpn_buffer_size = -1;
139 }
140
141 void
142 fill_default_server_options(ServerOptions *options)
143 {
144         int sock;
145         int socksize;
146         int socksizelen = sizeof(int);
147
148         /* Portable-specific options */
149         if (options->use_pam == -1)
150                 options->use_pam = 0;
151
152         /* Standard Options */
153         if (options->protocol == SSH_PROTO_UNKNOWN)
154                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
155         if (options->num_host_key_files == 0) {
156                 /* fill default hostkeys for protocols */
157                 if (options->protocol & SSH_PROTO_1)
158                         options->host_key_files[options->num_host_key_files++] =
159                             _PATH_HOST_KEY_FILE;
160                 if (options->protocol & SSH_PROTO_2) {
161                         options->host_key_files[options->num_host_key_files++] =
162                             _PATH_HOST_RSA_KEY_FILE;
163                         options->host_key_files[options->num_host_key_files++] =
164                             _PATH_HOST_DSA_KEY_FILE;
165                 }
166         }
167         if (options->num_ports == 0)
168                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
169         if (options->listen_addrs == NULL)
170                 add_listen_addr(options, NULL, 0);
171         if (options->pid_file == NULL)
172                 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
173         if (options->server_key_bits == -1)
174                 options->server_key_bits = 768;
175         if (options->login_grace_time == -1)
176                 options->login_grace_time = 120;
177         if (options->key_regeneration_time == -1)
178                 options->key_regeneration_time = 3600;
179         if (options->permit_root_login == PERMIT_NOT_SET)
180                 options->permit_root_login = PERMIT_YES;
181         if (options->ignore_rhosts == -1)
182                 options->ignore_rhosts = 1;
183         if (options->ignore_user_known_hosts == -1)
184                 options->ignore_user_known_hosts = 0;
185         if (options->print_motd == -1)
186                 options->print_motd = 1;
187         if (options->print_lastlog == -1)
188                 options->print_lastlog = 1;
189         if (options->x11_forwarding == -1)
190                 options->x11_forwarding = 0;
191         if (options->x11_display_offset == -1)
192                 options->x11_display_offset = 10;
193         if (options->x11_use_localhost == -1)
194                 options->x11_use_localhost = 1;
195         if (options->xauth_location == NULL)
196                 options->xauth_location = _PATH_XAUTH;
197         if (options->strict_modes == -1)
198                 options->strict_modes = 1;
199         if (options->tcp_keep_alive == -1)
200                 options->tcp_keep_alive = 1;
201         if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
202                 options->log_facility = SYSLOG_FACILITY_AUTH;
203         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
204                 options->log_level = SYSLOG_LEVEL_INFO;
205         if (options->rhosts_rsa_authentication == -1)
206                 options->rhosts_rsa_authentication = 0;
207         if (options->hostbased_authentication == -1)
208                 options->hostbased_authentication = 0;
209         if (options->hostbased_uses_name_from_packet_only == -1)
210                 options->hostbased_uses_name_from_packet_only = 0;
211         if (options->rsa_authentication == -1)
212                 options->rsa_authentication = 1;
213         if (options->pubkey_authentication == -1)
214                 options->pubkey_authentication = 1;
215         if (options->kerberos_authentication == -1)
216                 options->kerberos_authentication = 0;
217         if (options->kerberos_or_local_passwd == -1)
218                 options->kerberos_or_local_passwd = 1;
219         if (options->kerberos_ticket_cleanup == -1)
220                 options->kerberos_ticket_cleanup = 1;
221         if (options->kerberos_get_afs_token == -1)
222                 options->kerberos_get_afs_token = 0;
223         if (options->gss_authentication == -1)
224                 options->gss_authentication = 1;
225         if (options->gss_deleg_creds == -1)
226                 options->gss_deleg_creds = 1;
227         if (options->gss_keyex == -1)
228                 options->gss_keyex = 1;
229         if (options->gss_cleanup_creds == -1)
230                 options->gss_cleanup_creds = 1;
231         if (options->gss_strict_acceptor == -1)
232                 options->gss_strict_acceptor = 1;
233         if (options->gsi_allow_limited_proxy == -1)
234                 options->gsi_allow_limited_proxy = 0;
235         if (options->password_authentication == -1)
236                 options->password_authentication = 1;
237         if (options->kbd_interactive_authentication == -1)
238                 options->kbd_interactive_authentication = 0;
239         if (options->challenge_response_authentication == -1)
240                 options->challenge_response_authentication = 1;
241         if (options->permit_empty_passwd == -1)
242                 options->permit_empty_passwd = 0;
243         if (options->permit_user_env == -1)
244                 options->permit_user_env = 0;
245         if (options->use_login == -1)
246                 options->use_login = 0;
247         if (options->compression == -1)
248                 options->compression = COMP_DELAYED;
249         if (options->allow_tcp_forwarding == -1)
250                 options->allow_tcp_forwarding = 1;
251         if (options->gateway_ports == -1)
252                 options->gateway_ports = 0;
253         if (options->max_startups == -1)
254                 options->max_startups = 10;
255         if (options->max_startups_rate == -1)
256                 options->max_startups_rate = 100;               /* 100% */
257         if (options->max_startups_begin == -1)
258                 options->max_startups_begin = options->max_startups;
259         if (options->max_authtries == -1)
260                 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
261         if (options->use_dns == -1)
262                 options->use_dns = 1;
263         if (options->client_alive_interval == -1)
264                 options->client_alive_interval = 0;
265         if (options->client_alive_count_max == -1)
266                 options->client_alive_count_max = 3;
267         if (options->authorized_keys_file2 == NULL) {
268                 /* authorized_keys_file2 falls back to authorized_keys_file */
269                 if (options->authorized_keys_file != NULL)
270                         options->authorized_keys_file2 = options->authorized_keys_file;
271                 else
272                         options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
273         }
274         if (options->authorized_keys_file == NULL)
275                 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
276         if (options->permit_tun == -1)
277                 options->permit_tun = SSH_TUNMODE_NO;
278
279         if (options->hpn_disabled == -1) 
280                 options->hpn_disabled = 0;
281
282         if (options->hpn_buffer_size == -1) {
283                 /* option not explicitly set. Now we have to figure out */
284                 /* what value to use */
285                 if (options->hpn_disabled == 1) {
286                         options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
287                 } else {
288                         /* get the current RCV size and set it to that */
289                         /*create a socket but don't connect it */
290                         /* we use that the get the rcv socket size */
291                         sock = socket(AF_INET, SOCK_STREAM, 0);
292                         getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
293                                    &socksize, &socksizelen);
294                         close(sock);
295                         options->hpn_buffer_size = socksize;
296                         debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
297                         
298                 } 
299         } else {
300                 /* we have to do this incase the user sets both values in a contradictory */
301                 /* manner. hpn_disabled overrrides hpn_buffer_size*/
302                 if (options->hpn_disabled <= 0) {
303                         if (options->hpn_buffer_size == 0)
304                                 options->hpn_buffer_size = 1;
305                         /* limit the maximum buffer to 64MB */
306                         if (options->hpn_buffer_size > 64*1024) {
307                                 options->hpn_buffer_size = 64*1024*1024;
308                         } else {
309                                 options->hpn_buffer_size *= 1024;
310                         }
311                 } else
312                         options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
313         }
314
315         /* Turn privilege separation on by default */
316         if (use_privsep == -1)
317                 use_privsep = 1;
318
319 #ifndef HAVE_MMAP
320         if (use_privsep && options->compression == 1) {
321                 error("This platform does not support both privilege "
322                     "separation and compression");
323                 error("Compression disabled");
324                 options->compression = 0;
325         }
326 #endif
327
328 }
329
330 /* Keyword tokens. */
331 typedef enum {
332         sBadOption,             /* == unknown option */
333         /* Portable-specific options */
334         sUsePAM,
335         /* Standard Options */
336         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
337         sPermitRootLogin, sLogFacility, sLogLevel,
338         sRhostsRSAAuthentication, sRSAAuthentication,
339         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
340         sKerberosGetAFSToken,
341         sKerberosTgtPassing, sChallengeResponseAuthentication,
342 #ifdef SESSION_HOOKS
343         sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
344 #endif
345         sPasswordAuthentication, sKbdInteractiveAuthentication,
346         sListenAddress, sAddressFamily,
347         sPrintMotd, sPrintLastLog, sIgnoreRhosts,
348         sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
349         sStrictModes, sEmptyPasswd, sTCPKeepAlive,
350         sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
351         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
352         sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
353         sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
354         sMaxStartups, sMaxAuthTries,
355         sBanner, sUseDNS, sHostbasedAuthentication,
356         sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
357         sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
358         sGssAuthentication, sGssCleanupCreds,
359     sGssDelegateCreds,
360     sGssStrictAcceptor,
361         sGssKeyEx, 
362     sGssCredsPath,
363         sGsiAllowLimitedProxy,
364     sAcceptEnv, sPermitTunnel,
365         sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
366         sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, 
367         sHPNDisabled, sHPNBufferSize,
368         sDeprecated, sUnsupported
369 } ServerOpCodes;
370
371 #define SSHCFG_GLOBAL   0x01    /* allowed in main section of sshd_config */
372 #define SSHCFG_MATCH    0x02    /* allowed inside a Match section */
373 #define SSHCFG_ALL      (SSHCFG_GLOBAL|SSHCFG_MATCH)
374
375 /* Textual representation of the tokens. */
376 static struct {
377         const char *name;
378         ServerOpCodes opcode;
379         u_int flags;
380 } keywords[] = {
381         /* Portable-specific options */
382 #ifdef USE_PAM
383         { "usepam", sUsePAM, SSHCFG_GLOBAL },
384 #else
385         { "usepam", sUnsupported, SSHCFG_GLOBAL },
386 #endif
387         { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
388         /* Standard Options */
389         { "port", sPort, SSHCFG_GLOBAL },
390         { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
391         { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },          /* alias */
392         { "pidfile", sPidFile, SSHCFG_GLOBAL },
393         { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
394         { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
395         { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
396         { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
397         { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
398         { "loglevel", sLogLevel, SSHCFG_GLOBAL },
399         { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
400         { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
401         { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
402         { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
403         { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
404         { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
405         { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },  /* alias */
406 #ifdef KRB5
407         { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
408         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
409         { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
410 #ifdef USE_AFS
411         { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
412 #else
413         { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
414 #endif
415 #else
416         { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
417         { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
418         { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
419         { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
420 #endif
421         { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
422         { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
423 #ifdef GSSAPI
424         { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
425         { "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_ALL },
426         { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
427         { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
428         { "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
429         { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
430 #ifdef GSI
431         { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
432 #endif
433 #else
434         { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
435         { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL },
436         { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
437         { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
438         { "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
439         { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
440 #ifdef GSI
441         { "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
442 #endif
443 #endif
444 #ifdef SESSION_HOOKS
445     { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
446     { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
447     { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
448 #endif        
449         { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
450         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
451         { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
452         { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
453         { "checkmail", sDeprecated, SSHCFG_GLOBAL },
454         { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
455         { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
456         { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
457         { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
458         { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
459         { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
460         { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
461         { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
462         { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
463         { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
464         { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
465         { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
466         { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
467         { "uselogin", sUseLogin, SSHCFG_GLOBAL },
468         { "compression", sCompression, SSHCFG_GLOBAL },
469         { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
470         { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },  /* obsolete alias */
471         { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
472         { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
473         { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
474         { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
475         { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
476         { "ciphers", sCiphers, SSHCFG_GLOBAL },
477         { "macs", sMacs, SSHCFG_GLOBAL },
478         { "protocol", sProtocol, SSHCFG_GLOBAL },
479         { "gatewayports", sGatewayPorts, SSHCFG_ALL },
480         { "subsystem", sSubsystem, SSHCFG_GLOBAL },
481         { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
482         { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
483         { "banner", sBanner, SSHCFG_ALL },
484         { "usedns", sUseDNS, SSHCFG_GLOBAL },
485         { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
486         { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
487         { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
488         { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
489         { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
490         { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
491         { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
492         { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
493         { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
494         { "match", sMatch, SSHCFG_ALL },
495         { "permitopen", sPermitOpen, SSHCFG_ALL },
496         { "forcecommand", sForceCommand, SSHCFG_ALL },
497         { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
498         { "noneenabled", sNoneEnabled },
499         { "hpndisabled", sHPNDisabled },
500         { "hpnbuffersize", sHPNBufferSize },
501         { "tcprcvbufpoll", sTcpRcvBufPoll },
502         { NULL, sBadOption, 0 }
503 };
504
505 /*
506  * Returns the number of the token pointed to by cp or sBadOption.
507  */
508
509 static ServerOpCodes
510 parse_token(const char *cp, const char *filename,
511             int linenum, u_int *flags)
512 {
513         u_int i;
514
515         for (i = 0; keywords[i].name; i++)
516                 if (strcasecmp(cp, keywords[i].name) == 0) {
517                         debug ("Config token is %s", keywords[i].name);
518                         *flags = keywords[i].flags;
519                         return keywords[i].opcode;
520                 }
521
522         error("%s: line %d: Bad configuration option: %s",
523             filename, linenum, cp);
524         return sBadOption;
525 }
526
527 static void
528 add_listen_addr(ServerOptions *options, char *addr, u_short port)
529 {
530         u_int i;
531
532         if (options->num_ports == 0)
533                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
534         if (options->address_family == -1)
535                 options->address_family = AF_UNSPEC;
536         if (port == 0)
537                 for (i = 0; i < options->num_ports; i++)
538                         add_one_listen_addr(options, addr, options->ports[i]);
539         else
540                 add_one_listen_addr(options, addr, port);
541 }
542
543 static void
544 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
545 {
546         struct addrinfo hints, *ai, *aitop;
547         char strport[NI_MAXSERV];
548         int gaierr;
549
550         memset(&hints, 0, sizeof(hints));
551         hints.ai_family = options->address_family;
552         hints.ai_socktype = SOCK_STREAM;
553         hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
554         snprintf(strport, sizeof strport, "%u", port);
555         if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
556                 fatal("bad addr or host: %s (%s)",
557                     addr ? addr : "<NULL>",
558                     ssh_gai_strerror(gaierr));
559         for (ai = aitop; ai->ai_next; ai = ai->ai_next)
560                 ;
561         ai->ai_next = options->listen_addrs;
562         options->listen_addrs = aitop;
563 }
564
565 /*
566  * The strategy for the Match blocks is that the config file is parsed twice.
567  *
568  * The first time is at startup.  activep is initialized to 1 and the
569  * directives in the global context are processed and acted on.  Hitting a
570  * Match directive unsets activep and the directives inside the block are
571  * checked for syntax only.
572  *
573  * The second time is after a connection has been established but before
574  * authentication.  activep is initialized to 2 and global config directives
575  * are ignored since they have already been processed.  If the criteria in a
576  * Match block is met, activep is set and the subsequent directives
577  * processed and actioned until EOF or another Match block unsets it.  Any
578  * options set are copied into the main server config.
579  *
580  * Potential additions/improvements:
581  *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
582  *
583  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
584  *      Match Address 192.168.0.*
585  *              Tag trusted
586  *      Match Group wheel
587  *              Tag trusted
588  *      Match Tag trusted
589  *              AllowTcpForwarding yes
590  *              GatewayPorts clientspecified
591  *              [...]
592  *
593  *  - Add a PermittedChannelRequests directive
594  *      Match Group shell
595  *              PermittedChannelRequests session,forwarded-tcpip
596  */
597
598 static int
599 match_cfg_line_group(const char *grps, int line, const char *user)
600 {
601         int result = 0;
602         u_int ngrps = 0;
603         char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
604         struct passwd *pw;
605
606         /*
607          * Even if we do not have a user yet, we still need to check for
608          * valid syntax.
609          */
610         arg = cp = xstrdup(grps);
611         while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
612                 if (ngrps >= MAX_MATCH_GROUPS) {
613                         error("line %d: too many groups in Match Group", line);
614                         result = -1;
615                         goto out;
616                 }
617                 grplist[ngrps++] = p;
618         }
619
620         if (user == NULL)
621                 goto out;
622
623         if ((pw = getpwnam(user)) == NULL) {
624                 debug("Can't match group at line %d because user %.100s does "
625                     "not exist", line, user);
626         } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
627                 debug("Can't Match group because user %.100s not in any group "
628                     "at line %d", user, line);
629         } else if (ga_match(grplist, ngrps) != 1) {
630                 debug("user %.100s does not match group %.100s at line %d",
631                     user, arg, line);
632         } else {
633                 debug("user %.100s matched group %.100s at line %d", user,
634                     arg, line);
635                 result = 1;
636         }
637 out:
638         ga_free();
639         xfree(arg);
640         return result;
641 }
642
643 static int
644 match_cfg_line(char **condition, int line, const char *user, const char *host,
645     const char *address)
646 {
647         int result = 1;
648         char *arg, *attrib, *cp = *condition;
649         size_t len;
650
651         if (user == NULL)
652                 debug3("checking syntax for 'Match %s'", cp);
653         else
654                 debug3("checking match for '%s' user %s host %s addr %s", cp,
655                     user ? user : "(null)", host ? host : "(null)",
656                     address ? address : "(null)");
657
658         while ((attrib = strdelim(&cp)) && *attrib != '\0') {
659                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
660                         error("Missing Match criteria for %s", attrib);
661                         return -1;
662                 }
663                 len = strlen(arg);
664                 if (strcasecmp(attrib, "user") == 0) {
665                         if (!user) {
666                                 result = 0;
667                                 continue;
668                         }
669                         if (match_pattern_list(user, arg, len, 0) != 1)
670                                 result = 0;
671                         else
672                                 debug("user %.100s matched 'User %.100s' at "
673                                     "line %d", user, arg, line);
674                 } else if (strcasecmp(attrib, "group") == 0) {
675                         switch (match_cfg_line_group(arg, line, user)) {
676                         case -1:
677                                 return -1;
678                         case 0:
679                                 result = 0;
680                         }
681                 } else if (strcasecmp(attrib, "host") == 0) {
682                         if (!host) {
683                                 result = 0;
684                                 continue;
685                         }
686                         if (match_hostname(host, arg, len) != 1)
687                                 result = 0;
688                         else
689                                 debug("connection from %.100s matched 'Host "
690                                     "%.100s' at line %d", host, arg, line);
691                 } else if (strcasecmp(attrib, "address") == 0) {
692                         if (!address) {
693                                 result = 0;
694                                 continue;
695                         }
696                         if (match_hostname(address, arg, len) != 1)
697                                 result = 0;
698                         else
699                                 debug("connection from %.100s matched 'Address "
700                                     "%.100s' at line %d", address, arg, line);
701                 } else {
702                         error("Unsupported Match attribute %s", attrib);
703                         return -1;
704                 }
705         }
706         if (user != NULL)
707                 debug3("match %sfound", result ? "" : "not ");
708         *condition = cp;
709         return result;
710 }
711
712 #define WHITESPACE " \t\r\n"
713
714 int
715 process_server_config_line(ServerOptions *options, char *line,
716     const char *filename, int linenum, int *activep, const char *user,
717     const char *host, const char *address)
718 {
719         char *cp, **charptr, *arg, *p;
720         int cmdline = 0, *intptr, value, n;
721         SyslogFacility *log_facility_ptr;
722         LogLevel *log_level_ptr;
723         ServerOpCodes opcode;
724         u_short port;
725         u_int i, flags = 0;
726         size_t len;
727
728         cp = line;
729         if ((arg = strdelim(&cp)) == NULL)
730                 return 0;
731         /* Ignore leading whitespace */
732         if (*arg == '\0')
733                 arg = strdelim(&cp);
734         if (!arg || !*arg || *arg == '#')
735                 return 0;
736         intptr = NULL;
737         charptr = NULL;
738         opcode = parse_token(arg, filename, linenum, &flags);
739
740         if (activep == NULL) { /* We are processing a command line directive */
741                 cmdline = 1;
742                 activep = &cmdline;
743         }
744         if (*activep && opcode != sMatch)
745                 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
746         if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
747                 if (user == NULL) {
748                         fatal("%s line %d: Directive '%s' is not allowed "
749                             "within a Match block", filename, linenum, arg);
750                 } else { /* this is a directive we have already processed */
751                         while (arg)
752                                 arg = strdelim(&cp);
753                         return 0;
754                 }
755         }
756
757         switch (opcode) {
758         /* Portable-specific options */
759         case sUsePAM:
760                 intptr = &options->use_pam;
761                 goto parse_flag;
762
763         /* Standard Options */
764         case sBadOption:
765                 return -1;
766         case sPort:
767                 /* ignore ports from configfile if cmdline specifies ports */
768                 if (options->ports_from_cmdline)
769                         return 0;
770                 if (options->listen_addrs != NULL)
771                         fatal("%s line %d: ports must be specified before "
772                             "ListenAddress.", filename, linenum);
773                 if (options->num_ports >= MAX_PORTS)
774                         fatal("%s line %d: too many ports.",
775                             filename, linenum);
776                 arg = strdelim(&cp);
777                 if (!arg || *arg == '\0')
778                         fatal("%s line %d: missing port number.",
779                             filename, linenum);
780                 options->ports[options->num_ports++] = a2port(arg);
781                 if (options->ports[options->num_ports-1] == 0)
782                         fatal("%s line %d: Badly formatted port number.",
783                             filename, linenum);
784                 break;
785
786         case sServerKeyBits:
787                 intptr = &options->server_key_bits;
788 parse_int:
789                 arg = strdelim(&cp);
790                 if (!arg || *arg == '\0')
791                         fatal("%s line %d: missing integer value.",
792                             filename, linenum);
793                 value = atoi(arg);
794                 if (*activep && *intptr == -1)
795                         *intptr = value;
796                 break;
797
798         case sLoginGraceTime:
799                 intptr = &options->login_grace_time;
800 parse_time:
801                 arg = strdelim(&cp);
802                 if (!arg || *arg == '\0')
803                         fatal("%s line %d: missing time value.",
804                             filename, linenum);
805                 if ((value = convtime(arg)) == -1)
806                         fatal("%s line %d: invalid time value.",
807                             filename, linenum);
808                 if (*intptr == -1)
809                         *intptr = value;
810                 break;
811
812         case sKeyRegenerationTime:
813                 intptr = &options->key_regeneration_time;
814                 goto parse_time;
815
816         case sListenAddress:
817                 arg = strdelim(&cp);
818                 if (arg == NULL || *arg == '\0')
819                         fatal("%s line %d: missing address",
820                             filename, linenum);
821                 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
822                 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
823                     && strchr(p+1, ':') != NULL) {
824                         add_listen_addr(options, arg, 0);
825                         break;
826                 }
827                 p = hpdelim(&arg);
828                 if (p == NULL)
829                         fatal("%s line %d: bad address:port usage",
830                             filename, linenum);
831                 p = cleanhostname(p);
832                 if (arg == NULL)
833                         port = 0;
834                 else if ((port = a2port(arg)) == 0)
835                         fatal("%s line %d: bad port number", filename, linenum);
836
837                 add_listen_addr(options, p, port);
838
839                 break;
840
841         case sAddressFamily:
842                 arg = strdelim(&cp);
843                 if (!arg || *arg == '\0')
844                         fatal("%s line %d: missing address family.",
845                             filename, linenum);
846                 intptr = &options->address_family;
847                 if (options->listen_addrs != NULL)
848                         fatal("%s line %d: address family must be specified before "
849                             "ListenAddress.", filename, linenum);
850                 if (strcasecmp(arg, "inet") == 0)
851                         value = AF_INET;
852                 else if (strcasecmp(arg, "inet6") == 0)
853                         value = AF_INET6;
854                 else if (strcasecmp(arg, "any") == 0)
855                         value = AF_UNSPEC;
856                 else
857                         fatal("%s line %d: unsupported address family \"%s\".",
858                             filename, linenum, arg);
859                 if (*intptr == -1)
860                         *intptr = value;
861                 break;
862
863         case sHostKeyFile:
864                 intptr = &options->num_host_key_files;
865                 if (*intptr >= MAX_HOSTKEYS)
866                         fatal("%s line %d: too many host keys specified (max %d).",
867                             filename, linenum, MAX_HOSTKEYS);
868                 charptr = &options->host_key_files[*intptr];
869 parse_filename:
870                 arg = strdelim(&cp);
871                 if (!arg || *arg == '\0')
872                         fatal("%s line %d: missing file name.",
873                             filename, linenum);
874                 if (*activep && *charptr == NULL) {
875                         *charptr = tilde_expand_filename(arg, getuid());
876                         /* increase optional counter */
877                         if (intptr != NULL)
878                                 *intptr = *intptr + 1;
879                 }
880                 break;
881
882         case sPidFile:
883                 charptr = &options->pid_file;
884                 goto parse_filename;
885
886         case sPermitRootLogin:
887                 intptr = &options->permit_root_login;
888                 arg = strdelim(&cp);
889                 if (!arg || *arg == '\0')
890                         fatal("%s line %d: missing yes/"
891                             "without-password/forced-commands-only/no "
892                             "argument.", filename, linenum);
893                 value = 0;      /* silence compiler */
894                 if (strcmp(arg, "without-password") == 0)
895                         value = PERMIT_NO_PASSWD;
896                 else if (strcmp(arg, "forced-commands-only") == 0)
897                         value = PERMIT_FORCED_ONLY;
898                 else if (strcmp(arg, "yes") == 0)
899                         value = PERMIT_YES;
900                 else if (strcmp(arg, "no") == 0)
901                         value = PERMIT_NO;
902                 else
903                         fatal("%s line %d: Bad yes/"
904                             "without-password/forced-commands-only/no "
905                             "argument: %s", filename, linenum, arg);
906                 if (*activep && *intptr == -1)
907                         *intptr = value;
908                 break;
909
910         case sIgnoreRhosts:
911                 intptr = &options->ignore_rhosts;
912 parse_flag:
913                 arg = strdelim(&cp);
914                 if (!arg || *arg == '\0')
915                         fatal("%s line %d: missing yes/no argument.",
916                             filename, linenum);
917                 value = 0;      /* silence compiler */
918                 if (strcmp(arg, "yes") == 0)
919                         value = 1;
920                 else if (strcmp(arg, "no") == 0)
921                         value = 0;
922                 else
923                         fatal("%s line %d: Bad yes/no argument: %s",
924                                 filename, linenum, arg);
925                 if (*activep && *intptr == -1)
926                         *intptr = value;
927                 break;
928
929         case sNoneEnabled:
930                 intptr = &options->none_enabled;
931                 goto parse_flag;
932
933         case sTcpRcvBufPoll:
934                 intptr = &options->tcp_rcv_buf_poll;
935                 goto parse_flag;
936
937         case sHPNDisabled:
938                 intptr = &options->hpn_disabled;
939                 goto parse_flag;
940
941         case sHPNBufferSize:
942                 intptr = &options->hpn_buffer_size;
943                 goto parse_int;
944
945         case sIgnoreUserKnownHosts:
946                 intptr = &options->ignore_user_known_hosts;
947                 goto parse_flag;
948
949         case sRhostsRSAAuthentication:
950                 intptr = &options->rhosts_rsa_authentication;
951                 goto parse_flag;
952
953         case sHostbasedAuthentication:
954                 intptr = &options->hostbased_authentication;
955                 goto parse_flag;
956
957         case sHostbasedUsesNameFromPacketOnly:
958                 intptr = &options->hostbased_uses_name_from_packet_only;
959                 goto parse_flag;
960
961         case sRSAAuthentication:
962                 intptr = &options->rsa_authentication;
963                 goto parse_flag;
964
965         case sPubkeyAuthentication:
966                 intptr = &options->pubkey_authentication;
967                 goto parse_flag;
968
969         case sKerberosAuthentication:
970                 intptr = &options->kerberos_authentication;
971                 goto parse_flag;
972
973         case sKerberosOrLocalPasswd:
974                 intptr = &options->kerberos_or_local_passwd;
975                 goto parse_flag;
976
977         case sKerberosTicketCleanup:
978                 intptr = &options->kerberos_ticket_cleanup;
979                 goto parse_flag;
980
981         case sKerberosGetAFSToken:
982                 intptr = &options->kerberos_get_afs_token;
983                 goto parse_flag;
984
985         case sGssAuthentication:
986                 intptr = &options->gss_authentication;
987                 goto parse_flag;
988
989         case sGssDelegateCreds:
990                 intptr = &options->gss_deleg_creds;
991                 goto parse_flag;
992
993         case sGssKeyEx:
994                 intptr = &options->gss_keyex;
995                 goto parse_flag;
996
997         case sGssCleanupCreds:
998                 intptr = &options->gss_cleanup_creds;
999                 goto parse_flag;
1000
1001         case sGssStrictAcceptor:
1002                 intptr = &options->gss_strict_acceptor;
1003                 goto parse_flag;
1004
1005         case sGssCredsPath:
1006                 charptr = &options->gss_creds_path;
1007                 goto parse_filename;
1008
1009         case sGsiAllowLimitedProxy:
1010                 intptr = &options->gsi_allow_limited_proxy;
1011                 goto parse_flag;
1012
1013 #ifdef SESSION_HOOKS
1014         case sAllowSessionHooks:
1015                 intptr = &options->session_hooks_allow;
1016                 goto parse_flag;
1017         case sSessionHookStartupCmd:
1018         case sSessionHookShutdownCmd:
1019                 arg = strdelim(&cp);
1020                 if (!arg || *arg == '\0')
1021                     fatal("%s line %d: empty session hook command",
1022                           filename, linenum);
1023                 if (opcode==sSessionHookStartupCmd)
1024                     options->session_hooks_startup_cmd = strdup(arg);
1025                 else
1026                     options->session_hooks_shutdown_cmd = strdup(arg);
1027                 break;
1028 #endif                  
1029
1030         case sPasswordAuthentication:
1031                 intptr = &options->password_authentication;
1032                 goto parse_flag;
1033
1034         case sKbdInteractiveAuthentication:
1035                 intptr = &options->kbd_interactive_authentication;
1036                 goto parse_flag;
1037
1038         case sChallengeResponseAuthentication:
1039                 intptr = &options->challenge_response_authentication;
1040                 goto parse_flag;
1041
1042         case sPrintMotd:
1043                 intptr = &options->print_motd;
1044                 goto parse_flag;
1045
1046         case sPrintLastLog:
1047                 intptr = &options->print_lastlog;
1048                 goto parse_flag;
1049
1050         case sX11Forwarding:
1051                 intptr = &options->x11_forwarding;
1052                 goto parse_flag;
1053
1054         case sX11DisplayOffset:
1055                 intptr = &options->x11_display_offset;
1056                 goto parse_int;
1057
1058         case sX11UseLocalhost:
1059                 intptr = &options->x11_use_localhost;
1060                 goto parse_flag;
1061
1062         case sXAuthLocation:
1063                 charptr = &options->xauth_location;
1064                 goto parse_filename;
1065
1066         case sStrictModes:
1067                 intptr = &options->strict_modes;
1068                 goto parse_flag;
1069
1070         case sTCPKeepAlive:
1071                 intptr = &options->tcp_keep_alive;
1072                 goto parse_flag;
1073
1074         case sEmptyPasswd:
1075                 intptr = &options->permit_empty_passwd;
1076                 goto parse_flag;
1077
1078         case sPermitUserEnvironment:
1079                 intptr = &options->permit_user_env;
1080                 goto parse_flag;
1081
1082         case sUseLogin:
1083                 intptr = &options->use_login;
1084                 goto parse_flag;
1085
1086         case sCompression:
1087                 intptr = &options->compression;
1088                 arg = strdelim(&cp);
1089                 if (!arg || *arg == '\0')
1090                         fatal("%s line %d: missing yes/no/delayed "
1091                             "argument.", filename, linenum);
1092                 value = 0;      /* silence compiler */
1093                 if (strcmp(arg, "delayed") == 0)
1094                         value = COMP_DELAYED;
1095                 else if (strcmp(arg, "yes") == 0)
1096                         value = COMP_ZLIB;
1097                 else if (strcmp(arg, "no") == 0)
1098                         value = COMP_NONE;
1099                 else
1100                         fatal("%s line %d: Bad yes/no/delayed "
1101                             "argument: %s", filename, linenum, arg);
1102                 if (*intptr == -1)
1103                         *intptr = value;
1104                 break;
1105
1106         case sGatewayPorts:
1107                 intptr = &options->gateway_ports;
1108                 arg = strdelim(&cp);
1109                 if (!arg || *arg == '\0')
1110                         fatal("%s line %d: missing yes/no/clientspecified "
1111                             "argument.", filename, linenum);
1112                 value = 0;      /* silence compiler */
1113                 if (strcmp(arg, "clientspecified") == 0)
1114                         value = 2;
1115                 else if (strcmp(arg, "yes") == 0)
1116                         value = 1;
1117                 else if (strcmp(arg, "no") == 0)
1118                         value = 0;
1119                 else
1120                         fatal("%s line %d: Bad yes/no/clientspecified "
1121                             "argument: %s", filename, linenum, arg);
1122                 if (*activep && *intptr == -1)
1123                         *intptr = value;
1124                 break;
1125
1126         case sUseDNS:
1127                 intptr = &options->use_dns;
1128                 goto parse_flag;
1129
1130         case sLogFacility:
1131                 log_facility_ptr = &options->log_facility;
1132                 arg = strdelim(&cp);
1133                 value = log_facility_number(arg);
1134                 if (value == SYSLOG_FACILITY_NOT_SET)
1135                         fatal("%.200s line %d: unsupported log facility '%s'",
1136                             filename, linenum, arg ? arg : "<NONE>");
1137                 if (*log_facility_ptr == -1)
1138                         *log_facility_ptr = (SyslogFacility) value;
1139                 break;
1140
1141         case sLogLevel:
1142                 log_level_ptr = &options->log_level;
1143                 arg = strdelim(&cp);
1144                 value = log_level_number(arg);
1145                 if (value == SYSLOG_LEVEL_NOT_SET)
1146                         fatal("%.200s line %d: unsupported log level '%s'",
1147                             filename, linenum, arg ? arg : "<NONE>");
1148                 if (*log_level_ptr == -1)
1149                         *log_level_ptr = (LogLevel) value;
1150                 break;
1151
1152         case sAllowTcpForwarding:
1153                 intptr = &options->allow_tcp_forwarding;
1154                 goto parse_flag;
1155
1156         case sUsePrivilegeSeparation:
1157                 intptr = &use_privsep;
1158                 goto parse_flag;
1159
1160         case sAllowUsers:
1161                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1162                         if (options->num_allow_users >= MAX_ALLOW_USERS)
1163                                 fatal("%s line %d: too many allow users.",
1164                                     filename, linenum);
1165                         options->allow_users[options->num_allow_users++] =
1166                             xstrdup(arg);
1167                 }
1168                 break;
1169
1170         case sDenyUsers:
1171                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1172                         if (options->num_deny_users >= MAX_DENY_USERS)
1173                                 fatal("%s line %d: too many deny users.",
1174                                     filename, linenum);
1175                         options->deny_users[options->num_deny_users++] =
1176                             xstrdup(arg);
1177                 }
1178                 break;
1179
1180         case sAllowGroups:
1181                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1182                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1183                                 fatal("%s line %d: too many allow groups.",
1184                                     filename, linenum);
1185                         options->allow_groups[options->num_allow_groups++] =
1186                             xstrdup(arg);
1187                 }
1188                 break;
1189
1190         case sDenyGroups:
1191                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1192                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
1193                                 fatal("%s line %d: too many deny groups.",
1194                                     filename, linenum);
1195                         options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1196                 }
1197                 break;
1198
1199         case sCiphers:
1200                 arg = strdelim(&cp);
1201                 if (!arg || *arg == '\0')
1202                         fatal("%s line %d: Missing argument.", filename, linenum);
1203                 if (!ciphers_valid(arg))
1204                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1205                             filename, linenum, arg ? arg : "<NONE>");
1206                 if (options->ciphers == NULL)
1207                         options->ciphers = xstrdup(arg);
1208                 break;
1209
1210         case sMacs:
1211                 arg = strdelim(&cp);
1212                 if (!arg || *arg == '\0')
1213                         fatal("%s line %d: Missing argument.", filename, linenum);
1214                 if (!mac_valid(arg))
1215                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1216                             filename, linenum, arg ? arg : "<NONE>");
1217                 if (options->macs == NULL)
1218                         options->macs = xstrdup(arg);
1219                 break;
1220
1221         case sProtocol:
1222                 intptr = &options->protocol;
1223                 arg = strdelim(&cp);
1224                 if (!arg || *arg == '\0')
1225                         fatal("%s line %d: Missing argument.", filename, linenum);
1226                 value = proto_spec(arg);
1227                 if (value == SSH_PROTO_UNKNOWN)
1228                         fatal("%s line %d: Bad protocol spec '%s'.",
1229                             filename, linenum, arg ? arg : "<NONE>");
1230                 if (*intptr == SSH_PROTO_UNKNOWN)
1231                         *intptr = value;
1232                 break;
1233
1234         case sSubsystem:
1235                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1236                         fatal("%s line %d: too many subsystems defined.",
1237                             filename, linenum);
1238                 }
1239                 arg = strdelim(&cp);
1240                 if (!arg || *arg == '\0')
1241                         fatal("%s line %d: Missing subsystem name.",
1242                             filename, linenum);
1243                 if (!*activep) {
1244                         arg = strdelim(&cp);
1245                         break;
1246                 }
1247                 for (i = 0; i < options->num_subsystems; i++)
1248                         if (strcmp(arg, options->subsystem_name[i]) == 0)
1249                                 fatal("%s line %d: Subsystem '%s' already defined.",
1250                                     filename, linenum, arg);
1251                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1252                 arg = strdelim(&cp);
1253                 if (!arg || *arg == '\0')
1254                         fatal("%s line %d: Missing subsystem command.",
1255                             filename, linenum);
1256                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1257
1258                 /* Collect arguments (separate to executable) */
1259                 p = xstrdup(arg);
1260                 len = strlen(p) + 1;
1261                 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1262                         len += 1 + strlen(arg);
1263                         p = xrealloc(p, 1, len);
1264                         strlcat(p, " ", len);
1265                         strlcat(p, arg, len);
1266                 }
1267                 options->subsystem_args[options->num_subsystems] = p;
1268                 options->num_subsystems++;
1269                 break;
1270
1271         case sMaxStartups:
1272                 arg = strdelim(&cp);
1273                 if (!arg || *arg == '\0')
1274                         fatal("%s line %d: Missing MaxStartups spec.",
1275                             filename, linenum);
1276                 if ((n = sscanf(arg, "%d:%d:%d",
1277                     &options->max_startups_begin,
1278                     &options->max_startups_rate,
1279                     &options->max_startups)) == 3) {
1280                         if (options->max_startups_begin >
1281                             options->max_startups ||
1282                             options->max_startups_rate > 100 ||
1283                             options->max_startups_rate < 1)
1284                                 fatal("%s line %d: Illegal MaxStartups spec.",
1285                                     filename, linenum);
1286                 } else if (n != 1)
1287                         fatal("%s line %d: Illegal MaxStartups spec.",
1288                             filename, linenum);
1289                 else
1290                         options->max_startups = options->max_startups_begin;
1291                 break;
1292
1293         case sMaxAuthTries:
1294                 intptr = &options->max_authtries;
1295                 goto parse_int;
1296
1297         case sBanner:
1298                 charptr = &options->banner;
1299                 goto parse_filename;
1300
1301         /*
1302          * These options can contain %X options expanded at
1303          * connect time, so that you can specify paths like:
1304          *
1305          * AuthorizedKeysFile   /etc/ssh_keys/%u
1306          */
1307         case sAuthorizedKeysFile:
1308         case sAuthorizedKeysFile2:
1309                 charptr = (opcode == sAuthorizedKeysFile) ?
1310                     &options->authorized_keys_file :
1311                     &options->authorized_keys_file2;
1312                 goto parse_filename;
1313
1314         case sClientAliveInterval:
1315                 intptr = &options->client_alive_interval;
1316                 goto parse_time;
1317
1318         case sClientAliveCountMax:
1319                 intptr = &options->client_alive_count_max;
1320                 goto parse_int;
1321
1322         case sAcceptEnv:
1323                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1324                         if (strchr(arg, '=') != NULL)
1325                                 fatal("%s line %d: Invalid environment name.",
1326                                     filename, linenum);
1327                         if (options->num_accept_env >= MAX_ACCEPT_ENV)
1328                                 fatal("%s line %d: too many allow env.",
1329                                     filename, linenum);
1330                         if (!*activep)
1331                                 break;
1332                         options->accept_env[options->num_accept_env++] =
1333                             xstrdup(arg);
1334                 }
1335                 break;
1336
1337         case sPermitTunnel:
1338                 intptr = &options->permit_tun;
1339                 arg = strdelim(&cp);
1340                 if (!arg || *arg == '\0')
1341                         fatal("%s line %d: Missing yes/point-to-point/"
1342                             "ethernet/no argument.", filename, linenum);
1343                 value = 0;      /* silence compiler */
1344                 if (strcasecmp(arg, "ethernet") == 0)
1345                         value = SSH_TUNMODE_ETHERNET;
1346                 else if (strcasecmp(arg, "point-to-point") == 0)
1347                         value = SSH_TUNMODE_POINTOPOINT;
1348                 else if (strcasecmp(arg, "yes") == 0)
1349                         value = SSH_TUNMODE_YES;
1350                 else if (strcasecmp(arg, "no") == 0)
1351                         value = SSH_TUNMODE_NO;
1352                 else
1353                         fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1354                             "no argument: %s", filename, linenum, arg);
1355                 if (*intptr == -1)
1356                         *intptr = value;
1357                 break;
1358
1359         case sMatch:
1360                 if (cmdline)
1361                         fatal("Match directive not supported as a command-line "
1362                            "option");
1363                 value = match_cfg_line(&cp, linenum, user, host, address);
1364                 if (value < 0)
1365                         fatal("%s line %d: Bad Match condition", filename,
1366                             linenum);
1367                 *activep = value;
1368                 break;
1369
1370         case sPermitOpen:
1371                 arg = strdelim(&cp);
1372                 if (!arg || *arg == '\0')
1373                         fatal("%s line %d: missing PermitOpen specification",
1374                             filename, linenum);
1375                 n = options->num_permitted_opens;       /* modified later */
1376                 if (strcmp(arg, "any") == 0) {
1377                         if (*activep && n == -1) {
1378                                 channel_clear_adm_permitted_opens();
1379                                 options->num_permitted_opens = 0;
1380                         }
1381                         break;
1382                 }
1383                 if (*activep && n == -1)
1384                         channel_clear_adm_permitted_opens();
1385                 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1386                         p = hpdelim(&arg);
1387                         if (p == NULL)
1388                                 fatal("%s line %d: missing host in PermitOpen",
1389                                     filename, linenum);
1390                         p = cleanhostname(p);
1391                         if (arg == NULL || (port = a2port(arg)) == 0)
1392                                 fatal("%s line %d: bad port number in "
1393                                     "PermitOpen", filename, linenum);
1394                         if (*activep && n == -1)
1395                                 options->num_permitted_opens =
1396                                     channel_add_adm_permitted_opens(p, port);
1397                 }
1398                 break;
1399
1400         case sForceCommand:
1401                 if (cp == NULL)
1402                         fatal("%.200s line %d: Missing argument.", filename,
1403                             linenum);
1404                 len = strspn(cp, WHITESPACE);
1405                 if (*activep && options->adm_forced_command == NULL)
1406                         options->adm_forced_command = xstrdup(cp + len);
1407                 return 0;
1408
1409         case sChrootDirectory:
1410                 charptr = &options->chroot_directory;
1411
1412                 arg = strdelim(&cp);
1413                 if (!arg || *arg == '\0')
1414                         fatal("%s line %d: missing file name.",
1415                             filename, linenum);
1416                 if (*activep && *charptr == NULL)
1417                         *charptr = xstrdup(arg);
1418                 break;
1419
1420         case sDeprecated:
1421                 logit("%s line %d: Deprecated option %s",
1422                     filename, linenum, arg);
1423                 while (arg)
1424                     arg = strdelim(&cp);
1425                 break;
1426
1427         case sUnsupported:
1428                 logit("%s line %d: Unsupported option %s",
1429                     filename, linenum, arg);
1430                 while (arg)
1431                     arg = strdelim(&cp);
1432                 break;
1433
1434         default:
1435                 fatal("%s line %d: Missing handler for opcode %s (%d)",
1436                     filename, linenum, arg, opcode);
1437         }
1438         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1439                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1440                     filename, linenum, arg);
1441         return 0;
1442 }
1443
1444 /* Reads the server configuration file. */
1445
1446 void
1447 load_server_config(const char *filename, Buffer *conf)
1448 {
1449         char line[1024], *cp;
1450         FILE *f;
1451
1452         debug2("%s: filename %s", __func__, filename);
1453         if ((f = fopen(filename, "r")) == NULL) {
1454                 perror(filename);
1455                 exit(1);
1456         }
1457         buffer_clear(conf);
1458         while (fgets(line, sizeof(line), f)) {
1459                 /*
1460                  * Trim out comments and strip whitespace
1461                  * NB - preserve newlines, they are needed to reproduce
1462                  * line numbers later for error messages
1463                  */
1464                 if ((cp = strchr(line, '#')) != NULL)
1465                         memcpy(cp, "\n", 2);
1466                 cp = line + strspn(line, " \t\r");
1467
1468                 buffer_append(conf, cp, strlen(cp));
1469         }
1470         buffer_append(conf, "\0", 1);
1471         fclose(f);
1472         debug2("%s: done config len = %d", __func__, buffer_len(conf));
1473 }
1474
1475 void
1476 parse_server_match_config(ServerOptions *options, const char *user,
1477     const char *host, const char *address)
1478 {
1479         ServerOptions mo;
1480
1481         initialize_server_options(&mo);
1482         parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1483         copy_set_server_options(options, &mo, 0);
1484 }
1485
1486 /* Helper macros */
1487 #define M_CP_INTOPT(n) do {\
1488         if (src->n != -1) \
1489                 dst->n = src->n; \
1490 } while (0)
1491 #define M_CP_STROPT(n) do {\
1492         if (src->n != NULL) { \
1493                 if (dst->n != NULL) \
1494                         xfree(dst->n); \
1495                 dst->n = src->n; \
1496         } \
1497 } while(0)
1498
1499 /*
1500  * Copy any supported values that are set.
1501  *
1502  * If the preauth flag is set, we do not bother copying the the string or
1503  * array values that are not used pre-authentication, because any that we
1504  * do use must be explictly sent in mm_getpwnamallow().
1505  */
1506 void
1507 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1508 {
1509         M_CP_INTOPT(password_authentication);
1510         M_CP_INTOPT(gss_authentication);
1511         M_CP_INTOPT(gss_deleg_creds);
1512         M_CP_INTOPT(rsa_authentication);
1513         M_CP_INTOPT(pubkey_authentication);
1514         M_CP_INTOPT(kerberos_authentication);
1515         M_CP_INTOPT(hostbased_authentication);
1516         M_CP_INTOPT(kbd_interactive_authentication);
1517         M_CP_INTOPT(permit_root_login);
1518
1519         M_CP_INTOPT(allow_tcp_forwarding);
1520         M_CP_INTOPT(gateway_ports);
1521         M_CP_INTOPT(x11_display_offset);
1522         M_CP_INTOPT(x11_forwarding);
1523         M_CP_INTOPT(x11_use_localhost);
1524
1525         M_CP_STROPT(banner);
1526         if (preauth)
1527                 return;
1528         M_CP_STROPT(adm_forced_command);
1529         M_CP_STROPT(chroot_directory);
1530 }
1531
1532 #undef M_CP_INTOPT
1533 #undef M_CP_STROPT
1534
1535 void
1536 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1537     const char *user, const char *host, const char *address)
1538 {
1539         int active, linenum, bad_options = 0;
1540         char *cp, *obuf, *cbuf;
1541
1542         debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1543
1544         obuf = cbuf = xstrdup(buffer_ptr(conf));
1545         active = user ? 0 : 1;
1546         linenum = 1;
1547         while ((cp = strsep(&cbuf, "\n")) != NULL) {
1548                 if (process_server_config_line(options, cp, filename,
1549                     linenum++, &active, user, host, address) != 0)
1550                         bad_options++;
1551         }
1552         xfree(obuf);
1553         if (bad_options > 0)
1554                 fatal("%s: terminating, %d bad configuration options",
1555                     filename, bad_options);
1556 }
This page took 1.558178 seconds and 3 git commands to generate.