1 /*
2  * ProFTPD - mod_sftp user authentication
3  * Copyright (c) 2008-2021 TJ Saunders
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, TJ Saunders and other respective copyright holders
20  * give permission to link this program with OpenSSL, and distribute the
21  * resulting executable, without including the source code for OpenSSL in the
22  * source distribution.
23  */
24 
25 #include "mod_sftp.h"
26 #include "ssh2.h"
27 #include "packet.h"
28 #include "msg.h"
29 #include "disconnect.h"
30 #include "interop.h"
31 #include "auth.h"
32 #include "crypto.h"
33 #include "cipher.h"
34 #include "mac.h"
35 #include "compress.h"
36 #include "session.h"
37 #include "keys.h"
38 #include "keystore.h"
39 #include "kbdint.h"
40 #include "utf8.h"
41 #include "display.h"
42 
43 /* From response.c */
44 extern pr_response_t *resp_list, *resp_err_list;
45 
46 /* This value of 6 is the same default as OpenSSH's MaxAuthTries. */
47 static unsigned int auth_attempts_max = 6;
48 static unsigned int auth_attempts = 0;
49 
50 static pool *auth_pool = NULL;
51 static char *auth_default_dir = NULL;
52 
53 static const char *auth_avail_meths = NULL;
54 
55 /* This is a bitset of flags, used to check on the authentication method
56  * used by the client, to see if the requested method is even enabled.
57  */
58 static unsigned int auth_meths_enabled_flags = 0;
59 
60 static array_header *auth_chains = NULL;
61 
62 static int auth_sent_userauth_banner_file = FALSE;
63 static int auth_sent_userauth_success = FALSE;
64 
65 static const char *auth_user = NULL;
66 static const char *auth_service = NULL;
67 
68 static const char *trace_channel = "ssh2";
69 
dup_passwd(pool * p,struct passwd * pw)70 static struct passwd *dup_passwd(pool *p, struct passwd *pw) {
71   struct passwd *res = NULL;
72 
73   res = pcalloc(p, sizeof(struct passwd));
74   res->pw_name = pstrdup(p, pw->pw_name);
75   res->pw_uid = pw->pw_uid;
76   res->pw_gid = pw->pw_gid;
77   res->pw_gecos = pstrdup(p, pw->pw_gecos);
78   res->pw_dir = pstrdup(p, pw->pw_dir);
79   res->pw_shell = pstrdup(p, pw->pw_shell);
80 
81   return res;
82 }
83 
ensure_open_passwd(pool * p)84 static void ensure_open_passwd(pool *p) {
85   pr_auth_setpwent(p);
86   pr_auth_setgrent(p);
87 
88   pr_auth_getpwent(p);
89   pr_auth_getgrent(p);
90 }
91 
get_default_chdir(pool * p)92 static const char *get_default_chdir(pool *p) {
93   config_rec *c;
94   const char *path = NULL;
95 
96   c = find_config(main_server->conf, CONF_PARAM, "DefaultChdir", FALSE);
97   while (c != NULL) {
98     int res;
99 
100     pr_signals_handle();
101 
102     if (c->argc < 2) {
103       path = c->argv[0];
104       break;
105     }
106 
107     res = pr_expr_eval_group_and(((char **) c->argv) + 1);
108     if (res) {
109       path = c->argv[0];
110       break;
111     }
112 
113     c = find_config_next(c, c->next, CONF_PARAM, "DefaultChdir", FALSE);
114   }
115 
116   if (path &&
117       *path != '/' &&
118       *path != '~') {
119     path = pdircat(p, session.cwd, path, NULL);
120   }
121 
122   if (path != NULL) {
123     path = path_subst_uservar(p, &path);
124   }
125 
126   return path;
127 }
128 
get_default_root(pool * p)129 static const char *get_default_root(pool *p) {
130   config_rec *c;
131   const char *path = NULL;
132 
133   c = find_config(main_server->conf, CONF_PARAM, "DefaultRoot", FALSE);
134   while (c) {
135     int res;
136 
137     pr_signals_handle();
138 
139     if (c->argc < 2) {
140       path = c->argv[0];
141       break;
142     }
143 
144     res = pr_expr_eval_group_and(((char **) c->argv) + 1);
145     if (res) {
146       path = c->argv[0];
147       break;
148     }
149 
150     c = find_config_next(c, c->next, CONF_PARAM, "DefaultRoot", FALSE);
151   }
152 
153   if (path) {
154     path = path_subst_uservar(p, &path);
155 
156     if (strncmp(path, "/", 2) == 0) {
157       path = NULL;
158 
159     } else {
160       char *real_path;
161       int xerrno = 0;
162 
163       PRIVS_USER
164       real_path = dir_realpath(p, path);
165       if (real_path == NULL) {
166         xerrno = errno;
167       }
168       PRIVS_RELINQUISH
169 
170       if (real_path) {
171         path = real_path;
172 
173       } else {
174         char interp_path[PR_TUNABLE_PATH_MAX + 1];
175 
176         memset(interp_path, '\0', sizeof(interp_path));
177         (void) pr_fs_interpolate(path, interp_path, sizeof(interp_path) - 1);
178 
179         pr_log_pri(PR_LOG_NOTICE,
180           "notice: unable to use DefaultRoot %s (resolved to '%s'): %s",
181             path, interp_path,
182           strerror(xerrno));
183       }
184     }
185   }
186 
187   return path;
188 }
189 
set_userauth_methods(void)190 static void set_userauth_methods(void) {
191   config_rec *c;
192   register unsigned int i;
193 
194   if (auth_chains != NULL) {
195     return;
196   }
197 
198   auth_avail_meths = NULL;
199   auth_meths_enabled_flags = 0;
200 
201   c = find_config(main_server->conf, CONF_PARAM, "SFTPAuthMethods", FALSE);
202   if (c != NULL) {
203     /* Sanity checking of the configured methods is done in the postparse
204      * event listener; we can use this as-is without fear.
205      */
206     auth_chains = c->argv[0];
207 
208   } else {
209     struct sftp_auth_chain *auth_chain;
210 
211     auth_chains = make_array(auth_pool, 0, sizeof(struct sftp_auth_chain *));
212 
213     c = find_config(main_server->conf, CONF_PARAM, "SFTPAuthorizedUserKeys",
214       FALSE);
215     if (c != NULL) {
216       auth_chain = sftp_auth_chain_alloc(auth_pool);
217       sftp_auth_chain_add_method(auth_chain, SFTP_AUTH_FL_METH_PUBLICKEY,
218         "publickey", NULL);
219       *((struct sftp_auth_chain **) push_array(auth_chains)) = auth_chain;
220 
221     } else {
222       pr_trace_msg(trace_channel, 9, "no SFTPAuthorizedUserKeys configured, "
223         "not offering 'publickey' authentication");
224     }
225 
226     c = find_config(main_server->conf, CONF_PARAM, "SFTPAuthorizedHostKeys",
227       FALSE);
228     if (c != NULL) {
229       auth_chain = sftp_auth_chain_alloc(auth_pool);
230       sftp_auth_chain_add_method(auth_chain, SFTP_AUTH_FL_METH_HOSTBASED,
231         "hostbased", NULL);
232       *((struct sftp_auth_chain **) push_array(auth_chains)) = auth_chain;
233 
234     } else {
235       pr_trace_msg(trace_channel, 9, "no SFTPAuthorizedHostKeys configured, "
236         "not offering 'hostbased' authentication");
237     }
238 
239     if (sftp_kbdint_have_drivers() > 0) {
240       auth_chain = sftp_auth_chain_alloc(auth_pool);
241       sftp_auth_chain_add_method(auth_chain, SFTP_AUTH_FL_METH_KBDINT,
242         "keyboard-interactive", NULL);
243       *((struct sftp_auth_chain **) push_array(auth_chains)) = auth_chain;
244 
245     } else {
246       pr_trace_msg(trace_channel, 9, "no kbdint drivers present, not "
247         "offering 'keyboard-interactive' authentication");
248     }
249 
250     /* The 'password' method is always available. */
251     auth_chain = sftp_auth_chain_alloc(auth_pool);
252     sftp_auth_chain_add_method(auth_chain, SFTP_AUTH_FL_METH_PASSWORD,
253       "password", NULL);
254     *((struct sftp_auth_chain **) push_array(auth_chains)) = auth_chain;
255   }
256 
257   for (i = 0 ; i < auth_chains->nelts; i++) {
258     struct sftp_auth_chain *auth_chain;
259     struct sftp_auth_method *meth;
260 
261     auth_chain = ((struct sftp_auth_chain **) auth_chains->elts)[i];
262     meth = ((struct sftp_auth_method **) auth_chain->methods->elts)[0];
263 
264     if (!(auth_meths_enabled_flags & meth->method_id)) {
265       auth_meths_enabled_flags |= meth->method_id;
266 
267       if (auth_avail_meths != NULL) {
268         auth_avail_meths = pstrcat(auth_pool, auth_avail_meths, ",",
269           meth->method_name, NULL);
270       } else {
271         auth_avail_meths = meth->method_name;
272       }
273     }
274   }
275 
276   pr_trace_msg(trace_channel, 9, "offering authentication methods: %s",
277     auth_avail_meths);
278 
279   /* Prepare the method-specific APIs, too. */
280   if (sftp_auth_hostbased_init(auth_pool) < 0) {
281     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
282       "error preparing for 'hostbased' authentication: %s", strerror(errno));
283   }
284 
285   if (sftp_auth_kbdint_init(auth_pool) < 0) {
286     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
287       "error preparing for 'keyboard-interactive' authentication: %s",
288       strerror(errno));
289   }
290 
291   if (sftp_auth_password_init(auth_pool) < 0) {
292     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
293       "error preparing for 'password' authentication: %s", strerror(errno));
294   }
295 
296   if (sftp_auth_publickey_init(auth_pool) < 0) {
297     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
298       "error preparing for 'publickey' authentication: %s", strerror(errno));
299   }
300 }
301 
setup_env(pool * p,const char * user)302 static int setup_env(pool *p, const char *user) {
303   struct passwd *pw;
304   config_rec *c;
305   int login_acl, i, res, root_revoke = TRUE, show_symlinks = FALSE, xerrno;
306   struct stat st;
307   const char *default_chdir, *default_root, *home_dir;
308   const char *sess_ttyname = NULL, *xferlog = NULL;
309   cmd_rec *cmd;
310 
311   session.hide_password = TRUE;
312 
313   pw = pr_auth_getpwnam(p, user);
314   if (pw == NULL) {
315     xerrno = errno;
316 
317     /* This is highly unlikely to happen...*/
318     pr_log_auth(PR_LOG_NOTICE,
319       "USER %s (Login failed): Unable to retrieve user information: %s", user,
320       strerror(xerrno));
321 
322     errno = xerrno;
323     return -1;
324   }
325 
326   pw = dup_passwd(p, pw);
327 
328   if (pw->pw_uid == PR_ROOT_UID) {
329     pr_event_generate("mod_auth.root-login", NULL);
330 
331     c = find_config(main_server->conf, CONF_PARAM, "RootLogin", FALSE);
332     if (c) {
333       if (*((int *) c->argv[0]) == FALSE) {
334         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
335           "root login attempted, denied by RootLogin configuration");
336         pr_log_auth(PR_LOG_NOTICE, "SECURITY VIOLATION: Root login attempted");
337         return -1;
338       }
339 
340     } else {
341       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
342         "root login attempted, denied by RootLogin configuration");
343       pr_log_auth(PR_LOG_NOTICE, "SECURITY VIOLATION: Root login attempted");
344       return -1;
345     }
346   }
347 
348   res = pr_auth_is_valid_shell(main_server->conf, pw->pw_shell);
349   if (res == FALSE) {
350     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
351       "authentication for user '%s' failed: Invalid shell", user);
352     pr_log_auth(PR_LOG_NOTICE, "USER %s (Login failed): Invalid shell: '%s'",
353       user, pw->pw_shell);
354     return -1;
355   }
356 
357   res = pr_auth_banned_by_ftpusers(main_server->conf, pw->pw_name);
358   if (res == TRUE) {
359     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
360       "authentication for user '%s' failed: User in " PR_FTPUSERS_PATH, user);
361     pr_log_auth(PR_LOG_NOTICE, "USER %s (Login failed): User in "
362       PR_FTPUSERS_PATH, pw->pw_name);
363     return -1;
364   }
365 
366   session.user = pstrdup(p, pw->pw_name);
367   session.group = pstrdup(p, pr_auth_gid2name(p, pw->pw_gid));
368 
369   session.login_uid = pw->pw_uid;
370   session.login_gid = pw->pw_gid;
371 
372   /* Note that we do NOT need to explicitly call pr_auth_get_home() here;
373    * that call already happens in the pr_auth_getpwnam() call above.  To
374    * call it again here would cause the home directory to be rewritten twice;
375    * depending on the configured rewrite rules, that would lead to an
376    * incorrect value (Bug#3421).
377    */
378 
379   pw->pw_dir = (char *) path_subst_uservar(p, (const char **) &pw->pw_dir);
380 
381   if (session.gids == NULL &&
382       session.groups == NULL) {
383     res = pr_auth_getgroups(p, pw->pw_name, &session.gids, &session.groups);
384     if (res < 1) {
385       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
386         "no supplemental groups found for user '%s'", pw->pw_name);
387     }
388   }
389 
390   login_acl = login_check_limits(main_server->conf, FALSE, TRUE, &i);
391   if (!login_acl) {
392     pr_log_auth(PR_LOG_NOTICE, "USER %s (Login failed): Limit configuration "
393       "denies login", user);
394     return -1;
395   }
396 
397   PRIVS_USER
398   home_dir = dir_realpath(p, pw->pw_dir);
399   PRIVS_RELINQUISH
400 
401   if (home_dir != NULL) {
402     sstrncpy(session.cwd, home_dir, sizeof(session.cwd));
403 
404   } else {
405     sstrncpy(session.cwd, pw->pw_dir, sizeof(session.cwd));
406   }
407 
408   c = find_config(main_server->conf, CONF_PARAM, "CreateHome", FALSE);
409   if (c != NULL) {
410     if (*((unsigned char *) c->argv[0]) == TRUE) {
411       if (create_home(p, session.cwd, user, pw->pw_uid, pw->pw_gid) < 0) {
412         return -1;
413       }
414     }
415   }
416 
417   default_chdir = get_default_chdir(p);
418   if (default_chdir != NULL) {
419     default_chdir = dir_abs_path(p, default_chdir, TRUE);
420     sstrncpy(session.cwd, default_chdir, sizeof(session.cwd));
421   }
422 
423   /* Make sure any <Limit LOGIN> sections still allow access. */
424   login_acl = login_check_limits(main_server->conf, FALSE, TRUE, &i);
425   if (!login_acl) {
426     pr_log_auth(PR_LOG_NOTICE, "USER %s: Limit configuration denies login",
427       user);
428     return -1;
429   }
430 
431   resolve_deferred_dirs(main_server);
432   fixup_dirs(main_server, CF_DEFER);
433 
434   session.wtmp_log = TRUE;
435 
436   c = find_config(main_server->conf, CONF_PARAM, "WtmpLog", FALSE);
437   if (c &&
438       *((unsigned char *) c->argv[0]) == FALSE) {
439     session.wtmp_log = FALSE;
440   }
441 
442   /* As per Bug#3482, we need to disable WtmpLog for FreeBSD 9.0, as
443    * an interim measure.
444    *
445    * The issue is that some platforms update multiple files for a single
446    * pututxline(3) call; proftpd tries to update those files manually,
447    * do to chroots (after which a pututxline(3) call will fail).  A proper
448    * solution requires a separate process, running with the correct
449    * privileges, which would handle wtmp logging. The proftpd session
450    * processes would send messages to this logging daemon (via Unix domain
451    * socket, or FIFO, or TCP socket).
452    *
453    * Also note that this hack to disable WtmpLog may need to be extended
454    * to other platforms in the future.
455    */
456 #if defined(HAVE_UTMPX_H) && \
457     defined(__FreeBSD_version) && __FreeBSD_version >= 900007
458   if (session.wtmp_log == TRUE) {
459     session.wtmp_log = FALSE;
460 
461     pr_log_debug(DEBUG5,
462       "WtpmLog automatically disabled; see Bug#3482 for details");
463   }
464 #endif
465 
466   PRIVS_ROOT
467 
468   if (session.wtmp_log) {
469     sess_ttyname = pr_session_get_ttyname(p);
470 
471     log_wtmp(sess_ttyname, session.user, session.c->remote_name,
472       session.c->remote_addr);
473   }
474 
475 #ifdef PR_USE_LASTLOG
476   c = find_config(main_server->conf, CONF_PARAM, "UseLastlog", FALSE);
477   if (c &&
478       *((unsigned char *) c->argv[0]) == TRUE) {
479     if (sess_ttyname == NULL) {
480       sess_ttyname = pr_session_get_ttyname(p);
481     }
482 
483     log_lastlog(pw->pw_uid, session.user, sess_ttyname,
484       session.c->remote_addr);
485   }
486 #endif /* PR_USE_LASTLOG */
487 
488   c = find_config(main_server->conf, CONF_PARAM, "TransferLog", FALSE);
489   if (c == NULL) {
490     xferlog = PR_XFERLOG_PATH;
491 
492   } else {
493     xferlog = c->argv[0];
494   }
495 
496   if (strncasecmp(xferlog, "none", 5) == 0) {
497     xferlog_open(NULL);
498 
499   } else {
500     xferlog_open(xferlog);
501   }
502 
503   res = set_groups(p, pw->pw_gid, session.gids);
504   xerrno = errno;
505   PRIVS_RELINQUISH
506 
507   if (res < 0) {
508     if (xerrno != ENOSYS) {
509       pr_log_pri(PR_LOG_WARNING, "unable to set process groups: %s",
510         strerror(xerrno));
511     }
512   }
513 
514   default_root = get_default_root(session.pool);
515   if (default_root) {
516     ensure_open_passwd(p);
517 
518     if (pr_auth_chroot(default_root) < 0) {
519       pr_log_pri(PR_LOG_WARNING, "unable to set DefaultRoot directory '%s'",
520         default_root);
521       return -1;
522     }
523 
524     if (strncmp(session.cwd, default_root, strlen(default_root)) == 0) {
525       char *new_cwd;
526 
527       new_cwd = &session.cwd[strlen(default_root)];
528 
529       if (*new_cwd == '/') {
530         new_cwd++;
531       }
532       session.cwd[0] = '/';
533 
534       sstrncpy(&session.cwd[1], new_cwd, sizeof(session.cwd));
535     }
536   }
537 
538   pr_signals_block();
539   PRIVS_ROOT
540   PRIVS_SETUP(pw->pw_uid, pw->pw_gid)
541   pr_signals_unblock();
542 
543   /* Should we give up root privs completely here? */
544   c = find_config(main_server->conf, CONF_PARAM, "RootRevoke", FALSE);
545   if (c != NULL) {
546     root_revoke = *((int *) c->argv[0]);
547 
548     if (root_revoke == FALSE) {
549       pr_log_debug(DEBUG8, MOD_SFTP_VERSION
550         ": retaining root privileges per RootRevoke setting");
551     }
552 
553   } else {
554     /* Do a recursive look for any UserOwner directives; honoring that
555      * configuration also requires root privs.
556      */
557     c = find_config(main_server->conf, CONF_PARAM, "UserOwner", TRUE);
558     if (c != NULL) {
559       pr_log_debug(DEBUG9, MOD_SFTP_VERSION
560         ": retaining root privileges per UserOwner setting");
561       root_revoke = FALSE;
562     }
563   }
564 
565   if (root_revoke) {
566     PRIVS_ROOT
567     PRIVS_REVOKE
568     session.disable_id_switching = TRUE;
569   }
570 
571 #ifdef HAVE_GETEUID
572   if (getegid() != pw->pw_gid ||
573       geteuid() != pw->pw_uid) {
574     pr_log_pri(PR_LOG_WARNING,
575       "process effective IDs do not match expected IDs");
576     return -1;
577   }
578 #endif
579 
580   if (pw->pw_dir == NULL ||
581       strncmp(pw->pw_dir, "", 1) == 0) {
582     pr_log_pri(PR_LOG_WARNING, "Home directory for user '%s' is NULL/empty",
583       session.user);
584     return -1;
585   }
586 
587   c = find_config(main_server->conf, CONF_PARAM, "ShowSymlinks", FALSE);
588   if (c) {
589     if (*((unsigned char *) c->argv[0]) == TRUE) {
590       show_symlinks = TRUE;
591     }
592   }
593 
594   if (pr_fsio_chdir_canon(session.cwd, !show_symlinks) < 0) {
595     xerrno = errno;
596 
597     if (session.chroot_path != NULL ||
598         default_root != NULL) {
599 
600       pr_log_debug(DEBUG2, "unable to chdir to %s (%s), defaulting to chroot "
601         "directory %s", session.cwd, strerror(xerrno),
602         (session.chroot_path ? session.chroot_path : default_root));
603 
604       if (pr_fsio_chdir_canon("/", !show_symlinks) == -1) {
605         xerrno = errno;
606 
607         pr_log_pri(PR_LOG_NOTICE, "%s chdir(\"/\") failed: %s", session.user,
608           strerror(xerrno));
609         errno = xerrno;
610         return -1;
611       }
612 
613     } else if (default_chdir) {
614       pr_log_debug(DEBUG2, "unable to chdir to %s (%s), defaulting to home "
615         "directory %s", session.cwd, strerror(errno), pw->pw_dir);
616 
617       if (pr_fsio_chdir_canon(pw->pw_dir, !show_symlinks) == -1) {
618         xerrno = errno;
619 
620         pr_log_pri(PR_LOG_NOTICE, "%s chdir(\"%s\") failed: %s", session.user,
621           session.cwd, strerror(xerrno));
622         errno = xerrno;
623         return -1;
624       }
625 
626     } else {
627       pr_log_pri(PR_LOG_NOTICE, "%s chdir(\"%s\") failed: %s", session.user,
628         session.cwd, strerror(xerrno));
629       errno = xerrno;
630       return -1;
631     }
632 
633   } else {
634     pr_log_debug(DEBUG10, "changed directory to '%s'", session.cwd);
635   }
636 
637   sstrncpy(session.cwd, pr_fs_getcwd(), sizeof(session.cwd));
638   sstrncpy(session.vwd, pr_fs_getvwd(), sizeof(session.vwd));
639 
640   /* Make sure directory config pointers are set correctly */
641   cmd = pr_cmd_alloc(p, 1, C_PASS);
642   cmd->cmd_class = CL_AUTH|CL_SSH;
643   cmd->arg = "";
644   dir_check_full(p, cmd, G_NONE, session.cwd, NULL);
645 
646   session.proc_prefix = pstrdup(session.pool, session.c->remote_name);
647   session.sf_flags = 0;
648 
649   pr_log_auth(PR_LOG_INFO, "USER %s: Login successful", user);
650 
651   if (pw->pw_uid == PR_ROOT_UID) {
652     pr_log_auth(PR_LOG_WARNING, "ROOT SFTP login successful");
653   }
654 
655   if (pr_fsio_stat(session.cwd, &st) != -1) {
656     build_dyn_config(p, session.cwd, &st, TRUE);
657   }
658 
659   pr_scoreboard_entry_update(session.pid,
660     PR_SCORE_USER, session.user,
661     PR_SCORE_CWD, session.cwd,
662     NULL);
663 
664   pr_timer_remove(PR_TIMER_LOGIN, ANY_MODULE);
665 
666   auth_default_dir = pstrdup(session.pool, pr_fs_getvwd());
667 
668   session.user = pstrdup(session.pool, session.user);
669 
670   if (session.group) {
671     session.group = pstrdup(session.pool, session.group);
672   }
673 
674   session.groups = copy_array_str(session.pool, session.groups);
675 
676   pr_resolve_fs_map();
677   return 0;
678 }
679 
send_userauth_banner_file(void)680 static int send_userauth_banner_file(void) {
681   struct ssh2_packet *pkt;
682   char *path;
683   unsigned char *buf, *ptr;
684   const char *msg;
685   int res;
686   uint32_t buflen, bufsz;
687   config_rec *c;
688   pr_fh_t *fh;
689   pool *sub_pool;
690   struct stat st;
691 
692   if (auth_sent_userauth_banner_file) {
693     /* Already sent the banner; no need to do it again. */
694     return 0;
695   }
696 
697   c = find_config(main_server->conf, CONF_PARAM, "SFTPDisplayBanner", FALSE);
698   if (c == NULL) {
699     return 0;
700   }
701   path = c->argv[0];
702 
703   if (!sftp_interop_supports_feature(SFTP_SSH2_FEAT_USERAUTH_BANNER)) {
704     pr_trace_msg(trace_channel, 3, "unable to send SFTPDisplayBanner '%s': "
705       "USERAUTH_BANNER supported by client", path);
706     return 0;
707   }
708 
709   fh = pr_fsio_open_canon(path, O_RDONLY);
710   if (fh == NULL) {
711     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
712       "error opening SFTPDisplayBanner '%s': %s", path, strerror(errno));
713     return 0;
714   }
715 
716   res = pr_fsio_fstat(fh, &st);
717   if (res < 0) {
718     int xerrno = errno;
719 
720     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
721       "unable to stat SFTPDisplayBanner '%s': %s", path, strerror(xerrno));
722 
723     pr_fsio_close(fh);
724     return 0;
725   }
726 
727   if (S_ISDIR(st.st_mode)) {
728     int xerrno = EISDIR;
729 
730     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
731       "unable to use SFTPDisplayBanner '%s': %s", path, strerror(xerrno));
732 
733     pr_fsio_close(fh);
734     return 0;
735   }
736 
737   sub_pool = make_sub_pool(auth_pool);
738   pr_pool_tag(sub_pool, "SSH2 auth banner pool");
739 
740   msg = sftp_display_fh_get_msg(sub_pool, fh);
741   pr_fsio_close(fh);
742 
743   if (msg == NULL) {
744     destroy_pool(sub_pool);
745     return -1;
746   }
747 
748   pr_trace_msg(trace_channel, 3,
749     "sending userauth banner from SFTPDisplayBanner file '%s'", path);
750 
751   pkt = sftp_ssh2_packet_create(sub_pool);
752 
753   buflen = bufsz = strlen(msg) + 32;
754   ptr = buf = palloc(pkt->pool, bufsz);
755 
756   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_USER_AUTH_BANNER);
757   sftp_msg_write_string(&buf, &buflen, msg);
758 
759   /* XXX locale of banner */
760   sftp_msg_write_string(&buf, &buflen, "");
761 
762   pkt->payload = ptr;
763   pkt->payload_len = (bufsz - buflen);
764 
765   res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
766   destroy_pool(pkt->pool);
767 
768   if (res < 0) {
769     destroy_pool(sub_pool);
770     return -1;
771   }
772 
773   auth_sent_userauth_banner_file = TRUE;
774   destroy_pool(sub_pool);
775   return 0;
776 }
777 
send_userauth_failure(char * failed_meth)778 static int send_userauth_failure(char *failed_meth) {
779   struct ssh2_packet *pkt;
780   unsigned char *buf, *ptr;
781   char *meths;
782   uint32_t buflen, bufsz = 1024;
783   int res;
784 
785   pkt = sftp_ssh2_packet_create(auth_pool);
786 
787   if (failed_meth) {
788     register unsigned int i;
789 
790     auth_avail_meths = NULL;
791     auth_meths_enabled_flags = 0;
792 
793     for (i = 0 ; i < auth_chains->nelts; i++) {
794       register unsigned int j;
795       struct sftp_auth_chain *auth_chain;
796       struct sftp_auth_method *meth = NULL;
797 
798       pr_signals_handle();
799       auth_chain = ((struct sftp_auth_chain **) auth_chains->elts)[i];
800 
801       for (j = 0; j < auth_chain->methods->nelts; j++) {
802         struct sftp_auth_method *m;
803 
804         m = ((struct sftp_auth_method **) auth_chain->methods->elts)[j];
805         if (m->succeeded != TRUE &&
806             m->failed != TRUE) {
807           meth = m;
808           break;
809         }
810       }
811 
812       if (meth == NULL) {
813         /* All of the methods in this list have failed; check the next
814          * list.
815          */
816         continue;
817       }
818 
819       if (strcmp(meth->method_name, failed_meth) != 0) {
820         if (!(auth_meths_enabled_flags & meth->method_id)) {
821           auth_meths_enabled_flags |= meth->method_id;
822 
823           if (auth_avail_meths != NULL) {
824             auth_avail_meths = pstrcat(auth_pool, auth_avail_meths, ",",
825               meth->method_name, NULL);
826           } else {
827             auth_avail_meths = meth->method_name;
828           }
829         }
830       } else {
831         meth->failed = TRUE;
832       }
833     }
834 
835     if (auth_avail_meths == NULL) {
836       /* If there are no more auth methods available, we have to disconnect. */
837       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
838         "no more auth methods available, disconnecting");
839       SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
840         NULL);
841     }
842 
843   } else {
844     if (auth_avail_meths == NULL) {
845       /* This situation can happen when the authentication method succeeded,
846        * BUT the subsequent login actions failed (such as failing to chroot,
847        * no such home directory, etc etc).  But we still need a list
848        * of authentication methods to send back to the client in this message;
849        * we thus use the empty string.
850        */
851       auth_avail_meths = "";
852     }
853   }
854 
855   meths = pstrdup(pkt->pool, auth_avail_meths);
856 
857   buflen = bufsz;
858   ptr = buf = palloc(pkt->pool, bufsz);
859 
860   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_USER_AUTH_FAILURE);
861   sftp_msg_write_string(&buf, &buflen, meths);
862   sftp_msg_write_bool(&buf, &buflen, FALSE);
863 
864   pkt->payload = ptr;
865   pkt->payload_len = (bufsz - buflen);
866 
867   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
868     "sending userauth failure; remaining userauth methods: %s", meths);
869 
870   res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
871   if (res < 0) {
872     destroy_pool(pkt->pool);
873     return -1;
874   }
875 
876   return 0;
877 }
878 
send_userauth_success(void)879 static int send_userauth_success(void) {
880   struct ssh2_packet *pkt;
881   unsigned char *buf, *ptr;
882   uint32_t buflen, bufsz = 1024;
883   int res;
884 
885   if (auth_sent_userauth_success) {
886     return 0;
887   }
888 
889   pkt = sftp_ssh2_packet_create(auth_pool);
890 
891   buflen = bufsz;
892   ptr = buf = palloc(pkt->pool, bufsz);
893 
894   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_USER_AUTH_SUCCESS);
895 
896   pkt->payload = ptr;
897   pkt->payload_len = (bufsz - buflen);
898 
899   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
900     "sending userauth success");
901 
902   res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
903   if (res < 0) {
904     destroy_pool(pkt->pool);
905     return -1;
906   }
907 
908   auth_sent_userauth_success = TRUE;
909 
910   /* We call the compression init routines here as well, in case the
911    * client selected "delayed" compression.
912    */
913   sftp_compress_init_read(SFTP_COMPRESS_FL_AUTHENTICATED);
914   sftp_compress_init_write(SFTP_COMPRESS_FL_AUTHENTICATED);
915 
916   return 0;
917 }
918 
set_userauth_success(const char * succeeded_meth)919 static int set_userauth_success(const char *succeeded_meth) {
920   register unsigned int i;
921   int completed = FALSE;
922 
923   auth_avail_meths = NULL;
924   auth_meths_enabled_flags = 0;
925 
926   for (i = 0 ; i < auth_chains->nelts; i++) {
927     register unsigned int j;
928     struct sftp_auth_chain *auth_chain;
929 
930     pr_signals_handle();
931     auth_chain = ((struct sftp_auth_chain **) auth_chains->elts)[i];
932 
933     for (j = 0; j < auth_chain->methods->nelts; j++) {
934       struct sftp_auth_method *meth = NULL;
935 
936       meth = ((struct sftp_auth_method **) auth_chain->methods->elts)[j];
937       if (meth->succeeded != TRUE &&
938           meth->failed != TRUE) {
939 
940         if (strcmp(meth->method_name, succeeded_meth) == 0) {
941           /* TODO: What about submethods, for kbdint drivers? */
942           meth->succeeded = TRUE;
943         }
944 
945         /* Add the next method in the list (if any) to the available methods. */
946         j++;
947         if (j < auth_chain->methods->nelts) {
948           meth = ((struct sftp_auth_method **) auth_chain->methods->elts)[j];
949 
950           if (!(auth_meths_enabled_flags & meth->method_id)) {
951             auth_meths_enabled_flags |= meth->method_id;
952 
953             if (auth_avail_meths != NULL) {
954               auth_avail_meths = pstrcat(auth_pool, auth_avail_meths, ",",
955                 meth->method_name, NULL);
956             } else {
957               auth_avail_meths = meth->method_name;
958             }
959           }
960         }
961 
962         break;
963       }
964     }
965   }
966 
967   /* Now, having marked the list items that have succeeded, check each list
968    * to see if any has been completed.
969    */
970 
971   for (i = 0 ; i < auth_chains->nelts; i++) {
972     register unsigned int j;
973     struct sftp_auth_chain *auth_chain;
974     int ok = TRUE;
975 
976     pr_signals_handle();
977     auth_chain = ((struct sftp_auth_chain **) auth_chains->elts)[i];
978 
979     for (j = 0; j < auth_chain->methods->nelts; j++) {
980       struct sftp_auth_method *meth = NULL;
981 
982       meth = ((struct sftp_auth_method **) auth_chain->methods->elts)[j];
983       if (meth->succeeded != TRUE) {
984         ok = FALSE;
985         break;
986       }
987     }
988 
989     if (ok == TRUE) {
990       /* We have a successfully completed list! */
991       auth_chain->completed = completed = TRUE;
992       break;
993     }
994   }
995 
996   if (completed == TRUE) {
997     return 1;
998   }
999 
1000   if (auth_avail_meths == NULL) {
1001     /* If there are no more auth methods available, we have to disconnect. */
1002     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1003       "no more auth methods available, disconnecting");
1004     SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
1005       NULL);
1006   }
1007 
1008   return 0;
1009 }
1010 
send_userauth_methods(char partial_success)1011 static int send_userauth_methods(char partial_success) {
1012   struct ssh2_packet *pkt;
1013   unsigned char *buf, *ptr;
1014   uint32_t buflen, bufsz = 1024;
1015   int res;
1016 
1017   pkt = sftp_ssh2_packet_create(auth_pool);
1018 
1019   buflen = bufsz;
1020   ptr = buf = palloc(pkt->pool, bufsz);
1021 
1022   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1023     "sending acceptable userauth methods: %s", auth_avail_meths);
1024 
1025   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_USER_AUTH_FAILURE);
1026   sftp_msg_write_string(&buf, &buflen, auth_avail_meths);
1027   sftp_msg_write_bool(&buf, &buflen, partial_success);
1028 
1029   pkt->payload = ptr;
1030   pkt->payload_len = (bufsz - buflen);
1031 
1032   res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
1033   if (res < 0) {
1034     destroy_pool(pkt->pool);
1035     return -1;
1036   }
1037 
1038   return 0;
1039 }
1040 
add_cmd_note(cmd_rec * cmd,const char * key,const char * val)1041 static void add_cmd_note(cmd_rec *cmd, const char *key, const char *val) {
1042   int res;
1043 
1044   res = pr_table_add(cmd->notes, key, val, 0);
1045   if (res < 0 &&
1046       errno != EEXIST) {
1047     pr_trace_msg(trace_channel, 19, "error adding '%s' command note: %s",
1048       key, strerror(errno));
1049   }
1050 }
1051 
remove_cmd_note(cmd_rec * cmd,const char * key)1052 static void remove_cmd_note(cmd_rec *cmd, const char *key) {
1053   (void) pr_table_remove(cmd->notes, key, NULL);
1054 }
1055 
dispatch_cmd_err(cmd_rec * cmd)1056 static void dispatch_cmd_err(cmd_rec *cmd) {
1057   pr_response_add_err(R_530, "Login incorrect.");
1058   pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1059   pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1060   pr_response_clear(&resp_err_list);
1061 }
1062 
dispatch_nonfatal_pass(cmd_rec * cmd,const char * method)1063 static void dispatch_nonfatal_pass(cmd_rec *cmd, const char *method) {
1064   const char *note = "mod_sftp.nonfatal-attempt";
1065 
1066   add_cmd_note(cmd, note, method);
1067   dispatch_cmd_err(cmd);
1068   remove_cmd_note(cmd, note);
1069 }
1070 
incr_auth_attempts(const char * user,cmd_rec * pass_cmd)1071 static void incr_auth_attempts(const char *user, cmd_rec *pass_cmd) {
1072   auth_attempts++;
1073 
1074   if (auth_attempts_max > 0 &&
1075       auth_attempts >= auth_attempts_max) {
1076     pr_log_auth(PR_LOG_NOTICE,
1077       "Maximum login attempts (%u) exceeded, connection refused",
1078       auth_attempts_max);
1079     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1080       "Maximum login attempts (%u) exceeded, refusing connection for user '%s'",
1081       auth_attempts_max, user);
1082 
1083     /* Ensure that the "mod_auth.orig_user" session note exists before
1084      * dispatching to the PASS error handlers.  Some of them look for this
1085      * session note (Issue #693).
1086      */
1087     if (pr_table_add_dup(session.notes, "mod_auth.orig-user", user, 0) < 0 &&
1088         errno != EEXIST) {
1089       pr_log_debug(DEBUG3, "error stashing 'mod_auth.orig-user' in "
1090         "session.notes: %s", strerror(errno));
1091     }
1092 
1093     dispatch_cmd_err(pass_cmd);
1094     pr_event_generate("mod_auth.max-login-attempts", session.c);
1095     SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
1096   }
1097 }
1098 
1099 /* Return -1 on error, 0 to continue, and 1 if the authentication succeeded. */
handle_userauth_req(struct ssh2_packet * pkt,char ** service)1100 static int handle_userauth_req(struct ssh2_packet *pkt, char **service) {
1101   unsigned char *buf;
1102   const char *orig_user, *user;
1103   char *method;
1104   uint32_t buflen;
1105   cmd_rec *cmd, *user_cmd, *pass_cmd;
1106   int res, send_userauth_fail = FALSE;
1107   config_rec *c;
1108 
1109   buf = pkt->payload;
1110   buflen = pkt->payload_len;
1111 
1112   orig_user = sftp_msg_read_string(pkt->pool, &buf, &buflen);
1113 
1114   user_cmd = pr_cmd_alloc(pkt->pool, 2, pstrdup(pkt->pool, C_USER), orig_user);
1115   user_cmd->cmd_class = CL_AUTH|CL_SSH;
1116   user_cmd->arg = (char *) orig_user;
1117 
1118   pass_cmd = pr_cmd_alloc(pkt->pool, 1, pstrdup(pkt->pool, C_PASS));
1119   pass_cmd->cmd_class = CL_AUTH|CL_SSH;
1120   pass_cmd->arg = pstrdup(pkt->pool, "(hidden)");
1121 
1122   /* Dispatch these as PRE_CMDs, so that mod_delay's tactics can be used
1123    * to ameliorate any timing-based attacks.
1124    */
1125   if (pr_cmd_dispatch_phase(user_cmd, PRE_CMD, 0) < 0) {
1126     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1127       "authentication request for user '%s' blocked by '%s' handler",
1128       orig_user, (char *) user_cmd->argv[0]);
1129 
1130     dispatch_cmd_err(user_cmd);
1131     return -1;
1132   }
1133 
1134   if (strcmp(orig_user, user_cmd->arg) == 0) {
1135     user = orig_user;
1136 
1137   } else {
1138     user = user_cmd->arg;
1139   }
1140 
1141   if (auth_user != NULL) {
1142     /* Check to see if the client has requested a different user name in
1143      * this USERAUTH_REQUEST.  As per Section 5 of RFC4252, if the user
1144      * name changes, we can disconnect the client.
1145      */
1146     if (strcmp(orig_user, auth_user) != 0) {
1147       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1148         "client used different user name '%s' in USERAUTH_REQUEST (was '%s'), "
1149         "disconnecting", orig_user, auth_user);
1150 
1151       dispatch_cmd_err(user_cmd);
1152       return -1;
1153     }
1154 
1155   } else {
1156     auth_user = pstrdup(auth_pool, orig_user);
1157   }
1158 
1159   *service = sftp_msg_read_string(pkt->pool, &buf, &buflen);
1160   if (auth_service != NULL) {
1161     /* Check to see if the client has requested a different service name in
1162      * this USERAUTH_REQUEST.  As per Section 5 of RFC4252, if the service
1163      * name changes, we can disconnect the client.
1164      */
1165     if (strcmp(*service, auth_service) != 0) {
1166       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1167         "client used different service name '%s' in USERAUTH_REQUEST (was "
1168         "'%s'), disconnecting", *service, auth_service);
1169 
1170       dispatch_cmd_err(user_cmd);
1171       return -1;
1172     }
1173 
1174   } else {
1175 
1176     /* Check to see if the requested service is one that we support.
1177      *
1178      * As far as I can tell, the only defined 'service names' are:
1179      *
1180      *  ssh-userauth (RFC4252)
1181      *  ssh-connection (RFC4254)
1182      *
1183      * If the requested service name is NOT one of the above,
1184      * we should disconnect, as recommended by RFC4252.
1185      */
1186 
1187     if (strncmp(*service, "ssh-userauth", 13) == 0 ||
1188         strncmp(*service, "ssh-connection", 15) == 0) {
1189       auth_service = pstrdup(auth_pool, *service);
1190 
1191     } else {
1192       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1193         "client requested unknown/unsupported service name '%s' in "
1194         "USERAUTH_REQUEST, disconnecting", *service);
1195 
1196       dispatch_cmd_err(user_cmd);
1197       return -1;
1198     }
1199   }
1200 
1201   pr_response_add(R_331, "Password required for %s", user);
1202   pr_cmd_dispatch_phase(user_cmd, POST_CMD, 0);
1203   pr_cmd_dispatch_phase(user_cmd, LOG_CMD, 0);
1204   pr_response_clear(&resp_list);
1205 
1206   method = sftp_msg_read_string(pkt->pool, &buf, &buflen);
1207 
1208   pr_trace_msg(trace_channel, 10, "auth requested for user '%s', service '%s', "
1209     "using method '%s'", user, *service, method);
1210 
1211   (void) pr_table_remove(session.notes, "mod_auth.orig-user", NULL);
1212   if (pr_table_add_dup(session.notes, "mod_auth.orig-user", user, 0) < 0 &&
1213       errno != EEXIST) {
1214     pr_log_debug(DEBUG3, "error stashing 'mod_auth.orig-user' in "
1215       "session.notes: %s", strerror(errno));
1216   }
1217 
1218   cmd = pr_cmd_alloc(pkt->pool, 3, pstrdup(pkt->pool, "USERAUTH_REQUEST"),
1219     pstrdup(pkt->pool, user), pstrdup(pkt->pool, method));
1220   cmd->arg = pstrcat(pkt->pool, user, " ", method, NULL);
1221   cmd->cmd_class = CL_AUTH|CL_SSH;
1222 
1223   if (auth_attempts_max > 0 &&
1224       auth_attempts > auth_attempts_max) {
1225     pr_log_auth(PR_LOG_NOTICE,
1226       "Maximum login attempts (%u) exceeded, connection refused",
1227       auth_attempts_max);
1228     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1229       "Maximum login attempts (%u) exceeded, refusing connection for user '%s'",
1230       auth_attempts_max, user);
1231 
1232     /* Ensure that the "mod_auth.orig_user" session note exists before
1233      * dispatching to the PASS error handlers.  Some of them look for this
1234      * session note (Issue #693).
1235      */
1236     if (pr_table_add_dup(session.notes, "mod_auth.orig-user", user, 0) < 0 &&
1237         errno != EEXIST) {
1238       pr_log_debug(DEBUG3, "error stashing 'mod_auth.orig-user' in "
1239         "session.notes: %s", strerror(errno));
1240     }
1241 
1242     dispatch_cmd_err(pass_cmd);
1243     pr_event_generate("mod_auth.max-login-attempts", session.c);
1244     SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
1245   }
1246 
1247   set_userauth_methods();
1248 
1249   /* Populate the environment for the requested authentication method,
1250    * so that it can be recorded regardless of success/failure.  Note that
1251    * the "none" method is not really expected by users, so we deliberately
1252    * skip/omit that value.
1253    */
1254   if (strcmp(method, "none") != 0) {
1255     pr_env_unset(cmd->pool, "SFTP_USER_AUTH_METHOD");
1256     pr_env_set(cmd->pool, "SFTP_USER_AUTH_METHOD", method);
1257     (void) pr_table_add_dup(session.notes, "SFTP_USER_AUTH_METHOD", method, 0);
1258   }
1259 
1260   /* In order for the actual user password (if any) to be populated properly
1261    * in the PRE_CMD PASS dispatch (e.g. this is needed for modules like
1262    * mod_radius; see Bug#3676), the PRE_CMD PASS dispatch needs to happen
1263    * in the method-specific auth functions, not here.
1264    *
1265    * Thus this code will look a little strange; the PRE_CMD PASS dispatching
1266    * happens in the auth-specific functions, but the POST/LOG_CMD PASS
1267    * dispatching will happen here.
1268    */
1269 
1270   if (strncmp(method, "none", 5) == 0) {
1271     /* If the client requested the "none" auth method at this point, then
1272      * the list of authentication methods supported by the server is being
1273      * queried.
1274      */
1275     if (send_userauth_methods(FALSE) < 0) {
1276       pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1277       pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1278       return -1;
1279     }
1280 
1281     pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
1282     pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1283     pr_response_clear(&resp_list);
1284 
1285     return 0;
1286 
1287   } else if (strncmp(method, "publickey", 10) == 0) {
1288     if (auth_meths_enabled_flags & SFTP_AUTH_FL_METH_PUBLICKEY) {
1289       int xerrno;
1290 
1291       res = sftp_auth_publickey(pkt, pass_cmd, orig_user, user, *service,
1292         &buf, &buflen, &send_userauth_fail);
1293       xerrno = errno;
1294 
1295       if (res < 0) {
1296         pr_event_generate("mod_sftp.ssh2.auth-publickey.failed", NULL);
1297 
1298       } else {
1299         pr_event_generate("mod_sftp.ssh2.auth-publickey", NULL);
1300       }
1301 
1302       errno = xerrno;
1303 
1304     } else {
1305       pr_trace_msg(trace_channel, 10, "auth method '%s' not enabled", method);
1306 
1307       if (send_userauth_methods(FALSE) < 0) {
1308         pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1309         pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1310         return -1;
1311       }
1312 
1313       pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
1314       pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1315 
1316       incr_auth_attempts(user, pass_cmd);
1317       return 0;
1318     }
1319 
1320   } else if (strncmp(method, "keyboard-interactive", 21) == 0) {
1321     if (auth_meths_enabled_flags & SFTP_AUTH_FL_METH_KBDINT) {
1322       int xerrno = errno;
1323 
1324       res = sftp_auth_kbdint(pkt, pass_cmd, orig_user, user, *service,
1325         &buf, &buflen, &send_userauth_fail);
1326       xerrno = errno;
1327 
1328       if (res < 0) {
1329         pr_event_generate("mod_sftp.ssh2.auth-kbdint.failed", NULL);
1330 
1331       } else {
1332         pr_event_generate("mod_sftp.ssh2.auth-kbdint", NULL);
1333       }
1334 
1335       errno = xerrno;
1336 
1337     } else {
1338       pr_trace_msg(trace_channel, 10, "auth method '%s' not enabled", method);
1339 
1340       if (send_userauth_methods(FALSE) < 0) {
1341         pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1342         pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1343         return -1;
1344       }
1345 
1346       pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
1347       pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1348 
1349       incr_auth_attempts(user, pass_cmd);
1350       return 0;
1351     }
1352 
1353   } else if (strncmp(method, "password", 9) == 0) {
1354     if (auth_meths_enabled_flags & SFTP_AUTH_FL_METH_PASSWORD) {
1355       int xerrno;
1356 
1357       res = sftp_auth_password(pkt, pass_cmd, orig_user, user, *service,
1358         &buf, &buflen, &send_userauth_fail);
1359       xerrno = errno;
1360 
1361       if (res < 0) {
1362         pr_event_generate("mod_sftp.ssh2.auth-password.failed", NULL);
1363 
1364       } else {
1365         pr_event_generate("mod_sftp.ssh2.auth-password", NULL);
1366       }
1367 
1368       errno = xerrno;
1369 
1370     } else {
1371       pr_trace_msg(trace_channel, 10, "auth method '%s' not enabled", method);
1372 
1373       if (send_userauth_methods(FALSE) < 0) {
1374         pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1375         pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1376         return -1;
1377       }
1378 
1379       pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
1380       pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1381 
1382       incr_auth_attempts(user, pass_cmd);
1383       return 0;
1384     }
1385 
1386   } else if (strncmp(method, "hostbased", 10) == 0) {
1387     if (auth_meths_enabled_flags & SFTP_AUTH_FL_METH_HOSTBASED) {
1388       int xerrno;
1389 
1390       res = sftp_auth_hostbased(pkt, pass_cmd, orig_user, user, *service,
1391         &buf, &buflen, &send_userauth_fail);
1392       xerrno = errno;
1393 
1394       if (res < 0) {
1395         pr_event_generate("mod_sftp.ssh2.auth-hostbased.failed", NULL);
1396 
1397       } else {
1398         pr_event_generate("mod_sftp.ssh2.auth-hostbased", NULL);
1399       }
1400 
1401       errno = xerrno;
1402 
1403     } else {
1404       pr_trace_msg(trace_channel, 10, "auth method '%s' not enabled", method);
1405 
1406       if (send_userauth_methods(FALSE) < 0) {
1407         pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1408         pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1409         return -1;
1410       }
1411 
1412       pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
1413       pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1414 
1415       incr_auth_attempts(user, pass_cmd);
1416       return 0;
1417     }
1418 
1419   } else {
1420     pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1421     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1422 
1423     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1424       "unsupported authentication method '%s' requested", method);
1425 
1426     incr_auth_attempts(user, pass_cmd);
1427     return 0;
1428   }
1429 
1430   /* Make sure that the password cmd_rec arg points back to the static
1431    * string for passwords.
1432    */
1433   pass_cmd->arg = pstrdup(pkt->pool, "(hidden)");
1434 
1435   if (res <= 0) {
1436     int xerrno = errno;
1437 
1438     /* For a failed authentication _attempt_ (but not yet a real error), we
1439      * attach a note to this fake PASS "error" command dispatch, so that
1440      * interested handlers can use it to determine if the command they receive
1441      * is a real error or not, for e.g. logging/accounting purposes
1442      * (Issue #693).
1443      */
1444     if (res < 0) {
1445       dispatch_cmd_err(pass_cmd);
1446 
1447     } else {
1448       dispatch_nonfatal_pass(pass_cmd, method);
1449     }
1450 
1451     pr_cmd_dispatch_phase(cmd, res == 0 ? POST_CMD : POST_CMD_ERR, 0);
1452     pr_cmd_dispatch_phase(cmd, res == 0 ? LOG_CMD : LOG_CMD_ERR, 0);
1453 
1454     if (send_userauth_fail) {
1455       errno = xerrno;
1456 
1457       if (send_userauth_failure(errno != EPERM ? NULL : method) < 0) {
1458         return -1;
1459       }
1460 
1461       incr_auth_attempts(user, pass_cmd);
1462     }
1463 
1464     return res;
1465   }
1466 
1467   res = set_userauth_success(method);
1468   if (res == 0) {
1469     pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
1470     pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1471 
1472     if (send_userauth_methods(TRUE) < 0) {
1473       return -1;
1474     }
1475 
1476     return res;
1477   }
1478 
1479   /* Past this point we will not call incr_auth_attempts(); the client has
1480    * successfully authenticated at this point, and should not be penalized
1481    * if an internal error causes the rest of the login process to fail.
1482    * Right?
1483    */
1484 
1485   if (setup_env(pkt->pool, user) < 0) {
1486     dispatch_cmd_err(pass_cmd);
1487 
1488     pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1489     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1490 
1491     if (send_userauth_failure(NULL) < 0) {
1492       return -1;
1493     }
1494 
1495     return 0;
1496   }
1497 
1498   if (send_userauth_success() < 0) {
1499     dispatch_cmd_err(pass_cmd);
1500 
1501     pr_cmd_dispatch_phase(cmd, POST_CMD_ERR, 0);
1502     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1503 
1504     return -1;
1505   }
1506 
1507   if (session.auth_mech != NULL) {
1508     pr_log_debug(DEBUG2, "user '%s' authenticated by %s", user,
1509       session.auth_mech);
1510   }
1511 
1512   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1513     "user '%s' authenticated via '%s' method", user, method);
1514 
1515   /* This allows for the %s response code LogFormat variable to be populated
1516    * in an AUTH ExtendedLog.
1517    */
1518   pr_response_add(R_230, "User %s logged in", user);
1519   pr_cmd_dispatch_phase(pass_cmd, POST_CMD, 0);
1520   pr_cmd_dispatch_phase(pass_cmd, LOG_CMD, 0);
1521   pr_response_clear(&resp_list);
1522 
1523   pr_cmd_dispatch_phase(cmd, POST_CMD, 0);
1524   pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1525 
1526   /* At this point, we can look up the Protocols config, which may have
1527    * been tweaked via mod_ifsession's user/group/class-specific sections.
1528    */
1529   c = find_config(main_server->conf, CONF_PARAM, "Protocols", FALSE);
1530   if (c != NULL) {
1531     register unsigned int i;
1532     unsigned int services = 0UL;
1533     array_header *protocols;
1534     char **elts;
1535 
1536     protocols = c->argv[0];
1537     elts = protocols->elts;
1538 
1539     for (i = 0; i < protocols->nelts; i++) {
1540       char *protocol;
1541 
1542       protocol = elts[i];
1543       if (protocol != NULL) {
1544         if (strncasecmp(protocol, "sftp", 5) == 0) {
1545           services |= SFTP_SERVICE_FL_SFTP;
1546 
1547         } else if (strncasecmp(protocol, "scp", 4) == 0) {
1548           services |= SFTP_SERVICE_FL_SCP;
1549 
1550         } else if (strncasecmp(protocol, "date", 5) == 0) {
1551           services |= SFTP_SERVICE_FL_SCP;
1552         }
1553       }
1554     }
1555 
1556     sftp_services = services;
1557   }
1558 
1559   return 1;
1560 }
1561 
1562 /* Auth Lists API */
sftp_auth_chain_alloc(pool * p)1563 struct sftp_auth_chain *sftp_auth_chain_alloc(pool *p) {
1564   pool *sub_pool;
1565   struct sftp_auth_chain *auth_chain;
1566 
1567   if (p == NULL) {
1568     errno = EINVAL;
1569     return NULL;
1570   }
1571 
1572   sub_pool = pr_pool_create_sz(p, 256);
1573   pr_pool_tag(sub_pool, "SSH2 Auth Chain Pool");
1574 
1575   auth_chain = pcalloc(sub_pool, sizeof(struct sftp_auth_chain));
1576   auth_chain->pool = sub_pool;
1577   auth_chain->methods = make_array(sub_pool, 1,
1578     sizeof(struct sftp_auth_method *));
1579   auth_chain->completed = FALSE;
1580 
1581   return auth_chain;
1582 }
1583 
1584 /* Check if 'password' or 'hostbased' methods appear multiple times in
1585  * this chain; if so, it's an invalid chain.  Multiple 'publickey' or
1586  * 'keyboard-interactive' methods are allowed, though.
1587  */
sftp_auth_chain_isvalid(struct sftp_auth_chain * auth_chain)1588 int sftp_auth_chain_isvalid(struct sftp_auth_chain *auth_chain) {
1589   register unsigned int i;
1590   int has_password = FALSE, has_hostbased = FALSE;
1591 
1592   for (i = 0; i < auth_chain->methods->nelts; i++) {
1593     struct sftp_auth_method *meth;
1594 
1595     meth = ((struct sftp_auth_method **) auth_chain->methods->elts)[i];
1596 
1597     switch (meth->method_id) {
1598       case SFTP_AUTH_FL_METH_PASSWORD:
1599         if (has_password == TRUE) {
1600           errno = EPERM;
1601           return -1;
1602         }
1603 
1604         has_password = TRUE;
1605         break;
1606 
1607       case SFTP_AUTH_FL_METH_HOSTBASED:
1608         if (has_hostbased == TRUE) {
1609           errno = EPERM;
1610           return -1;
1611         }
1612 
1613         has_hostbased = TRUE;
1614         break;
1615 
1616       case SFTP_AUTH_FL_METH_PUBLICKEY:
1617       case SFTP_AUTH_FL_METH_KBDINT:
1618       default:
1619         break;
1620     }
1621   }
1622 
1623   return 0;
1624 }
1625 
sftp_auth_chain_add_method(struct sftp_auth_chain * auth_chain,unsigned int method_id,const char * method_name,const char * submethod_name)1626 int sftp_auth_chain_add_method(struct sftp_auth_chain *auth_chain,
1627     unsigned int method_id, const char *method_name,
1628     const char *submethod_name) {
1629   struct sftp_auth_method *meth;
1630 
1631   if (auth_chain == NULL ||
1632       method_name == NULL) {
1633     errno = EINVAL;
1634     return -1;
1635   }
1636 
1637   /* We currently only allow submethod names for kbdint methods. */
1638   if (submethod_name != NULL &&
1639       method_id != SFTP_AUTH_FL_METH_KBDINT) {
1640     errno = EPERM;
1641     return -1;
1642   }
1643 
1644   meth = pcalloc(auth_chain->pool, sizeof(struct sftp_auth_method));
1645   meth->method_id = method_id;
1646   meth->method_name = pstrdup(auth_chain->pool, method_name);
1647   if (submethod_name != NULL) {
1648     meth->submethod_name = pstrdup(auth_chain->pool, submethod_name);
1649   }
1650   meth->succeeded = FALSE;
1651   meth->failed = FALSE;
1652 
1653   *((struct sftp_auth_method **) push_array(auth_chain->methods)) = meth;
1654   return 0;
1655 }
1656 
sftp_auth_chain_parse_method(pool * p,const char * name,unsigned int * method_id,const char ** method_name,const char ** submethod_name)1657 int sftp_auth_chain_parse_method(pool *p, const char *name,
1658     unsigned int *method_id, const char **method_name,
1659     const char **submethod_name) {
1660   char *ptr;
1661   size_t method_namelen;
1662 
1663   if (name == NULL ||
1664       method_id == NULL ||
1665       method_name == NULL) {
1666     errno = EINVAL;
1667     return -1;
1668   }
1669 
1670   /* Look for the syntax indicating a submethod name. */
1671   ptr = strchr(name, ':');
1672   if (ptr == NULL) {
1673     method_namelen = strlen(name);
1674   } else {
1675     method_namelen = ptr - name - 1;
1676   }
1677 
1678   if (strncmp(name, "publickey", method_namelen) == 0) {
1679     *method_id = SFTP_AUTH_FL_METH_PUBLICKEY;
1680     *method_name = name;
1681 
1682   } else if (strncmp(name, "hostbased", method_namelen) == 0) {
1683     *method_id = SFTP_AUTH_FL_METH_HOSTBASED;
1684     *method_name = name;
1685 
1686   } else if (strncmp(name, "password", method_namelen) == 0) {
1687     *method_id = SFTP_AUTH_FL_METH_PASSWORD;
1688     *method_name = name;
1689 
1690   } else if (strncmp(name, "keyboard-interactive", method_namelen) == 0) {
1691     *method_id = SFTP_AUTH_FL_METH_KBDINT;
1692 
1693     if (sftp_kbdint_have_drivers() == 0) {
1694       errno = EPERM;
1695       return -1;
1696     }
1697 
1698     /* If we have a submethod name, check whether it matches one of our
1699      * loaded kbdint drivers.
1700      */
1701     if (ptr != NULL) {
1702       if (sftp_kbdint_get_driver(ptr) == NULL) {
1703         errno = EPERM;
1704         return -1;
1705       }
1706 
1707       *method_name = pstrndup(p, name, method_namelen);
1708       if (submethod_name != NULL) {
1709         *submethod_name = ptr;
1710       }
1711 
1712     } else {
1713       *method_name = name;
1714     }
1715 
1716   } else {
1717     /* Unknown/unsupported method name. */
1718     errno = EINVAL;
1719     return -1;
1720   }
1721 
1722   return 0;
1723 }
1724 
sftp_auth_chain_parse_method_chain(pool * p,const char * method_list)1725 array_header *sftp_auth_chain_parse_method_chain(pool *p,
1726     const char *method_list) {
1727   char *ptr;
1728   size_t method_listlen;
1729   array_header *method_names;
1730 
1731   if (p == NULL ||
1732       method_list == NULL) {
1733     errno = EINVAL;
1734     return NULL;
1735   }
1736 
1737   ptr = strchr(method_list, '+');
1738   if (ptr == NULL) {
1739     method_names = make_array(p, 0, sizeof(char *));
1740     *((char **) push_array(method_names)) = pstrdup(p, method_list);
1741     return method_names;
1742   }
1743 
1744   if (ptr == method_list) {
1745     /* Leading '+'. */
1746     errno = EPERM;
1747     return NULL;
1748   }
1749 
1750   method_listlen = strlen(method_list);
1751   if (method_list[method_listlen-1] == '+') {
1752     /* Trailing '+'. */
1753     errno = EPERM;
1754     return NULL;
1755   }
1756 
1757   method_names = make_array(p, 0, sizeof(char *));
1758 
1759   while (ptr != NULL) {
1760     size_t namelen;
1761 
1762     pr_signals_handle();
1763 
1764     namelen = (ptr - method_list);
1765     if (namelen == 0) {
1766       /* Double '+' characters. */
1767       errno = EPERM;
1768       return NULL;
1769     }
1770 
1771     *((char **) push_array(method_names)) = pstrndup(p, method_list, namelen);
1772 
1773     method_list = ptr + 1;
1774     ptr = strchr(method_list, '+');
1775 
1776     /* Don't forget the last name in the list. */
1777     if (ptr == NULL) {
1778       *((char **) push_array(method_names)) = pstrdup(p, method_list);
1779     }
1780   }
1781 
1782   return method_names;
1783 }
1784 
sftp_auth_get_default_dir(void)1785 char *sftp_auth_get_default_dir(void) {
1786   return auth_default_dir;
1787 }
1788 
sftp_auth_send_banner(const char * banner)1789 int sftp_auth_send_banner(const char *banner) {
1790   struct ssh2_packet *pkt;
1791   unsigned char *buf, *ptr;
1792   uint32_t buflen, bufsz;
1793   size_t banner_len;
1794   int res;
1795 
1796   if (banner == NULL) {
1797     errno = EINVAL;
1798     return -1;
1799   }
1800 
1801   /* If the client has finished authenticating, then we can no longer
1802    * send USERAUTH_BANNER messages.
1803    */
1804   if (sftp_sess_state & SFTP_SESS_STATE_HAVE_AUTH) {
1805     pr_trace_msg(trace_channel, 1,
1806       "unable to send banner: client has authenticated");
1807     return 0;
1808   }
1809 
1810   /* Make sure that the given banner string ends in CRLF, as required by
1811    * RFC4252 Section 5.4.
1812    */
1813   banner_len = strlen(banner);
1814   if (banner[banner_len-2] != '\r' ||
1815       banner[banner_len-1] != '\n') {
1816     banner = pstrcat(auth_pool, banner, "\r\n", NULL);
1817     banner_len = strlen(banner);
1818   }
1819 
1820   pkt = sftp_ssh2_packet_create(auth_pool);
1821 
1822   buflen = bufsz = banner_len + 32;
1823   ptr = buf = palloc(pkt->pool, bufsz);
1824 
1825   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_USER_AUTH_BANNER);
1826   sftp_msg_write_string(&buf, &buflen, banner);
1827 
1828   /* XXX locale of banner */
1829   sftp_msg_write_string(&buf, &buflen, "");
1830 
1831   pkt->payload = ptr;
1832   pkt->payload_len = (bufsz - buflen);
1833 
1834   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1835     "sending userauth banner");
1836 
1837   res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
1838   if (res < 0) {
1839     destroy_pool(pkt->pool);
1840     return -1;
1841   }
1842 
1843   destroy_pool(pkt->pool);
1844   return 0;
1845 }
1846 
sftp_auth_handle(struct ssh2_packet * pkt)1847 int sftp_auth_handle(struct ssh2_packet *pkt) {
1848   char *service = NULL;
1849   int res;
1850 
1851   /* The send_userauth_banner_file() function makes sure that the
1852    * SFTPDisplayBanner file is not sent multiple times.
1853    */
1854   if (send_userauth_banner_file() < 0) {
1855     return -1;
1856   }
1857 
1858   if (pr_response_get_pool() == NULL) {
1859     /* We set this pool for use by the Response API, for logging response codes/
1860      * messages during login.
1861      */
1862     pr_response_set_pool(session.pool);
1863   }
1864 
1865   res = handle_userauth_req(pkt, &service);
1866   if (res < 0) {
1867     destroy_pool(pkt->pool);
1868     SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_PROTOCOL_ERROR, NULL);
1869   }
1870 
1871   destroy_pool(pkt->pool);
1872   return res;
1873 }
1874 
sftp_auth_init(void)1875 int sftp_auth_init(void) {
1876 
1877   /* There's no point in trying to handle the case where a client will
1878    * want/attempt to authenticate again, as a different user.
1879    *
1880    * The issue is that if a client successfully authenticates, and the
1881    * authenticated session is chrooted, a subsequent attempt to authenticate
1882    * will occur in a chrooted process, and that will likely lead to all
1883    * sorts of brokenness.
1884    */
1885 
1886   if (auth_pool == NULL) {
1887     unsigned int *max_logins;
1888 
1889     auth_pool = make_sub_pool(sftp_pool);
1890     pr_pool_tag(auth_pool, "SSH2 Auth Pool");
1891 
1892     max_logins = get_param_ptr(main_server->conf, "MaxLoginAttempts", FALSE);
1893     if (max_logins != NULL) {
1894       auth_attempts_max = *max_logins;
1895     }
1896   }
1897 
1898   return 0;
1899 }
1900