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