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