Changeset View
Changeset View
Standalone View
Standalone View
monitor.c
/* $OpenBSD: monitor.c,v 1.186 2018/07/20 03:46:34 djm Exp $ */ | /* $OpenBSD: monitor.c,v 1.199 2019/10/07 23:10:38 djm Exp $ */ | ||||
/* | /* | ||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu> | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | ||||
* Copyright 2002 Markus Friedl <markus@openbsd.org> | * Copyright 2002 Markus Friedl <markus@openbsd.org> | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
Show All 25 Lines | |||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#ifdef HAVE_PATHS_H | #ifdef HAVE_PATHS_H | ||||
#include <paths.h> | #include <paths.h> | ||||
#endif | #endif | ||||
#include <pwd.h> | #include <pwd.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#ifdef HAVE_STDINT_H | #ifdef HAVE_STDINT_H | ||||
#include <stdint.h> | # include <stdint.h> | ||||
#endif | #endif | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#ifdef HAVE_POLL_H | #ifdef HAVE_POLL_H | ||||
#include <poll.h> | #include <poll.h> | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
extern struct sshbuf *loginmsg; | extern struct sshbuf *loginmsg; | ||||
extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ | extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ | ||||
/* State exported from the child */ | /* State exported from the child */ | ||||
static struct sshbuf *child_state; | static struct sshbuf *child_state; | ||||
/* Functions on the monitor that answer unprivileged requests */ | /* Functions on the monitor that answer unprivileged requests */ | ||||
int mm_answer_moduli(int, struct sshbuf *); | int mm_answer_moduli(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_sign(int, struct sshbuf *); | int mm_answer_sign(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pwnamallow(int, struct sshbuf *); | int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_auth2_read_banner(int, struct sshbuf *); | int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_authserv(int, struct sshbuf *); | int mm_answer_authserv(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_authpassword(int, struct sshbuf *); | int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_bsdauthquery(int, struct sshbuf *); | int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_bsdauthrespond(int, struct sshbuf *); | int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_keyallowed(int, struct sshbuf *); | int mm_answer_skeyquery(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_keyverify(int, struct sshbuf *); | int mm_answer_skeyrespond(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pty(int, struct sshbuf *); | int mm_answer_keyallowed(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pty_cleanup(int, struct sshbuf *); | int mm_answer_keyverify(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_term(int, struct sshbuf *); | int mm_answer_pty(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_rsa_keyallowed(int, struct sshbuf *); | int mm_answer_pty_cleanup(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_rsa_challenge(int, struct sshbuf *); | int mm_answer_term(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_rsa_response(int, struct sshbuf *); | int mm_answer_rsa_keyallowed(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_sesskey(int, struct sshbuf *); | int mm_answer_rsa_challenge(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_sessid(int, struct sshbuf *); | int mm_answer_rsa_response(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_sesskey(struct ssh *, int, struct sshbuf *); | |||||
int mm_answer_sessid(struct ssh *, int, struct sshbuf *); | |||||
#ifdef USE_PAM | #ifdef USE_PAM | ||||
int mm_answer_pam_start(int, struct sshbuf *); | int mm_answer_pam_start(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pam_account(int, struct sshbuf *); | int mm_answer_pam_account(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pam_init_ctx(int, struct sshbuf *); | int mm_answer_pam_init_ctx(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pam_query(int, struct sshbuf *); | int mm_answer_pam_query(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pam_respond(int, struct sshbuf *); | int mm_answer_pam_respond(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_pam_free_ctx(int, struct sshbuf *); | int mm_answer_pam_free_ctx(struct ssh *, int, struct sshbuf *); | ||||
#endif | #endif | ||||
#ifdef GSSAPI | #ifdef GSSAPI | ||||
int mm_answer_gss_setup_ctx(int, struct sshbuf *); | int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_gss_accept_ctx(int, struct sshbuf *); | int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_gss_userok(int, struct sshbuf *); | int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_gss_checkmic(int, struct sshbuf *); | int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); | ||||
#endif | #endif | ||||
#ifdef SSH_AUDIT_EVENTS | #ifdef SSH_AUDIT_EVENTS | ||||
int mm_answer_audit_event(int, struct sshbuf *); | int mm_answer_audit_event(struct ssh *, int, struct sshbuf *); | ||||
int mm_answer_audit_command(int, struct sshbuf *); | int mm_answer_audit_command(struct ssh *, int, struct sshbuf *); | ||||
#endif | #endif | ||||
static int monitor_read_log(struct monitor *); | |||||
static Authctxt *authctxt; | static Authctxt *authctxt; | ||||
/* local state for key verify */ | /* local state for key verify */ | ||||
static u_char *key_blob = NULL; | static u_char *key_blob = NULL; | ||||
static size_t key_bloblen = 0; | static size_t key_bloblen = 0; | ||||
static int key_blobtype = MM_NOKEY; | static int key_blobtype = MM_NOKEY; | ||||
static struct sshauthopt *key_opts = NULL; | static struct sshauthopt *key_opts = NULL; | ||||
static char *hostbased_cuser = NULL; | static char *hostbased_cuser = NULL; | ||||
static char *hostbased_chost = NULL; | static char *hostbased_chost = NULL; | ||||
static char *auth_method = "unknown"; | static char *auth_method = "unknown"; | ||||
static char *auth_submethod = NULL; | static char *auth_submethod = NULL; | ||||
static u_int session_id2_len = 0; | static u_int session_id2_len = 0; | ||||
static u_char *session_id2 = NULL; | static u_char *session_id2 = NULL; | ||||
static pid_t monitor_child_pid; | static pid_t monitor_child_pid; | ||||
struct mon_table { | struct mon_table { | ||||
enum monitor_reqtype type; | enum monitor_reqtype type; | ||||
int flags; | int flags; | ||||
int (*f)(int, struct sshbuf *); | int (*f)(struct ssh *, int, struct sshbuf *); | ||||
}; | }; | ||||
#define MON_ISAUTH 0x0004 /* Required for Authentication */ | #define MON_ISAUTH 0x0004 /* Required for Authentication */ | ||||
#define MON_AUTHDECIDE 0x0008 /* Decides Authentication */ | #define MON_AUTHDECIDE 0x0008 /* Decides Authentication */ | ||||
#define MON_ONCE 0x0010 /* Disable after calling */ | #define MON_ONCE 0x0010 /* Disable after calling */ | ||||
#define MON_ALOG 0x0020 /* Log auth attempt without authenticating */ | #define MON_ALOG 0x0020 /* Log auth attempt without authenticating */ | ||||
#define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE) | #define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE) | ||||
#define MON_PERMIT 0x1000 /* Request is permitted */ | #define MON_PERMIT 0x1000 /* Request is permitted */ | ||||
static int monitor_read(struct ssh *, struct monitor *, struct mon_table *, | |||||
struct mon_table **); | |||||
static int monitor_read_log(struct monitor *); | |||||
struct mon_table mon_dispatch_proto20[] = { | struct mon_table mon_dispatch_proto20[] = { | ||||
#ifdef WITH_OPENSSL | #ifdef WITH_OPENSSL | ||||
{MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, | {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, | ||||
#endif | #endif | ||||
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, | {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, | ||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | ||||
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, | {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, | ||||
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, | {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | if (ent->flags & MON_AUTH) { | ||||
ent->flags &= ~MON_PERMIT; | ent->flags &= ~MON_PERMIT; | ||||
ent->flags |= permit ? MON_PERMIT : 0; | ent->flags |= permit ? MON_PERMIT : 0; | ||||
} | } | ||||
ent++; | ent++; | ||||
} | } | ||||
} | } | ||||
void | void | ||||
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
struct mon_table *ent; | struct mon_table *ent; | ||||
int authenticated = 0, partial = 0; | int authenticated = 0, partial = 0; | ||||
debug3("preauth child monitor started"); | debug3("preauth child monitor started"); | ||||
if (pmonitor->m_recvfd >= 0) | if (pmonitor->m_recvfd >= 0) | ||||
close(pmonitor->m_recvfd); | close(pmonitor->m_recvfd); | ||||
if (pmonitor->m_log_sendfd >= 0) | if (pmonitor->m_log_sendfd >= 0) | ||||
close(pmonitor->m_log_sendfd); | close(pmonitor->m_log_sendfd); | ||||
pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; | pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; | ||||
authctxt = _authctxt; | authctxt = (Authctxt *)ssh->authctxt; | ||||
memset(authctxt, 0, sizeof(*authctxt)); | memset(authctxt, 0, sizeof(*authctxt)); | ||||
ssh->authctxt = authctxt; | ssh->authctxt = authctxt; | ||||
authctxt->loginmsg = loginmsg; | authctxt->loginmsg = loginmsg; | ||||
mon_dispatch = mon_dispatch_proto20; | mon_dispatch = mon_dispatch_proto20; | ||||
/* Permit requests for moduli and signatures */ | /* Permit requests for moduli and signatures */ | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | ||||
/* The first few requests do not require asynchronous access */ | /* The first few requests do not require asynchronous access */ | ||||
while (!authenticated) { | while (!authenticated) { | ||||
partial = 0; | partial = 0; | ||||
auth_method = "unknown"; | auth_method = "unknown"; | ||||
auth_submethod = NULL; | auth_submethod = NULL; | ||||
auth2_authctxt_reset_info(authctxt); | auth2_authctxt_reset_info(authctxt); | ||||
authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); | authenticated = (monitor_read(ssh, pmonitor, | ||||
mon_dispatch, &ent) == 1); | |||||
/* Special handling for multiple required authentications */ | /* Special handling for multiple required authentications */ | ||||
if (options.num_auth_methods != 0) { | if (options.num_auth_methods != 0) { | ||||
if (authenticated && | if (authenticated && | ||||
!auth2_update_methods_lists(authctxt, | !auth2_update_methods_lists(authctxt, | ||||
auth_method, auth_submethod)) { | auth_method, auth_submethod)) { | ||||
debug3("%s: method %s: partial", __func__, | debug3("%s: method %s: partial", __func__, | ||||
auth_method); | auth_method); | ||||
Show All 15 Lines | #ifdef USE_PAM | ||||
struct sshbuf *m; | struct sshbuf *m; | ||||
if ((m = sshbuf_new()) == NULL) | if ((m = sshbuf_new()) == NULL) | ||||
fatal("%s: sshbuf_new failed", | fatal("%s: sshbuf_new failed", | ||||
__func__); | __func__); | ||||
mm_request_receive_expect(pmonitor->m_sendfd, | mm_request_receive_expect(pmonitor->m_sendfd, | ||||
MONITOR_REQ_PAM_ACCOUNT, m); | MONITOR_REQ_PAM_ACCOUNT, m); | ||||
authenticated = mm_answer_pam_account( | authenticated = mm_answer_pam_account( | ||||
pmonitor->m_sendfd, m); | ssh, pmonitor->m_sendfd, m); | ||||
sshbuf_free(m); | sshbuf_free(m); | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { | if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { | ||||
auth_log(authctxt, authenticated, partial, | auth_log(ssh, authenticated, partial, | ||||
auth_method, auth_submethod); | auth_method, auth_submethod); | ||||
if (!partial && !authenticated) | if (!partial && !authenticated) | ||||
authctxt->failures++; | authctxt->failures++; | ||||
if (authenticated || partial) { | if (authenticated || partial) { | ||||
auth2_update_session_info(authctxt, | auth2_update_session_info(authctxt, | ||||
auth_method, auth_submethod); | auth_method, auth_submethod); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (!authctxt->valid) | if (!authctxt->valid) | ||||
fatal("%s: authenticated invalid user", __func__); | fatal("%s: authenticated invalid user", __func__); | ||||
if (strcmp(auth_method, "unknown") == 0) | if (strcmp(auth_method, "unknown") == 0) | ||||
fatal("%s: authentication method name unknown", __func__); | fatal("%s: authentication method name unknown", __func__); | ||||
debug("%s: %s has been authenticated by privileged process", | debug("%s: %s has been authenticated by privileged process", | ||||
__func__, authctxt->user); | __func__, authctxt->user); | ||||
ssh->authctxt = NULL; | ssh->authctxt = NULL; | ||||
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); | ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); | ||||
mm_get_keystate(pmonitor); | mm_get_keystate(ssh, pmonitor); | ||||
/* Drain any buffered messages from the child */ | /* Drain any buffered messages from the child */ | ||||
while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) | while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) | ||||
; | ; | ||||
if (pmonitor->m_recvfd >= 0) | if (pmonitor->m_recvfd >= 0) | ||||
close(pmonitor->m_recvfd); | close(pmonitor->m_recvfd); | ||||
if (pmonitor->m_log_sendfd >= 0) | if (pmonitor->m_log_sendfd >= 0) | ||||
Show All 9 Lines | |||||
static void | static void | ||||
monitor_child_handler(int sig) | monitor_child_handler(int sig) | ||||
{ | { | ||||
kill(monitor_child_pid, sig); | kill(monitor_child_pid, sig); | ||||
} | } | ||||
void | void | ||||
monitor_child_postauth(struct monitor *pmonitor) | monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) | ||||
{ | { | ||||
close(pmonitor->m_recvfd); | close(pmonitor->m_recvfd); | ||||
pmonitor->m_recvfd = -1; | pmonitor->m_recvfd = -1; | ||||
monitor_set_child_handler(pmonitor->m_pid); | monitor_set_child_handler(pmonitor->m_pid); | ||||
signal(SIGHUP, &monitor_child_handler); | signal(SIGHUP, &monitor_child_handler); | ||||
signal(SIGTERM, &monitor_child_handler); | signal(SIGTERM, &monitor_child_handler); | ||||
signal(SIGINT, &monitor_child_handler); | signal(SIGINT, &monitor_child_handler); | ||||
Show All 9 Lines | #endif | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | ||||
if (auth_opts->permit_pty_flag) { | if (auth_opts->permit_pty_flag) { | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); | ||||
} | } | ||||
for (;;) | for (;;) | ||||
monitor_read(pmonitor, mon_dispatch, NULL); | monitor_read(ssh, pmonitor, mon_dispatch, NULL); | ||||
} | } | ||||
static int | static int | ||||
monitor_read_log(struct monitor *pmonitor) | monitor_read_log(struct monitor *pmonitor) | ||||
{ | { | ||||
struct sshbuf *logmsg; | struct sshbuf *logmsg; | ||||
u_int len, level; | u_int len, level; | ||||
char *msg; | char *msg; | ||||
Show All 38 Lines | monitor_read_log(struct monitor *pmonitor) | ||||
do_log2(level, "%s [preauth]", msg); | do_log2(level, "%s [preauth]", msg); | ||||
sshbuf_free(logmsg); | sshbuf_free(logmsg); | ||||
free(msg); | free(msg); | ||||
return 0; | return 0; | ||||
} | } | ||||
int | static int | ||||
monitor_read(struct monitor *pmonitor, struct mon_table *ent, | monitor_read(struct ssh *ssh, struct monitor *pmonitor, struct mon_table *ent, | ||||
struct mon_table **pent) | struct mon_table **pent) | ||||
{ | { | ||||
struct sshbuf *m; | struct sshbuf *m; | ||||
int r, ret; | int r, ret; | ||||
u_char type; | u_char type; | ||||
struct pollfd pfd[2]; | struct pollfd pfd[2]; | ||||
for (;;) { | for (;;) { | ||||
Show All 33 Lines | if (ent->type == type) | ||||
break; | break; | ||||
ent++; | ent++; | ||||
} | } | ||||
if (ent->f != NULL) { | if (ent->f != NULL) { | ||||
if (!(ent->flags & MON_PERMIT)) | if (!(ent->flags & MON_PERMIT)) | ||||
fatal("%s: unpermitted request %d", __func__, | fatal("%s: unpermitted request %d", __func__, | ||||
type); | type); | ||||
ret = (*ent->f)(pmonitor->m_sendfd, m); | ret = (*ent->f)(ssh, pmonitor->m_sendfd, m); | ||||
sshbuf_free(m); | sshbuf_free(m); | ||||
/* The child may use this request only once, disable it */ | /* The child may use this request only once, disable it */ | ||||
if (ent->flags & MON_ONCE) { | if (ent->flags & MON_ONCE) { | ||||
debug2("%s: %d used once, disabling now", __func__, | debug2("%s: %d used once, disabling now", __func__, | ||||
type); | type); | ||||
ent->flags &= ~MON_PERMIT; | ent->flags &= ~MON_PERMIT; | ||||
} | } | ||||
Show All 34 Lines | monitor_reset_key_state(void) | ||||
key_blobtype = MM_NOKEY; | key_blobtype = MM_NOKEY; | ||||
key_opts = NULL; | key_opts = NULL; | ||||
hostbased_cuser = NULL; | hostbased_cuser = NULL; | ||||
hostbased_chost = NULL; | hostbased_chost = NULL; | ||||
} | } | ||||
#ifdef WITH_OPENSSL | #ifdef WITH_OPENSSL | ||||
int | int | ||||
mm_answer_moduli(int sock, struct sshbuf *m) | mm_answer_moduli(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
DH *dh; | DH *dh; | ||||
const BIGNUM *dh_p, *dh_g; | const BIGNUM *dh_p, *dh_g; | ||||
int r; | int r; | ||||
u_int min, want, max; | u_int min, want, max; | ||||
if ((r = sshbuf_get_u32(m, &min)) != 0 || | if ((r = sshbuf_get_u32(m, &min)) != 0 || | ||||
(r = sshbuf_get_u32(m, &want)) != 0 || | (r = sshbuf_get_u32(m, &want)) != 0 || | ||||
Show All 25 Lines | if (dh == NULL) { | ||||
DH_free(dh); | DH_free(dh); | ||||
} | } | ||||
mm_request_send(sock, MONITOR_ANS_MODULI, m); | mm_request_send(sock, MONITOR_ANS_MODULI, m); | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif | #endif | ||||
int | int | ||||
mm_answer_sign(int sock, struct sshbuf *m) | mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
extern int auth_sock; /* XXX move to state struct? */ | extern int auth_sock; /* XXX move to state struct? */ | ||||
struct sshkey *key; | struct sshkey *key; | ||||
struct sshbuf *sigbuf = NULL; | struct sshbuf *sigbuf = NULL; | ||||
u_char *p = NULL, *signature = NULL; | u_char *p = NULL, *signature = NULL; | ||||
char *alg = NULL; | char *alg = NULL; | ||||
size_t datlen, siglen, alglen; | size_t datlen, siglen, alglen; | ||||
int r, is_proof = 0; | int r, is_proof = 0; | ||||
u_int keyid, compat; | u_int keyid, compat; | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen, | ||||
p, datlen, alg, compat)) != 0) { | p, datlen, alg, compat)) != 0) { | ||||
fatal("%s: ssh_agent_sign failed: %s", | fatal("%s: ssh_agent_sign failed: %s", | ||||
__func__, ssh_err(r)); | __func__, ssh_err(r)); | ||||
} | } | ||||
} else | } else | ||||
fatal("%s: no hostkey from index %d", __func__, keyid); | fatal("%s: no hostkey from index %d", __func__, keyid); | ||||
debug3("%s: %s signature %p(%zu)", __func__, | debug3("%s: %s signature %p(%zu)", __func__, | ||||
is_proof ? "KEX" : "hostkey proof", signature, siglen); | is_proof ? "hostkey proof" : "KEX", signature, siglen); | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
if ((r = sshbuf_put_string(m, signature, siglen)) != 0) | if ((r = sshbuf_put_string(m, signature, siglen)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
free(alg); | free(alg); | ||||
free(p); | free(p); | ||||
free(signature); | free(signature); | ||||
mm_request_send(sock, MONITOR_ANS_SIGN, m); | mm_request_send(sock, MONITOR_ANS_SIGN, m); | ||||
/* Turn on permissions for getpwnam */ | /* Turn on permissions for getpwnam */ | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* Retrieves the password entry and also checks if the user is permitted */ | /* Retrieves the password entry and also checks if the user is permitted */ | ||||
int | int | ||||
mm_answer_pwnamallow(int sock, struct sshbuf *m) | mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
char *username; | char *username; | ||||
struct passwd *pwent; | struct passwd *pwent; | ||||
int r, allowed = 0; | int r, allowed = 0; | ||||
u_int i; | u_int i; | ||||
debug3("%s", __func__); | debug3("%s", __func__); | ||||
if (authctxt->attempt++ != 0) | if (authctxt->attempt++ != 0) | ||||
fatal("%s: multiple attempts for getpwnam", __func__); | fatal("%s: multiple attempts for getpwnam", __func__); | ||||
if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) | if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
pwent = getpwnamallow(username); | pwent = getpwnamallow(ssh, username); | ||||
authctxt->user = xstrdup(username); | authctxt->user = xstrdup(username); | ||||
setproctitle("%s [priv]", pwent ? username : "unknown"); | setproctitle("%s [priv]", pwent ? username : "unknown"); | ||||
free(username); | free(username); | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
if (pwent == NULL) { | if (pwent == NULL) { | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
#ifdef USE_PAM | #ifdef USE_PAM | ||||
if (options.use_pam) | if (options.use_pam) | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); | ||||
#endif | #endif | ||||
return (0); | return (0); | ||||
} | } | ||||
int mm_answer_auth2_read_banner(int sock, struct sshbuf *m) | int mm_answer_auth2_read_banner(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
char *banner; | char *banner; | ||||
int r; | int r; | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
banner = auth2_read_banner(); | banner = auth2_read_banner(); | ||||
if ((r = sshbuf_put_cstring(m, banner != NULL ? banner : "")) != 0) | if ((r = sshbuf_put_cstring(m, banner != NULL ? banner : "")) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); | mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); | ||||
free(banner); | free(banner); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_authserv(int sock, struct sshbuf *m) | mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
int r; | int r; | ||||
monitor_permit_authentications(1); | monitor_permit_authentications(1); | ||||
if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || | if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || | ||||
(r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0) | (r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
debug3("%s: service=%s, style=%s", | debug3("%s: service=%s, style=%s", | ||||
__func__, authctxt->service, authctxt->style); | __func__, authctxt->service, authctxt->style); | ||||
if (strlen(authctxt->style) == 0) { | if (strlen(authctxt->style) == 0) { | ||||
free(authctxt->style); | free(authctxt->style); | ||||
authctxt->style = NULL; | authctxt->style = NULL; | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | |||||
* Check that the key type appears in the supplied pattern list, ignoring | |||||
* mismatches in the signature algorithm. (Signature algorithm checks are | |||||
* performed in the unprivileged authentication code). | |||||
* Returns 1 on success, 0 otherwise. | |||||
*/ | |||||
static int | |||||
key_base_type_match(const char *method, const struct sshkey *key, | |||||
const char *list) | |||||
{ | |||||
char *s, *l, *ol = xstrdup(list); | |||||
int found = 0; | |||||
l = ol; | |||||
for ((s = strsep(&l, ",")); s && *s != '\0'; (s = strsep(&l, ","))) { | |||||
if (sshkey_type_from_name(s) == key->type) { | |||||
found = 1; | |||||
break; | |||||
} | |||||
} | |||||
if (!found) { | |||||
error("%s key type %s is not in permitted list %s", method, | |||||
sshkey_ssh_name(key), list); | |||||
} | |||||
free(ol); | |||||
return found; | |||||
} | |||||
int | int | ||||
mm_answer_authpassword(int sock, struct sshbuf *m) | mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
static int call_count; | static int call_count; | ||||
char *passwd; | char *passwd; | ||||
int r, authenticated; | int r, authenticated; | ||||
size_t plen; | size_t plen; | ||||
if (!options.password_authentication) | if (!options.password_authentication) | ||||
fatal("%s: password authentication not enabled", __func__); | fatal("%s: password authentication not enabled", __func__); | ||||
if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0) | if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0) | ||||
Show All 22 Lines | else | ||||
auth_method = "password"; | auth_method = "password"; | ||||
/* Causes monitor loop to terminate if authenticated */ | /* Causes monitor loop to terminate if authenticated */ | ||||
return (authenticated); | return (authenticated); | ||||
} | } | ||||
#ifdef BSD_AUTH | #ifdef BSD_AUTH | ||||
int | int | ||||
mm_answer_bsdauthquery(int sock, struct sshbuf *m) | mm_answer_bsdauthquery(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
char *name, *infotxt; | char *name, *infotxt; | ||||
u_int numprompts, *echo_on, success; | u_int numprompts, *echo_on, success; | ||||
char **prompts; | char **prompts; | ||||
int r; | int r; | ||||
if (!options.kbd_interactive_authentication) | if (!options.kbd_interactive_authentication) | ||||
fatal("%s: kbd-int authentication not enabled", __func__); | fatal("%s: kbd-int authentication not enabled", __func__); | ||||
Show All 17 Lines | if (success) { | ||||
free(prompts); | free(prompts); | ||||
free(echo_on); | free(echo_on); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_bsdauthrespond(int sock, struct sshbuf *m) | mm_answer_bsdauthrespond(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
char *response; | char *response; | ||||
int r, authok; | int r, authok; | ||||
if (!options.kbd_interactive_authentication) | if (!options.kbd_interactive_authentication) | ||||
fatal("%s: kbd-int authentication not enabled", __func__); | fatal("%s: kbd-int authentication not enabled", __func__); | ||||
if (authctxt->as == NULL) | if (authctxt->as == NULL) | ||||
fatal("%s: no bsd auth session", __func__); | fatal("%s: no bsd auth session", __func__); | ||||
Show All 17 Lines | mm_answer_bsdauthrespond(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
auth_submethod = "bsdauth"; | auth_submethod = "bsdauth"; | ||||
return (authok != 0); | return (authok != 0); | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef USE_PAM | #ifdef USE_PAM | ||||
int | int | ||||
mm_answer_pam_start(int sock, struct sshbuf *m) | mm_answer_pam_start(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
if (!options.use_pam) | if (!options.use_pam) | ||||
fatal("UsePAM not set, but ended up in %s anyway", __func__); | fatal("UsePAM not set, but ended up in %s anyway", __func__); | ||||
start_pam(authctxt); | start_pam(ssh); | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); | ||||
if (options.kbd_interactive_authentication) | if (options.kbd_interactive_authentication) | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_pam_account(int sock, struct sshbuf *m) | mm_answer_pam_account(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
u_int ret; | u_int ret; | ||||
int r; | int r; | ||||
if (!options.use_pam) | if (!options.use_pam) | ||||
fatal("%s: PAM not enabled", __func__); | fatal("%s: PAM not enabled", __func__); | ||||
ret = do_pam_account(); | ret = do_pam_account(); | ||||
if ((r = sshbuf_put_u32(m, ret)) != 0 || | if ((r = sshbuf_put_u32(m, ret)) != 0 || | ||||
(r = sshbuf_put_stringb(m, loginmsg)) != 0) | (r = sshbuf_put_stringb(m, loginmsg)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); | mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static void *sshpam_ctxt, *sshpam_authok; | static void *sshpam_ctxt, *sshpam_authok; | ||||
extern KbdintDevice sshpam_device; | extern KbdintDevice sshpam_device; | ||||
int | int | ||||
mm_answer_pam_init_ctx(int sock, struct sshbuf *m) | mm_answer_pam_init_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
u_int ok = 0; | u_int ok = 0; | ||||
int r; | int r; | ||||
debug3("%s", __func__); | debug3("%s", __func__); | ||||
if (!options.kbd_interactive_authentication) | if (!options.kbd_interactive_authentication) | ||||
fatal("%s: kbd-int authentication not enabled", __func__); | fatal("%s: kbd-int authentication not enabled", __func__); | ||||
if (sshpam_ctxt != NULL) | if (sshpam_ctxt != NULL) | ||||
fatal("%s: already called", __func__); | fatal("%s: already called", __func__); | ||||
sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); | sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); | ||||
sshpam_authok = NULL; | sshpam_authok = NULL; | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
if (sshpam_ctxt != NULL) { | if (sshpam_ctxt != NULL) { | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 1); | ||||
ok = 1; | ok = 1; | ||||
} | } | ||||
if ((r = sshbuf_put_u32(m, ok)) != 0) | if ((r = sshbuf_put_u32(m, ok)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); | mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_pam_query(int sock, struct sshbuf *m) | mm_answer_pam_query(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
char *name = NULL, *info = NULL, **prompts = NULL; | char *name = NULL, *info = NULL, **prompts = NULL; | ||||
u_int i, num = 0, *echo_on = 0; | u_int i, num = 0, *echo_on = 0; | ||||
int r, ret; | int r, ret; | ||||
debug3("%s", __func__); | debug3("%s", __func__); | ||||
sshpam_authok = NULL; | sshpam_authok = NULL; | ||||
if (sshpam_ctxt == NULL) | if (sshpam_ctxt == NULL) | ||||
Show All 24 Lines | mm_answer_pam_query(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
free(echo_on); | free(echo_on); | ||||
auth_method = "keyboard-interactive"; | auth_method = "keyboard-interactive"; | ||||
auth_submethod = "pam"; | auth_submethod = "pam"; | ||||
mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); | mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_pam_respond(int sock, struct sshbuf *m) | mm_answer_pam_respond(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
char **resp; | char **resp; | ||||
u_int i, num; | u_int i, num; | ||||
int r, ret; | int r, ret; | ||||
debug3("%s", __func__); | debug3("%s", __func__); | ||||
if (sshpam_ctxt == NULL) | if (sshpam_ctxt == NULL) | ||||
fatal("%s: no context", __func__); | fatal("%s: no context", __func__); | ||||
Show All 21 Lines | mm_answer_pam_respond(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
auth_method = "keyboard-interactive"; | auth_method = "keyboard-interactive"; | ||||
auth_submethod = "pam"; | auth_submethod = "pam"; | ||||
if (ret == 0) | if (ret == 0) | ||||
sshpam_authok = sshpam_ctxt; | sshpam_authok = sshpam_ctxt; | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_pam_free_ctx(int sock, struct sshbuf *m) | mm_answer_pam_free_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; | int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; | ||||
debug3("%s", __func__); | debug3("%s", __func__); | ||||
if (sshpam_ctxt == NULL) | if (sshpam_ctxt == NULL) | ||||
fatal("%s: no context", __func__); | fatal("%s: no context", __func__); | ||||
(sshpam_device.free_ctx)(sshpam_ctxt); | (sshpam_device.free_ctx)(sshpam_ctxt); | ||||
sshpam_ctxt = sshpam_authok = NULL; | sshpam_ctxt = sshpam_authok = NULL; | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); | mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); | ||||
/* Allow another attempt */ | /* Allow another attempt */ | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); | ||||
auth_method = "keyboard-interactive"; | auth_method = "keyboard-interactive"; | ||||
auth_submethod = "pam"; | auth_submethod = "pam"; | ||||
return r; | return r; | ||||
} | } | ||||
#endif | #endif | ||||
int | int | ||||
mm_answer_keyallowed(int sock, struct sshbuf *m) | mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
struct sshkey *key = NULL; | struct sshkey *key = NULL; | ||||
char *cuser, *chost; | char *cuser, *chost; | ||||
u_int pubkey_auth_attempt; | u_int pubkey_auth_attempt; | ||||
enum mm_keytype type = 0; | enum mm_keytype type = 0; | ||||
int r, allowed = 0; | int r, allowed = 0; | ||||
struct sshauthopt *opts = NULL; | struct sshauthopt *opts = NULL; | ||||
debug3("%s entering", __func__); | debug3("%s entering", __func__); | ||||
Show All 14 Lines | if (key != NULL && authctxt->valid) { | ||||
switch (type) { | switch (type) { | ||||
case MM_USERKEY: | case MM_USERKEY: | ||||
auth_method = "publickey"; | auth_method = "publickey"; | ||||
if (!options.pubkey_authentication) | if (!options.pubkey_authentication) | ||||
break; | break; | ||||
if (auth2_key_already_used(authctxt, key)) | if (auth2_key_already_used(authctxt, key)) | ||||
break; | break; | ||||
if (match_pattern_list(sshkey_ssh_name(key), | if (!key_base_type_match(auth_method, key, | ||||
options.pubkey_key_types, 0) != 1) | options.pubkey_key_types)) | ||||
break; | break; | ||||
allowed = user_key_allowed(ssh, authctxt->pw, key, | allowed = user_key_allowed(ssh, authctxt->pw, key, | ||||
pubkey_auth_attempt, &opts); | pubkey_auth_attempt, &opts); | ||||
break; | break; | ||||
case MM_HOSTKEY: | case MM_HOSTKEY: | ||||
auth_method = "hostbased"; | auth_method = "hostbased"; | ||||
if (!options.hostbased_authentication) | if (!options.hostbased_authentication) | ||||
break; | break; | ||||
if (auth2_key_already_used(authctxt, key)) | if (auth2_key_already_used(authctxt, key)) | ||||
break; | break; | ||||
if (match_pattern_list(sshkey_ssh_name(key), | if (!key_base_type_match(auth_method, key, | ||||
options.hostbased_key_types, 0) != 1) | options.hostbased_key_types)) | ||||
break; | break; | ||||
allowed = hostbased_key_allowed(authctxt->pw, | allowed = hostbased_key_allowed(ssh, authctxt->pw, | ||||
cuser, chost, key); | cuser, chost, key); | ||||
auth2_record_info(authctxt, | auth2_record_info(authctxt, | ||||
"client user \"%.100s\", client host \"%.100s\"", | "client user \"%.100s\", client host \"%.100s\"", | ||||
cuser, chost); | cuser, chost); | ||||
break; | break; | ||||
default: | default: | ||||
fatal("%s: unknown key type %d", __func__, type); | fatal("%s: unknown key type %d", __func__, type); | ||||
break; | break; | ||||
Show All 15 Lines | if (allowed) { | ||||
if ((r = sshkey_to_blob(key, &key_blob, &key_bloblen)) != 0) | if ((r = sshkey_to_blob(key, &key_blob, &key_bloblen)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
key_blobtype = type; | key_blobtype = type; | ||||
key_opts = opts; | key_opts = opts; | ||||
hostbased_cuser = cuser; | hostbased_cuser = cuser; | ||||
hostbased_chost = chost; | hostbased_chost = chost; | ||||
} else { | } else { | ||||
/* Log failed attempt */ | /* Log failed attempt */ | ||||
auth_log(authctxt, 0, 0, auth_method, NULL); | auth_log(ssh, 0, 0, auth_method, NULL); | ||||
free(cuser); | free(cuser); | ||||
free(chost); | free(chost); | ||||
} | } | ||||
sshkey_free(key); | sshkey_free(key); | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
if ((r = sshbuf_put_u32(m, allowed)) != 0) | if ((r = sshbuf_put_u32(m, allowed)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, | ||||
if (sshbuf_len(b) != 0) | if (sshbuf_len(b) != 0) | ||||
fail++; | fail++; | ||||
sshbuf_free(b); | sshbuf_free(b); | ||||
return (fail == 0); | return (fail == 0); | ||||
} | } | ||||
int | int | ||||
mm_answer_keyverify(int sock, struct sshbuf *m) | mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
struct sshkey *key; | struct sshkey *key; | ||||
u_char *signature, *data, *blob; | u_char *signature, *data, *blob; | ||||
char *sigalg; | char *sigalg; | ||||
size_t signaturelen, datalen, bloblen; | size_t signaturelen, datalen, bloblen; | ||||
int r, ret, valid_data = 0, encoded_ret; | int r, ret, valid_data = 0, encoded_ret; | ||||
if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || | if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || | ||||
(r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || | (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || | ||||
Show All 28 Lines | mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
default: | default: | ||||
valid_data = 0; | valid_data = 0; | ||||
break; | break; | ||||
} | } | ||||
if (!valid_data) | if (!valid_data) | ||||
fatal("%s: bad signature data blob", __func__); | fatal("%s: bad signature data blob", __func__); | ||||
ret = sshkey_verify(key, signature, signaturelen, data, datalen, | ret = sshkey_verify(key, signature, signaturelen, data, datalen, | ||||
sigalg, active_state->compat); | sigalg, ssh->compat); | ||||
debug3("%s: %s %p signature %s", __func__, auth_method, key, | debug3("%s: %s %p signature %s", __func__, auth_method, key, | ||||
(ret == 0) ? "verified" : "unverified"); | (ret == 0) ? "verified" : "unverified"); | ||||
auth2_record_key(authctxt, ret == 0, key); | auth2_record_key(authctxt, ret == 0, key); | ||||
free(blob); | free(blob); | ||||
free(signature); | free(signature); | ||||
free(data); | free(data); | ||||
free(sigalg); | free(sigalg); | ||||
Show All 10 Lines | mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
if ((r = sshbuf_put_u32(m, encoded_ret)) != 0) | if ((r = sshbuf_put_u32(m, encoded_ret)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); | mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); | ||||
return ret == 0; | return ret == 0; | ||||
} | } | ||||
static void | static void | ||||
mm_record_login(Session *s, struct passwd *pw) | mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
socklen_t fromlen; | socklen_t fromlen; | ||||
struct sockaddr_storage from; | struct sockaddr_storage from; | ||||
/* | /* | ||||
* Get IP address of client. If the connection is not a socket, let | * Get IP address of client. If the connection is not a socket, let | ||||
* the address be 0.0.0.0. | * the address be 0.0.0.0. | ||||
*/ | */ | ||||
memset(&from, 0, sizeof(from)); | memset(&from, 0, sizeof(from)); | ||||
fromlen = sizeof(from); | fromlen = sizeof(from); | ||||
if (packet_connection_is_on_socket()) { | if (ssh_packet_connection_is_on_socket(ssh)) { | ||||
if (getpeername(packet_get_connection_in(), | if (getpeername(ssh_packet_get_connection_in(ssh), | ||||
(struct sockaddr *)&from, &fromlen) < 0) { | (struct sockaddr *)&from, &fromlen) == -1) { | ||||
debug("getpeername: %.100s", strerror(errno)); | debug("getpeername: %.100s", strerror(errno)); | ||||
cleanup_exit(255); | cleanup_exit(255); | ||||
} | } | ||||
} | } | ||||
/* Record that there was a login on that tty from the remote host. */ | /* Record that there was a login on that tty from the remote host. */ | ||||
record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid, | record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid, | ||||
session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), | session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), | ||||
(struct sockaddr *)&from, fromlen); | (struct sockaddr *)&from, fromlen); | ||||
} | } | ||||
static void | static void | ||||
mm_session_close(Session *s) | mm_session_close(Session *s) | ||||
{ | { | ||||
debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); | debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); | ||||
if (s->ttyfd != -1) { | if (s->ttyfd != -1) { | ||||
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); | debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); | ||||
session_pty_cleanup2(s); | session_pty_cleanup2(s); | ||||
} | } | ||||
session_unused(s->self); | session_unused(s->self); | ||||
} | } | ||||
int | int | ||||
mm_answer_pty(int sock, struct sshbuf *m) | mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
extern struct monitor *pmonitor; | extern struct monitor *pmonitor; | ||||
Session *s; | Session *s; | ||||
int r, res, fd0; | int r, res, fd0; | ||||
debug3("%s entering", __func__); | debug3("%s entering", __func__); | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
Show All 11 Lines | mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
if ((r = sshbuf_put_u32(m, 1)) != 0 || | if ((r = sshbuf_put_u32(m, 1)) != 0 || | ||||
(r = sshbuf_put_cstring(m, s->tty)) != 0) | (r = sshbuf_put_cstring(m, s->tty)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
/* We need to trick ttyslot */ | /* We need to trick ttyslot */ | ||||
if (dup2(s->ttyfd, 0) == -1) | if (dup2(s->ttyfd, 0) == -1) | ||||
fatal("%s: dup2", __func__); | fatal("%s: dup2", __func__); | ||||
mm_record_login(s, authctxt->pw); | mm_record_login(ssh, s, authctxt->pw); | ||||
/* Now we can close the file descriptor again */ | /* Now we can close the file descriptor again */ | ||||
close(0); | close(0); | ||||
/* send messages generated by record_login */ | /* send messages generated by record_login */ | ||||
if ((r = sshbuf_put_stringb(m, loginmsg)) != 0) | if ((r = sshbuf_put_stringb(m, loginmsg)) != 0) | ||||
fatal("%s: put login message: %s", __func__, ssh_err(r)); | fatal("%s: put login message: %s", __func__, ssh_err(r)); | ||||
sshbuf_reset(loginmsg); | sshbuf_reset(loginmsg); | ||||
mm_request_send(sock, MONITOR_ANS_PTY, m); | mm_request_send(sock, MONITOR_ANS_PTY, m); | ||||
if (mm_send_fd(sock, s->ptyfd) == -1 || | if (mm_send_fd(sock, s->ptyfd) == -1 || | ||||
mm_send_fd(sock, s->ttyfd) == -1) | mm_send_fd(sock, s->ttyfd) == -1) | ||||
fatal("%s: send fds failed", __func__); | fatal("%s: send fds failed", __func__); | ||||
/* make sure nothing uses fd 0 */ | /* make sure nothing uses fd 0 */ | ||||
if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) | if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) == -1) | ||||
fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); | fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); | ||||
if (fd0 != 0) | if (fd0 != 0) | ||||
error("%s: fd0 %d != 0", __func__, fd0); | error("%s: fd0 %d != 0", __func__, fd0); | ||||
/* slave is not needed */ | /* slave is not needed */ | ||||
close(s->ttyfd); | close(s->ttyfd); | ||||
s->ttyfd = s->ptyfd; | s->ttyfd = s->ptyfd; | ||||
/* no need to dup() because nobody closes ptyfd */ | /* no need to dup() because nobody closes ptyfd */ | ||||
s->ptymaster = s->ptyfd; | s->ptymaster = s->ptyfd; | ||||
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); | debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); | ||||
return (0); | return (0); | ||||
error: | error: | ||||
if (s != NULL) | if (s != NULL) | ||||
mm_session_close(s); | mm_session_close(s); | ||||
if ((r = sshbuf_put_u32(m, 0)) != 0) | if ((r = sshbuf_put_u32(m, 0)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
mm_request_send(sock, MONITOR_ANS_PTY, m); | mm_request_send(sock, MONITOR_ANS_PTY, m); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_pty_cleanup(int sock, struct sshbuf *m) | mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
Session *s; | Session *s; | ||||
char *tty; | char *tty; | ||||
int r; | int r; | ||||
debug3("%s entering", __func__); | debug3("%s entering", __func__); | ||||
if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) | if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
if ((s = session_by_tty(tty)) != NULL) | if ((s = session_by_tty(tty)) != NULL) | ||||
mm_session_close(s); | mm_session_close(s); | ||||
sshbuf_reset(m); | sshbuf_reset(m); | ||||
free(tty); | free(tty); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_term(int sock, struct sshbuf *req) | mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
extern struct monitor *pmonitor; | extern struct monitor *pmonitor; | ||||
int res, status; | int res, status; | ||||
debug3("%s: tearing down sessions", __func__); | debug3("%s: tearing down sessions", __func__); | ||||
/* The child is terminating */ | /* The child is terminating */ | ||||
session_destroy_all(ssh, &mm_session_close); | session_destroy_all(ssh, &mm_session_close); | ||||
Show All 10 Lines | #endif | ||||
/* Terminate process */ | /* Terminate process */ | ||||
exit(res); | exit(res); | ||||
} | } | ||||
#ifdef SSH_AUDIT_EVENTS | #ifdef SSH_AUDIT_EVENTS | ||||
/* Report that an audit event occurred */ | /* Report that an audit event occurred */ | ||||
int | int | ||||
mm_answer_audit_event(int socket, struct sshbuf *m) | mm_answer_audit_event(struct ssh *ssh, int socket, struct sshbuf *m) | ||||
{ | { | ||||
u_int n; | u_int n; | ||||
ssh_audit_event_t event; | ssh_audit_event_t event; | ||||
int r; | int r; | ||||
debug3("%s entering", __func__); | debug3("%s entering", __func__); | ||||
if ((r = sshbuf_get_u32(m, &n)) != 0) | if ((r = sshbuf_get_u32(m, &n)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
event = (ssh_audit_event_t)n; | event = (ssh_audit_event_t)n; | ||||
switch (event) { | switch (event) { | ||||
case SSH_AUTH_FAIL_PUBKEY: | case SSH_AUTH_FAIL_PUBKEY: | ||||
case SSH_AUTH_FAIL_HOSTBASED: | case SSH_AUTH_FAIL_HOSTBASED: | ||||
case SSH_AUTH_FAIL_GSSAPI: | case SSH_AUTH_FAIL_GSSAPI: | ||||
case SSH_LOGIN_EXCEED_MAXTRIES: | case SSH_LOGIN_EXCEED_MAXTRIES: | ||||
case SSH_LOGIN_ROOT_DENIED: | case SSH_LOGIN_ROOT_DENIED: | ||||
case SSH_CONNECTION_CLOSE: | case SSH_CONNECTION_CLOSE: | ||||
case SSH_INVALID_USER: | case SSH_INVALID_USER: | ||||
audit_event(event); | audit_event(ssh, event); | ||||
break; | break; | ||||
default: | default: | ||||
fatal("Audit event type %d not permitted", event); | fatal("Audit event type %d not permitted", event); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_audit_command(int socket, struct sshbuf *m) | mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) | ||||
{ | { | ||||
char *cmd; | char *cmd; | ||||
int r; | int r; | ||||
debug3("%s entering", __func__); | debug3("%s entering", __func__); | ||||
if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) | if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
/* sanity check command, if so how? */ | /* sanity check command, if so how? */ | ||||
audit_run_command(cmd); | audit_run_command(cmd); | ||||
free(cmd); | free(cmd); | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif /* SSH_AUDIT_EVENTS */ | #endif /* SSH_AUDIT_EVENTS */ | ||||
void | void | ||||
monitor_clear_keystate(struct monitor *pmonitor) | monitor_clear_keystate(struct ssh *ssh, struct monitor *pmonitor) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
ssh_clear_newkeys(ssh, MODE_IN); | ssh_clear_newkeys(ssh, MODE_IN); | ||||
ssh_clear_newkeys(ssh, MODE_OUT); | ssh_clear_newkeys(ssh, MODE_OUT); | ||||
sshbuf_free(child_state); | sshbuf_free(child_state); | ||||
child_state = NULL; | child_state = NULL; | ||||
} | } | ||||
void | void | ||||
monitor_apply_keystate(struct monitor *pmonitor) | monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) | ||||
{ | { | ||||
struct ssh *ssh = active_state; /* XXX */ | |||||
struct kex *kex; | struct kex *kex; | ||||
int r; | int r; | ||||
debug3("%s: packet_set_state", __func__); | debug3("%s: packet_set_state", __func__); | ||||
if ((r = ssh_packet_set_state(ssh, child_state)) != 0) | if ((r = ssh_packet_set_state(ssh, child_state)) != 0) | ||||
fatal("%s: packet_set_state: %s", __func__, ssh_err(r)); | fatal("%s: packet_set_state: %s", __func__, ssh_err(r)); | ||||
sshbuf_free(child_state); | sshbuf_free(child_state); | ||||
child_state = NULL; | child_state = NULL; | ||||
if ((kex = ssh->kex) != NULL) { | if ((kex = ssh->kex) != NULL) { | ||||
/* XXX set callbacks */ | /* XXX set callbacks */ | ||||
#ifdef WITH_OPENSSL | #ifdef WITH_OPENSSL | ||||
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; | ||||
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; | kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; | ||||
kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; | kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; | ||||
kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; | kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; | ||||
kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server; | kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; | ||||
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | ||||
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | ||||
# ifdef OPENSSL_HAS_ECC | # ifdef OPENSSL_HAS_ECC | ||||
kex->kex[KEX_ECDH_SHA2] = kexecdh_server; | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; | ||||
# endif | # endif | ||||
#endif /* WITH_OPENSSL */ | #endif /* WITH_OPENSSL */ | ||||
kex->kex[KEX_C25519_SHA256] = kexc25519_server; | kex->kex[KEX_C25519_SHA256] = kex_gen_server; | ||||
kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; | |||||
kex->load_host_public_key=&get_hostkey_public_by_type; | kex->load_host_public_key=&get_hostkey_public_by_type; | ||||
kex->load_host_private_key=&get_hostkey_private_by_type; | kex->load_host_private_key=&get_hostkey_private_by_type; | ||||
kex->host_key_index=&get_hostkey_index; | kex->host_key_index=&get_hostkey_index; | ||||
kex->sign = sshd_hostkey_sign; | kex->sign = sshd_hostkey_sign; | ||||
} | } | ||||
} | } | ||||
/* This function requries careful sanity checking */ | /* This function requries careful sanity checking */ | ||||
void | void | ||||
mm_get_keystate(struct monitor *pmonitor) | mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) | ||||
{ | { | ||||
debug3("%s: Waiting for new keys", __func__); | debug3("%s: Waiting for new keys", __func__); | ||||
if ((child_state = sshbuf_new()) == NULL) | if ((child_state = sshbuf_new()) == NULL) | ||||
fatal("%s: sshbuf_new failed", __func__); | fatal("%s: sshbuf_new failed", __func__); | ||||
mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, | mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, | ||||
child_state); | child_state); | ||||
debug3("%s: GOT new keys", __func__); | debug3("%s: GOT new keys", __func__); | ||||
Show All 13 Lines | monitor_openfds(struct monitor *mon, int do_logfds) | ||||
int pair[2]; | int pair[2]; | ||||
#ifdef SO_ZEROIZE | #ifdef SO_ZEROIZE | ||||
int on = 1; | int on = 1; | ||||
#endif | #endif | ||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) | if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) | ||||
fatal("%s: socketpair: %s", __func__, strerror(errno)); | fatal("%s: socketpair: %s", __func__, strerror(errno)); | ||||
#ifdef SO_ZEROIZE | #ifdef SO_ZEROIZE | ||||
if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0) | if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) == -1) | ||||
error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno)); | error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno)); | ||||
if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0) | if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) == -1) | ||||
error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno)); | error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno)); | ||||
#endif | #endif | ||||
FD_CLOSEONEXEC(pair[0]); | FD_CLOSEONEXEC(pair[0]); | ||||
FD_CLOSEONEXEC(pair[1]); | FD_CLOSEONEXEC(pair[1]); | ||||
mon->m_recvfd = pair[0]; | mon->m_recvfd = pair[0]; | ||||
mon->m_sendfd = pair[1]; | mon->m_sendfd = pair[1]; | ||||
if (do_logfds) { | if (do_logfds) { | ||||
Show All 23 Lines | |||||
void | void | ||||
monitor_reinit(struct monitor *mon) | monitor_reinit(struct monitor *mon) | ||||
{ | { | ||||
monitor_openfds(mon, 0); | monitor_openfds(mon, 0); | ||||
} | } | ||||
#ifdef GSSAPI | #ifdef GSSAPI | ||||
int | int | ||||
mm_answer_gss_setup_ctx(int sock, struct sshbuf *m) | mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
gss_OID_desc goid; | gss_OID_desc goid; | ||||
OM_uint32 major; | OM_uint32 major; | ||||
size_t len; | size_t len; | ||||
u_char *p; | u_char *p; | ||||
int r; | int r; | ||||
if (!options.gss_authentication) | if (!options.gss_authentication) | ||||
Show All 16 Lines | mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
/* Now we have a context, enable the step */ | /* Now we have a context, enable the step */ | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) | mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
gss_buffer_desc in; | gss_buffer_desc in; | ||||
gss_buffer_desc out = GSS_C_EMPTY_BUFFER; | gss_buffer_desc out = GSS_C_EMPTY_BUFFER; | ||||
OM_uint32 major, minor; | OM_uint32 major, minor; | ||||
OM_uint32 flags = 0; /* GSI needs this */ | OM_uint32 flags = 0; /* GSI needs this */ | ||||
int r; | int r; | ||||
if (!options.gss_authentication) | if (!options.gss_authentication) | ||||
Show All 17 Lines | if (major == GSS_S_COMPLETE) { | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_gss_checkmic(int sock, struct sshbuf *m) | mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
gss_buffer_desc gssbuf, mic; | gss_buffer_desc gssbuf, mic; | ||||
OM_uint32 ret; | OM_uint32 ret; | ||||
int r; | int r; | ||||
if (!options.gss_authentication) | if (!options.gss_authentication) | ||||
fatal("%s: GSSAPI authentication not enabled", __func__); | fatal("%s: GSSAPI authentication not enabled", __func__); | ||||
Show All 14 Lines | mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
if (!GSS_ERROR(ret)) | if (!GSS_ERROR(ret)) | ||||
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
mm_answer_gss_userok(int sock, struct sshbuf *m) | mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
{ | { | ||||
int r, authenticated; | int r, authenticated; | ||||
const char *displayname; | const char *displayname; | ||||
if (!options.gss_authentication) | if (!options.gss_authentication) | ||||
fatal("%s: GSSAPI authentication not enabled", __func__); | fatal("%s: GSSAPI authentication not enabled", __func__); | ||||
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | ||||
Show All 18 Lines |