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