diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index 83be3cb5cbb5..a2e1fa10ce45 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -568,6 +568,9 @@ getpwnamallow(const char *user) struct ssh *ssh = active_state; /* XXX */ #ifdef HAVE_LOGIN_CAP extern login_cap_t *lc; +#ifdef HAVE_AUTH_HOSTOK + const char *from_host, *from_ip; +#endif #ifdef BSD_AUTH auth_session_t *as; #endif @@ -622,6 +625,21 @@ getpwnamallow(const char *user) debug("unable to get login class: %s", user); return (NULL); } +#ifdef HAVE_AUTH_HOSTOK + from_host = auth_get_canonical_hostname(ssh, options.use_dns); + from_ip = ssh_remote_ipaddr(ssh); + if (!auth_hostok(lc, from_host, from_ip)) { + debug("Denied connection for %.200s from %.200s [%.200s].", + pw->pw_name, from_host, from_ip); + return (NULL); + } +#endif /* HAVE_AUTH_HOSTOK */ +#ifdef HAVE_AUTH_TIMEOK + if (!auth_timeok(lc, time(NULL))) { + debug("LOGIN %.200s REFUSED (TIME)", pw->pw_name); + return (NULL); + } +#endif /* HAVE_AUTH_TIMEOK */ #ifdef BSD_AUTH if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c index 612cc3f8f2f3..af6fdae97193 100644 --- a/crypto/openssh/auth2.c +++ b/crypto/openssh/auth2.c @@ -314,25 +314,6 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) authctxt->user, authctxt->service, user, service); } -#ifdef HAVE_LOGIN_CAP - if (authctxt->pw != NULL && - (lc = PRIVSEP(login_getpwclass(authctxt->pw))) != NULL) { - from_host = auth_get_canonical_hostname(ssh, options.use_dns); - from_ip = ssh_remote_ipaddr(ssh); - if (!auth_hostok(lc, from_host, from_ip)) { - logit("Denied connection for %.200s from %.200s [%.200s].", - authctxt->pw->pw_name, from_host, from_ip); - packet_disconnect("Sorry, you are not allowed to connect."); - } - if (!auth_timeok(lc, time(NULL))) { - logit("LOGIN %.200s REFUSED (TIME) FROM %.200s", - authctxt->pw->pw_name, from_host); - packet_disconnect("Logins not available right now."); - } - PRIVSEP(login_close(lc)); - } -#endif /* HAVE_LOGIN_CAP */ - /* reset state */ auth2_challenge_stop(ssh); diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h index 17d7e53666e9..dbdad4faaca1 100644 --- a/crypto/openssh/config.h +++ b/crypto/openssh/config.h @@ -211,6 +211,12 @@ /* Define to 1 if you have the `aug_get_machine' function. */ /* #undef HAVE_AUG_GET_MACHINE */ +/* Define to 1 if you have the `auth_hostok' function. */ +#define HAVE_AUTH_HOSTOK 1 + +/* Define to 1 if you have the `auth_timeok' function. */ +#define HAVE_AUTH_TIMEOK 1 + /* Define to 1 if you have the `b64_ntop' function. */ /* #undef HAVE_B64_NTOP */ diff --git a/crypto/openssh/configure.ac b/crypto/openssh/configure.ac index 60c170285979..538f389c6da3 100644 --- a/crypto/openssh/configure.ac +++ b/crypto/openssh/configure.ac @@ -1751,6 +1751,8 @@ fi dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS([ \ + auth_hostok \ + auth_timeok \ Blowfish_initstate \ Blowfish_expandstate \ Blowfish_expand0state \ diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c index c5e3708c2563..531b2993ab6b 100644 --- a/crypto/openssh/monitor.c +++ b/crypto/openssh/monitor.c @@ -114,9 +114,6 @@ static struct sshbuf *child_state; int mm_answer_moduli(int, struct sshbuf *); int mm_answer_sign(int, struct sshbuf *); -#ifdef HAVE_LOGIN_CAP -int mm_answer_login_getpwclass(int, struct sshbuf *); -#endif int mm_answer_pwnamallow(int, struct sshbuf *); int mm_answer_auth2_read_banner(int, struct sshbuf *); int mm_answer_authserv(int, struct sshbuf *); @@ -192,9 +189,6 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, -#ifdef HAVE_LOGIN_CAP - {MONITOR_REQ_GETPWCLASS, MON_ISAUTH, mm_answer_login_getpwclass}, -#endif {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, @@ -713,48 +707,6 @@ mm_answer_sign(int sock, struct sshbuf *m) return (0); } -#ifdef HAVE_LOGIN_CAP -int -mm_answer_login_getpwclass(int sock, struct sshbuf *m) -{ - login_cap_t *lc; - struct passwd *pw; - int r; - u_int len; - - debug3("%s", __func__); - - pw = sshbuf_get_passwd(m); - if (pw == NULL) - fatal("%s: receive get struct passwd failed", __func__); - - lc = login_getpwclass(pw); - - sshbuf_reset(m); - - if (lc == NULL) { - if (r = sshbuf_put_u8(m, 0) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - goto out; - } - - if ((r = sshbuf_put_u8(m, 1)) != 0 || - (r = sshbuf_put_cstring(m, lc->lc_class)) != 0 || - (r = sshbuf_put_cstring(m, lc->lc_cap)) != 0 || - (r = sshbuf_put_cstring(m, lc->lc_style)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - login_close(lc); - out: - debug3("%s: sending MONITOR_ANS_GETPWCLASS", __func__); - mm_request_send(sock, MONITOR_ANS_GETPWCLASS, m); - - sshbuf_free_passwd(pw); - - return (0); -} -#endif - /* Retrieves the password entry and also checks if the user is permitted */ int @@ -793,8 +745,19 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m) authctxt->pw = pwent; authctxt->valid = 1; + /* XXX don't sent pwent to unpriv; send fake class/dir/shell too */ if ((r = sshbuf_put_u8(m, 1)) != 0 || - (r = sshbuf_put_passwd(m, pwent)) != 0) + (r = sshbuf_put_string(m, pwent, sizeof(*pwent))) != 0 || + (r = sshbuf_put_cstring(m, pwent->pw_name)) != 0 || + (r = sshbuf_put_cstring(m, "*")) != 0 || +#ifdef HAVE_STRUCT_PASSWD_PW_GECOS + (r = sshbuf_put_cstring(m, pwent->pw_gecos)) != 0 || +#endif +#ifdef HAVE_STRUCT_PASSWD_PW_CLASS + (r = sshbuf_put_cstring(m, pwent->pw_class)) != 0 || +#endif + (r = sshbuf_put_cstring(m, pwent->pw_dir)) != 0 || + (r = sshbuf_put_cstring(m, pwent->pw_shell)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); out: diff --git a/crypto/openssh/monitor.h b/crypto/openssh/monitor.h index abf2ca4018b4..16047299f882 100644 --- a/crypto/openssh/monitor.h +++ b/crypto/openssh/monitor.h @@ -53,8 +53,7 @@ enum monitor_reqtype { MONITOR_REQ_GSSSTEP = 44, MONITOR_ANS_GSSSTEP = 45, MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, - MONITOR_REQ_GETPWCLASS = 50, MONITOR_ANS_GETPWCLASS = 51, - MONITOR_REQ_TERM = 52, + MONITOR_REQ_TERM = 50, MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c index bb458f131483..732fb3476bf0 100644 --- a/crypto/openssh/monitor_wrap.c +++ b/crypto/openssh/monitor_wrap.c @@ -247,61 +247,6 @@ mm_sshkey_sign(struct sshkey *key, u_char **sigp, size_t *lenp, return (0); } -#ifdef HAVE_LOGIN_CAP -login_cap_t * -mm_login_getpwclass(const struct passwd *pwent) -{ - int r; - struct sshbuf *m; - char rc; - login_cap_t *lc; - - debug3("%s entering", __func__); - - if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); - if ((r = sshbuf_put_passwd(m, pwent)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GETPWCLASS, m); - - debug3("%s: waiting for MONITOR_ANS_GETPWCLASS", __func__); - mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GETPWCLASS, m); - - if ((r = sshbuf_get_u8(m, &rc)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - if (rc == 0) { - lc = NULL; - goto out; - } - - lc = xmalloc(sizeof(*lc)); - if ((r = sshbuf_get_cstring(m, &lc->lc_class, NULL)) != 0 || - (r = sshbuf_get_cstring(m, &lc->lc_cap, NULL)) != 0 || - (r = sshbuf_get_cstring(m, &lc->lc_style, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - out: - sshbuf_free(m); - - return (lc); -} -#endif - -#ifdef HAVE_LOGIN_CAP -void -mm_login_close(login_cap_t *lc) -{ - if (lc == NULL) - return; - free(lc->lc_style); - free(lc->lc_class); - free(lc->lc_cap); - free(lc); -} -#endif - struct passwd * mm_getpwnamallow(const char *username) { @@ -334,9 +279,25 @@ mm_getpwnamallow(const char *username) goto out; } - pw = sshbuf_get_passwd(m); - if (pw == NULL) - fatal("%s: receive get struct passwd failed", __func__); + /* XXX don't like passing struct passwd like this */ + pw = xcalloc(sizeof(*pw), 1); + if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (len != sizeof(*pw)) + fatal("%s: struct passwd size mismatch", __func__); + memcpy(pw, p, sizeof(*pw)); + + if ((r = sshbuf_get_cstring(m, &pw->pw_name, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &pw->pw_passwd, NULL)) != 0 || +#ifdef HAVE_STRUCT_PASSWD_PW_GECOS + (r = sshbuf_get_cstring(m, &pw->pw_gecos, NULL)) != 0 || +#endif +#ifdef HAVE_STRUCT_PASSWD_PW_CLASS + (r = sshbuf_get_cstring(m, &pw->pw_class, NULL)) != 0 || +#endif + (r = sshbuf_get_cstring(m, &pw->pw_dir, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &pw->pw_shell, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); out: /* copy options block as a Match directive may have changed some */ diff --git a/crypto/openssh/monitor_wrap.h b/crypto/openssh/monitor_wrap.h index 5b5dea1ed828..644da081db8d 100644 --- a/crypto/openssh/monitor_wrap.h +++ b/crypto/openssh/monitor_wrap.h @@ -44,10 +44,6 @@ DH *mm_choose_dh(int, int, int); int mm_sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int compat); void mm_inform_authserv(char *, char *); -#ifdef HAVE_LOGIN_CAP -struct login_cap *mm_login_getpwclass(const struct passwd *pwd); -void mm_login_close(struct login_cap *lc); -#endif struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h index f6a100622de8..57b7bb3e375c 100644 --- a/crypto/openssh/ssh_namespace.h +++ b/crypto/openssh/ssh_namespace.h @@ -657,7 +657,6 @@ #define sshbuf_dump_data Fssh_sshbuf_dump_data #define sshbuf_dup_string Fssh_sshbuf_dup_string #define sshbuf_free Fssh_sshbuf_free -#define sshbuf_free_passwd Fssh_sshbuf_free_passwd #define sshbuf_from Fssh_sshbuf_from #define sshbuf_fromb Fssh_sshbuf_fromb #define sshbuf_froms Fssh_sshbuf_froms @@ -668,7 +667,6 @@ #define sshbuf_get_cstring Fssh_sshbuf_get_cstring #define sshbuf_get_ec Fssh_sshbuf_get_ec #define sshbuf_get_eckey Fssh_sshbuf_get_eckey -#define sshbuf_get_passwd Fssh_sshbuf_get_passwd #define sshbuf_get_string Fssh_sshbuf_get_string #define sshbuf_get_string_direct Fssh_sshbuf_get_string_direct #define sshbuf_get_stringb Fssh_sshbuf_get_stringb @@ -690,7 +688,6 @@ #define sshbuf_put_cstring Fssh_sshbuf_put_cstring #define sshbuf_put_ec Fssh_sshbuf_put_ec #define sshbuf_put_eckey Fssh_sshbuf_put_eckey -#define sshbuf_put_passwd Fssh_sshbuf_put_passwd #define sshbuf_put_string Fssh_sshbuf_put_string #define sshbuf_put_stringb Fssh_sshbuf_put_stringb #define sshbuf_put_u16 Fssh_sshbuf_put_u16 diff --git a/crypto/openssh/sshbuf-getput-basic.c b/crypto/openssh/sshbuf-getput-basic.c index 70ee303a23e4..9092a7eebf97 100644 --- a/crypto/openssh/sshbuf-getput-basic.c +++ b/crypto/openssh/sshbuf-getput-basic.c @@ -463,103 +463,3 @@ sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, } return 0; } - -/* - * store struct pwd - */ -int -sshbuf_put_passwd(struct sshbuf *buf, const struct passwd *pwent) -{ - int r; - - /* - * We never send pointer values of struct passwd. - * It is safe from wild pointer even if a new pointer member is added. - */ - - if ((r = sshbuf_put_u64(buf, sizeof(*pwent)) != 0) || - (r = sshbuf_put_cstring(buf, pwent->pw_name)) != 0 || - (r = sshbuf_put_cstring(buf, "*")) != 0 || - (r = sshbuf_put_u32(buf, pwent->pw_uid)) != 0 || - (r = sshbuf_put_u32(buf, pwent->pw_gid)) != 0 || -#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE - (r = sshbuf_put_time(buf, pwent->pw_change)) != 0 || -#endif -#ifdef HAVE_STRUCT_PASSWD_PW_GECOS - (r = sshbuf_put_cstring(buf, pwent->pw_gecos)) != 0 || -#endif -#ifdef HAVE_STRUCT_PASSWD_PW_CLASS - (r = sshbuf_put_cstring(buf, pwent->pw_class)) != 0 || -#endif - (r = sshbuf_put_cstring(buf, pwent->pw_dir)) != 0 || - (r = sshbuf_put_cstring(buf, pwent->pw_shell)) != 0 || -#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE - (r = sshbuf_put_time(buf, pwent->pw_expire)) != 0 || -#endif - (r = sshbuf_put_u32(buf, pwent->pw_fields)) != 0) { - return r; - } - return 0; -} - -/* - * extract struct pwd - */ -struct passwd * -sshbuf_get_passwd(struct sshbuf *buf) -{ - struct passwd *pw; - u_int64_t len; - int r; - - /* check if size of struct passwd is as same as sender's size */ - r = sshbuf_get_u64(buf, &len); - if (r != 0 || len != sizeof(*pw)) - return NULL; - - pw = xcalloc(1, sizeof(*pw)); - if (sshbuf_get_cstring(buf, &pw->pw_name, NULL) != 0 || - sshbuf_get_cstring(buf, &pw->pw_passwd, NULL) != 0 || - sshbuf_get_u32(buf, &pw->pw_uid) != 0 || - sshbuf_get_u32(buf, &pw->pw_gid) != 0 || -#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE - sshbuf_get_time(buf, &pw->pw_change) != 0 || -#endif -#ifdef HAVE_STRUCT_PASSWD_PW_GECOS - sshbuf_get_cstring(buf, &pw->pw_gecos, NULL) != 0 || -#endif -#ifdef HAVE_STRUCT_PASSWD_PW_CLASS - sshbuf_get_cstring(buf, &pw->pw_class, NULL) != 0 || -#endif - sshbuf_get_cstring(buf, &pw->pw_dir, NULL) != 0 || - sshbuf_get_cstring(buf, &pw->pw_shell, NULL) != 0 || -#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE - sshbuf_get_time(buf, &pw->pw_expire) != 0 || -#endif - sshbuf_get_u32(buf, &pw->pw_fields) != 0) { - sshbuf_free_passwd(pw); - return NULL; - } - return pw; -} - -/* - * free struct passwd obtained from sshbuf_get_passwd. - */ -void -sshbuf_free_passwd(struct passwd *pwent) -{ - if (pwent == NULL) - return; - free(pwent->pw_shell); - free(pwent->pw_dir); -#ifdef HAVE_STRUCT_PASSWD_PW_CLASS - free(pwent->pw_class); -#endif -#ifdef HAVE_STRUCT_PASSWD_PW_GECOS - free(pwent->pw_gecos); -#endif - free(pwent->pw_passwd); - free(pwent->pw_name); - free(pwent); -} diff --git a/crypto/openssh/sshbuf.h b/crypto/openssh/sshbuf.h index aba18d2aa922..87aa1560eabe 100644 --- a/crypto/openssh/sshbuf.h +++ b/crypto/openssh/sshbuf.h @@ -254,21 +254,6 @@ int sshbuf_b64tod(struct sshbuf *buf, const char *b64); */ char *sshbuf_dup_string(struct sshbuf *buf); -/* - * store struct pwd - */ -int sshbuf_put_passwd(struct sshbuf *buf, const struct passwd *pwent); - -/* - * extract struct pwd - */ -struct passwd *sshbuf_get_passwd(struct sshbuf *buf); - -/* - * free struct passwd obtained from sshbuf_get_passwd. - */ -void sshbuf_free_passwd(struct passwd *pwent); - /* Macros for decoding/encoding integers */ #define PEEK_U64(p) \ (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \