*/
#include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $");
+RCSID("$OpenBSD: monitor.c,v 1.55 2004/02/05 05:37:17 dtucker Exp $");
#include <openssl/dh.h>
#include "auth.h"
#include "kex.h"
#include "dh.h"
+#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
+#undef TARGET_OS_MAC
#include "zlib.h"
+#define TARGET_OS_MAC 1
+#else
+#include "zlib.h"
+#endif
#include "packet.h"
#include "auth-options.h"
#include "sshpty.h"
int mm_answer_gss_setup_ctx(int, Buffer *);
int mm_answer_gss_accept_ctx(int, Buffer *);
int mm_answer_gss_userok(int, Buffer *);
+int mm_answer_gss_checkmic(int, Buffer *);
#endif
#ifdef GSSAPI
{MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error},
{MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
{MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname},
+ {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
#endif
{0, 0, NULL}
};
}
}
-Authctxt *
-monitor_child_preauth(struct monitor *pmonitor)
+void
+monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
{
struct mon_table *ent;
int authenticated = 0;
debug3("preauth child monitor started");
+ authctxt = _authctxt;
+ memset(authctxt, 0, sizeof(*authctxt));
+
if (compat20) {
mon_dispatch = mon_dispatch_proto20;
monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
}
- authctxt = authctxt_new();
-
/* The first few requests do not require asynchronous access */
while (!authenticated) {
authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
authenticated = 0;
#ifdef USE_PAM
/* PAM needs to perform account checks after auth */
- if (options.use_pam) {
+ if (options.use_pam && authenticated) {
Buffer m;
buffer_init(&m);
- mm_request_receive_expect(pmonitor->m_sendfd,
+ mm_request_receive_expect(pmonitor->m_sendfd,
MONITOR_REQ_PAM_ACCOUNT, &m);
authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m);
buffer_free(&m);
__func__, authctxt->user);
mm_get_keystate(pmonitor);
-
- return (authctxt);
}
static void
if (pwent == NULL) {
buffer_put_char(m, 0);
+ authctxt->pw = fakepw();
goto out;
}
char challenge[1024];
u_int success;
- success = skeychallenge(&skey, authctxt->user, challenge) < 0 ? 0 : 1;
+ success = _compat_skeychallenge(&skey, authctxt->user, challenge,
+ sizeof(challenge)) < 0 ? 0 : 1;
buffer_clear(m);
buffer_put_int(m, success);
int
mm_answer_pam_start(int socket, Buffer *m)
{
- char *user;
-
if (!options.use_pam)
fatal("UsePAM not set, but ended up in %s anyway", __func__);
- user = buffer_get_string(m, NULL);
-
- start_pam(user);
-
- xfree(user);
+ start_pam(authctxt);
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1);
mm_answer_pam_account(int socket, Buffer *m)
{
u_int ret;
-
+
if (!options.use_pam)
fatal("UsePAM not set, but ended up in %s anyway", __func__);
debug3("%s: key_from_blob: %p", __func__, key);
- if (key != NULL && authctxt->pw != NULL) {
+ if (key != NULL && authctxt->valid) {
switch(type) {
case MM_USERKEY:
allowed = options.pubkey_authentication &&
if (getpeername(packet_get_connection_in(),
(struct sockaddr *) & from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno));
- fatal_cleanup();
+ cleanup_exit(255);
}
}
/* Record that there was a login on that tty from the remote host. */
debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
if (s->ttyfd != -1) {
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
- fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
session_pty_cleanup2(s);
}
s->used = 0;
res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
if (res == 0)
goto error;
- fatal_add_cleanup(session_pty_cleanup2, (void *)s);
pty_setowner(authctxt->pw, s->tty);
buffer_put_int(m, 1);
mon = xmalloc(sizeof(*mon));
+ mon->m_pid = 0;
monitor_socketpair(pair);
mon->m_recvfd = pair[0];
gss_release_buffer(&minor, &out);
- /* Complete - now we can do signing */
if (major==GSS_S_COMPLETE) {
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
}
return (0);
}
+int
+mm_answer_gss_checkmic(int socket, Buffer *m)
+{
+ gss_buffer_desc gssbuf, mic;
+ OM_uint32 ret;
+ u_int len;
+
+ gssbuf.value = buffer_get_string(m, &len);
+ gssbuf.length = len;
+ mic.value = buffer_get_string(m, &len);
+ mic.length = len;
+
+ ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic);
+
+ xfree(gssbuf.value);
+ xfree(mic.value);
+
+ buffer_clear(m);
+ buffer_put_int(m, ret);
+
+ mm_request_send(socket, MONITOR_ANS_GSSCHECKMIC, m);
+
+ if (!GSS_ERROR(ret))
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
+
+ return (0);
+}
+
int
mm_answer_gss_userok(int socket, Buffer *m)
{
debug3("%s: sending result %d", __func__, authenticated);
mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
- auth_method="gssapi";
+ auth_method="gssapi-with-mic";
/* Monitor loop will terminate if authenticated */
return (authenticated);
mm_answer_gss_sign(int socket, Buffer *m) {
gss_buffer_desc data,hash;
OM_uint32 major,minor;
+ u_int len;
- data.value = buffer_get_string(m,&data.length);
- if (data.length != 16) { /* HACK - i.e. we are using SSHv1 */
+ data.value = buffer_get_string(m, &len);
+ data.length = len;
if (data.length != 20)
- fatal("%s: data length incorrect: %d", __func__, data.length);
+ fatal("%s: data length incorrect: %d", __func__,
+ (int)data.length);
/* Save the session ID - only first time round */
if (session_id2_len == 0) {
session_id2 = xmalloc(session_id2_len);
memcpy(session_id2, data.value, session_id2_len);
}
- } /* HACK - end */
major=ssh_gssapi_sign(gsscontext, &data, &hash);
xfree(data.value);