Page MenuHomeFreeBSD

D17128.diff
No OneTemporary

D17128.diff

Index: head/crypto/openssh/auth2.c
===================================================================
--- head/crypto/openssh/auth2.c
+++ head/crypto/openssh/auth2.c
@@ -316,7 +316,7 @@
#ifdef HAVE_LOGIN_CAP
if (authctxt->pw != NULL &&
- (lc = login_getpwclass(authctxt->pw)) != NULL) {
+ (lc = PRIVSEP(login_getpwclass(authctxt->pw))) != NULL) {
logit("user %s login class %s", authctxt->pw->pw_name,
authctxt->pw->pw_class);
from_host = auth_get_canonical_hostname(ssh, options.use_dns);
@@ -331,7 +331,7 @@
authctxt->pw->pw_name, from_host);
packet_disconnect("Logins not available right now.");
}
- login_close(lc);
+ PRIVSEP(login_close(lc));
}
#endif /* HAVE_LOGIN_CAP */
Index: head/crypto/openssh/monitor.h
===================================================================
--- head/crypto/openssh/monitor.h
+++ head/crypto/openssh/monitor.h
@@ -53,7 +53,8 @@
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_TERM = 50,
+ MONITOR_REQ_GETPWCLASS = 50, MONITOR_ANS_GETPWCLASS = 51,
+ MONITOR_REQ_TERM = 52,
MONITOR_REQ_PAM_START = 100,
MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
Index: head/crypto/openssh/monitor.c
===================================================================
--- head/crypto/openssh/monitor.c
+++ head/crypto/openssh/monitor.c
@@ -114,6 +114,7 @@
int mm_answer_moduli(int, struct sshbuf *);
int mm_answer_sign(int, struct sshbuf *);
+int mm_answer_login_getpwclass(int, struct sshbuf *);
int mm_answer_pwnamallow(int, struct sshbuf *);
int mm_answer_auth2_read_banner(int, struct sshbuf *);
int mm_answer_authserv(int, struct sshbuf *);
@@ -189,6 +190,7 @@
{MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
#endif
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
+ {MONITOR_REQ_GETPWCLASS, MON_AUTH, mm_answer_login_getpwclass},
{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},
@@ -707,6 +709,46 @@
return (0);
}
+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);
+}
+
/* Retrieves the password entry and also checks if the user is permitted */
int
@@ -745,19 +787,8 @@
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_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)
+ (r = sshbuf_put_passwd(m, pwent)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
out:
Index: head/crypto/openssh/monitor_wrap.h
===================================================================
--- head/crypto/openssh/monitor_wrap.h
+++ head/crypto/openssh/monitor_wrap.h
@@ -28,6 +28,8 @@
#ifndef _MM_WRAP_H_
#define _MM_WRAP_H_
+#include <login_cap.h>
+
extern int use_privsep;
#define PRIVSEP(x) (use_privsep ? mm_##x : x)
@@ -45,6 +47,8 @@
const char *, u_int compat);
void mm_inform_authserv(char *, char *);
struct passwd *mm_getpwnamallow(const char *);
+login_cap_t *mm_login_getpwclass(const struct passwd *pwd);
+void mm_login_close(login_cap_t *lc);
char *mm_auth2_read_banner(void);
int mm_auth_password(struct ssh *, char *);
int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *,
Index: head/crypto/openssh/monitor_wrap.c
===================================================================
--- head/crypto/openssh/monitor_wrap.c
+++ head/crypto/openssh/monitor_wrap.c
@@ -247,6 +247,57 @@
return (0);
}
+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);
+}
+
+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);
+}
+
struct passwd *
mm_getpwnamallow(const char *username)
{
@@ -279,25 +330,9 @@
goto out;
}
- /* 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));
+ pw = sshbuf_get_passwd(m);
+ if (pw == NULL)
+ fatal("%s: receive get struct passwd failed", __func__);
out:
/* copy options block as a Match directive may have changed some */
Index: head/crypto/openssh/sandbox-capsicum.c
===================================================================
--- head/crypto/openssh/sandbox-capsicum.c
+++ head/crypto/openssh/sandbox-capsicum.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <capsicum_helpers.h>
#include "log.h"
#include "monitor.h"
@@ -70,6 +71,8 @@
{
struct rlimit rl_zero;
cap_rights_t rights;
+
+ caph_cache_tzdata();
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
Index: head/crypto/openssh/sshbuf-getput-basic.c
===================================================================
--- head/crypto/openssh/sshbuf-getput-basic.c
+++ head/crypto/openssh/sshbuf-getput-basic.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <string.h>
+#include "xmalloc.h"
#include "ssherr.h"
#include "sshbuf.h"
@@ -461,4 +462,96 @@
return SSH_ERR_INTERNAL_ERROR;
}
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 ||
+ (r = sshbuf_put_u64(buf, pwent->pw_change)) != 0 ||
+#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 ||
+ (r = sshbuf_put_u64(buf, pwent->pw_expire)) != 0 ||
+ (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;
+ int r;
+ size_t len;
+
+ /* 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 ||
+ sshbuf_get_u64(buf, &pw->pw_change) != 0 ||
+#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 ||
+ sshbuf_get_u64(buf, &pw->pw_expire) != 0 ||
+ 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);
}
Index: head/crypto/openssh/sshbuf.h
===================================================================
--- head/crypto/openssh/sshbuf.h
+++ head/crypto/openssh/sshbuf.h
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
+#include <pwd.h>
#ifdef WITH_OPENSSL
# include <openssl/bn.h>
# ifdef OPENSSL_HAS_ECC
@@ -245,6 +246,21 @@
* nul character.
*/
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) \
Index: head/crypto/openssh/sshd.c
===================================================================
--- head/crypto/openssh/sshd.c
+++ head/crypto/openssh/sshd.c
@@ -2143,6 +2143,11 @@
*/
remote_ip = ssh_remote_ipaddr(ssh);
+#ifdef HAVE_LOGIN_CAP
+ /* Also caches remote hostname for sandboxed child. */
+ auth_get_canonical_hostname(ssh, options.use_dns);
+#endif
+
#ifdef SSH_AUDIT_EVENTS
audit_connection_from(remote_ip, remote_port);
#endif

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 17, 1:52 PM (1 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23833805
Default Alt Text
D17128.diff (11 KB)

Event Timeline