From eab4bae03894f07ea556db4d781795c724245af7 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 29 Apr 2003 23:22:40 +1000 Subject: - (djm) Add back radix.o (used by AFS support), after it went missing from Makefile many moons ago - (djm) Apply "owl-always-auth" patch from Openwall/Solar Designer - (djm) Fix blibpath specification for AIX/gcc - (djm) Some systems have basename in -lgen. Fix from ayamura@ayamura.org --- monitor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'monitor.c') diff --git a/monitor.c b/monitor.c index 46db0e9b0..99b4d56ec 100644 --- a/monitor.c +++ b/monitor.c @@ -606,7 +606,7 @@ mm_answer_authpassword(int socket, Buffer *m) passwd = buffer_get_string(m, &plen); /* Only authenticate if the context is valid */ authenticated = options.password_authentication && - authctxt->valid && auth_password(authctxt, passwd); + auth_password(authctxt, passwd) && authctxt->valid; memset(passwd, 0, strlen(passwd)); xfree(passwd); -- cgit v1.2.3 From 4f9f42a9bb6a6aa8f6100d873dc6344f2f9994de Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 10 May 2003 19:28:02 +1000 Subject: - (djm) Merge FreeBSD PAM code: replaces PAM password auth kludge with proper challenge-response module --- ChangeLog | 4 +- Makefile.in | 4 +- auth-chall.c | 26 ++ auth-pam.c | 895 +++++++++++++++++++++++++++++++++++---------------------- auth-pam.h | 6 +- auth-passwd.c | 16 +- auth.h | 3 +- auth1.c | 14 +- auth2-chall.c | 19 +- auth2-kbdint.c | 4 - auth2-pam.c | 165 ----------- auth2-pam.h | 8 - configure.ac | 4 +- monitor.c | 113 +++++++- monitor.h | 5 + monitor_wrap.c | 82 ++++++ monitor_wrap.h | 5 + 17 files changed, 819 insertions(+), 554 deletions(-) delete mode 100644 auth2-pam.c delete mode 100644 auth2-pam.h (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index 5b4ff341b..4acedd1a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ "make install". Patch by roth@feep.net. - (dtucker) Bug #536: Test for and work around openpty/controlling tty problem on Linux (fixes "could not set controlling tty" errors). + - (djm) Merge FreeBSD PAM code: replaces PAM password auth kludge with + proper challenge-response module 20030504 - (dtucker) Bug #497: Move #include of bsd-cygwin_util.h to openbsd-compat.h. @@ -1376,4 +1378,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2672 2003/05/10 07:05:46 dtucker Exp $ +$Id: ChangeLog,v 1.2673 2003/05/10 09:28:02 djm Exp $ diff --git a/Makefile.in b/Makefile.in index 23a9d413c..670d9b500 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.230 2003/05/10 06:48:23 dtucker Exp $ +# $Id: Makefile.in,v 1.231 2003/05/10 09:28:02 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -81,7 +81,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ monitor_mm.o monitor.o monitor_wrap.o monitor_fdpass.o \ kexdhs.o kexgexs.o \ auth-krb5.o auth-krb4.o \ - loginrec.o auth-pam.o auth2-pam.o auth-sia.o md5crypt.o + loginrec.o auth-pam.o auth-sia.o md5crypt.o MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 diff --git a/auth-chall.c b/auth-chall.c index 45e0c3452..6b7c8bd13 100644 --- a/auth-chall.c +++ b/auth-chall.c @@ -76,7 +76,33 @@ verify_response(Authctxt *authctxt, const char *response) return 0; resp[0] = (char *)response; res = device->respond(authctxt->kbdintctxt, 1, resp); + if (res == 1) { + /* postponed - send a null query just in case */ + char *name, *info, **prompts; + u_int i, numprompts, *echo_on; + + res = device->query(authctxt->kbdintctxt, &name, &info, + &numprompts, &prompts, &echo_on); + if (res == 0) { + for (i = 0; i < numprompts; i++) + xfree(prompts[i]); + xfree(prompts); + xfree(name); + xfree(echo_on); + xfree(info); + } + /* if we received more prompts, we're screwed */ + res = (numprompts != 0); + } device->free_ctx(authctxt->kbdintctxt); authctxt->kbdintctxt = NULL; return res ? 0 : 1; } +void +abandon_challenge_response(Authctxt *authctxt) +{ + if (authctxt->kbdintctxt != NULL) { + device->free_ctx(authctxt->kbdintctxt); + authctxt->kbdintctxt = NULL; + } +} diff --git a/auth-pam.c b/auth-pam.c index f3d1956ea..f4718035d 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -1,5 +1,11 @@ -/* - * Copyright (c) 2000 Damien Miller. All rights reserved. +/*- + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by ThinkSec AS and + * NAI Labs, the Security Research Division of Network Associates, Inc. + * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the + * DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,446 +16,633 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include "includes.h" +RCSID("$FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $"); #ifdef USE_PAM -#include "xmalloc.h" -#include "log.h" +#include + #include "auth.h" -#include "auth-options.h" #include "auth-pam.h" -#include "servconf.h" +#include "buffer.h" +#include "bufaux.h" #include "canohost.h" +#include "log.h" +#include "monitor_wrap.h" +#include "msg.h" +#include "packet.h" #include "readpass.h" +#include "servconf.h" +#include "ssh2.h" +#include "xmalloc.h" -extern char *__progname; - -extern int use_privsep; +#define __unused -RCSID("$Id: auth-pam.c,v 1.57 2003/04/29 13:22:40 djm Exp $"); +#ifdef USE_POSIX_THREADS +#include +/* + * Avoid namespace clash when *not* using pthreads for systems *with* + * pthreads, which unconditionally define pthread_t via sys/types.h + * (e.g. Linux) + */ +typedef pthread_t sp_pthread_t; +#else +/* + * Simulate threads with processes. + */ +typedef pid_t sp_pthread_t; -#define NEW_AUTHTOK_MSG \ - "Warning: Your password has expired, please change it now." -#define NEW_AUTHTOK_MSG_PRIVSEP \ - "Your password has expired, the session cannot proceed." +static void +pthread_exit(void *value __unused) +{ + _exit(0); +} -static int do_pam_conversation(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr); +static int +pthread_create(sp_pthread_t *thread, const void *attr __unused, + void *(*thread_start)(void *), void *arg) +{ + pid_t pid; + + switch ((pid = fork())) { + case -1: + error("fork(): %s", strerror(errno)); + return (-1); + case 0: + thread_start(arg); + _exit(1); + default: + *thread = pid; + return (0); + } +} -/* module-local variables */ -static struct pam_conv conv = { - (int (*)())do_pam_conversation, - NULL -}; -static char *__pam_msg = NULL; -static pam_handle_t *__pamh = NULL; -static const char *__pampasswd = NULL; - -/* states for do_pam_conversation() */ -enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN; -/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */ -static int password_change_required = 0; -/* remember whether the last pam_authenticate() succeeded or not */ -static int was_authenticated = 0; - -/* Remember what has been initialised */ -static int session_opened = 0; -static int creds_set = 0; - -/* accessor which allows us to switch conversation structs according to - * the authentication method being used */ -void do_pam_set_conv(struct pam_conv *conv) +static int +pthread_cancel(sp_pthread_t thread) { - pam_set_item(__pamh, PAM_CONV, conv); + return (kill(thread, SIGTERM)); } -/* start an authentication run */ -int do_pam_authenticate(int flags) +static int +pthread_join(sp_pthread_t thread, void **value __unused) { - int retval = pam_authenticate(__pamh, flags); - was_authenticated = (retval == PAM_SUCCESS); - return retval; + int status; + + waitpid(thread, &status, 0); + return (status); } +#endif + + +static pam_handle_t *sshpam_handle; +static int sshpam_err; +static int sshpam_authenticated; +static int sshpam_new_authtok_reqd; +static int sshpam_session_open; +static int sshpam_cred_established; + +struct pam_ctxt { + sp_pthread_t pam_thread; + int pam_psock; + int pam_csock; + int pam_done; +}; + +static void sshpam_free_ctx(void *); /* - * PAM conversation function. - * There are two states this can run in. - * - * INITIAL_LOGIN mode simply feeds the password from the client into - * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output - * messages with into __pam_msg. This is used during initial - * authentication to bypass the normal PAM password prompt. - * - * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase() - * and outputs messages to stderr. This mode is used if pam_chauthtok() - * is called to update expired passwords. + * Conversation function for authentication thread. */ -static int do_pam_conversation(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr) +static int +sshpam_thread_conv(int n, + const struct pam_message **msg, + struct pam_response **resp, + void *data) { - struct pam_response *reply; - int count; - char buf[1024]; - - /* PAM will free this later */ - reply = xmalloc(num_msg * sizeof(*reply)); - - for (count = 0; count < num_msg; count++) { - if (pamstate == INITIAL_LOGIN) { - /* - * We can't use stdio yet, queue messages for - * printing later - */ - switch(PAM_MSG_MEMBER(msg, count, msg_style)) { - case PAM_PROMPT_ECHO_ON: - xfree(reply); - return PAM_CONV_ERR; - case PAM_PROMPT_ECHO_OFF: - if (__pampasswd == NULL) { - xfree(reply); - return PAM_CONV_ERR; - } - reply[count].resp = xstrdup(__pampasswd); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - if (PAM_MSG_MEMBER(msg, count, msg) != NULL) { - message_cat(&__pam_msg, - PAM_MSG_MEMBER(msg, count, msg)); - } - reply[count].resp = xstrdup(""); - reply[count].resp_retcode = PAM_SUCCESS; - break; - default: - xfree(reply); - return PAM_CONV_ERR; - } - } else { - /* - * stdio is connected, so interact directly - */ - switch(PAM_MSG_MEMBER(msg, count, msg_style)) { - case PAM_PROMPT_ECHO_ON: - fputs(PAM_MSG_MEMBER(msg, count, msg), stderr); - fgets(buf, sizeof(buf), stdin); - reply[count].resp = xstrdup(buf); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_PROMPT_ECHO_OFF: - reply[count].resp = - read_passphrase(PAM_MSG_MEMBER(msg, count, - msg), RP_ALLOW_STDIN); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - if (PAM_MSG_MEMBER(msg, count, msg) != NULL) - fprintf(stderr, "%s\n", - PAM_MSG_MEMBER(msg, count, msg)); - reply[count].resp = xstrdup(""); - reply[count].resp_retcode = PAM_SUCCESS; - break; - default: - xfree(reply); - return PAM_CONV_ERR; - } + Buffer buffer; + struct pam_ctxt *ctxt; + int i; + + ctxt = data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + *resp = xmalloc(n * sizeof **resp); + buffer_init(&buffer); + for (i = 0; i < n; ++i) { + resp[i]->resp_retcode = 0; + resp[i]->resp = NULL; + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + ssh_msg_recv(ctxt->pam_csock, &buffer); + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + resp[i]->resp = buffer_get_string(&buffer, NULL); + break; + case PAM_PROMPT_ECHO_ON: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + ssh_msg_recv(ctxt->pam_csock, &buffer); + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + resp[i]->resp = buffer_get_string(&buffer, NULL); + break; + case PAM_ERROR_MSG: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + break; + case PAM_TEXT_INFO: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + break; + default: + goto fail; } + buffer_clear(&buffer); } + buffer_free(&buffer); + return (PAM_SUCCESS); + fail: + while (i) + xfree(resp[--i]); + xfree(*resp); + *resp = NULL; + buffer_free(&buffer); + return (PAM_CONV_ERR); +} - *resp = reply; +/* + * Authentication thread. + */ +static void * +sshpam_thread(void *ctxtp) +{ + struct pam_ctxt *ctxt = ctxtp; + Buffer buffer; + struct pam_conv sshpam_conv = { sshpam_thread_conv, ctxt }; +#ifndef USE_POSIX_THREADS + const char *pam_user; + + pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); + setproctitle("%s [pam]", pam_user); +#endif - return PAM_SUCCESS; + buffer_init(&buffer); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&sshpam_conv); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + sshpam_err = pam_authenticate(sshpam_handle, 0); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + sshpam_err = pam_acct_mgmt(sshpam_handle, 0); + if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) + goto auth_fail; + buffer_put_cstring(&buffer, "OK"); + ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); + buffer_free(&buffer); + pthread_exit(NULL); + + auth_fail: + buffer_put_cstring(&buffer, + pam_strerror(sshpam_handle, sshpam_err)); + ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); + buffer_free(&buffer); + pthread_exit(NULL); + + return (NULL); /* Avoid warning for non-pthread case */ } -/* Called at exit to cleanly shutdown PAM */ -void do_pam_cleanup_proc(void *context) +static void +sshpam_thread_cleanup(void *ctxtp) { - int pam_retval = PAM_SUCCESS; + struct pam_ctxt *ctxt = ctxtp; - if (__pamh && session_opened) { - pam_retval = pam_close_session(__pamh, 0); - if (pam_retval != PAM_SUCCESS) - logit("Cannot close PAM session[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } + pthread_cancel(ctxt->pam_thread); + pthread_join(ctxt->pam_thread, NULL); + close(ctxt->pam_psock); + close(ctxt->pam_csock); +} - if (__pamh && creds_set) { - pam_retval = pam_setcred(__pamh, PAM_DELETE_CRED); - if (pam_retval != PAM_SUCCESS) - debug("Cannot delete credentials[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } +static int +sshpam_null_conv(int n, + const struct pam_message **msg, + struct pam_response **resp, + void *data) +{ + + return (PAM_CONV_ERR); +} - if (__pamh) { - pam_retval = pam_end(__pamh, pam_retval); - if (pam_retval != PAM_SUCCESS) - logit("Cannot release PAM authentication[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); +static struct pam_conv null_conv = { sshpam_null_conv, NULL }; + +static void +sshpam_cleanup(void *arg) +{ + (void)arg; + debug("PAM: cleanup"); + pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); + if (sshpam_cred_established) { + pam_setcred(sshpam_handle, PAM_DELETE_CRED); + sshpam_cred_established = 0; + } + if (sshpam_session_open) { + pam_close_session(sshpam_handle, PAM_SILENT); + sshpam_session_open = 0; } + sshpam_authenticated = sshpam_new_authtok_reqd = 0; + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; } -/* Attempt password authentication using PAM */ -int auth_pam_password(Authctxt *authctxt, const char *password) +static int +sshpam_init(const char *user) { extern ServerOptions options; - int pam_retval; - struct passwd *pw = authctxt->pw; - - do_pam_set_conv(&conv); - - __pampasswd = password; - - pamstate = INITIAL_LOGIN; - pam_retval = do_pam_authenticate( - options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0); - if (pam_retval == PAM_SUCCESS && pw) { - debug("PAM password authentication accepted for " - "%.100s", pw->pw_name); - return 1; - } else { - debug("PAM password authentication failed for " - "%.100s: %s", pw ? pw->pw_name : "an illegal user", - PAM_STRERROR(__pamh, pam_retval)); - return 0; + extern u_int utmp_len; + const char *pam_rhost, *pam_user; + + if (sshpam_handle != NULL) { + /* We already have a PAM context; check if the user matches */ + sshpam_err = pam_get_item(sshpam_handle, + PAM_USER, (const void **)&pam_user); + if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) + return (0); + fatal_remove_cleanup(sshpam_cleanup, NULL); + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + } + debug("PAM: initializing for \"%s\"", user); + sshpam_err = pam_start("sshd", user, &null_conv, &sshpam_handle); + if (sshpam_err != PAM_SUCCESS) + return (-1); + pam_rhost = get_remote_name_or_ip(utmp_len, + options.verify_reverse_mapping); + debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); + sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); } + fatal_add_cleanup(sshpam_cleanup, NULL); + return (0); } -/* Do account management using PAM */ -int do_pam_account(char *username, char *remote_user) +static void * +sshpam_init_ctx(Authctxt *authctxt) { - int pam_retval; + struct pam_ctxt *ctxt; + int socks[2]; - do_pam_set_conv(&conv); + /* Initialize PAM */ + if (sshpam_init(authctxt->user) == -1) { + error("PAM: initialization failed"); + return (NULL); + } - if (remote_user) { - debug("PAM setting ruser to \"%.200s\"", remote_user); - pam_retval = pam_set_item(__pamh, PAM_RUSER, remote_user); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set ruser failed[%d]: %.200s", pam_retval, - PAM_STRERROR(__pamh, pam_retval)); + ctxt = xmalloc(sizeof *ctxt); + ctxt->pam_done = 0; + + /* Start the authentication thread */ + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { + error("PAM: failed create sockets: %s", strerror(errno)); + xfree(ctxt); + return (NULL); + } + ctxt->pam_psock = socks[0]; + ctxt->pam_csock = socks[1]; + if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) { + error("PAM: failed to start authentication thread: %s", + strerror(errno)); + close(socks[0]); + close(socks[1]); + xfree(ctxt); + return (NULL); } + fatal_add_cleanup(sshpam_thread_cleanup, ctxt); + return (ctxt); +} - pam_retval = pam_acct_mgmt(__pamh, 0); - debug2("pam_acct_mgmt() = %d", pam_retval); - switch (pam_retval) { - case PAM_SUCCESS: - /* This is what we want */ +static int +sshpam_query(void *ctx, char **name, char **info, + u_int *num, char ***prompts, u_int **echo_on) +{ + Buffer buffer; + struct pam_ctxt *ctxt = ctx; + size_t plen; + u_char type; + char *msg; + + buffer_init(&buffer); + *name = xstrdup(""); + *info = xstrdup(""); + *prompts = xmalloc(sizeof(char *)); + **prompts = NULL; + plen = 0; + *echo_on = xmalloc(sizeof(u_int)); + while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { + type = buffer_get_char(&buffer); + msg = buffer_get_string(&buffer, NULL); + switch (type) { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + *num = 1; + **prompts = xrealloc(**prompts, plen + strlen(msg) + 1); + plen += sprintf(**prompts + plen, "%s", msg); + **echo_on = (type == PAM_PROMPT_ECHO_ON); + xfree(msg); + return (0); + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + /* accumulate messages */ + **prompts = xrealloc(**prompts, plen + strlen(msg) + 1); + plen += sprintf(**prompts + plen, "%s", msg); + xfree(msg); break; -#if 0 case PAM_NEW_AUTHTOK_REQD: - message_cat(&__pam_msg, use_privsep ? - NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG); - /* flag that password change is necessary */ - password_change_required = 1; - /* disallow other functionality for now */ - no_port_forwarding_flag |= 2; - no_agent_forwarding_flag |= 2; - no_x11_forwarding_flag |= 2; - break; + sshpam_new_authtok_reqd = 1; + /* FALLTHROUGH */ + case PAM_SUCCESS: + case PAM_AUTH_ERR: + if (**prompts != NULL) { + /* drain any accumulated messages */ +#if 0 /* XXX - not compatible with privsep */ + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(**prompts); + packet_put_cstring(""); + packet_send(); + packet_write_wait(); #endif + xfree(**prompts); + **prompts = NULL; + } + if (type == PAM_SUCCESS) { + *num = 0; + **echo_on = 0; + ctxt->pam_done = 1; + xfree(msg); + return (0); + } + error("PAM: %s", msg); default: - logit("PAM rejected by account configuration[%d]: " - "%.200s", pam_retval, PAM_STRERROR(__pamh, - pam_retval)); - return(0); + *num = 0; + **echo_on = 0; + xfree(msg); + ctxt->pam_done = -1; + return (-1); + } } - - return(1); + return (-1); } -/* Do PAM-specific session initialisation */ -void do_pam_session(char *username, const char *ttyname) +/* XXX - see also comment in auth-chall.c:verify_response */ +static int +sshpam_respond(void *ctx, u_int num, char **resp) { - int pam_retval; - - do_pam_set_conv(&conv); - - if (ttyname != NULL) { - debug("PAM setting tty to \"%.200s\"", ttyname); - pam_retval = pam_set_item(__pamh, PAM_TTY, ttyname); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set tty failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); + Buffer buffer; + struct pam_ctxt *ctxt = ctx; + + debug2("PAM: %s", __func__); + switch (ctxt->pam_done) { + case 1: + sshpam_authenticated = 1; + return (0); + case 0: + break; + default: + return (-1); } - - pam_retval = pam_open_session(__pamh, 0); - if (pam_retval != PAM_SUCCESS) - fatal("PAM session setup failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - - session_opened = 1; + if (num != 1) { + error("PAM: expected one response, got %u", num); + return (-1); + } + buffer_init(&buffer); + buffer_put_cstring(&buffer, *resp); + ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer); + buffer_free(&buffer); + return (1); } -/* Set PAM credentials */ -void do_pam_setcred(int init) +static void +sshpam_free_ctx(void *ctxtp) { - int pam_retval; - - if (__pamh == NULL) - return; + struct pam_ctxt *ctxt = ctxtp; - do_pam_set_conv(&conv); - - debug("PAM establishing creds"); - pam_retval = pam_setcred(__pamh, - init ? PAM_ESTABLISH_CRED : PAM_REINITIALIZE_CRED); - if (pam_retval != PAM_SUCCESS) { - if (was_authenticated) - fatal("PAM setcred failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - else - debug("PAM setcred failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } else - creds_set = 1; + fatal_remove_cleanup(sshpam_thread_cleanup, ctxt); + sshpam_thread_cleanup(ctxtp); + xfree(ctxt); + /* + * We don't call sshpam_cleanup() here because we may need the PAM + * handle at a later stage, e.g. when setting up a session. It's + * still on the cleanup list, so pam_end() *will* be called before + * the server process terminates. + */ } -/* accessor function for file scope static variable */ -int is_pam_password_change_required(void) -{ - return password_change_required; -} +KbdintDevice sshpam_device = { + "pam", + sshpam_init_ctx, + sshpam_query, + sshpam_respond, + sshpam_free_ctx +}; + +KbdintDevice mm_sshpam_device = { + "pam", + mm_sshpam_init_ctx, + mm_sshpam_query, + mm_sshpam_respond, + mm_sshpam_free_ctx +}; /* - * Have user change authentication token if pam_acct_mgmt() indicated - * it was expired. This needs to be called after an interactive - * session is established and the user's pty is connected to - * stdin/stdout/stderr. + * This replaces auth-pam.c */ -void do_pam_chauthtok(void) +void +start_pam(const char *user) { - int pam_retval; - - do_pam_set_conv(&conv); - - if (password_change_required) { - if (use_privsep) - fatal("Password changing is currently unsupported" - " with privilege separation"); - pamstate = OTHER; - pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); - if (pam_retval != PAM_SUCCESS) - fatal("PAM pam_chauthtok failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); -#if 0 - /* XXX: This would need to be done in the parent process, - * but there's currently no way to pass such request. */ - no_port_forwarding_flag &= ~2; - no_agent_forwarding_flag &= ~2; - no_x11_forwarding_flag &= ~2; - if (!no_port_forwarding_flag && options.allow_tcp_forwarding) - channel_permit_all_opens(); -#endif - } + if (sshpam_init(user) == -1) + fatal("PAM: initialisation failed"); } -/* Cleanly shutdown PAM */ -void finish_pam(void) +void +finish_pam(void) { - do_pam_cleanup_proc(NULL); - fatal_remove_cleanup(&do_pam_cleanup_proc, NULL); + fatal_remove_cleanup(sshpam_cleanup, NULL); + sshpam_cleanup(NULL); } -/* Start PAM authentication for specified account */ -void start_pam(const char *user) +int +do_pam_account(const char *user, const char *ruser) { - int pam_retval; - extern ServerOptions options; - extern u_int utmp_len; - const char *rhost; - - debug("Starting up PAM with username \"%.200s\"", user); - - pam_retval = pam_start(SSHD_PAM_SERVICE, user, &conv, &__pamh); - - if (pam_retval != PAM_SUCCESS) - fatal("PAM initialisation failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - - rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping); - debug("PAM setting rhost to \"%.200s\"", rhost); + /* XXX */ + return (1); +} - pam_retval = pam_set_item(__pamh, PAM_RHOST, rhost); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set rhost failed[%d]: %.200s", pam_retval, - PAM_STRERROR(__pamh, pam_retval)); -#ifdef PAM_TTY_KLUDGE - /* - * Some PAM modules (e.g. pam_time) require a TTY to operate, - * and will fail in various stupid ways if they don't get one. - * sshd doesn't set the tty until too late in the auth process and may - * not even need one (for tty-less connections) - * Kludge: Set a fake PAM_TTY - */ - pam_retval = pam_set_item(__pamh, PAM_TTY, "NODEVssh"); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set tty failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); -#endif /* PAM_TTY_KLUDGE */ +void +do_pam_session(const char *user, const char *tty) +{ + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&null_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_CONV: %s", + pam_strerror(sshpam_handle, sshpam_err)); + debug("PAM: setting PAM_TTY to \"%s\"", tty); + sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, tty); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_TTY: %s", + pam_strerror(sshpam_handle, sshpam_err)); + sshpam_err = pam_open_session(sshpam_handle, 0); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: pam_open_session(): %s", + pam_strerror(sshpam_handle, sshpam_err)); + sshpam_session_open = 1; +} - fatal_add_cleanup(&do_pam_cleanup_proc, NULL); +void +do_pam_setcred(int init) +{ + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&null_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_CONV: %s", + pam_strerror(sshpam_handle, sshpam_err)); + if (init) { + debug("PAM: establishing credentials"); + sshpam_err = pam_setcred(sshpam_handle, PAM_ESTABLISH_CRED); + } else { + debug("PAM: reinitializing credentials"); + sshpam_err = pam_setcred(sshpam_handle, PAM_REINITIALIZE_CRED); + } + if (sshpam_err == PAM_SUCCESS) { + sshpam_cred_established = 1; + return; + } + if (sshpam_authenticated) + fatal("PAM: pam_setcred(): %s", + pam_strerror(sshpam_handle, sshpam_err)); + else + debug("PAM: pam_setcred(): %s", + pam_strerror(sshpam_handle, sshpam_err)); } -/* Return list of PAM environment strings */ -char **fetch_pam_environment(void) +int +is_pam_password_change_required(void) { -#ifdef HAVE_PAM_GETENVLIST - return(pam_getenvlist(__pamh)); -#else /* HAVE_PAM_GETENVLIST */ - return(NULL); -#endif /* HAVE_PAM_GETENVLIST */ + return (sshpam_new_authtok_reqd); } -void free_pam_environment(char **env) +static int +pam_chauthtok_conv(int n, + const struct pam_message **msg, + struct pam_response **resp, + void *data) { + char input[PAM_MAX_MSG_SIZE]; int i; - if (env != NULL) { - for (i = 0; env[i] != NULL; i++) - xfree(env[i]); + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + *resp = xmalloc(n * sizeof **resp); + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + resp[i]->resp = + read_passphrase(PAM_MSG_MEMBER(msg, i, msg), + RP_ALLOW_STDIN); + resp[i]->resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_ON: + fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); + fgets(input, sizeof input, stdin); + resp[i]->resp = xstrdup(input); + resp[i]->resp_retcode = PAM_SUCCESS; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); + resp[i]->resp_retcode = PAM_SUCCESS; + break; + default: + goto fail; + } } + return (PAM_SUCCESS); + fail: + while (i) + xfree(resp[--i]); + xfree(*resp); + *resp = NULL; + return (PAM_CONV_ERR); } -/* Print any messages that have been generated during authentication */ -/* or account checking to stderr */ -void print_pam_messages(void) +/* + * XXX this should be done in the authentication phase, but ssh1 doesn't + * support that + */ +void +do_pam_chauthtok(void) { - if (__pam_msg != NULL) - fputs(__pam_msg, stderr); + struct pam_conv pam_conv = { pam_chauthtok_conv, NULL }; + + if (use_privsep) + fatal("PAM: chauthtok not supprted with privsep"); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&pam_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_CONV: %s", + pam_strerror(sshpam_handle, sshpam_err)); + debug("PAM: changing password"); + sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: pam_chauthtok(): %s", + pam_strerror(sshpam_handle, sshpam_err)); } -/* Append a message to buffer */ -void message_cat(char **p, const char *a) +void +print_pam_messages(void) { - char *cp; - size_t new_len; - - new_len = strlen(a); + /* XXX */ +} - if (*p) { - size_t len = strlen(*p); +char ** +fetch_pam_environment(void) +{ +#ifdef HAVE_PAM_GETENVLIST + debug("PAM: retrieving environment"); + return (pam_getenvlist(sshpam_handle)); +#else + return (NULL); +#endif +} - *p = xrealloc(*p, new_len + len + 2); - cp = *p + len; - } else - *p = cp = xmalloc(new_len + 2); +void +free_pam_environment(char **env) +{ + char **envp; - memcpy(cp, a, new_len); - cp[new_len] = '\n'; - cp[new_len + 1] = '\0'; + for (envp = env; *envp; envp++) + xfree(*envp); + xfree(env); } #endif /* USE_PAM */ diff --git a/auth-pam.h b/auth-pam.h index 7881b6b80..5df65caa3 100644 --- a/auth-pam.h +++ b/auth-pam.h @@ -1,4 +1,4 @@ -/* $Id: auth-pam.h,v 1.16 2002/07/23 00:44:07 stevesk Exp $ */ +/* $Id: auth-pam.h,v 1.17 2003/05/10 09:28:02 djm Exp $ */ /* * Copyright (c) 2000 Damien Miller. All rights reserved. @@ -37,8 +37,8 @@ int auth_pam_password(Authctxt *authctxt, const char *password); char **fetch_pam_environment(void); void free_pam_environment(char **env); int do_pam_authenticate(int flags); -int do_pam_account(char *username, char *remote_user); -void do_pam_session(char *username, const char *ttyname); +int do_pam_account(const char *user, const char *ruser); +void do_pam_session(const char *user, const char *tty); void do_pam_setcred(int init); void print_pam_messages(void); int is_pam_password_change_required(void); diff --git a/auth-passwd.c b/auth-passwd.c index 62ea3a52d..b893165bf 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -43,8 +43,8 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); #include "servconf.h" #include "auth.h" -#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) -/* Don't need any of these headers for the PAM or SIA cases */ +#if !defined(HAVE_OSF_SIA) +/* Don't need any of these headers for the SIA cases */ # ifdef HAVE_CRYPT_H # include # endif @@ -78,7 +78,7 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); # include # define is_winnt (GetVersion() < 0x80000000) # endif -#endif /* !USE_PAM && !HAVE_OSF_SIA */ +#endif /* !HAVE_OSF_SIA */ extern ServerOptions options; #ifdef WITH_AIXAUTHENTICATE @@ -94,7 +94,7 @@ auth_password(Authctxt *authctxt, const char *password) { struct passwd * pw = authctxt->pw; int ok = authctxt->valid; -#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) +#if !defined(HAVE_OSF_SIA) char *encrypted_password; char *pw_password; char *salt; @@ -112,7 +112,7 @@ auth_password(Authctxt *authctxt, const char *password) int authsuccess; int reenter = 1; # endif -#endif /* !defined(USE_PAM) && !defined(HAVE_OSF_SIA) */ +#endif /* !defined(HAVE_OSF_SIA) */ /* deny if no user. */ if (pw == NULL) @@ -124,9 +124,7 @@ auth_password(Authctxt *authctxt, const char *password) if (*password == '\0' && options.permit_empty_passwd == 0) ok = 0; -#if defined(USE_PAM) - return auth_pam_password(authctxt, password) && ok; -#elif defined(HAVE_OSF_SIA) +#if defined(HAVE_OSF_SIA) if (!ok) return 0; return auth_sia_password(authctxt, password); @@ -235,5 +233,5 @@ auth_password(Authctxt *authctxt, const char *password) /* Authentication is accepted if the encrypted passwords are identical. */ return (strcmp(encrypted_password, pw_password) == 0); -#endif /* !USE_PAM && !HAVE_OSF_SIA */ +#endif /* !HAVE_OSF_SIA */ } diff --git a/auth.h b/auth.h index c75d75366..81d9655f7 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,5 @@ /* $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $ */ +/* $FreeBSD: src/crypto/openssh/auth.h,v 1.10 2003/03/31 13:45:36 des Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -133,7 +134,6 @@ void krb5_cleanup_proc(void *authctxt); #endif /* KRB5 */ #include "auth-pam.h" -#include "auth2-pam.h" Authctxt *do_authentication(void); Authctxt *do_authentication2(void); @@ -159,6 +159,7 @@ struct passwd * getpwnamallow(const char *user); char *get_challenge(Authctxt *); int verify_response(Authctxt *, const char *); +void abandon_challenge_response(Authctxt *); struct passwd * auth_get_user(void); diff --git a/auth1.c b/auth1.c index e7d744f6e..5086a47c3 100644 --- a/auth1.c +++ b/auth1.c @@ -73,7 +73,7 @@ do_authloop(Authctxt *authctxt) char info[1024]; u_int dlen; u_int ulen; - int type = 0; + int prev, type = 0; struct passwd *pw = authctxt->pw; debug("Attempting authentication for %s%.100s.", @@ -103,8 +103,20 @@ do_authloop(Authctxt *authctxt) info[0] = '\0'; /* Get a packet from the client. */ + prev = type; type = packet_read(); + /* + * If we started challenge-response authentication but the + * next packet is not a response to our challenge, release + * the resources allocated by get_challenge() (which would + * normally have been released by verify_response() had we + * received such a response) + */ + if (prev == SSH_CMSG_AUTH_TIS && + type != SSH_CMSG_AUTH_TIS_RESPONSE) + abandon_challenge_response(authctxt); + /* Process the packet. */ switch (type) { diff --git a/auth2-chall.c b/auth2-chall.c index 0d1709307..12e3cc934 100644 --- a/auth2-chall.c +++ b/auth2-chall.c @@ -41,6 +41,9 @@ static void input_userauth_info_response(int, u_int32_t, void *); #ifdef BSD_AUTH extern KbdintDevice bsdauth_device; #else +#ifdef USE_PAM +extern KbdintDevice sshpam_device; +#endif #ifdef SKEY extern KbdintDevice skey_device; #endif @@ -50,6 +53,9 @@ KbdintDevice *devices[] = { #ifdef BSD_AUTH &bsdauth_device, #else +#ifdef USE_PAM + &sshpam_device, +#endif #ifdef SKEY &skey_device, #endif @@ -323,15 +329,22 @@ privsep_challenge_enable(void) #ifdef BSD_AUTH extern KbdintDevice mm_bsdauth_device; #endif +#ifdef USE_PAM + extern KbdintDevice mm_sshpam_device; +#endif #ifdef SKEY extern KbdintDevice mm_skey_device; #endif - /* As long as SSHv1 has devices[0] hard coded this is fine */ + int n = 0; + #ifdef BSD_AUTH - devices[0] = &mm_bsdauth_device; + devices[n++] = &mm_bsdauth_device; #else +#ifdef USE_PAM + devices[n++] = &mm_sshpam_device; +#endif #ifdef SKEY - devices[0] = &mm_skey_device; + devices[n++] = &mm_skey_device; #endif #endif } diff --git a/auth2-kbdint.c b/auth2-kbdint.c index e60992881..1696ef4d3 100644 --- a/auth2-kbdint.c +++ b/auth2-kbdint.c @@ -49,10 +49,6 @@ userauth_kbdint(Authctxt *authctxt) if (options.challenge_response_authentication) authenticated = auth2_challenge(authctxt, devs); -#ifdef USE_PAM - if (authenticated == 0 && options.pam_authentication_via_kbd_int) - authenticated = auth2_pam(authctxt); -#endif xfree(devs); xfree(lang); #ifdef HAVE_CYGWIN diff --git a/auth2-pam.c b/auth2-pam.c deleted file mode 100644 index ac28fb245..000000000 --- a/auth2-pam.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "includes.h" -RCSID("$Id: auth2-pam.c,v 1.15 2003/01/08 01:37:03 djm Exp $"); - -#ifdef USE_PAM -#include - -#include "ssh.h" -#include "ssh2.h" -#include "auth.h" -#include "auth-pam.h" -#include "packet.h" -#include "xmalloc.h" -#include "dispatch.h" -#include "log.h" - -static int do_pam_conversation_kbd_int(int num_msg, - const struct pam_message **msg, struct pam_response **resp, - void *appdata_ptr); -void input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt); - -struct { - int finished, num_received, num_expected; - int *prompts; - struct pam_response *responses; -} context_pam2 = {0, 0, 0, NULL}; - -static struct pam_conv conv2 = { - do_pam_conversation_kbd_int, - NULL, -}; - -int -auth2_pam(Authctxt *authctxt) -{ - int retval = -1; - - if (authctxt->user == NULL) - fatal("auth2_pam: internal error: no user"); - - conv2.appdata_ptr = authctxt; - do_pam_set_conv(&conv2); - - dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, - &input_userauth_info_response_pam); - retval = (do_pam_authenticate(0) == PAM_SUCCESS); - dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); - - return retval; -} - -static int -do_pam_conversation_kbd_int(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr) -{ - int i, j, done; - char *text; - - context_pam2.finished = 0; - context_pam2.num_received = 0; - context_pam2.num_expected = 0; - context_pam2.prompts = xmalloc(sizeof(int) * num_msg); - context_pam2.responses = xmalloc(sizeof(struct pam_response) * num_msg); - memset(context_pam2.responses, 0, sizeof(struct pam_response) * num_msg); - - text = NULL; - for (i = 0, context_pam2.num_expected = 0; i < num_msg; i++) { - int style = PAM_MSG_MEMBER(msg, i, msg_style); - switch (style) { - case PAM_PROMPT_ECHO_ON: - case PAM_PROMPT_ECHO_OFF: - context_pam2.num_expected++; - break; - case PAM_TEXT_INFO: - case PAM_ERROR_MSG: - default: - /* Capture all these messages to be sent at once */ - message_cat(&text, PAM_MSG_MEMBER(msg, i, msg)); - break; - } - } - - if (context_pam2.num_expected == 0) - return PAM_SUCCESS; - - packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); - packet_put_cstring(""); /* Name */ - packet_put_cstring(""); /* Instructions */ - packet_put_cstring(""); /* Language */ - packet_put_int(context_pam2.num_expected); - - for (i = 0, j = 0; i < num_msg; i++) { - int style = PAM_MSG_MEMBER(msg, i, msg_style); - - /* Skip messages which don't need a reply */ - if (style != PAM_PROMPT_ECHO_ON && style != PAM_PROMPT_ECHO_OFF) - continue; - - context_pam2.prompts[j++] = i; - if (text) { - message_cat(&text, PAM_MSG_MEMBER(msg, i, msg)); - packet_put_cstring(text); - text = NULL; - } else - packet_put_cstring(PAM_MSG_MEMBER(msg, i, msg)); - packet_put_char(style == PAM_PROMPT_ECHO_ON); - } - packet_send(); - packet_write_wait(); - - /* - * Grabbing control of execution and spinning until we get what - * we want is probably rude, but it seems to work properly, and - * the client *should* be in lock-step with us, so the loop should - * only be traversed once. - */ - while(context_pam2.finished == 0) { - done = 1; - dispatch_run(DISPATCH_BLOCK, &done, appdata_ptr); - if (context_pam2.finished == 0) - debug("extra packet during conversation"); - } - - if (context_pam2.num_received == context_pam2.num_expected) { - *resp = context_pam2.responses; - return PAM_SUCCESS; - } else - return PAM_CONV_ERR; -} - -void -input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt) -{ - Authctxt *authctxt = ctxt; - unsigned int nresp = 0, rlen = 0, i = 0; - char *resp; - - if (authctxt == NULL) - fatal("input_userauth_info_response_pam: no authentication context"); - - nresp = packet_get_int(); /* Number of responses. */ - debug("got %d responses", nresp); - - - if (nresp != context_pam2.num_expected) - fatal("%s: Received incorrect number of responses " - "(expected %d, received %u)", __func__, - context_pam2.num_expected, nresp); - - if (nresp > 100) - fatal("%s: too many replies", __func__); - - for (i = 0; i < nresp; i++) { - int j = context_pam2.prompts[i]; - - resp = packet_get_string(&rlen); - context_pam2.responses[j].resp_retcode = PAM_SUCCESS; - context_pam2.responses[j].resp = resp; - context_pam2.num_received++; - } - - context_pam2.finished = 1; - - packet_check_eom(); -} -#endif diff --git a/auth2-pam.h b/auth2-pam.h deleted file mode 100644 index c54f811cf..000000000 --- a/auth2-pam.h +++ /dev/null @@ -1,8 +0,0 @@ -/* $Id: auth2-pam.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - -#include "includes.h" -#ifdef USE_PAM - -int auth2_pam(Authctxt *authctxt); - -#endif /* USE_PAM */ diff --git a/configure.ac b/configure.ac index dee852854..7a24838fe 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.116 2003/05/10 07:05:46 dtucker Exp $ +# $Id: configure.ac,v 1.117 2003/05/10 09:28:02 djm Exp $ AC_INIT AC_CONFIG_SRCDIR([ssh.c]) @@ -963,7 +963,7 @@ int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); } # Some Linux systems (Slackware) need crypt() from libcrypt, *not* the # version in OpenSSL. Skip this for PAM -if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then +if test "x$check_for_libcrypt_later" = "x1"; then AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt") fi diff --git a/monitor.c b/monitor.c index 99b4d56ec..46241fbbd 100644 --- a/monitor.c +++ b/monitor.c @@ -118,6 +118,10 @@ int mm_answer_sessid(int, Buffer *); #ifdef USE_PAM int mm_answer_pam_start(int, Buffer *); +int mm_answer_pam_init_ctx(int, Buffer *); +int mm_answer_pam_query(int, Buffer *); +int mm_answer_pam_respond(int, Buffer *); +int mm_answer_pam_free_ctx(int, Buffer *); #endif #ifdef KRB4 @@ -163,6 +167,10 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, + {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, + {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, + {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, @@ -205,6 +213,10 @@ struct mon_table mon_dispatch_proto15[] = { #endif #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, + {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, + {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, + {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif #ifdef KRB4 {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4}, @@ -285,10 +297,6 @@ monitor_child_preauth(struct monitor *pmonitor) if (authctxt->pw->pw_uid == 0 && !auth_root_allowed(auth_method)) authenticated = 0; -#ifdef USE_PAM - if (!do_pam_account(authctxt->pw->pw_name, NULL)) - authenticated = 0; -#endif } if (ent->flags & MON_AUTHDECIDE) { @@ -747,6 +755,103 @@ mm_answer_pam_start(int socket, Buffer *m) return (0); } + +static void *sshpam_ctxt, *sshpam_authok; +extern KbdintDevice sshpam_device; + +int +mm_answer_pam_init_ctx(int socket, Buffer *m) +{ + + debug3("%s", __func__); + authctxt->user = buffer_get_string(m, NULL); + sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); + sshpam_authok = NULL; + buffer_clear(m); + if (sshpam_ctxt != NULL) { + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); + buffer_put_int(m, 1); + } else { + buffer_put_int(m, 0); + } + mm_request_send(socket, MONITOR_ANS_PAM_INIT_CTX, m); + return (0); +} + +int +mm_answer_pam_query(int socket, Buffer *m) +{ + char *name, *info, **prompts; + u_int num, *echo_on; + int i, ret; + + debug3("%s", __func__); + sshpam_authok = NULL; + ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); + if (ret == 0 && num == 0) + sshpam_authok = sshpam_ctxt; + if (num > 1 || name == NULL || info == NULL) + ret = -1; + buffer_clear(m); + buffer_put_int(m, ret); + buffer_put_cstring(m, name); + xfree(name); + buffer_put_cstring(m, info); + xfree(info); + buffer_put_int(m, num); + for (i = 0; i < num; ++i) { + buffer_put_cstring(m, prompts[i]); + xfree(prompts[i]); + buffer_put_int(m, echo_on[i]); + } + if (prompts != NULL) + xfree(prompts); + if (echo_on != NULL) + xfree(echo_on); + mm_request_send(socket, MONITOR_ANS_PAM_QUERY, m); + return (0); +} + +int +mm_answer_pam_respond(int socket, Buffer *m) +{ + char **resp; + u_int num; + int i, ret; + + debug3("%s", __func__); + sshpam_authok = NULL; + num = buffer_get_int(m); + if (num > 0) { + resp = xmalloc(num * sizeof(char *)); + for (i = 0; i < num; ++i) + resp[i] = buffer_get_string(m, NULL); + ret = (sshpam_device.respond)(sshpam_ctxt, num, resp); + for (i = 0; i < num; ++i) + xfree(resp[i]); + xfree(resp); + } else { + ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL); + } + buffer_clear(m); + buffer_put_int(m, ret); + mm_request_send(socket, MONITOR_ANS_PAM_RESPOND, m); + auth_method = "keyboard-interactive/pam"; + if (ret == 0) + sshpam_authok = sshpam_ctxt; + return (0); +} + +int +mm_answer_pam_free_ctx(int socket, Buffer *m) +{ + + debug3("%s", __func__); + (sshpam_device.free_ctx)(sshpam_ctxt); + buffer_clear(m); + mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m); + return (sshpam_authok == sshpam_ctxt); +} #endif static void diff --git a/monitor.h b/monitor.h index 668ac9897..3284ec5e6 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,5 @@ /* $OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */ +/* $FreeBSD: src/crypto/openssh/monitor.h,v 1.3 2002/10/29 10:16:02 des Exp $ */ /* * Copyright 2002 Niels Provos @@ -52,6 +53,10 @@ enum monitor_reqtype { MONITOR_REQ_KRB4, MONITOR_ANS_KRB4, MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, MONITOR_REQ_PAM_START, + MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, + MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, + MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, + MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX, MONITOR_REQ_TERM }; diff --git a/monitor_wrap.c b/monitor_wrap.c index 183ae8d0e..a83413a5f 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -677,6 +677,88 @@ mm_start_pam(char *user) buffer_free(&m); } + +void * +mm_sshpam_init_ctx(Authctxt *authctxt) +{ + Buffer m; + int success; + + debug3("%s", __func__); + buffer_init(&m); + buffer_put_cstring(&m, authctxt->user); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); + success = buffer_get_int(&m); + if (success == 0) { + debug3("%s: pam_init_ctx failed", __func__); + buffer_free(&m); + return (NULL); + } + buffer_free(&m); + return (authctxt); +} + +int +mm_sshpam_query(void *ctx, char **name, char **info, + u_int *num, char ***prompts, u_int **echo_on) +{ + Buffer m; + int i, ret; + + debug3("%s", __func__); + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); + ret = buffer_get_int(&m); + debug3("%s: pam_query returned %d", __func__, ret); + *name = buffer_get_string(&m, NULL); + *info = buffer_get_string(&m, NULL); + *num = buffer_get_int(&m); + *prompts = xmalloc((*num + 1) * sizeof(char *)); + *echo_on = xmalloc((*num + 1) * sizeof(u_int)); + for (i = 0; i < *num; ++i) { + (*prompts)[i] = buffer_get_string(&m, NULL); + (*echo_on)[i] = buffer_get_int(&m); + } + buffer_free(&m); + return (ret); +} + +int +mm_sshpam_respond(void *ctx, u_int num, char **resp) +{ + Buffer m; + int i, ret; + + debug3("%s", __func__); + buffer_init(&m); + buffer_put_int(&m, num); + for (i = 0; i < num; ++i) + buffer_put_cstring(&m, resp[i]); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); + ret = buffer_get_int(&m); + debug3("%s: pam_respond returned %d", __func__, ret); + buffer_free(&m); + return (ret); +} + +void +mm_sshpam_free_ctx(void *ctxtp) +{ + Buffer m; + + debug3("%s", __func__); + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); + buffer_free(&m); +} #endif /* USE_PAM */ /* Request process termination */ diff --git a/monitor_wrap.h b/monitor_wrap.h index d960a3d0b..f85bb2eda 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,5 @@ /* $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */ +/* $FreeBSD: src/crypto/openssh/monitor_wrap.h,v 1.3 2002/10/29 10:16:02 des Exp $ */ /* * Copyright 2002 Niels Provos @@ -57,6 +58,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); #ifdef USE_PAM void mm_start_pam(char *); +void *mm_sshpam_init_ctx(struct Authctxt *); +int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); +int mm_sshpam_respond(void *, u_int, char **); +void mm_sshpam_free_ctx(void *); #endif void mm_terminate(void); -- cgit v1.2.3 From d558092522153caa627e33e4a76c6f64332bc609 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 14 May 2003 13:40:06 +1000 Subject: - (djm) RCSID sync w/ OpenBSD --- ChangeLog | 3 ++- auth-krb4.c | 2 +- auth-options.c | 2 +- auth-rh-rsa.c | 2 +- auth-rhosts.c | 2 +- auth-rsa.c | 2 +- auth.c | 2 +- auth1.c | 2 +- auth2-hostbased.c | 2 +- auth2-passwd.c | 2 +- auth2-pubkey.c | 2 +- auth2.c | 2 +- authfd.c | 2 +- bufaux.c | 2 +- canohost.c | 2 +- channels.c | 2 +- clientloop.c | 2 +- compat.c | 2 +- dh.c | 2 +- dispatch.c | 2 +- groupaccess.c | 2 +- hostfile.c | 2 +- log.c | 2 +- log.h | 2 +- monitor.c | 2 +- nchan.c | 2 +- packet.c | 2 +- packet.h | 2 +- scard.c | 2 +- servconf.c | 20 ++++++++++++-------- session.c | 2 +- sftp-client.c | 2 +- sftp-server.c | 2 +- ssh-agent.c | 2 +- ssh-keygen.c | 2 +- ssh.c | 2 +- sshconnect.c | 2 +- sshconnect1.c | 2 +- sshconnect2.c | 2 +- sshd.c | 2 +- sshlogin.c | 2 +- ttymodes.c | 2 +- 42 files changed, 54 insertions(+), 49 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index 37694bf37..44ec8f4f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 20030514 - (djm) Bug #117: Don't lie to PAM about username + - (djm) RCSID sync w/ OpenBSD 20030512 - (djm) Redhat spec: Don't install profile.d scripts when not @@ -1387,4 +1388,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2676 2003/05/14 00:27:09 djm Exp $ +$Id: ChangeLog,v 1.2677 2003/05/14 03:40:06 djm Exp $ diff --git a/auth-krb4.c b/auth-krb4.c index 0cc058387..9e1c800be 100644 --- a/auth-krb4.c +++ b/auth-krb4.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-krb4.c,v 1.29 2003/02/21 10:34:48 mpech Exp $"); +RCSID("$OpenBSD: auth-krb4.c,v 1.30 2003/04/08 20:21:28 itojun Exp $"); #include "ssh.h" #include "ssh1.h" diff --git a/auth-options.c b/auth-options.c index a3845f6b0..d8976b172 100644 --- a/auth-options.c +++ b/auth-options.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-options.c,v 1.26 2002/07/30 17:03:55 markus Exp $"); +RCSID("$OpenBSD: auth-options.c,v 1.27 2003/04/08 20:21:28 itojun Exp $"); #include "xmalloc.h" #include "match.h" diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c index 8675de580..4d6f0d234 100644 --- a/auth-rh-rsa.c +++ b/auth-rh-rsa.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rh-rsa.c,v 1.34 2002/03/25 09:25:06 markus Exp $"); +RCSID("$OpenBSD: auth-rh-rsa.c,v 1.35 2003/04/08 20:21:28 itojun Exp $"); #include "packet.h" #include "uidswap.h" diff --git a/auth-rhosts.c b/auth-rhosts.c index 9b651bacd..de2cb67f3 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rhosts.c,v 1.28 2002/05/13 21:26:49 markus Exp $"); +RCSID("$OpenBSD: auth-rhosts.c,v 1.29 2003/04/08 20:21:28 itojun Exp $"); #include "packet.h" #include "uidswap.h" diff --git a/auth-rsa.c b/auth-rsa.c index bb2c91741..5631d238c 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rsa.c,v 1.56 2002/06/10 16:53:06 stevesk Exp $"); +RCSID("$OpenBSD: auth-rsa.c,v 1.57 2003/04/08 20:21:28 itojun Exp $"); #include #include diff --git a/auth.c b/auth.c index 10f7b2a1f..a17cc5576 100644 --- a/auth.c +++ b/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.46 2002/11/04 10:07:53 markus Exp $"); +RCSID("$OpenBSD: auth.c,v 1.47 2003/04/08 20:21:28 itojun Exp $"); #ifdef HAVE_LOGIN_H #include diff --git a/auth1.c b/auth1.c index 45cc2d6f0..7fe363156 100644 --- a/auth1.c +++ b/auth1.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.47 2003/02/06 21:22:42 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.48 2003/04/08 20:21:28 itojun Exp $"); #include "xmalloc.h" #include "rsa.h" diff --git a/auth2-hostbased.c b/auth2-hostbased.c index 72df83bd4..f8b4ae852 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); +RCSID("$OpenBSD: auth2-hostbased.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); #include "ssh2.h" #include "xmalloc.h" diff --git a/auth2-passwd.c b/auth2-passwd.c index 3c2734b56..8eb18f2e3 100644 --- a/auth2-passwd.c +++ b/auth2-passwd.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); +RCSID("$OpenBSD: auth2-passwd.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); #include "xmalloc.h" #include "packet.h" diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 8c5436e35..85ee33eed 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); +RCSID("$OpenBSD: auth2-pubkey.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); #include "ssh2.h" #include "xmalloc.h" diff --git a/auth2.c b/auth2.c index a761ba5fa..b2f14bacd 100644 --- a/auth2.c +++ b/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.96 2003/02/06 21:22:43 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.97 2003/04/08 20:21:28 itojun Exp $"); #include "ssh2.h" #include "xmalloc.h" diff --git a/authfd.c b/authfd.c index 3d20da8be..7e96269a4 100644 --- a/authfd.c +++ b/authfd.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.58 2003/01/23 13:50:27 markus Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.59 2003/04/08 20:21:28 itojun Exp $"); #include diff --git a/bufaux.c b/bufaux.c index 16cd2d01c..37cc27ff6 100644 --- a/bufaux.c +++ b/bufaux.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: bufaux.c,v 1.28 2002/10/23 10:40:16 markus Exp $"); +RCSID("$OpenBSD: bufaux.c,v 1.29 2003/04/08 20:21:28 itojun Exp $"); #include #include "bufaux.h" diff --git a/canohost.c b/canohost.c index 21a7eba85..417d95c18 100644 --- a/canohost.c +++ b/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.35 2002/11/26 02:38:54 stevesk Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.36 2003/04/08 20:21:28 itojun Exp $"); #include "packet.h" #include "xmalloc.h" diff --git a/channels.c b/channels.c index e27ae1fa3..41abb8d6b 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.187 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.188 2003/04/08 20:21:28 itojun Exp $"); #include "ssh.h" #include "ssh1.h" diff --git a/clientloop.c b/clientloop.c index f07725bbc..e4ef71632 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.108 2003/04/02 09:48:07 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.109 2003/04/08 20:21:28 itojun Exp $"); #include "ssh.h" #include "ssh1.h" diff --git a/compat.c b/compat.c index a5241c491..63a5d91ff 100644 --- a/compat.c +++ b/compat.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: compat.c,v 1.66 2003/04/01 10:31:26 markus Exp $"); +RCSID("$OpenBSD: compat.c,v 1.67 2003/04/08 20:21:28 itojun Exp $"); #include "buffer.h" #include "packet.h" diff --git a/dh.c b/dh.c index fd41e2102..996428b7f 100644 --- a/dh.c +++ b/dh.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: dh.c,v 1.23 2002/11/21 22:22:50 markus Exp $"); +RCSID("$OpenBSD: dh.c,v 1.24 2003/04/08 20:21:28 itojun Exp $"); #include "xmalloc.h" diff --git a/dispatch.c b/dispatch.c index e962fb34b..c5ff65031 100644 --- a/dispatch.c +++ b/dispatch.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: dispatch.c,v 1.15 2002/01/11 13:39:36 markus Exp $"); +RCSID("$OpenBSD: dispatch.c,v 1.16 2003/04/08 20:21:28 itojun Exp $"); #include "ssh1.h" #include "ssh2.h" diff --git a/groupaccess.c b/groupaccess.c index b90791832..fbf794fc8 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: groupaccess.c,v 1.5 2002/03/04 17:27:39 stevesk Exp $"); +RCSID("$OpenBSD: groupaccess.c,v 1.6 2003/04/08 20:21:28 itojun Exp $"); #include "groupaccess.h" #include "xmalloc.h" diff --git a/hostfile.c b/hostfile.c index 31147cba1..42a8aa71d 100644 --- a/hostfile.c +++ b/hostfile.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: hostfile.c,v 1.30 2002/07/24 16:11:18 markus Exp $"); +RCSID("$OpenBSD: hostfile.c,v 1.31 2003/04/08 20:21:28 itojun Exp $"); #include "packet.h" #include "match.h" diff --git a/log.c b/log.c index 685717aef..bc9a2dc1b 100644 --- a/log.c +++ b/log.c @@ -34,7 +34,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.25 2003/01/11 18:29:43 markus Exp $"); +RCSID("$OpenBSD: log.c,v 1.26 2003/04/08 20:21:28 itojun Exp $"); #include "log.h" #include "xmalloc.h" diff --git a/log.h b/log.h index 4aad9ac7c..c3666818f 100644 --- a/log.h +++ b/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.8 2002/07/19 15:43:33 markus Exp $ */ +/* $OpenBSD: log.h,v 1.9 2003/04/08 20:21:28 itojun Exp $ */ /* * Author: Tatu Ylonen diff --git a/monitor.c b/monitor.c index 46241fbbd..1f6677581 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.37 2003/04/02 09:48:07 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.38 2003/04/08 20:21:28 itojun Exp $"); #include diff --git a/nchan.c b/nchan.c index c358e6aaa..2935df320 100644 --- a/nchan.c +++ b/nchan.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: nchan.c,v 1.47 2002/06/19 00:27:55 deraadt Exp $"); +RCSID("$OpenBSD: nchan.c,v 1.48 2003/04/08 20:21:29 itojun Exp $"); #include "ssh1.h" #include "ssh2.h" diff --git a/packet.c b/packet.c index 2abfeddb8..cdcb83faa 100644 --- a/packet.c +++ b/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.105 2003/04/02 09:48:07 markus Exp $"); +RCSID("$OpenBSD: packet.c,v 1.106 2003/04/08 20:21:29 itojun Exp $"); #include "openbsd-compat/sys-queue.h" diff --git a/packet.h b/packet.h index 7b2de6349..fa000d686 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.38 2003/04/02 09:48:07 markus Exp $ */ +/* $OpenBSD: packet.h,v 1.39 2003/04/08 20:21:29 itojun Exp $ */ /* * Author: Tatu Ylonen diff --git a/scard.c b/scard.c index d23aa5b52..65f8bff14 100644 --- a/scard.c +++ b/scard.c @@ -24,7 +24,7 @@ #include "includes.h" #if defined(SMARTCARD) && defined(USE_SECTOK) -RCSID("$OpenBSD: scard.c,v 1.26 2002/06/23 03:30:17 deraadt Exp $"); +RCSID("$OpenBSD: scard.c,v 1.27 2003/04/08 20:21:29 itojun Exp $"); #include #include diff --git a/servconf.c b/servconf.c index c6fe371b2..8e2839085 100644 --- a/servconf.c +++ b/servconf.c @@ -10,20 +10,24 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.116 2003/02/21 09:05:53 markus Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.118 2003/04/09 08:23:52 hin Exp $"); #if defined(KRB4) #include #endif + #if defined(KRB5) -#ifdef HEIMDAL -#include -#else -/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V - * keytab */ -#define KEYFILE "/etc/krb5.keytab" -#endif +# ifdef HEIMDAL +# include +# else +/* + * XXX: Bodge - but then, so is using the kerberos IV KEYFILE to get a + * Kerberos V keytab + */ +# define KEYFILE "/etc/krb5.keytab" +# endif #endif + #ifdef AFS #include #endif diff --git a/session.c b/session.c index 9e1dd914a..f52bc6585 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.155 2003/04/08 20:21:29 itojun Exp $"); #include "ssh.h" #include "ssh1.h" diff --git a/sftp-client.c b/sftp-client.c index 4ad6be8bd..a48d56e69 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -28,7 +28,7 @@ /* XXX: copy between two remote sites */ #include "includes.h" -RCSID("$OpenBSD: sftp-client.c,v 1.42 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: sftp-client.c,v 1.43 2003/04/08 20:21:29 itojun Exp $"); #include "openbsd-compat/sys-queue.h" diff --git a/sftp-server.c b/sftp-server.c index 9c332ec86..794404ae5 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: sftp-server.c,v 1.41 2003/03/26 04:02:51 deraadt Exp $"); +RCSID("$OpenBSD: sftp-server.c,v 1.42 2003/04/08 20:21:29 itojun Exp $"); #include "buffer.h" #include "bufaux.h" diff --git a/ssh-agent.c b/ssh-agent.c index 5dee9df45..c179ceaa2 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.109 2003/04/08 20:21:29 itojun Exp $"); #include #include diff --git a/ssh-keygen.c b/ssh-keygen.c index a264f099f..4bd79af6a 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keygen.c,v 1.102 2002/11/26 00:45:03 wcobb Exp $"); +RCSID("$OpenBSD: ssh-keygen.c,v 1.103 2003/04/08 20:21:29 itojun Exp $"); #include #include diff --git a/ssh.c b/ssh.c index 21bfc56e3..307b5f26a 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.190 2003/02/06 09:27:29 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.191 2003/04/08 20:21:29 itojun Exp $"); #include #include diff --git a/sshconnect.c b/sshconnect.c index b0ba3f0c6..16db13fa1 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.137 2002/11/21 23:03:51 deraadt Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.138 2003/04/08 20:21:29 itojun Exp $"); #include diff --git a/sshconnect1.c b/sshconnect1.c index 491b4f67d..2a822a98f 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.53 2003/04/08 20:21:29 itojun Exp $"); #include #include diff --git a/sshconnect2.c b/sshconnect2.c index 90b884a39..d32960447 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.115 2003/04/02 09:48:07 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.116 2003/04/08 20:21:29 itojun Exp $"); #include "ssh.h" #include "ssh2.h" diff --git a/sshd.c b/sshd.c index 63070ac23..0f3fbb230 100644 --- a/sshd.c +++ b/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.263 2003/02/16 17:09:57 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.264 2003/04/08 20:21:29 itojun Exp $"); #include #include diff --git a/sshlogin.c b/sshlogin.c index 12555d635..188a6b3ae 100644 --- a/sshlogin.c +++ b/sshlogin.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshlogin.c,v 1.5 2002/08/29 15:57:25 stevesk Exp $"); +RCSID("$OpenBSD: sshlogin.c,v 1.6 2003/04/08 20:21:29 itojun Exp $"); #include "loginrec.h" diff --git a/ttymodes.c b/ttymodes.c index ee752ebba..c32e213a4 100644 --- a/ttymodes.c +++ b/ttymodes.c @@ -43,7 +43,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ttymodes.c,v 1.18 2002/06/19 00:27:55 deraadt Exp $"); +RCSID("$OpenBSD: ttymodes.c,v 1.19 2003/04/08 20:21:29 itojun Exp $"); #include "packet.h" #include "log.h" -- cgit v1.2.3 From 3ab496b3dd961423bc5e312fd5dbbef975f4d238 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 14 May 2003 13:47:37 +1000 Subject: - markus@cvs.openbsd.org 2003/05/14 02:15:47 [auth2.c monitor.c sshconnect2.c auth2-krb5.c] implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@ server interops with commercial client; ok jakob@ djm@ --- ChangeLog | 6 +++- auth2-krb5.c | 66 ++++++++++++++++++++++++++++++++++++++ auth2.c | 8 ++++- monitor.c | 7 +++- sshconnect2.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 auth2-krb5.c (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index 53d039fc3..e37d26ad7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -63,6 +63,10 @@ [sftp.1] emphasise the batchmode functionality and make reference to pubkey auth, both of which are FAQs; ok markus@ + - markus@cvs.openbsd.org 2003/05/14 02:15:47 + [auth2.c monitor.c sshconnect2.c auth2-krb5.c] + implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@ + server interops with commercial client; ok jakob@ djm@ 20030512 - (djm) Redhat spec: Don't install profile.d scripts when not @@ -1450,4 +1454,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2691 2003/05/14 03:47:07 djm Exp $ +$Id: ChangeLog,v 1.2692 2003/05/14 03:47:37 djm Exp $ diff --git a/auth2-krb5.c b/auth2-krb5.c new file mode 100644 index 000000000..ea4d76da0 --- /dev/null +++ b/auth2-krb5.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: auth2-krb5.c,v 1.1 2003/05/14 02:15:47 markus Exp $"); + +#include + +#include "ssh2.h" +#include "xmalloc.h" +#include "packet.h" +#include "log.h" +#include "auth.h" +#include "monitor_wrap.h" +#include "servconf.h" + +/* import */ +extern ServerOptions options; + +static int +userauth_kerberos(Authctxt *authctxt) +{ + krb5_data tkt, reply; + char *client = NULL; + int authenticated = 0; + + tkt.data = packet_get_string(&tkt.length); + packet_check_eom(); + + if (PRIVSEP(auth_krb5(authctxt, &tkt, &client, &reply))) { + authenticated = 1; + if (reply.length) + xfree(reply.data); + } + if (client) + xfree(client); + xfree(tkt.data); + return (authenticated); +} + +Authmethod method_kerberos = { + "kerberos-2@ssh.com", + userauth_kerberos, + &options.kerberos_authentication +}; diff --git a/auth2.c b/auth2.c index b2f14bacd..03d170e23 100644 --- a/auth2.c +++ b/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.97 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.98 2003/05/14 02:15:47 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -50,6 +50,9 @@ extern Authmethod method_pubkey; extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; +#ifdef KRB5 +extern Authmethod method_kerberos; +#endif Authmethod *authmethods[] = { &method_none, @@ -57,6 +60,9 @@ Authmethod *authmethods[] = { &method_passwd, &method_kbdint, &method_hostbased, +#ifdef KRB5 + &method_kerberos, +#endif NULL }; diff --git a/monitor.c b/monitor.c index 1f6677581..78d1e2e0c 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.38 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.39 2003/05/14 02:15:47 markus Exp $"); #include @@ -182,6 +182,9 @@ struct mon_table mon_dispatch_proto20[] = { #endif {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, +#ifdef KRB5 + {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, +#endif {0, 0, NULL} }; @@ -1483,6 +1486,8 @@ mm_answer_krb5(int socket, Buffer *m) } mm_request_send(socket, MONITOR_ANS_KRB5, m); + auth_method = "kerberos"; + return success; } #endif diff --git a/sshconnect2.c b/sshconnect2.c index 74d699ff2..0605e4e5f 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,11 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.117 2003/05/12 16:55:37 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.118 2003/05/14 02:15:47 markus Exp $"); + +#ifdef KRB5 +#include +#endif #include "ssh.h" #include "ssh2.h" @@ -190,6 +194,7 @@ int userauth_pubkey(Authctxt *); int userauth_passwd(Authctxt *); int userauth_kbdint(Authctxt *); int userauth_hostbased(Authctxt *); +int userauth_kerberos(Authctxt *); void userauth(Authctxt *, char *); @@ -208,6 +213,12 @@ Authmethod authmethods[] = { userauth_hostbased, &options.hostbased_authentication, NULL}, +#if KRB5 + {"kerberos-2@ssh.com", + userauth_kerberos, + &options.kerberos_authentication, + NULL}, +#endif {"publickey", userauth_pubkey, &options.pubkey_authentication, @@ -1112,6 +1123,94 @@ userauth_hostbased(Authctxt *authctxt) return 1; } +#if KRB5 +static int +ssh_krb5_helper(krb5_data *ap) +{ + krb5_context xcontext = NULL; /* XXX share with ssh1 */ + krb5_auth_context xauth_context = NULL; + + krb5_context *context; + krb5_auth_context *auth_context; + krb5_error_code problem; + const char *tkfile; + struct stat buf; + krb5_ccache ccache = NULL; + const char *remotehost; + int ret; + + memset(ap, 0, sizeof(*ap)); + + context = &xcontext; + auth_context = &xauth_context; + + problem = krb5_init_context(context); + if (problem) { + debug("Kerberos v5: krb5_init_context failed"); + ret = 0; + goto out; + } + + tkfile = krb5_cc_default_name(*context); + if (strncmp(tkfile, "FILE:", 5) == 0) + tkfile += 5; + + if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) { + debug("Kerberos v5: could not get default ccache (permission denied)."); + ret = 0; + goto out; + } + + problem = krb5_cc_default(*context, &ccache); + if (problem) { + debug("Kerberos v5: krb5_cc_default failed: %s", + krb5_get_err_text(*context, problem)); + ret = 0; + goto out; + } + + remotehost = get_canonical_hostname(1); + + problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED, + "host", remotehost, NULL, ccache, ap); + if (problem) { + debug("Kerberos v5: krb5_mk_req failed: %s", + krb5_get_err_text(*context, problem)); + ret = 0; + goto out; + } + ret = 1; + + out: + if (ccache != NULL) + krb5_cc_close(*context, ccache); + if (*auth_context) + krb5_auth_con_free(*context, *auth_context); + if (*context) + krb5_free_context(*context); + return (ret); +} + +int +userauth_kerberos(Authctxt *authctxt) +{ + krb5_data ap; + + if (ssh_krb5_helper(&ap) == 0) + return (0); + + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_string(ap.data, ap.length); + packet_send(); + + krb5_data_free(&ap); + return (1); +} +#endif + /* find auth method */ /* -- cgit v1.2.3 From 4e448a31ae12e6f84caa7cdfc8b4c23db92459db Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 14 May 2003 15:11:48 +1000 Subject: - (djm) Add new UsePAM configuration directive to allow runtime control over usage of PAM. This allows non-root use of sshd when built with --with-pam --- ChangeLog | 5 ++++- auth-pam.c | 7 ++++++- auth.c | 10 +++++----- auth1.c | 8 ++------ auth2.c | 16 ++++------------ monitor.c | 6 +++++- monitor_wrap.c | 4 ++++ servconf.c | 18 +++++++++++------- servconf.h | 2 +- session.c | 30 +++++++++++++++++------------- sshd.c | 3 ++- sshd_config.5 | 15 +++++++++------ 12 files changed, 70 insertions(+), 54 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index 6d79daeba..2bf9cd7e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -68,6 +68,9 @@ implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@ server interops with commercial client; ok jakob@ djm@ - (djm) Make portable build with MIT krb5 (some issues remain) + - (djm) Add new UsePAM configuration directive to allow runtime control + over usage of PAM. This allows non-root use of sshd when built with + --with-pam 20030512 - (djm) Redhat spec: Don't install profile.d scripts when not @@ -1455,4 +1458,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2693 2003/05/14 04:31:11 djm Exp $ +$Id: ChangeLog,v 1.2694 2003/05/14 05:11:48 djm Exp $ diff --git a/auth-pam.c b/auth-pam.c index f4718035d..234e8f435 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -49,6 +49,8 @@ RCSID("$FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48: #include "ssh2.h" #include "xmalloc.h" +extern ServerOptions options; + #define __unused #ifdef USE_POSIX_THREADS @@ -276,7 +278,6 @@ sshpam_cleanup(void *arg) static int sshpam_init(const char *user) { - extern ServerOptions options; extern u_int utmp_len; const char *pam_rhost, *pam_user; @@ -313,6 +314,10 @@ sshpam_init_ctx(Authctxt *authctxt) struct pam_ctxt *ctxt; int socks[2]; + /* Refuse to start if we don't have PAM enabled */ + if (!options.use_pam) + return NULL; + /* Initialize PAM */ if (sshpam_init(authctxt->user) == -1) { error("PAM: initialization failed"); diff --git a/auth.c b/auth.c index a17cc5576..8b58cc671 100644 --- a/auth.c +++ b/auth.c @@ -78,8 +78,8 @@ allowed_user(struct passwd * pw) #ifdef WITH_AIXAUTHENTICATE char *loginmsg; #endif /* WITH_AIXAUTHENTICATE */ -#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ - !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ + defined(HAS_SHADOW_EXPIRE) struct spwd *spw; time_t today; #endif @@ -88,10 +88,10 @@ allowed_user(struct passwd * pw) if (!pw || !pw->pw_name) return 0; -#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ - !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ + defined(HAS_SHADOW_EXPIRE) #define DAY (24L * 60 * 60) /* 1 day in seconds */ - if ((spw = getspnam(pw->pw_name)) != NULL) { + if (!options.use_pam && (spw = getspnam(pw->pw_name)) != NULL) { today = time(NULL) / DAY; debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" " sp_max %d", (int)today, (int)spw->sp_expire, diff --git a/auth1.c b/auth1.c index 7fe363156..6cb0b04b2 100644 --- a/auth1.c +++ b/auth1.c @@ -342,11 +342,6 @@ do_authloop(Authctxt *authctxt) !auth_root_allowed(get_authname(type))) authenticated = 0; #endif -#ifdef USE_PAM - if (!use_privsep && authenticated && - !do_pam_account(pw->pw_name, client_user)) - authenticated = 0; -#endif /* Log before sending the reply */ auth_log(authctxt, authenticated, get_authname(type), info); @@ -413,7 +408,8 @@ do_authentication(void) use_privsep ? " [net]" : ""); #ifdef USE_PAM - PRIVSEP(start_pam(user)); + if (options.use_pam) + PRIVSEP(start_pam(user)); #endif /* diff --git a/auth2.c b/auth2.c index 03d170e23..5ca020001 100644 --- a/auth2.c +++ b/auth2.c @@ -91,10 +91,6 @@ do_authentication2(void) /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; - if (options.pam_authentication_via_kbd_int) - options.kbd_interactive_authentication = 1; - if (use_privsep) - options.pam_authentication_via_kbd_int = 0; dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); @@ -163,12 +159,14 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) authctxt->valid = 1; debug2("input_userauth_request: setting up authctxt for %s", user); #ifdef USE_PAM - PRIVSEP(start_pam(authctxt->pw->pw_name)); + if (options.use_pam) + PRIVSEP(start_pam(authctxt->pw->pw_name)); #endif } else { logit("input_userauth_request: illegal user %s", user); #ifdef USE_PAM - PRIVSEP(start_pam(user)); + if (options.use_pam) + PRIVSEP(start_pam(user)); #endif } setproctitle("%s%s", authctxt->pw ? user : "unknown", @@ -215,12 +213,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) !auth_root_allowed(method)) authenticated = 0; -#ifdef USE_PAM - if (!use_privsep && authenticated && authctxt->user && - !do_pam_account(authctxt->user, NULL)) - authenticated = 0; -#endif /* USE_PAM */ - #ifdef _UNICOS if (authenticated && cray_access_denied(authctxt->user)) { authenticated = 0; diff --git a/monitor.c b/monitor.c index 78d1e2e0c..36f9a6c20 100644 --- a/monitor.c +++ b/monitor.c @@ -567,7 +567,8 @@ mm_answer_pwnamallow(int socket, Buffer *m) } #ifdef USE_PAM - monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); + if (options.use_pam) + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif return (0); @@ -750,6 +751,9 @@ 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); diff --git a/monitor_wrap.c b/monitor_wrap.c index a83413a5f..bd3a01a2b 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -47,6 +47,7 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.26 2003/04/07 08:29:57 markus Exp $"); #include "atomicio.h" #include "monitor_fdpass.h" #include "getput.h" +#include "servconf.h" #include "auth.h" #include "channels.h" @@ -59,6 +60,7 @@ extern z_stream incoming_stream; extern z_stream outgoing_stream; extern struct monitor *pmonitor; extern Buffer input, output; +extern ServerOptions options; void mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) @@ -669,6 +671,8 @@ mm_start_pam(char *user) Buffer m; debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); buffer_init(&m); buffer_put_cstring(&m, user); diff --git a/servconf.c b/servconf.c index 8e2839085..fbdc4d8fa 100644 --- a/servconf.c +++ b/servconf.c @@ -59,8 +59,10 @@ initialize_server_options(ServerOptions *options) { memset(options, 0, sizeof(*options)); +#ifdef USE_PAM /* Portable-specific options */ - options->pam_authentication_via_kbd_int = -1; + options->use_pam = -1; +#endif /* Standard Options */ options->num_ports = 0; @@ -136,8 +138,10 @@ void fill_default_server_options(ServerOptions *options) { /* Portable-specific options */ - if (options->pam_authentication_via_kbd_int == -1) - options->pam_authentication_via_kbd_int = 0; +#ifdef USE_PAM + if (options->use_pam == -1) + options->use_pam = 1; +#endif /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) @@ -279,7 +283,7 @@ fill_default_server_options(ServerOptions *options) typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ - sPAMAuthenticationViaKbdInt, + sUsePAM, /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, @@ -315,7 +319,7 @@ static struct { ServerOpCodes opcode; } keywords[] = { /* Portable-specific options */ - { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, + { "UsePAM", sUsePAM }, /* Standard Options */ { "port", sPort }, { "hostkey", sHostKeyFile }, @@ -462,8 +466,8 @@ process_server_config_line(ServerOptions *options, char *line, opcode = parse_token(arg, filename, linenum); switch (opcode) { /* Portable-specific options */ - case sPAMAuthenticationViaKbdInt: - intptr = &options->pam_authentication_via_kbd_int; + case sUsePAM: + intptr = &options->use_pam; goto parse_flag; /* Standard Options */ diff --git a/servconf.h b/servconf.h index 024987dd6..afa80675e 100644 --- a/servconf.h +++ b/servconf.h @@ -131,7 +131,7 @@ typedef struct { char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; - int pam_authentication_via_kbd_int; + int use_pam; /* Enable auth via PAM */ } ServerOptions; void initialize_server_options(ServerOptions *); diff --git a/session.c b/session.c index 1a86f5f81..5b445f93b 100644 --- a/session.c +++ b/session.c @@ -456,11 +456,13 @@ do_exec_no_pty(Session *s, const char *command) session_proctitle(s); #if defined(USE_PAM) - do_pam_session(s->pw->pw_name, NULL); - do_pam_setcred(1); - if (is_pam_password_change_required()) - packet_disconnect("Password change required but no " - "TTY available"); + if (options.use_pam) { + do_pam_session(s->pw->pw_name, NULL); + do_pam_setcred(1); + if (is_pam_password_change_required()) + packet_disconnect("Password change required but no " + "TTY available"); + } #endif /* USE_PAM */ /* Fork the child. */ @@ -583,8 +585,10 @@ do_exec_pty(Session *s, const char *command) ttyfd = s->ttyfd; #if defined(USE_PAM) - do_pam_session(s->pw->pw_name, s->tty); - do_pam_setcred(1); + if (options.use_pam) { + do_pam_session(s->pw->pw_name, s->tty); + do_pam_setcred(1); + } #endif /* Fork the child. */ @@ -753,7 +757,7 @@ do_login(Session *s, const char *command) * If password change is needed, do it now. * This needs to occur before the ~/.hushlogin check. */ - if (is_pam_password_change_required()) { + if (options.use_pam && is_pam_password_change_required()) { print_pam_messages(); do_pam_chauthtok(); } @@ -763,7 +767,7 @@ do_login(Session *s, const char *command) return; #ifdef USE_PAM - if (!is_pam_password_change_required()) + if (options.use_pam && !is_pam_password_change_required()) print_pam_messages(); #endif /* USE_PAM */ #ifdef WITH_AIXAUTHENTICATE @@ -1077,10 +1081,9 @@ do_setup_env(Session *s, const char *shell) * Pull in any environment variables that may have * been set by PAM. */ - { - char **p; + if (options.use_pam) { + char **p = fetch_pam_environment(); - p = fetch_pam_environment(); copy_environment(p, &env, &envsize); free_pam_environment(p); } @@ -1248,7 +1251,8 @@ do_setusercontext(struct passwd *pw) * These will have been wiped by the above initgroups() call. * Reestablish them here. */ - do_pam_setcred(0); + if (options.use_pam) + do_pam_setcred(0); # endif /* USE_PAM */ # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) irix_setusercontext(pw); diff --git a/sshd.c b/sshd.c index 9e2e218c6..cb70fa0c6 100644 --- a/sshd.c +++ b/sshd.c @@ -1544,7 +1544,8 @@ main(int ac, char **av) verbose("Closing connection to %.100s", remote_ip); #ifdef USE_PAM - finish_pam(); + if (options.use_pam) + finish_pam(); #endif /* USE_PAM */ packet_close(); diff --git a/sshd_config.5 b/sshd_config.5 index 31ef3996d..1278cb61f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -422,12 +422,15 @@ The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches .Dq full (60). -.It Cm PAMAuthenticationViaKbdInt -Specifies whether PAM challenge response authentication is allowed. This -allows the use of most PAM challenge response authentication modules, but -it will allow password authentication regardless of whether -.Cm PasswordAuthentication -is enabled. + +.It Cm UsePAM +Enables PAM authentication (via challenge-response) and session set up. +If you enable this, you should probably disable +.Cm PasswordAuthentication . +If you enable +.CM UsePAM +then you will not be able to run sshd as a non-root user. + .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is -- cgit v1.2.3 From be64d43d01bd6cdad89fee1db0e3b559d97cef96 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 14 May 2003 19:31:12 +1000 Subject: - markus@cvs.openbsd.org 2003/05/14 08:57:49 [monitor.c] http://bugzilla.mindrot.org/show_bug.cgi?id=560 Privsep child continues to run after monitor killed. Pass monitor signals through to child; Darren Tucker --- ChangeLog | 7 ++++++- monitor.c | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index 6fc81a360..6b8fe8474 100644 --- a/ChangeLog +++ b/ChangeLog @@ -72,6 +72,11 @@ - better formatting in SYNOPSIS - whitespace at EOL ok djm@ + - markus@cvs.openbsd.org 2003/05/14 08:57:49 + [monitor.c] + http://bugzilla.mindrot.org/show_bug.cgi?id=560 + Privsep child continues to run after monitor killed. + Pass monitor signals through to child; Darren Tucker - (djm) Make portable build with MIT krb5 (some issues remain) - (djm) Add new UsePAM configuration directive to allow runtime control over usage of PAM. This allows non-root use of sshd when built with @@ -1465,4 +1470,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2697 2003/05/14 09:30:38 djm Exp $ +$Id: ChangeLog,v 1.2698 2003/05/14 09:31:12 djm Exp $ diff --git a/monitor.c b/monitor.c index 36f9a6c20..700925c8c 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.39 2003/05/14 02:15:47 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.40 2003/05/14 08:57:49 markus Exp $"); #include @@ -143,6 +143,7 @@ static char *hostbased_chost = NULL; static char *auth_method = "unknown"; static int session_id2_len = 0; static u_char *session_id2 = NULL; +static pid_t monitor_child_pid; struct mon_table { enum monitor_reqtype type; @@ -321,9 +322,25 @@ monitor_child_preauth(struct monitor *pmonitor) return (authctxt); } +static void +monitor_set_child_handler(pid_t pid) +{ + monitor_child_pid = pid; +} + +static void +monitor_child_handler(int signal) +{ + kill(monitor_child_pid, signal); +} + void monitor_child_postauth(struct monitor *pmonitor) { + monitor_set_child_handler(pmonitor->m_pid); + signal(SIGHUP, &monitor_child_handler); + signal(SIGTERM, &monitor_child_handler); + if (compat20) { mon_dispatch = mon_dispatch_postauth20; -- cgit v1.2.3 From 04bd8b0bcc92eca7304898ce35705e0f403514c1 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 25 May 2003 14:38:33 +1000 Subject: - djm@cvs.openbsd.org 2003/05/24 09:30:40 [authfile.c monitor.c sftp-common.c sshpty.c] cast some types for printing; ok markus@ --- ChangeLog | 5 ++++- authfile.c | 4 ++-- monitor.c | 4 ++-- sftp-common.c | 6 +++--- sshpty.c | 6 +++--- 5 files changed, 14 insertions(+), 11 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index 4ac810479..1ee9299a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ - djm@cvs.openbsd.org 2003/05/24 09:02:22 [log.c] pass logged data through strnvis; ok markus + - djm@cvs.openbsd.org 2003/05/24 09:30:40 + [authfile.c monitor.c sftp-common.c sshpty.c] + cast some types for printing; ok markus@ 20030524 - (dtucker) Correct --osfsia in INSTALL. Patch by skeleten at shillest.net @@ -1611,4 +1614,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2750 2003/05/25 04:38:02 djm Exp $ +$Id: ChangeLog,v 1.2751 2003/05/25 04:38:33 djm Exp $ diff --git a/authfile.c b/authfile.c index d563abb71..1f46093e3 100644 --- a/authfile.c +++ b/authfile.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfile.c,v 1.53 2003/05/11 16:56:48 markus Exp $"); +RCSID("$OpenBSD: authfile.c,v 1.54 2003/05/24 09:30:39 djm Exp $"); #include #include @@ -514,7 +514,7 @@ key_perm_ok(int fd, const char *filename) error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("Permissions 0%3.3o for '%s' are too open.", - st.st_mode & 0777, filename); + (u_int)st.st_mode & 0777, filename); error("It is recommended that your private key files are NOT accessible by others."); error("This private key will be ignored."); return 0; diff --git a/monitor.c b/monitor.c index 700925c8c..3b7a6f8e3 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.40 2003/05/14 08:57:49 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.41 2003/05/24 09:30:40 djm Exp $"); #include @@ -1164,7 +1164,7 @@ mm_record_login(Session *s, struct passwd *pw) static void mm_session_close(Session *s) { - debug3("%s: session %d pid %d", __func__, s->self, s->pid); + 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); diff --git a/sftp-common.c b/sftp-common.c index 31d41385b..5313b134d 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sftp-common.c,v 1.8 2002/10/16 14:31:48 itojun Exp $"); +RCSID("$OpenBSD: sftp-common.c,v 1.9 2003/05/24 09:30:40 djm Exp $"); #include "buffer.h" #include "bufaux.h" @@ -206,8 +206,8 @@ ls_file(char *name, struct stat *st, int remote) tbuf[0] = '\0'; ulen = MAX(strlen(user), 8); glen = MAX(strlen(group), 8); - snprintf(buf, sizeof buf, "%s %3d %-*s %-*s %8llu %s %s", mode, - st->st_nlink, ulen, user, glen, group, + snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, + (u_int)st->st_nlink, ulen, user, glen, group, (unsigned long long)st->st_size, tbuf, name); return xstrdup(buf); } diff --git a/sshpty.c b/sshpty.c index 0cac10d3f..ee2b9d3b1 100644 --- a/sshpty.c +++ b/sshpty.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshpty.c,v 1.8 2003/02/03 08:56:16 markus Exp $"); +RCSID("$OpenBSD: sshpty.c,v 1.9 2003/05/24 09:30:40 djm Exp $"); #ifdef HAVE_UTIL_H # include @@ -409,10 +409,10 @@ pty_setowner(struct passwd *pw, const char *ttyname) if (errno == EROFS && (st.st_mode & (S_IRGRP | S_IROTH)) == 0) debug("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); + ttyname, (u_int)mode, strerror(errno)); else fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); + ttyname, (u_int)mode, strerror(errno)); } } } -- cgit v1.2.3 From 3a961dc0d36c1f87788b707130f6d07709822d38 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 3 Jun 2003 10:25:48 +1000 Subject: - (djm) OpenBSD CVS Sync - markus@cvs.openbsd.org 2003/06/02 09:17:34 [auth2-hostbased.c auth.c auth-options.c auth-rhosts.c auth-rh-rsa.c] [canohost.c monitor.c servconf.c servconf.h session.c sshd_config] [sshd_config.5] deprecate VerifyReverseMapping since it's dangerous if combined with IP based access control as noted by Mike Harding; replace with a UseDNS option, UseDNS is on by default and includes the VerifyReverseMapping check; with itojun@, provos@, jakob@ and deraadt@ ok deraadt@, djm@ - (djm) Fix portable-specific uses of verify_reverse_mapping too --- ChangeLog | 13 ++++++++++++- auth-options.c | 4 ++-- auth-pam.c | 5 ++--- auth-passwd.c | 16 +++++++++------- auth-rh-rsa.c | 4 ++-- auth-rhosts.c | 4 ++-- auth-sia.c | 4 ++-- auth.c | 4 ++-- auth2-hostbased.c | 4 ++-- canohost.c | 44 +++++++++++++++++++++++++++----------------- monitor.c | 4 ++-- servconf.c | 19 ++++++++++--------- servconf.h | 4 ++-- session.c | 8 ++++---- sshd_config | 4 ++-- sshd_config.5 | 18 +++++++++--------- 16 files changed, 91 insertions(+), 68 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index ada1bd2d9..6627ec3fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,17 @@ 20030603 - (djm) Replace setproctitle replacement with code derived from UCB sendmail + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/02 09:17:34 + [auth2-hostbased.c auth.c auth-options.c auth-rhosts.c auth-rh-rsa.c] + [canohost.c monitor.c servconf.c servconf.h session.c sshd_config] + [sshd_config.5] + deprecate VerifyReverseMapping since it's dangerous if combined + with IP based access control as noted by Mike Harding; replace with + a UseDNS option, UseDNS is on by default and includes the + VerifyReverseMapping check; with itojun@, provos@, jakob@ and deraadt@ + ok deraadt@, djm@ + - (djm) Fix portable-specific uses of verify_reverse_mapping too 20030602 - (djm) Fix segv from bad reordering in auth-pam.c @@ -1648,4 +1659,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2764 2003/06/03 00:14:28 djm Exp $ +$Id: ChangeLog,v 1.2765 2003/06/03 00:25:48 djm Exp $ diff --git a/auth-options.c b/auth-options.c index d8976b172..0e146ab15 100644 --- a/auth-options.c +++ b/auth-options.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-options.c,v 1.27 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth-options.c,v 1.28 2003/06/02 09:17:34 markus Exp $"); #include "xmalloc.h" #include "match.h" @@ -173,7 +173,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) if (strncasecmp(opts, cp, strlen(cp)) == 0) { const char *remote_ip = get_remote_ipaddr(); const char *remote_host = get_canonical_hostname( - options.verify_reverse_mapping); + options.use_dns); char *patterns = xmalloc(strlen(opts) + 1); opts += strlen(cp); diff --git a/auth-pam.c b/auth-pam.c index b8381646b..057164ad3 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -31,7 +31,7 @@ /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ #include "includes.h" -RCSID("$Id: auth-pam.c,v 1.63 2003/06/02 01:04:39 djm Exp $"); +RCSID("$Id: auth-pam.c,v 1.64 2003/06/03 00:25:48 djm Exp $"); #ifdef USE_PAM #include @@ -299,8 +299,7 @@ sshpam_init(const char *user) sshpam_handle = NULL; return (-1); } - pam_rhost = get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping); + pam_rhost = get_remote_name_or_ip(utmp_len, options.use_dns); debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); if (sshpam_err != PAM_SUCCESS) { diff --git a/auth-passwd.c b/auth-passwd.c index b893165bf..9a94c373f 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -144,22 +144,24 @@ auth_password(Authctxt *authctxt, const char *password) HANDLE hToken = cygwin_logon_user(pw, password); if (hToken == INVALID_HANDLE_VALUE) - return 0; + return (0); cygwin_set_impersonation_token(hToken); - return 1; + return (1); } # endif # ifdef WITH_AIXAUTHENTICATE authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); - if (authsuccess) + if (authsuccess) { /* We don't have a pty yet, so just label the line as "ssh" */ if (loginsuccess(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh", &aixloginmsg) < 0) - aixloginmsg = NULL; + get_canonical_hostname(options.use_dns), + "ssh", &aixloginmsg) < 0) { + aixloginmsg = NULL; + } + } - return(authsuccess); + return (authsuccess); # endif # ifdef KRB4 if (options.kerberos_authentication == 1) { diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c index 4d6f0d234..2eb7e6e2d 100644 --- a/auth-rh-rsa.c +++ b/auth-rh-rsa.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rh-rsa.c,v 1.35 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth-rh-rsa.c,v 1.36 2003/06/02 09:17:34 markus Exp $"); #include "packet.h" #include "uidswap.h" @@ -63,7 +63,7 @@ auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key) client_host_key->rsa == NULL) return 0; - chost = (char *)get_canonical_hostname(options.verify_reverse_mapping); + chost = (char *)get_canonical_hostname(options.use_dns); debug("Rhosts RSA authentication: canonical host %.900s", chost); if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) { diff --git a/auth-rhosts.c b/auth-rhosts.c index a38478108..b42a64c90 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rhosts.c,v 1.30 2003/05/17 03:25:58 itojun Exp $"); +RCSID("$OpenBSD: auth-rhosts.c,v 1.31 2003/06/02 09:17:34 markus Exp $"); #include "packet.h" #include "uidswap.h" @@ -156,7 +156,7 @@ auth_rhosts(struct passwd *pw, const char *client_user) { const char *hostname, *ipaddr; - hostname = get_canonical_hostname(options.verify_reverse_mapping); + hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); return auth_rhosts2(pw, client_user, hostname, ipaddr); } diff --git a/auth-sia.c b/auth-sia.c index 05cf47c40..cae5f0912 100644 --- a/auth-sia.c +++ b/auth-sia.c @@ -52,7 +52,7 @@ auth_sia_password(Authctxt *authctxt, char *pass) SIAENTITY *ent = NULL; const char *host; - host = get_canonical_hostname(options.verify_reverse_mapping); + host = get_canonical_hostname(options.use_dns); if (!authctxt->user || pass == NULL || pass[0] == '\0') return (0); @@ -81,7 +81,7 @@ session_setup_sia(struct passwd *pw, char *tty) SIAENTITY *ent = NULL; const char *host; - host = get_canonical_hostname(options.verify_reverse_mapping); + host = get_canonical_hostname(options.use_dns); if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name, tty, 0, NULL) != SIASUCCESS) diff --git a/auth.c b/auth.c index 8b58cc671..6b48addf7 100644 --- a/auth.c +++ b/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.47 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth.c,v 1.48 2003/06/02 09:17:34 markus Exp $"); #ifdef HAVE_LOGIN_H #include @@ -141,7 +141,7 @@ allowed_user(struct passwd * pw) } if (options.num_deny_users > 0 || options.num_allow_users > 0) { - hostname = get_canonical_hostname(options.verify_reverse_mapping); + hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } diff --git a/auth2-hostbased.c b/auth2-hostbased.c index f8b4ae852..bbc7d8a4d 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-hostbased.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth2-hostbased.c,v 1.4 2003/06/02 09:17:34 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -136,7 +136,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, HostStatus host_status; int len; - resolvedname = get_canonical_hostname(options.verify_reverse_mapping); + resolvedname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", diff --git a/canohost.c b/canohost.c index 417d95c18..533f2c24a 100644 --- a/canohost.c +++ b/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.36 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $"); #include "packet.h" #include "xmalloc.h" @@ -27,7 +27,7 @@ static void check_ip_options(int, char *); */ static char * -get_remote_hostname(int socket, int verify_reverse_mapping) +get_remote_hostname(int socket, int use_dns) { struct sockaddr_storage from; int i; @@ -72,6 +72,9 @@ get_remote_hostname(int socket, int verify_reverse_mapping) NULL, 0, NI_NUMERICHOST) != 0) fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + if (!use_dns) + return xstrdup(ntop); + if (from.ss_family == AF_INET) check_ip_options(socket, ntop); @@ -80,14 +83,24 @@ get_remote_hostname(int socket, int verify_reverse_mapping) if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), NULL, 0, NI_NAMEREQD) != 0) { /* Host name not found. Use ip address. */ -#if 0 - logit("Could not reverse map address %.100s.", ntop); -#endif return xstrdup(ntop); } - /* Got host name. */ - name[sizeof(name) - 1] = '\0'; + /* + * if reverse lookup result looks like a numeric hostname, + * someone is trying to trick us by PTR record like following: + * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(name, "0", &hints, &ai) == 0) { + logit("Nasty PTR record \"%s\" is set up for %s, ignoring", + name, ntop); + freeaddrinfo(ai); + return xstrdup(ntop); + } + /* * Convert it to all lowercase (which is expected by the rest * of this software). @@ -95,9 +108,6 @@ get_remote_hostname(int socket, int verify_reverse_mapping) for (i = 0; name[i]; i++) if (isupper(name[i])) name[i] = tolower(name[i]); - - if (!verify_reverse_mapping) - return xstrdup(name); /* * Map it back to an IP address and check that the given * address actually is an address of this host. This is @@ -180,14 +190,14 @@ check_ip_options(int socket, char *ipaddr) */ const char * -get_canonical_hostname(int verify_reverse_mapping) +get_canonical_hostname(int use_dns) { static char *canonical_host_name = NULL; - static int verify_reverse_mapping_done = 0; + static int use_dns_done = 0; /* Check if we have previously retrieved name with same option. */ if (canonical_host_name != NULL) { - if (verify_reverse_mapping_done != verify_reverse_mapping) + if (use_dns_done != use_dns) xfree(canonical_host_name); else return canonical_host_name; @@ -196,11 +206,11 @@ get_canonical_hostname(int verify_reverse_mapping) /* Get the real hostname if socket; otherwise return UNKNOWN. */ if (packet_connection_is_on_socket()) canonical_host_name = get_remote_hostname( - packet_get_connection_in(), verify_reverse_mapping); + packet_get_connection_in(), use_dns); else canonical_host_name = xstrdup("UNKNOWN"); - verify_reverse_mapping_done = verify_reverse_mapping; + use_dns_done = use_dns; return canonical_host_name; } @@ -294,11 +304,11 @@ get_remote_ipaddr(void) } const char * -get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping) +get_remote_name_or_ip(u_int utmp_len, int use_dns) { static const char *remote = ""; if (utmp_len > 0) - remote = get_canonical_hostname(verify_reverse_mapping); + remote = get_canonical_hostname(use_dns); if (utmp_len == 0 || strlen(remote) > utmp_len) remote = get_remote_ipaddr(); return remote; diff --git a/monitor.c b/monitor.c index 3b7a6f8e3..707d314b3 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.41 2003/05/24 09:30:40 djm Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.42 2003/06/02 09:17:34 markus Exp $"); #include @@ -1157,7 +1157,7 @@ mm_record_login(Session *s, struct passwd *pw) } /* 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, - get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), + get_remote_name_or_ip(utmp_len, options.use_dns), (struct sockaddr *)&from, fromlen); } diff --git a/servconf.c b/servconf.c index a737f4b46..c501d7b64 100644 --- a/servconf.c +++ b/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.121 2003/05/15 14:02:47 jakob Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.122 2003/06/02 09:17:34 markus Exp $"); #if defined(KRB4) #include @@ -116,7 +116,7 @@ initialize_server_options(ServerOptions *options) options->max_startups_rate = -1; options->max_startups = -1; options->banner = NULL; - options->verify_reverse_mapping = -1; + options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; options->authorized_keys_file = NULL; @@ -232,8 +232,8 @@ fill_default_server_options(ServerOptions *options) options->max_startups_rate = 100; /* 100% */ if (options->max_startups_begin == -1) options->max_startups_begin = options->max_startups; - if (options->verify_reverse_mapping == -1) - options->verify_reverse_mapping = 0; + if (options->use_dns == -1) + options->use_dns = 1; if (options->client_alive_interval == -1) options->client_alive_interval = 0; if (options->client_alive_count_max == -1) @@ -282,7 +282,7 @@ typedef enum { sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, - sBanner, sVerifyReverseMapping, sHostbasedAuthentication, + sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sUsePrivilegeSeparation, @@ -366,8 +366,9 @@ static struct { { "subsystem", sSubsystem }, { "maxstartups", sMaxStartups }, { "banner", sBanner }, - { "verifyreversemapping", sVerifyReverseMapping }, - { "reversemappingcheck", sVerifyReverseMapping }, + { "usedns", sUseDNS }, + { "verifyreversemapping", sDeprecated }, + { "reversemappingcheck", sDeprecated }, { "clientaliveinterval", sClientAliveInterval }, { "clientalivecountmax", sClientAliveCountMax }, { "authorizedkeysfile", sAuthorizedKeysFile }, @@ -723,8 +724,8 @@ parse_flag: intptr = &options->gateway_ports; goto parse_flag; - case sVerifyReverseMapping: - intptr = &options->verify_reverse_mapping; + case sUseDNS: + intptr = &options->use_dns; goto parse_flag; case sLogFacility: diff --git a/servconf.h b/servconf.h index 4ad1ee7be..b676f2b67 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.60 2003/05/15 01:48:10 jakob Exp $ */ +/* $OpenBSD: servconf.h,v 1.61 2003/06/02 09:17:34 markus Exp $ */ /* * Author: Tatu Ylonen @@ -112,7 +112,7 @@ typedef struct { int max_startups_rate; int max_startups; char *banner; /* SSH-2 banner message */ - int verify_reverse_mapping; /* cross-check ip and dns */ + int use_dns; int client_alive_interval; /* * poke the client this often to * see if it's still there diff --git a/session.c b/session.c index 796c5177c..dc9777de9 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.157 2003/05/14 22:24:42 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.158 2003/06/02 09:17:34 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -694,7 +694,7 @@ do_pre_login(Session *s) } record_utmp_only(pid, s->tty, s->pw->pw_name, - get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), + get_remote_name_or_ip(utmp_len, options.use_dns), (struct sockaddr *)&from, fromlen); } #endif @@ -749,7 +749,7 @@ do_login(Session *s, const char *command) if (!use_privsep) record_login(pid, s->tty, pw->pw_name, pw->pw_uid, get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping), + options.use_dns), (struct sockaddr *)&from, fromlen); #ifdef USE_PAM @@ -1353,7 +1353,7 @@ do_child(Session *s, const char *command) /* we have to stash the hostname before we close our socket. */ if (options.use_login) hostname = get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping); + options.use_dns); /* * Close the connection descriptors; note that this is the child, and * the server will still have the socket open, and it is important diff --git a/sshd_config b/sshd_config index 78fc67c23..c93396b51 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.59 2002/09/25 11:17:16 markus Exp $ +# $OpenBSD: sshd_config,v 1.60 2003/06/02 09:17:34 markus Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -88,7 +88,7 @@ #MaxStartups 10 # no default banner path #Banner /some/path -#VerifyReverseMapping no +#UseDNS yes # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server diff --git a/sshd_config.5 b/sshd_config.5 index 86b3289a1..0c6108e0f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.17 2003/05/20 12:09:32 jmc Exp $ +.\" $OpenBSD: sshd_config.5,v 1.18 2003/06/02 09:17:34 markus Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -585,6 +585,14 @@ Gives the facility code that is used when logging messages from The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. +.It Cm UseDNS +Specifies whether +.Nm sshd +should lookup the remote host name and check that +the resolved host name for the remote IP address maps back to the +very same IP address. +The default is +.Dq yes . .It Cm UseLogin Specifies whether .Xr login 1 @@ -622,14 +630,6 @@ The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes. The default is .Dq yes . -.It Cm VerifyReverseMapping -Specifies whether -.Nm sshd -should try to verify the remote host name and check that -the resolved host name for the remote IP address maps back to the -very same IP address. -The default is -.Dq no . .It Cm X11DisplayOffset Specifies the first display number available for .Nm sshd Ns 's -- cgit v1.2.3 From 469954debd6cb78d8c109785e418b235cf004565 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 18 Jun 2003 20:25:33 +1000 Subject: - (djm) OpenBSD CVS Sync - markus@cvs.openbsd.org 2003/06/12 07:57:38 [monitor.c sshlogin.c sshpty.c] typos; dtucker at zip.com.au --- ChangeLog | 9 ++++++++- monitor.c | 4 ++-- sshlogin.c | 6 +++--- sshpty.c | 4 ++-- 4 files changed, 15 insertions(+), 8 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index deb0c6335..b627c1334 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20030618 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/12 07:57:38 + [monitor.c sshlogin.c sshpty.c] + typos; dtucker at zip.com.au + + 20030614 - (djm) Update license on fake-rfc2553.[ch]; ok itojun@ @@ -512,4 +519,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2801 2003/06/13 22:43:22 djm Exp $ +$Id: ChangeLog,v 1.2802 2003/06/18 10:25:33 djm Exp $ diff --git a/monitor.c b/monitor.c index 707d314b3..f306794d4 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.42 2003/06/02 09:17:34 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.43 2003/06/12 07:57:38 markus Exp $"); #include @@ -93,7 +93,7 @@ struct { u_int olen; } child_state; -/* Functions on the montior that answer unprivileged requests */ +/* Functions on the monitor that answer unprivileged requests */ int mm_answer_moduli(int, Buffer *); int mm_answer_sign(int, Buffer *); diff --git a/sshlogin.c b/sshlogin.c index 188a6b3ae..36b648934 100644 --- a/sshlogin.c +++ b/sshlogin.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshlogin.c,v 1.6 2003/04/08 20:21:29 itojun Exp $"); +RCSID("$OpenBSD: sshlogin.c,v 1.7 2003/06/12 07:57:38 markus Exp $"); #include "loginrec.h" @@ -60,8 +60,8 @@ get_last_login_time(uid_t uid, const char *logname, } /* - * Records that the user has logged in. I these parts of operating systems - * were more standardized. + * Records that the user has logged in. I wish these parts of operating + * systems were more standardized. */ void record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, diff --git a/sshpty.c b/sshpty.c index ee2b9d3b1..109fc96ac 100644 --- a/sshpty.c +++ b/sshpty.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshpty.c,v 1.9 2003/05/24 09:30:40 djm Exp $"); +RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); #ifdef HAVE_UTIL_H # include @@ -258,7 +258,7 @@ pty_release(const char *ttyname) error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); } -/* Makes the tty the processes controlling tty and sets it to sane modes. */ +/* Makes the tty the process's controlling tty and sets it to sane modes. */ void pty_make_controlling_tty(int *ttyfd, const char *ttyname) -- cgit v1.2.3 From 502d384b74fae68dd9e265f48c2026cef6c12806 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 28 Jun 2003 12:38:01 +1000 Subject: - markus@cvs.openbsd.org 2003/06/24 08:23:46 [auth2-hostbased.c auth2-pubkey.c auth2.c channels.c key.c key.h monitor.c packet.c packet.h serverloop.c sshconnect2.c sshd.c] int -> u_int; ok djm@, deraadt@, mouring@ --- ChangeLog | 6 +++++- auth2-hostbased.c | 4 ++-- auth2-pubkey.c | 4 ++-- auth2.c | 4 ++-- channels.c | 4 ++-- key.c | 6 +++--- key.h | 4 ++-- monitor.c | 4 ++-- packet.c | 8 ++++---- packet.h | 6 +++--- serverloop.c | 6 +++--- sshconnect2.c | 6 +++--- sshd.c | 4 ++-- 13 files changed, 35 insertions(+), 31 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index e6d0ce878..e64ef5b33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,10 @@ - markus@cvs.openbsd.org 2003/06/23 09:02:44 [ssh_config.5] document EnableSSHKeysign; bugzilla #599; ok deraadt@, jmc@ + - markus@cvs.openbsd.org 2003/06/24 08:23:46 + [auth2-hostbased.c auth2-pubkey.c auth2.c channels.c key.c key.h + monitor.c packet.c packet.h serverloop.c sshconnect2.c sshd.c] + int -> u_int; ok djm@, deraadt@, mouring@ 20030624 - (dtucker) Have configure refer the user to config.log and @@ -589,4 +593,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2824 2003/06/28 02:33:12 dtucker Exp $ +$Id: ChangeLog,v 1.2825 2003/06/28 02:38:01 dtucker Exp $ diff --git a/auth2-hostbased.c b/auth2-hostbased.c index bbc7d8a4d..505d3eff4 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-hostbased.c,v 1.4 2003/06/02 09:17:34 markus Exp $"); +RCSID("$OpenBSD: auth2-hostbased.c,v 1.5 2003/06/24 08:23:46 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -42,7 +42,7 @@ RCSID("$OpenBSD: auth2-hostbased.c,v 1.4 2003/06/02 09:17:34 markus Exp $"); /* import */ extern ServerOptions options; extern u_char *session_id2; -extern int session_id2_len; +extern u_int session_id2_len; static int userauth_hostbased(Authctxt *authctxt) diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 85ee33eed..d51e939f1 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-pubkey.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth2-pubkey.c,v 1.4 2003/06/24 08:23:46 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -44,7 +44,7 @@ RCSID("$OpenBSD: auth2-pubkey.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); /* import */ extern ServerOptions options; extern u_char *session_id2; -extern int session_id2_len; +extern u_int session_id2_len; static int userauth_pubkey(Authctxt *authctxt) diff --git a/auth2.c b/auth2.c index 5ca020001..639bf9117 100644 --- a/auth2.c +++ b/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.98 2003/05/14 02:15:47 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.99 2003/06/24 08:23:46 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -39,7 +39,7 @@ RCSID("$OpenBSD: auth2.c,v 1.98 2003/05/14 02:15:47 markus Exp $"); /* import */ extern ServerOptions options; extern u_char *session_id2; -extern int session_id2_len; +extern u_int session_id2_len; Authctxt *x_authctxt = NULL; diff --git a/channels.c b/channels.c index ad879cc61..04ef6575c 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.190 2003/05/11 20:30:24 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.191 2003/06/24 08:23:46 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -419,7 +419,7 @@ channel_not_very_much_buffered_data(void) } #endif if (buffer_len(&c->output) > packet_get_maxsize()) { - debug2("channel %d: big output buffer %d > %d", + debug2("channel %d: big output buffer %u > %u", c->self, buffer_len(&c->output), packet_get_maxsize()); return 0; diff --git a/key.c b/key.c index d918cfd0a..b101e1b27 100644 --- a/key.c +++ b/key.c @@ -32,7 +32,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: key.c,v 1.52 2003/05/14 18:16:20 jakob Exp $"); +RCSID("$OpenBSD: key.c,v 1.53 2003/06/24 08:23:46 markus Exp $"); #include @@ -438,7 +438,7 @@ key_read(Key *ret, char **cpp) xfree(blob); return -1; } - k = key_from_blob(blob, n); + k = key_from_blob(blob, (u_int)n); xfree(blob); if (k == NULL) { error("key_read: key_from_blob %s failed", cp); @@ -674,7 +674,7 @@ key_names_valid2(const char *names) } Key * -key_from_blob(u_char *blob, int blen) +key_from_blob(u_char *blob, u_int blen) { Buffer b; char *ktype; diff --git a/key.h b/key.h index a7b6afe86..28753fdfa 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.21 2003/05/14 18:16:20 jakob Exp $ */ +/* $OpenBSD: key.h,v 1.22 2003/06/24 08:23:46 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -71,7 +71,7 @@ Key *key_generate(int, u_int); Key *key_from_private(Key *); int key_type_from_name(char *); -Key *key_from_blob(u_char *, int); +Key *key_from_blob(u_char *, u_int); int key_to_blob(Key *, u_char **, u_int *); char *key_ssh_name(Key *); int key_names_valid2(const char *); diff --git a/monitor.c b/monitor.c index f306794d4..3a8735f58 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.43 2003/06/12 07:57:38 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.44 2003/06/24 08:23:46 markus Exp $"); #include @@ -141,7 +141,7 @@ static int key_blobtype = MM_NOKEY; static char *hostbased_cuser = NULL; static char *hostbased_chost = NULL; static char *auth_method = "unknown"; -static int session_id2_len = 0; +static u_int session_id2_len = 0; static u_char *session_id2 = NULL; static pid_t monitor_child_pid; diff --git a/packet.c b/packet.c index 07e90b899..022212074 100644 --- a/packet.c +++ b/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.107 2003/06/10 22:20:52 deraadt Exp $"); +RCSID("$OpenBSD: packet.c,v 1.108 2003/06/24 08:23:46 markus Exp $"); #include "openbsd-compat/sys-queue.h" @@ -108,7 +108,7 @@ static int compression_buffer_ready = 0; static int packet_compression = 0; /* default maximum packet size */ -int max_packet_size = 32768; +u_int max_packet_size = 32768; /* Flag indicating whether this module has been initialized. */ static int initialized = 0; @@ -1446,8 +1446,8 @@ packet_is_interactive(void) return interactive_mode; } -int -packet_set_maxsize(int s) +u_int +packet_set_maxsize(u_int s) { static int called = 0; diff --git a/packet.h b/packet.h index fa000d686..7732fafb7 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.39 2003/04/08 20:21:29 itojun Exp $ */ +/* $OpenBSD: packet.h,v 1.40 2003/06/24 08:23:46 markus Exp $ */ /* * Author: Tatu Ylonen @@ -81,8 +81,8 @@ void packet_add_padding(u_char); void tty_make_modes(int, struct termios *); void tty_parse_modes(int, int *); -extern int max_packet_size; -int packet_set_maxsize(int); +extern u_int max_packet_size; +u_int packet_set_maxsize(u_int); #define packet_get_maxsize() max_packet_size /* don't allow remaining bytes after the end of the message */ diff --git a/serverloop.c b/serverloop.c index 90eec0855..a95390273 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.109 2003/06/04 12:03:59 djm Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.110 2003/06/24 08:23:46 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -158,7 +158,7 @@ sigchld_handler(int sig) static void make_packets_from_stderr_data(void) { - int len; + u_int len; /* Send buffered stderr data to the client. */ while (buffer_len(&stderr_buffer) > 0 && @@ -187,7 +187,7 @@ make_packets_from_stderr_data(void) static void make_packets_from_stdout_data(void) { - int len; + u_int len; /* Send buffered stdout data to the client. */ while (buffer_len(&stdout_buffer) > 0 && diff --git a/sshconnect2.c b/sshconnect2.c index 1b85730fe..6a0bd409a 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.119 2003/05/15 00:28:28 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.120 2003/06/24 08:23:46 markus Exp $"); #ifdef KRB5 #include @@ -67,7 +67,7 @@ extern Options options; */ u_char *session_id2 = NULL; -int session_id2_len = 0; +u_int session_id2_len = 0; char *xxx_host; struct sockaddr *xxx_hostaddr; @@ -591,7 +591,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) Buffer b; u_char *blob, *signature; u_int bloblen, slen; - int skip = 0; + u_int skip = 0; int ret = -1; int have_sig = 1; diff --git a/sshd.c b/sshd.c index bc458488b..b8f360841 100644 --- a/sshd.c +++ b/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.268 2003/06/04 10:23:48 djm Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.269 2003/06/24 08:23:46 markus Exp $"); #include #include @@ -188,7 +188,7 @@ u_char session_id[16]; /* same for ssh2 */ u_char *session_id2 = NULL; -int session_id2_len = 0; +u_int session_id2_len = 0; /* record remote hostname or ip */ u_int utmp_len = MAXHOSTNAMELEN; -- cgit v1.2.3 From 6aaa58c4709c43ffb9f3f2be299cd5c4044f24a3 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 2 Aug 2003 22:24:49 +1000 Subject: - (dtucker) OpenBSD CVS Sync - markus@cvs.openbsd.org 2003/07/22 13:35:22 [auth1.c auth.h auth-passwd.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h servconf.c servconf.h session.c ssh.1 ssh.c ssh_config.5 sshconnect1.c sshd.c sshd_config.5 ssh.h] remove (already disabled) KRB4/AFS support, re-enable -k in ssh(1); test+ok henning@ - (dtucker) [Makefile.in acconfig.h configure.ac] Remove KRB4/AFS support. - (dtucker) [auth-krb4.c radix.c radix.h] Remove KRB4/AFS specific files. I hope I got this right.... --- ChangeLog | 11 +- Makefile.in | 6 +- acconfig.h | 8 +- auth-krb4.c | 368 --------------------------------------------------------- auth-passwd.c | 10 +- auth.h | 19 +-- auth1.c | 45 +------ configure.ac | 87 +------------- monitor.c | 54 +-------- monitor.h | 1 - monitor_wrap.c | 38 +----- monitor_wrap.h | 5 +- radix.c | 158 ------------------------- radix.h | 28 ----- readconf.c | 17 +-- readconf.h | 3 +- servconf.c | 25 +--- servconf.h | 3 +- session.c | 57 +-------- ssh.1 | 4 +- ssh.c | 9 +- ssh.h | 5 +- ssh_config.5 | 10 +- sshconnect1.c | 287 +------------------------------------------- sshd.c | 21 +--- sshd_config.5 | 9 +- 26 files changed, 52 insertions(+), 1236 deletions(-) delete mode 100644 auth-krb4.c delete mode 100644 radix.c delete mode 100644 radix.h (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index c930ad347..67ca07ce4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 20030802 - (dtucker) [monitor.h monitor_wrap.h] Remove excess ident tags. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/07/22 13:35:22 + [auth1.c auth.h auth-passwd.c monitor.c monitor.h monitor_wrap.c + monitor_wrap.h readconf.c readconf.h servconf.c servconf.h session.c ssh.1 + ssh.c ssh_config.5 sshconnect1.c sshd.c sshd_config.5 ssh.h] + remove (already disabled) KRB4/AFS support, re-enable -k in ssh(1); + test+ok henning@ + - (dtucker) [Makefile.in acconfig.h configure.ac] Remove KRB4/AFS support. + - (dtucker) [auth-krb4.c radix.c radix.h] Remove KRB4/AFS specific files. 20030730 - (djm) [auth-pam.c] Don't use crappy APIs like sprintf. Thanks bal @@ -738,4 +747,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2868 2003/08/02 10:37:03 dtucker Exp $ +$Id: ChangeLog,v 1.2869 2003/08/02 12:24:49 dtucker Exp $ diff --git a/Makefile.in b/Makefile.in index 4252ae6f3..c5674c735 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.238 2003/06/05 08:53:43 djm Exp $ +# $Id: Makefile.in,v 1.239 2003/08/02 12:24:49 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -63,7 +63,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keys LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \ cipher.o cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \ compat.o compress.o crc32.o deattack.o fatal.o \ - hostfile.o log.o match.o mpaux.o nchan.o packet.o radix.o \ + hostfile.o log.o match.o mpaux.o nchan.o packet.o \ readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \ key.o dispatch.o kex.o mac.o uuencode.o misc.o \ rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o kexgex.o \ @@ -81,7 +81,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o monitor_fdpass.o \ kexdhs.o kexgexs.o \ - auth-krb5.o auth2-krb5.o auth-krb4.o \ + auth-krb5.o auth2-krb5.o \ loginrec.o auth-pam.o auth-sia.o md5crypt.o MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out diff --git a/acconfig.h b/acconfig.h index 0af93663c..24c07beed 100644 --- a/acconfig.h +++ b/acconfig.h @@ -1,4 +1,4 @@ -/* $Id: acconfig.h,v 1.159 2003/07/14 06:21:44 dtucker Exp $ */ +/* $Id: acconfig.h,v 1.160 2003/08/02 12:24:49 dtucker Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -238,12 +238,6 @@ /* Define this if you are using the Heimdal version of Kerberos V5 */ #undef HEIMDAL -/* Define if you want Kerberos 4 support */ -#undef KRB4 - -/* Define if you want AFS support */ -#undef AFS - /* Define if you want S/Key support */ #undef SKEY diff --git a/auth-krb4.c b/auth-krb4.c deleted file mode 100644 index 9e1c800be..000000000 --- a/auth-krb4.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 1999 Dug Song. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth-krb4.c,v 1.30 2003/04/08 20:21:28 itojun Exp $"); - -#include "ssh.h" -#include "ssh1.h" -#include "packet.h" -#include "xmalloc.h" -#include "log.h" -#include "servconf.h" -#include "uidswap.h" -#include "auth.h" - -#ifdef AFS -#include "radix.h" -#endif - -#ifdef KRB4 -extern ServerOptions options; - -static int -krb4_init(void *context) -{ - static int cleanup_registered = 0; - Authctxt *authctxt = (Authctxt *)context; - const char *tkt_root = TKT_ROOT; - struct stat st; - int fd; - - if (!authctxt->krb4_ticket_file) { - /* Set unique ticket string manually since we're still root. */ - authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN); -#ifdef AFS - if (lstat("/ticket", &st) != -1) - tkt_root = "/ticket/"; -#endif /* AFS */ - snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%ld", - tkt_root, authctxt->pw->pw_uid, (long)getpid()); - krb_set_tkt_string(authctxt->krb4_ticket_file); - } - /* Register ticket cleanup in case of fatal error. */ - if (!cleanup_registered) { - fatal_add_cleanup(krb4_cleanup_proc, authctxt); - cleanup_registered = 1; - } - /* Try to create our ticket file. */ - if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) { - close(fd); - return (1); - } - /* Ticket file exists - make sure user owns it (just passed ticket). */ - if (lstat(authctxt->krb4_ticket_file, &st) != -1) { - if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && - st.st_uid == authctxt->pw->pw_uid) - return (1); - } - /* Failure - cancel cleanup function, leaving ticket for inspection. */ - logit("WARNING: bad ticket file %s", authctxt->krb4_ticket_file); - - fatal_remove_cleanup(krb4_cleanup_proc, authctxt); - cleanup_registered = 0; - - xfree(authctxt->krb4_ticket_file); - authctxt->krb4_ticket_file = NULL; - - return (0); -} - -/* - * try krb4 authentication, - * return 1 on success, 0 on failure, -1 if krb4 is not available - */ -int -auth_krb4_password(Authctxt *authctxt, const char *password) -{ - AUTH_DAT adata; - KTEXT_ST tkt; - struct hostent *hp; - struct passwd *pw; - char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ]; - u_int32_t faddr; - int r; - - if ((pw = authctxt->pw) == NULL) - return (0); - - /* - * Try Kerberos password authentication only for non-root - * users and only if Kerberos is installed. - */ - if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { - /* Set up our ticket file. */ - if (!krb4_init(authctxt)) { - logit("Couldn't initialize Kerberos ticket file for %s!", - pw->pw_name); - goto failure; - } - /* Try to get TGT using our password. */ - r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm, - "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password); - if (r != INTK_OK) { - debug("Kerberos v4 password authentication for %s " - "failed: %s", pw->pw_name, krb_err_txt[r]); - goto failure; - } - /* Successful authentication. */ - chown(tkt_string(), pw->pw_uid, pw->pw_gid); - - /* - * Now that we have a TGT, try to get a local - * "rcmd" ticket to ensure that we are not talking - * to a bogus Kerberos server. - */ - gethostname(localhost, sizeof(localhost)); - strlcpy(phost, (char *)krb_get_phost(localhost), - sizeof(phost)); - r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); - - if (r == KSUCCESS) { - if ((hp = gethostbyname(localhost)) == NULL) { - logit("Couldn't get local host address!"); - goto failure; - } - memmove((void *)&faddr, (void *)hp->h_addr, - sizeof(faddr)); - - /* Verify our "rcmd" ticket. */ - r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, - faddr, &adata, ""); - if (r == RD_AP_UNDEC) { - /* - * Probably didn't have a srvtab on - * localhost. Disallow login. - */ - logit("Kerberos v4 TGT for %s unverifiable, " - "no srvtab installed? krb_rd_req: %s", - pw->pw_name, krb_err_txt[r]); - goto failure; - } else if (r != KSUCCESS) { - logit("Kerberos v4 %s ticket unverifiable: %s", - KRB4_SERVICE_NAME, krb_err_txt[r]); - goto failure; - } - } else if (r == KDC_PR_UNKNOWN) { - /* - * Disallow login if no rcmd service exists, and - * log the error. - */ - logit("Kerberos v4 TGT for %s unverifiable: %s; %s.%s " - "not registered, or srvtab is wrong?", pw->pw_name, - krb_err_txt[r], KRB4_SERVICE_NAME, phost); - goto failure; - } else { - /* - * TGT is bad, forget it. Possibly spoofed! - */ - debug("WARNING: Kerberos v4 TGT possibly spoofed " - "for %s: %s", pw->pw_name, krb_err_txt[r]); - goto failure; - } - /* Authentication succeeded. */ - return (1); - } else - /* Logging in as root or no local Kerberos realm. */ - debug("Unable to authenticate to Kerberos."); - - failure: - krb4_cleanup_proc(authctxt); - - if (!options.kerberos_or_local_passwd) - return (0); - - /* Fall back to ordinary passwd authentication. */ - return (-1); -} - -void -krb4_cleanup_proc(void *context) -{ - Authctxt *authctxt = (Authctxt *)context; - debug("krb4_cleanup_proc called"); - if (authctxt->krb4_ticket_file) { - (void) dest_tkt(); - xfree(authctxt->krb4_ticket_file); - authctxt->krb4_ticket_file = NULL; - } -} - -int -auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply) -{ - AUTH_DAT adat = {0}; - Key_schedule schedule; - struct sockaddr_in local, foreign; - char instance[INST_SZ]; - socklen_t slen; - u_int cksum; - int r, s; - - s = packet_get_connection_in(); - - slen = sizeof(local); - memset(&local, 0, sizeof(local)); - if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) - debug("getsockname failed: %.100s", strerror(errno)); - slen = sizeof(foreign); - memset(&foreign, 0, sizeof(foreign)); - if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { - debug("getpeername failed: %.100s", strerror(errno)); - fatal_cleanup(); - } - instance[0] = '*'; - instance[1] = 0; - - /* Get the encrypted request, challenge, and session key. */ - if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, - 0, &adat, ""))) { - debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]); - return (0); - } - des_key_sched((des_cblock *) adat.session, schedule); - - *client = xmalloc(MAX_K_NAME_SZ); - (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, - *adat.pinst ? "." : "", adat.pinst, adat.prealm); - - /* Check ~/.klogin authorization now. */ - if (kuserok(&adat, authctxt->user) != KSUCCESS) { - logit("Kerberos v4 .klogin authorization failed for %s to " - "account %s", *client, authctxt->user); - xfree(*client); - *client = NULL; - return (0); - } - /* Increment the checksum, and return it encrypted with the - session key. */ - cksum = adat.checksum + 1; - cksum = htonl(cksum); - - /* If we can't successfully encrypt the checksum, we send back an - empty message, admitting our failure. */ - if ((r = krb_mk_priv((u_char *) & cksum, reply->dat, sizeof(cksum) + 1, - schedule, &adat.session, &local, &foreign)) < 0) { - debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]); - reply->dat[0] = 0; - reply->length = 0; - } else - reply->length = r; - - /* Clear session key. */ - memset(&adat.session, 0, sizeof(adat.session)); - return (1); -} -#endif /* KRB4 */ - -#ifdef AFS -int -auth_krb4_tgt(Authctxt *authctxt, const char *string) -{ - CREDENTIALS creds; - struct passwd *pw; - - if ((pw = authctxt->pw) == NULL) - goto failure; - - temporarily_use_uid(pw); - - if (!radix_to_creds(string, &creds)) { - logit("Protocol error decoding Kerberos v4 TGT"); - goto failure; - } - if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ - strlcpy(creds.service, "krbtgt", sizeof creds.service); - - if (strcmp(creds.service, "krbtgt")) { - logit("Kerberos v4 TGT (%s%s%s@%s) rejected for %s", - creds.pname, creds.pinst[0] ? "." : "", creds.pinst, - creds.realm, pw->pw_name); - goto failure; - } - if (!krb4_init(authctxt)) - goto failure; - - if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) - goto failure; - - if (save_credentials(creds.service, creds.instance, creds.realm, - creds.session, creds.lifetime, creds.kvno, &creds.ticket_st, - creds.issue_date) != KSUCCESS) { - debug("Kerberos v4 TGT refused: couldn't save credentials"); - goto failure; - } - /* Successful authentication, passed all checks. */ - chown(tkt_string(), pw->pw_uid, pw->pw_gid); - - debug("Kerberos v4 TGT accepted (%s%s%s@%s)", - creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm); - memset(&creds, 0, sizeof(creds)); - - restore_uid(); - - return (1); - - failure: - krb4_cleanup_proc(authctxt); - memset(&creds, 0, sizeof(creds)); - restore_uid(); - - return (0); -} - -int -auth_afs_token(Authctxt *authctxt, const char *token_string) -{ - CREDENTIALS creds; - struct passwd *pw; - uid_t uid; - - if ((pw = authctxt->pw) == NULL) - return (0); - - if (!radix_to_creds(token_string, &creds)) { - logit("Protocol error decoding AFS token"); - return (0); - } - if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ - strlcpy(creds.service, "afs", sizeof creds.service); - - if (strncmp(creds.pname, "AFS ID ", 7) == 0) - uid = atoi(creds.pname + 7); - else - uid = pw->pw_uid; - - if (kafs_settoken(creds.realm, uid, &creds)) { - logit("AFS token (%s@%s) rejected for %s", - creds.pname, creds.realm, pw->pw_name); - memset(&creds, 0, sizeof(creds)); - return (0); - } - debug("AFS token accepted (%s@%s)", creds.pname, creds.realm); - memset(&creds, 0, sizeof(creds)); - - return (1); -} -#endif /* AFS */ diff --git a/auth-passwd.c b/auth-passwd.c index c0b7f725f..780e92344 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); +RCSID("$OpenBSD: auth-passwd.c,v 1.28 2003/07/22 13:35:22 markus Exp $"); #include "packet.h" #include "log.h" @@ -131,14 +131,6 @@ auth_password(Authctxt *authctxt, const char *password) return (authsuccess); } # endif -# ifdef KRB4 - if (options.kerberos_authentication == 1) { - int ret = auth_krb4_password(authctxt, password); - if (ret == 1 || ret == 0) - return ret; - /* Fall back to ordinary passwd authentication. */ - } -# endif # ifdef BSD_AUTH if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh", (char *)password) == 0) diff --git a/auth.h b/auth.h index 776e4195c..1ed92e018 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.42 2003/04/16 14:35:27 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.43 2003/07/22 13:35:22 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -60,9 +60,6 @@ struct Authctxt { #ifdef BSD_AUTH auth_session_t *as; #endif -#ifdef KRB4 - char *krb4_ticket_file; -#endif #ifdef KRB5 krb5_context krb5_ctx; krb5_auth_context krb5_auth_ctx; @@ -117,20 +114,6 @@ int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); int user_key_allowed(struct passwd *, Key *); -#ifdef KRB4 -#include -int auth_krb4(Authctxt *, KTEXT, char **, KTEXT); -int auth_krb4_password(Authctxt *, const char *); -void krb4_cleanup_proc(void *); - -#ifdef AFS -#include -int auth_krb4_tgt(Authctxt *, const char *); -int auth_afs_token(Authctxt *, const char *); -#endif /* AFS */ - -#endif /* KRB4 */ - #ifdef KRB5 int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); diff --git a/auth1.c b/auth1.c index 6cb0b04b2..877e2e62d 100644 --- a/auth1.c +++ b/auth1.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.48 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.49 2003/07/22 13:35:22 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -49,7 +49,7 @@ get_authname(int type) case SSH_CMSG_AUTH_TIS: case SSH_CMSG_AUTH_TIS_RESPONSE: return "challenge-response"; -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 case SSH_CMSG_AUTH_KERBEROS: return "kerberos"; #endif @@ -81,7 +81,7 @@ do_authloop(Authctxt *authctxt) /* If the user has no password, accept authentication immediately. */ if (options.password_authentication && -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 (!options.kerberos_authentication || options.kerberos_or_local_passwd) && #endif PRIVSEP(auth_password(authctxt, ""))) { @@ -120,7 +120,7 @@ do_authloop(Authctxt *authctxt) /* Process the packet. */ switch (type) { -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 case SSH_CMSG_AUTH_KERBEROS: if (!options.kerberos_authentication) { verbose("Kerberos authentication disabled."); @@ -128,30 +128,7 @@ do_authloop(Authctxt *authctxt) char *kdata = packet_get_string(&dlen); packet_check_eom(); - if (kdata[0] == 4) { /* KRB_PROT_VERSION */ -#ifdef KRB4 - KTEXT_ST tkt, reply; - tkt.length = dlen; - if (tkt.length < MAX_KTXT_LEN) - memcpy(tkt.dat, kdata, tkt.length); - - if (PRIVSEP(auth_krb4(authctxt, &tkt, - &client_user, &reply))) { - authenticated = 1; - snprintf(info, sizeof(info), - " tktuser %.100s", - client_user); - - packet_start( - SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) - reply.dat, reply.length); - packet_send(); - packet_write_wait(); - } -#endif /* KRB4 */ - } else { -#ifdef KRB5 + if (kdata[0] != 4) { /* KRB_PROT_VERSION */ krb5_data tkt, reply; tkt.length = dlen; tkt.data = kdata; @@ -174,24 +151,14 @@ do_authloop(Authctxt *authctxt) if (reply.length) xfree(reply.data); } -#endif /* KRB5 */ } xfree(kdata); } break; -#endif /* KRB4 || KRB5 */ - -#if defined(AFS) || defined(KRB5) - /* XXX - punt on backward compatibility here. */ case SSH_CMSG_HAVE_KERBEROS_TGT: packet_send_debug("Kerberos TGT passing disabled before authentication."); break; -#ifdef AFS - case SSH_CMSG_HAVE_AFS_TOKEN: - packet_send_debug("AFS token passing disabled before authentication."); - break; -#endif /* AFS */ -#endif /* AFS || KRB5 */ +#endif case SSH_CMSG_AUTH_RHOSTS: if (!options.rhosts_authentication) { diff --git a/configure.ac b/configure.ac index 74909343d..68fa5c1f2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.137 2003/07/23 04:33:10 dtucker Exp $ +# $Id: configure.ac,v 1.138 2003/08/02 12:24:49 dtucker Exp $ AC_INIT AC_CONFIG_SRCDIR([ssh.c]) @@ -54,7 +54,6 @@ fi # Check for some target-specific stuff case "$host" in *-*-aix*) - AFS_LIBS="-lld" CPPFLAGS="$CPPFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" AC_MSG_CHECKING([how to specify blibpath for linker ($LD)]) @@ -1940,87 +1939,7 @@ AC_ARG_WITH(kerberos5, fi ] ) -# Check whether user wants Kerberos 4 support -KRB4_MSG="no" -AC_ARG_WITH(kerberos4, - [ --with-kerberos4=PATH Enable Kerberos 4 support], - [ - if test "x$withval" != "xno" ; then - if test "x$withval" != "xyes" ; then - CPPFLAGS="$CPPFLAGS -I${withval}/include" - LDFLAGS="$LDFLAGS -L${withval}/lib" - if test ! -z "$need_dash_r" ; then - LDFLAGS="$LDFLAGS -R${withval}/lib" - fi - if test ! -z "$blibpath" ; then - blibpath="$blibpath:${withval}/lib" - fi - else - if test -d /usr/include/kerberosIV ; then - CPPFLAGS="$CPPFLAGS -I/usr/include/kerberosIV" - fi - fi - - AC_CHECK_HEADERS(krb.h) - if test "$ac_cv_header_krb_h" != yes; then - AC_MSG_WARN([Cannot find krb.h, build may fail]) - fi - AC_CHECK_LIB(krb, main) - if test "$ac_cv_lib_krb_main" != yes; then - AC_CHECK_LIB(krb4, main) - if test "$ac_cv_lib_krb4_main" != yes; then - AC_MSG_WARN([Cannot find libkrb nor libkrb4, build may fail]) - else - KLIBS="-lkrb4" - fi - else - KLIBS="-lkrb" - fi - AC_CHECK_LIB(des, des_cbc_encrypt) - if test "$ac_cv_lib_des_des_cbc_encrypt" != yes; then - AC_CHECK_LIB(des425, des_cbc_encrypt) - if test "$ac_cv_lib_des425_des_cbc_encrypt" != yes; then - AC_MSG_WARN([Cannot find libdes nor libdes425, build may fail]) - else - KLIBS="-ldes425" - fi - else - KLIBS="-ldes" - fi - AC_CHECK_LIB(resolv, dn_expand, , ) - KRB4=yes - KRB4_MSG="yes" - AC_DEFINE(KRB4) - fi - ] -) - -# Check whether user wants AFS support -AFS_MSG="no" -AC_ARG_WITH(afs, - [ --with-afs=PATH Enable AFS support], - [ - if test "x$withval" != "xno" ; then - - if test "x$withval" != "xyes" ; then - CPPFLAGS="$CPPFLAGS -I${withval}/include" - LDFLAGS="$LDFLAGS -L${withval}/lib" - fi - - if test -z "$KRB4" ; then - AC_MSG_WARN([AFS requires Kerberos IV support, build may fail]) - fi - - LIBS="-lkafs $LIBS" - if test ! -z "$AFS_LIBS" ; then - LIBS="$LIBS $AFS_LIBS" - fi - AC_DEFINE(AFS) - AFS_MSG="yes" - fi - ] -) -LIBS="$LIBS $KLIBS $K5LIBS" +LIBS="$LIBS $K5LIBS" # Looking for programs, paths and files @@ -2648,10 +2567,8 @@ fi echo " Manpage format: $MANTYPE" echo " DNS support: $DNS_MSG" echo " PAM support: $PAM_MSG" -echo " KerberosIV support: $KRB4_MSG" echo " KerberosV support: $KRB5_MSG" echo " Smartcard support: $SCARD_MSG" -echo " AFS support: $AFS_MSG" echo " S/KEY support: $SKEY_MSG" echo " TCP Wrappers support: $TCPW_MSG" echo " MD5 password support: $MD5_MSG" diff --git a/monitor.c b/monitor.c index 3a8735f58..95fd0cf64 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.44 2003/06/24 08:23:46 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.45 2003/07/22 13:35:22 markus Exp $"); #include @@ -124,9 +124,6 @@ int mm_answer_pam_respond(int, Buffer *); int mm_answer_pam_free_ctx(int, Buffer *); #endif -#ifdef KRB4 -int mm_answer_krb4(int, Buffer *); -#endif #ifdef KRB5 int mm_answer_krb5(int, Buffer *); #endif @@ -222,9 +219,6 @@ struct mon_table mon_dispatch_proto15[] = { {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif -#ifdef KRB4 - {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4}, -#endif #ifdef KRB5 {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, #endif @@ -1428,52 +1422,6 @@ mm_answer_rsa_response(int socket, Buffer *m) return (success); } -#ifdef KRB4 -int -mm_answer_krb4(int socket, Buffer *m) -{ - KTEXT_ST auth, reply; - char *client, *p; - int success; - u_int alen; - - reply.length = auth.length = 0; - - p = buffer_get_string(m, &alen); - if (alen >= MAX_KTXT_LEN) - fatal("%s: auth too large", __func__); - memcpy(auth.dat, p, alen); - auth.length = alen; - memset(p, 0, alen); - xfree(p); - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb4(authctxt, &auth, &client, &reply); - - memset(auth.dat, 0, alen); - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client); - buffer_put_string(m, reply.dat, reply.length); - if (client) - xfree(client); - if (reply.length) - memset(reply.dat, 0, reply.length); - } - - debug3("%s: sending result %d", __func__, success); - mm_request_send(socket, MONITOR_ANS_KRB4, m); - - auth_method = "kerberos"; - - /* Causes monitor loop to terminate if authenticated */ - return (success); -} -#endif - #ifdef KRB5 int mm_answer_krb5(int socket, Buffer *m) diff --git a/monitor.h b/monitor.h index 97044cb87..7d86b4595 100644 --- a/monitor.h +++ b/monitor.h @@ -49,7 +49,6 @@ enum monitor_reqtype { MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED, MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE, MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, - MONITOR_REQ_KRB4, MONITOR_ANS_KRB4, MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, MONITOR_REQ_PAM_START, MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, diff --git a/monitor_wrap.c b/monitor_wrap.c index 10a79c035..c7ba86ffc 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.27 2003/06/28 16:23:06 deraadt Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.28 2003/07/22 13:35:22 markus Exp $"); #include #include @@ -1043,42 +1043,6 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) return (success); } -#ifdef KRB4 -int -mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply) -{ - KTEXT auth, reply; - Buffer m; - u_int rlen; - int success = 0; - char *p; - - debug3("%s entering", __func__); - auth = _auth; - reply = _reply; - - buffer_init(&m); - buffer_put_string(&m, auth->dat, auth->length); - - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m); - mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m); - - success = buffer_get_int(&m); - if (success) { - *client = buffer_get_string(&m, NULL); - p = buffer_get_string(&m, &rlen); - if (rlen >= MAX_KTXT_LEN) - fatal("%s: reply from monitor too large", __func__); - reply->length = rlen; - memcpy(reply->dat, p, rlen); - memset(p, 0, rlen); - xfree(p); - } - buffer_free(&m); - return (success); -} -#endif - #ifdef KRB5 int mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) diff --git a/monitor_wrap.h b/monitor_wrap.h index d551c9d41..e0dd73bd0 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.9 2003/07/22 13:35:22 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -88,9 +88,6 @@ int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); /* auth_krb */ -#ifdef KRB4 -int mm_auth_krb4(struct Authctxt *, void *, char **, void *); -#endif #ifdef KRB5 /* auth and reply are really krb5_data objects, but we don't want to * include all of the krb5 headers here */ diff --git a/radix.c b/radix.c deleted file mode 100644 index c680d6bf3..000000000 --- a/radix.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 1999 Dug Song. All rights reserved. - * Copyright (c) 2002 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -#include "uuencode.h" - -RCSID("$OpenBSD: radix.c,v 1.22 2002/09/09 14:54:15 markus Exp $"); - -#ifdef AFS -#include - -#include -#include "bufaux.h" - -int -creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen) -{ - Buffer b; - int ret; - - buffer_init(&b); - - buffer_put_char(&b, 1); /* version */ - - buffer_append(&b, creds->service, strlen(creds->service)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->instance, strlen(creds->instance)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->realm, strlen(creds->realm)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->pname, strlen(creds->pname)); - buffer_put_char(&b, '\0'); - buffer_append(&b, creds->pinst, strlen(creds->pinst)); - buffer_put_char(&b, '\0'); - - /* Null string to repeat the realm. */ - buffer_put_char(&b, '\0'); - - buffer_put_int(&b, creds->issue_date); - buffer_put_int(&b, krb_life_to_time(creds->issue_date, - creds->lifetime)); - buffer_append(&b, creds->session, sizeof(creds->session)); - buffer_put_short(&b, creds->kvno); - - /* 32 bit size + data */ - buffer_put_string(&b, creds->ticket_st.dat, creds->ticket_st.length); - - ret = uuencode(buffer_ptr(&b), buffer_len(&b), (char *)buf, buflen); - - buffer_free(&b); - return ret; -} - -#define GETSTRING(b, t, tlen) \ - do { \ - int i, found = 0; \ - for (i = 0; i < tlen; i++) { \ - if (buffer_len(b) == 0) \ - goto done; \ - t[i] = buffer_get_char(b); \ - if (t[i] == '\0') { \ - found = 1; \ - break; \ - } \ - } \ - if (!found) \ - goto done; \ - } while(0) - -int -radix_to_creds(const char *buf, CREDENTIALS *creds) -{ - Buffer b; - u_char *space; - char c, version, *p; - u_int endTime, len; - int blen, ret; - - ret = 0; - blen = strlen(buf); - - /* sanity check for size */ - if (blen > 8192) - return 0; - - buffer_init(&b); - space = buffer_append_space(&b, blen); - - /* check version and length! */ - len = uudecode(buf, space, blen); - if (len < 1) - goto done; - - version = buffer_get_char(&b); - - GETSTRING(&b, creds->service, sizeof creds->service); - GETSTRING(&b, creds->instance, sizeof creds->instance); - GETSTRING(&b, creds->realm, sizeof creds->realm); - GETSTRING(&b, creds->pname, sizeof creds->pname); - GETSTRING(&b, creds->pinst, sizeof creds->pinst); - - if (buffer_len(&b) == 0) - goto done; - - /* Ignore possibly different realm. */ - while (buffer_len(&b) > 0 && (c = buffer_get_char(&b)) != '\0') - ; - - if (buffer_len(&b) == 0) - goto done; - - creds->issue_date = buffer_get_int(&b); - - endTime = buffer_get_int(&b); - creds->lifetime = krb_time_to_life(creds->issue_date, endTime); - - len = buffer_len(&b); - if (len < sizeof(creds->session)) - goto done; - memcpy(&creds->session, buffer_ptr(&b), sizeof(creds->session)); - buffer_consume(&b, sizeof(creds->session)); - - creds->kvno = buffer_get_short(&b); - - p = buffer_get_string(&b, &len); - if (len < 0 || len > sizeof(creds->ticket_st.dat)) - goto done; - memcpy(&creds->ticket_st.dat, p, len); - creds->ticket_st.length = len; - - ret = 1; -done: - buffer_free(&b); - return ret; -} -#endif /* AFS */ diff --git a/radix.h b/radix.h deleted file mode 100644 index e94e4acc6..000000000 --- a/radix.h +++ /dev/null @@ -1,28 +0,0 @@ -/* $OpenBSD: radix.h,v 1.4 2001/06/26 17:27:24 markus Exp $ */ - -/* - * Copyright (c) 1999 Dug Song. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -int creds_to_radix(CREDENTIALS *, u_char *, size_t); -int radix_to_creds(const char *, CREDENTIALS *); diff --git a/readconf.c b/readconf.c index 3c08f7638..332500e7c 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.114 2003/07/03 08:09:05 djm Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.115 2003/07/22 13:35:22 markus Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -94,7 +94,7 @@ typedef enum { oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, oPasswordAuthentication, oRSAAuthentication, oChallengeResponseAuthentication, oXAuthLocation, - oKerberosAuthentication, oKerberosTgtPassing, oAFSTokenPassing, + oKerberosAuthentication, oKerberosTgtPassing, oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, @@ -134,18 +134,14 @@ static struct { { "challengeresponseauthentication", oChallengeResponseAuthentication }, { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 { "kerberosauthentication", oKerberosAuthentication }, { "kerberostgtpassing", oKerberosTgtPassing }, #else { "kerberosauthentication", oUnsupported }, { "kerberostgtpassing", oUnsupported }, #endif -#if defined(AFS) - { "afstokenpassing", oAFSTokenPassing }, -#else { "afstokenpassing", oUnsupported }, -#endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, { "identityfile", oIdentityFile }, @@ -399,10 +395,6 @@ parse_flag: intptr = &options->kerberos_tgt_passing; goto parse_flag; - case oAFSTokenPassing: - intptr = &options->afs_token_passing; - goto parse_flag; - case oBatchMode: intptr = &options->batch_mode; goto parse_flag; @@ -828,7 +820,6 @@ initialize_options(Options * options) options->challenge_response_authentication = -1; options->kerberos_authentication = -1; options->kerberos_tgt_passing = -1; - options->afs_token_passing = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; @@ -905,8 +896,6 @@ fill_default_options(Options * options) options->kerberos_authentication = 1; if (options->kerberos_tgt_passing == -1) options->kerberos_tgt_passing = 1; - if (options->afs_token_passing == -1) - options->afs_token_passing = 1; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) diff --git a/readconf.h b/readconf.h index 4e0b74318..cc94253e6 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.51 2003/07/03 08:09:06 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.52 2003/07/22 13:35:22 markus Exp $ */ /* * Author: Tatu Ylonen @@ -43,7 +43,6 @@ typedef struct { /* Try S/Key or TIS, authentication. */ int kerberos_authentication; /* Try Kerberos authentication. */ int kerberos_tgt_passing; /* Try Kerberos TGT passing. */ - int afs_token_passing; /* Try AFS token passing. */ int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c index 6df2a255b..c4b2bb284 100644 --- a/servconf.c +++ b/servconf.c @@ -10,15 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.122 2003/06/02 09:17:34 markus Exp $"); - -#if defined(KRB4) -#include -#endif - -#ifdef AFS -#include -#endif +RCSID("$OpenBSD: servconf.c,v 1.123 2003/07/22 13:35:22 markus Exp $"); #include "ssh.h" #include "log.h" @@ -82,7 +74,6 @@ initialize_server_options(ServerOptions *options) options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_tgt_passing = -1; - options->afs_token_passing = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; @@ -194,8 +185,6 @@ fill_default_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = 1; if (options->kerberos_tgt_passing == -1) options->kerberos_tgt_passing = 0; - if (options->afs_token_passing == -1) - options->afs_token_passing = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -261,7 +250,7 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosTgtPassing, sAFSTokenPassing, sChallengeResponseAuthentication, + sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, @@ -306,7 +295,7 @@ static struct { { "rsaauthentication", sRSAAuthentication }, { "pubkeyauthentication", sPubkeyAuthentication }, { "dsaauthentication", sPubkeyAuthentication }, /* alias */ -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 { "kerberosauthentication", sKerberosAuthentication }, { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, { "kerberosticketcleanup", sKerberosTicketCleanup }, @@ -317,11 +306,7 @@ static struct { { "kerberosticketcleanup", sUnsupported }, { "kerberostgtpassing", sUnsupported }, #endif -#if defined(AFS) - { "afstokenpassing", sAFSTokenPassing }, -#else { "afstokenpassing", sUnsupported }, -#endif { "passwordauthentication", sPasswordAuthentication }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, { "challengeresponseauthentication", sChallengeResponseAuthentication }, @@ -644,10 +629,6 @@ parse_flag: intptr = &options->kerberos_tgt_passing; goto parse_flag; - case sAFSTokenPassing: - intptr = &options->afs_token_passing; - goto parse_flag; - case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; diff --git a/servconf.h b/servconf.h index b676f2b67..65ad2071a 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.61 2003/06/02 09:17:34 markus Exp $ */ +/* $OpenBSD: servconf.h,v 1.62 2003/07/22 13:35:22 markus Exp $ */ /* * Author: Tatu Ylonen @@ -84,7 +84,6 @@ typedef struct { * file on logout. */ int kerberos_tgt_passing; /* If true, permit Kerberos TGT * passing. */ - int afs_token_passing; /* If true, permit AFS token passing. */ int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c index 4b443831b..7a064ad50 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.158 2003/06/02 09:17:34 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.159 2003/07/22 13:35:22 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -222,10 +222,6 @@ do_authenticated(Authctxt *authctxt) /* remove agent socket */ if (auth_sock_name != NULL) auth_sock_cleanup_proc(authctxt->pw); -#ifdef KRB4 - if (options.kerberos_ticket_cleanup) - krb4_cleanup_proc(authctxt); -#endif #ifdef KRB5 if (options.kerberos_ticket_cleanup) krb5_cleanup_proc(authctxt); @@ -338,7 +334,7 @@ do_authenticated1(Authctxt *authctxt) success = 1; break; -#if defined(AFS) || defined(KRB5) +#ifdef KRB5 case SSH_CMSG_HAVE_KERBEROS_TGT: if (!options.kerberos_tgt_passing) { verbose("Kerberos TGT passing disabled."); @@ -346,9 +342,8 @@ do_authenticated1(Authctxt *authctxt) char *kdata = packet_get_string(&dlen); packet_check_eom(); - /* XXX - 0x41, see creds_to_radix version */ + /* XXX - 0x41, used for AFS */ if (kdata[0] != 0x41) { -#ifdef KRB5 krb5_data tgt; tgt.data = kdata; tgt.length = dlen; @@ -357,38 +352,11 @@ do_authenticated1(Authctxt *authctxt) success = 1; else verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user); -#endif /* KRB5 */ - } else { -#ifdef AFS - if (auth_krb4_tgt(s->authctxt, kdata)) - success = 1; - else - verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user); -#endif /* AFS */ } xfree(kdata); } break; -#endif /* AFS || KRB5 */ - -#ifdef AFS - case SSH_CMSG_HAVE_AFS_TOKEN: - if (!options.afs_token_passing || !k_hasafs()) { - verbose("AFS token passing disabled."); - } else { - /* Accept AFS token. */ - char *token = packet_get_string(&dlen); - packet_check_eom(); - - if (auth_afs_token(s->authctxt, token)) - success = 1; - else - verbose("AFS token refused for %.100s", - s->authctxt->user); - xfree(token); - } - break; -#endif /* AFS */ +#endif case SSH_CMSG_EXEC_SHELL: case SSH_CMSG_EXEC_CMD: @@ -1066,11 +1034,6 @@ do_setup_env(Session *s, const char *shell) read_environment_file(&env, &envsize, "/etc/environment"); } #endif -#ifdef KRB4 - if (s->authctxt->krb4_ticket_file) - child_set_env(&env, &envsize, "KRBTKFILE", - s->authctxt->krb4_ticket_file); -#endif #ifdef KRB5 if (s->authctxt->krb5_ticket_file) child_set_env(&env, &envsize, "KRB5CCNAME", @@ -1396,18 +1359,6 @@ do_child(Session *s, const char *command) */ environ = env; -#ifdef AFS - /* Try to get AFS tokens for the local cell. */ - if (k_hasafs()) { - char cell[64]; - - if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) - krb_afslog(cell, 0); - - krb_afslog(0, 0); - } -#endif /* AFS */ - /* Change current directory to the user\'s home directory. */ if (chdir(pw->pw_dir) < 0) { fprintf(stderr, "Could not chdir to home directory %s: %s\n", diff --git a/ssh.1 b/ssh.1 index 8a7d2f428..c81cb42c6 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.174 2003/07/02 14:51:16 markus Exp $ +.\" $OpenBSD: ssh.1,v 1.175 2003/07/22 13:35:22 markus Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -494,7 +494,7 @@ The argument is the device should use to communicate with a smartcard used for storing the user's private RSA key. .It Fl k -Disables forwarding of Kerberos tickets and AFS tokens. +Disables forwarding of Kerberos tickets. This may also be specified on a per-host basis in the configuration file. .It Fl l Ar login_name Specifies the user to log in as on the remote machine. diff --git a/ssh.c b/ssh.c index 2bcd5871e..82b40193d 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.197 2003/07/16 10:34:53 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.198 2003/07/22 13:35:22 markus Exp $"); #include #include @@ -154,9 +154,7 @@ usage(void) _PATH_SSH_USER_CONFFILE); fprintf(stderr, " -A Enable authentication agent forwarding.\n"); fprintf(stderr, " -a Disable authentication agent forwarding (default).\n"); -#ifdef AFS - fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); -#endif /* AFS */ + fprintf(stderr, " -k Disable Kerberos ticket forwarding.\n"); fprintf(stderr, " -X Enable X11 connection forwarding.\n"); fprintf(stderr, " -x Disable X11 connection forwarding (default).\n"); fprintf(stderr, " -i file Identity for public key authentication " @@ -306,12 +304,9 @@ again: case 'A': options.forward_agent = 1; break; -#ifdef AFS case 'k': options.kerberos_tgt_passing = 0; - options.afs_token_passing = 0; break; -#endif case 'i': if (stat(optarg, &st) < 0) { fprintf(stderr, "Warning: Identity file %s " diff --git a/ssh.h b/ssh.h index 25a9213f3..607621769 100644 --- a/ssh.h +++ b/ssh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.h,v 1.72 2003/06/28 16:23:06 deraadt Exp $ */ +/* $OpenBSD: ssh.h,v 1.73 2003/07/22 13:35:22 markus Exp $ */ /* * Author: Tatu Ylonen @@ -88,9 +88,6 @@ */ #define SSH_SESSION_KEY_LENGTH 32 -/* Name of Kerberos service for SSH to use. */ -#define KRB4_SERVICE_NAME "rcmd" - /* Used to identify ``EscapeChar none'' */ #define SSH_ESCAPECHAR_NONE -2 diff --git a/ssh_config.5 b/ssh_config.5 index 79d05f018..3a79af8f0 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.15 2003/07/02 14:51:16 markus Exp $ +.\" $OpenBSD: ssh_config.5,v 1.16 2003/07/22 13:35:22 markus Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -123,13 +123,6 @@ Valid arguments are (Use IPv4 only) or .Dq inet6 (Use IPv6 only.) -.It Cm AFSTokenPassing -Specifies whether to pass AFS tokens to remote host. -The argument to this keyword must be -.Dq yes -or -.Dq no . -This option applies to protocol version 1 only. .It Cm BatchMode If set to .Dq yes , @@ -410,7 +403,6 @@ or .Dq no . .It Cm KerberosTgtPassing Specifies whether a Kerberos TGT will be forwarded to the server. -This will only work if the Kerberos server is actually an AFS kaserver. The argument to this keyword must be .Dq yes or diff --git a/sshconnect1.c b/sshconnect1.c index 2a822a98f..8851c35f6 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -13,24 +13,17 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.53 2003/04/08 20:21:29 itojun Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.54 2003/07/22 13:35:22 markus Exp $"); #include #include -#ifdef KRB4 -#include -#endif #ifdef KRB5 #include #ifndef HEIMDAL #define krb5_get_err_text(context,code) error_message(code) #endif /* !HEIMDAL */ #endif -#ifdef AFS -#include -#include "radix.h" -#endif #include "ssh.h" #include "ssh1.h" @@ -380,128 +373,6 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key) return 0; } -#ifdef KRB4 -static int -try_krb4_authentication(void) -{ - KTEXT_ST auth; /* Kerberos data */ - char *reply; - char inst[INST_SZ]; - char *realm; - CREDENTIALS cred; - int r, type; - socklen_t slen; - Key_schedule schedule; - u_long checksum, cksum; - MSG_DAT msg_data; - struct sockaddr_in local, foreign; - struct stat st; - - /* Don't do anything if we don't have any tickets. */ - if (stat(tkt_string(), &st) < 0) - return 0; - - strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)), - INST_SZ); - - realm = (char *)krb_realmofhost(get_canonical_hostname(1)); - if (!realm) { - debug("Kerberos v4: no realm for %s", get_canonical_hostname(1)); - return 0; - } - /* This can really be anything. */ - checksum = (u_long)getpid(); - - r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); - if (r != KSUCCESS) { - debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]); - return 0; - } - /* Get session key to decrypt the server's reply with. */ - r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); - if (r != KSUCCESS) { - debug("get_cred failed: %s", krb_err_txt[r]); - return 0; - } - des_key_sched((des_cblock *) cred.session, schedule); - - /* Send authentication info to server. */ - packet_start(SSH_CMSG_AUTH_KERBEROS); - packet_put_string((char *) auth.dat, auth.length); - packet_send(); - packet_write_wait(); - - /* Zero the buffer. */ - (void) memset(auth.dat, 0, MAX_KTXT_LEN); - - slen = sizeof(local); - memset(&local, 0, sizeof(local)); - if (getsockname(packet_get_connection_in(), - (struct sockaddr *)&local, &slen) < 0) - debug("getsockname failed: %s", strerror(errno)); - - slen = sizeof(foreign); - memset(&foreign, 0, sizeof(foreign)); - if (getpeername(packet_get_connection_in(), - (struct sockaddr *)&foreign, &slen) < 0) { - debug("getpeername failed: %s", strerror(errno)); - fatal_cleanup(); - } - /* Get server reply. */ - type = packet_read(); - switch (type) { - case SSH_SMSG_FAILURE: - /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ - debug("Kerberos v4 authentication failed."); - return 0; - break; - - case SSH_SMSG_AUTH_KERBEROS_RESPONSE: - /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ - debug("Kerberos v4 authentication accepted."); - - /* Get server's response. */ - reply = packet_get_string((u_int *) &auth.length); - if (auth.length >= MAX_KTXT_LEN) - fatal("Kerberos v4: Malformed response from server"); - memcpy(auth.dat, reply, auth.length); - xfree(reply); - - packet_check_eom(); - - /* - * If his response isn't properly encrypted with the session - * key, and the decrypted checksum fails to match, he's - * bogus. Bail out. - */ - r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, - &foreign, &local, &msg_data); - if (r != KSUCCESS) { - debug("Kerberos v4 krb_rd_priv failed: %s", - krb_err_txt[r]); - packet_disconnect("Kerberos v4 challenge failed!"); - } - /* Fetch the (incremented) checksum that we supplied in the request. */ - memcpy((char *)&cksum, (char *)msg_data.app_data, - sizeof(cksum)); - cksum = ntohl(cksum); - - /* If it matches, we're golden. */ - if (cksum == checksum + 1) { - debug("Kerberos v4 challenge successful."); - return 1; - } else - packet_disconnect("Kerberos v4 challenge failed!"); - break; - - default: - packet_disconnect("Protocol error on Kerberos v4 response: %d", type); - } - return 0; -} - -#endif /* KRB4 */ - #ifdef KRB5 static int try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) @@ -729,129 +600,6 @@ send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) } #endif /* KRB5 */ -#ifdef AFS -static void -send_krb4_tgt(void) -{ - CREDENTIALS *creds; - struct stat st; - char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; - int problem, type; - - /* Don't do anything if we don't have any tickets. */ - if (stat(tkt_string(), &st) < 0) - return; - - creds = xmalloc(sizeof(*creds)); - - problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm); - if (problem) - goto out; - - problem = krb_get_cred("krbtgt", prealm, prealm, creds); - if (problem) - goto out; - - if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { - problem = RD_AP_EXP; - goto out; - } - creds_to_radix(creds, (u_char *)buffer, sizeof(buffer)); - - packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); - packet_put_cstring(buffer); - packet_send(); - packet_write_wait(); - - type = packet_read(); - - if (type == SSH_SMSG_SUCCESS) - debug("Kerberos v4 TGT forwarded (%s%s%s@%s).", - creds->pname, creds->pinst[0] ? "." : "", - creds->pinst, creds->realm); - else - debug("Kerberos v4 TGT rejected."); - - xfree(creds); - return; - - out: - debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]); - xfree(creds); -} - -static void -send_afs_tokens(void) -{ - CREDENTIALS creds; - struct ViceIoctl parms; - struct ClearToken ct; - int i, type, len; - char buf[2048], *p, *server_cell; - char buffer[8192]; - - /* Move over ktc_GetToken, here's something leaner. */ - for (i = 0; i < 100; i++) { /* just in case */ - parms.in = (char *) &i; - parms.in_size = sizeof(i); - parms.out = buf; - parms.out_size = sizeof(buf); - if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) - break; - p = buf; - - /* Get secret token. */ - memcpy(&creds.ticket_st.length, p, sizeof(u_int)); - if (creds.ticket_st.length > MAX_KTXT_LEN) - break; - p += sizeof(u_int); - memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); - p += creds.ticket_st.length; - - /* Get clear token. */ - memcpy(&len, p, sizeof(len)); - if (len != sizeof(struct ClearToken)) - break; - p += sizeof(len); - memcpy(&ct, p, len); - p += len; - p += sizeof(len); /* primary flag */ - server_cell = p; - - /* Flesh out our credentials. */ - strlcpy(creds.service, "afs", sizeof(creds.service)); - creds.instance[0] = '\0'; - strlcpy(creds.realm, server_cell, REALM_SZ); - memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); - creds.issue_date = ct.BeginTimestamp; - creds.lifetime = krb_time_to_life(creds.issue_date, - ct.EndTimestamp); - creds.kvno = ct.AuthHandle; - snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); - creds.pinst[0] = '\0'; - - /* Encode token, ship it off. */ - if (creds_to_radix(&creds, (u_char *)buffer, - sizeof(buffer)) <= 0) - break; - packet_start(SSH_CMSG_HAVE_AFS_TOKEN); - packet_put_cstring(buffer); - packet_send(); - packet_write_wait(); - - /* Roger, Roger. Clearance, Clarence. What's your vector, - Victor? */ - type = packet_read(); - - if (type == SSH_SMSG_FAILURE) - debug("AFS token for cell %s rejected.", server_cell); - else if (type != SSH_SMSG_SUCCESS) - packet_disconnect("Protocol error on AFS token response: %d", type); - } -} - -#endif /* AFS */ - /* * Tries to authenticate with any string-based challenge/response system. * Note that the client code is not tied to s/key or TIS. @@ -1183,21 +931,6 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, } #endif /* KRB5 */ -#ifdef KRB4 - if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && - options.kerberos_authentication) { - debug("Trying Kerberos v4 authentication."); - - if (try_krb4_authentication()) { - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type); - } - } -#endif /* KRB4 */ - /* * Use rhosts authentication if running in privileged socket and we * do not wish to remain anonymous. @@ -1284,23 +1017,5 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, if (context) krb5_free_context(context); #endif - -#ifdef AFS - /* Try Kerberos v4 TGT passing if the server supports it. */ - if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && - options.kerberos_tgt_passing) { - if (options.cipher == SSH_CIPHER_NONE) - logit("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - send_krb4_tgt(); - } - /* Try AFS token passing if the server supports it. */ - if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && - options.afs_token_passing && k_hasafs()) { - if (options.cipher == SSH_CIPHER_NONE) - logit("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); - send_afs_tokens(); - } -#endif /* AFS */ - return; /* need statement after label */ } diff --git a/sshd.c b/sshd.c index a8cb966b0..896e56c76 100644 --- a/sshd.c +++ b/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.273 2003/07/16 10:34:53 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.274 2003/07/22 13:35:22 markus Exp $"); #include #include @@ -1476,20 +1476,13 @@ main(int ac, char **av) "originating port %d not trusted.", remote_port); options.rhosts_authentication = 0; } -#if defined(KRB4) && !defined(KRB5) +#ifdef KRB5 if (!packet_connection_is_ipv4() && options.kerberos_authentication) { debug("Kerberos Authentication disabled, only available for IPv4."); options.kerberos_authentication = 0; } -#endif /* KRB4 && !KRB5 */ -#ifdef AFS - /* If machine has AFS, set process authentication group. */ - if (k_hasafs()) { - k_setpag(); - k_unlog(); - } -#endif /* AFS */ +#endif packet_set_nonblocking(); @@ -1656,17 +1649,11 @@ do_ssh1_kex(void) auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; if (options.rsa_authentication) auth_mask |= 1 << SSH_AUTH_RSA; -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 if (options.kerberos_authentication) auth_mask |= 1 << SSH_AUTH_KERBEROS; -#endif -#if defined(AFS) || defined(KRB5) if (options.kerberos_tgt_passing) auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; -#endif -#ifdef AFS - if (options.afs_token_passing) - auth_mask |= 1 << SSH_PASS_AFS_TOKEN; #endif if (options.challenge_response_authentication == 1) auth_mask |= 1 << SSH_AUTH_TIS; diff --git a/sshd_config.5 b/sshd_config.5 index dfd3565a6..223ff8aae 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.20 2003/06/20 05:47:58 djm Exp $ +.\" $OpenBSD: sshd_config.5,v 1.21 2003/07/22 13:35:22 markus Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -61,10 +61,6 @@ The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): .Bl -tag -width Ds -.It Cm AFSTokenPassing -Specifies whether an AFS token may be forwarded to the server. -Default is -.Dq no . .It Cm AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. @@ -327,8 +323,7 @@ Default is .It Cm KerberosTgtPassing Specifies whether a Kerberos TGT may be forwarded to the server. Default is -.Dq no , -as this only works when the Kerberos KDC is actually an AFS kaserver. +.Dq no . .It Cm KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket cache file on logout. -- cgit v1.2.3 From 1f499fd3688d034daf787859044ede73767b6141 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 25 Aug 2003 13:08:49 +1000 Subject: - (djm) Bug #564: Perform PAM account checks for all authentications when UsePAM=yes; ok dtucker --- ChangeLog | 4 +++- auth-pam.c | 52 +++++++++++++++++++++++++++------------------------- auth-pam.h | 4 ++-- auth1.c | 6 ++++++ auth2.c | 5 +++++ monitor.c | 34 ++++++++++++++++++++++++++++++++++ monitor.h | 1 + monitor_wrap.c | 24 ++++++++++++++++++++++++ monitor_wrap.h | 1 + session.c | 1 + 10 files changed, 104 insertions(+), 28 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index f1162fac1..0bf1e54aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,8 @@ be our 'mysignal' by default. OK djm@ - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny any access to locked accounts. ok djm@ + - (djm) Bug #564: Perform PAM account checks for all authentications when + UsePAM=yes; ok dtucker 20030822 - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal @@ -862,4 +864,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2902 2003/08/25 01:51:19 dtucker Exp $ +$Id: ChangeLog,v 1.2903 2003/08/25 03:08:49 djm Exp $ diff --git a/auth-pam.c b/auth-pam.c index 970ff61cb..c0b6ded12 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -31,7 +31,7 @@ /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ #include "includes.h" -RCSID("$Id: auth-pam.c,v 1.66 2003/08/08 03:43:37 dtucker Exp $"); +RCSID("$Id: auth-pam.c,v 1.67 2003/08/25 03:08:49 djm Exp $"); #ifdef USE_PAM #include @@ -49,6 +49,7 @@ RCSID("$Id: auth-pam.c,v 1.66 2003/08/08 03:43:37 dtucker Exp $"); #include "servconf.h" #include "ssh2.h" #include "xmalloc.h" +#include "auth-options.h" extern ServerOptions options; @@ -130,10 +131,8 @@ static void sshpam_free_ctx(void *); * Conversation function for authentication thread. */ static int -sshpam_thread_conv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) +sshpam_thread_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { Buffer buffer; struct pam_ctxt *ctxt; @@ -216,9 +215,6 @@ sshpam_thread(void *ctxtp) sshpam_err = pam_authenticate(sshpam_handle, 0); if (sshpam_err != PAM_SUCCESS) goto auth_fail; - sshpam_err = pam_acct_mgmt(sshpam_handle, 0); - if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) - goto auth_fail; buffer_put_cstring(&buffer, "OK"); ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); buffer_free(&buffer); @@ -246,12 +242,9 @@ sshpam_thread_cleanup(void *ctxtp) } static int -sshpam_null_conv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) +sshpam_null_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { - return (PAM_CONV_ERR); } @@ -303,7 +296,7 @@ sshpam_init(const char *user) debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); if (sshpam_err != PAM_SUCCESS) { - pam_end(sshpam_handle, sshpam_err); + pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; return (-1); } @@ -403,9 +396,6 @@ sshpam_query(void *ctx, char **name, char **info, plen += snprintf(**prompts + plen, len, "%s", msg); xfree(msg); break; - case PAM_NEW_AUTHTOK_REQD: - sshpam_new_authtok_reqd = 1; - /* FALLTHROUGH */ case PAM_SUCCESS: case PAM_AUTH_ERR: if (**prompts != NULL) { @@ -519,10 +509,24 @@ finish_pam(void) sshpam_cleanup(NULL); } -int -do_pam_account(const char *user, const char *ruser) +u_int +do_pam_account(void) { - /* XXX */ + sshpam_err = pam_acct_mgmt(sshpam_handle, 0); + debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err); + + if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) + return (0); + + if (sshpam_err == PAM_NEW_AUTHTOK_REQD) { + sshpam_new_authtok_reqd = 1; + + /* Prevent forwardings until password changed */ + no_port_forwarding_flag |= 2; + no_agent_forwarding_flag |= 2; + no_x11_forwarding_flag |= 2; + } + return (1); } @@ -582,10 +586,8 @@ is_pam_password_change_required(void) } static int -pam_chauthtok_conv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) +pam_chauthtok_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { char input[PAM_MAX_MSG_SIZE]; int i; @@ -635,7 +637,7 @@ do_pam_chauthtok(void) struct pam_conv pam_conv = { pam_chauthtok_conv, NULL }; if (use_privsep) - fatal("PAM: chauthtok not supprted with privsep"); + fatal("Password expired (unable to change with privsep)"); sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&pam_conv); if (sshpam_err != PAM_SUCCESS) diff --git a/auth-pam.h b/auth-pam.h index fdbd0febd..7f7c16d2e 100644 --- a/auth-pam.h +++ b/auth-pam.h @@ -1,4 +1,4 @@ -/* $Id: auth-pam.h,v 1.18 2003/05/19 01:28:44 djm Exp $ */ +/* $Id: auth-pam.h,v 1.19 2003/08/25 03:08:49 djm Exp $ */ /* * Copyright (c) 2000 Damien Miller. All rights reserved. @@ -33,7 +33,7 @@ void start_pam(const char *); void finish_pam(void); -int do_pam_account(const char *, const char *); +u_int do_pam_account(void); void do_pam_session(const char *, const char *); void do_pam_setcred(int ); int is_pam_password_change_required(void); diff --git a/auth1.c b/auth1.c index 7c0100103..d8b5836ba 100644 --- a/auth1.c +++ b/auth1.c @@ -290,6 +290,12 @@ do_authloop(Authctxt *authctxt) authenticated = 0; #endif +#ifdef USE_PAM + if (options.use_pam && authenticated && + !PRIVSEP(do_pam_account())) + authenticated = 0; +#endif + /* Log before sending the reply */ auth_log(authctxt, authenticated, get_authname(type), info); diff --git a/auth2.c b/auth2.c index 639bf9117..e6ec8ddcd 100644 --- a/auth2.c +++ b/auth2.c @@ -213,6 +213,11 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) !auth_root_allowed(method)) authenticated = 0; +#ifdef USE_PAM + if (options.use_pam && authenticated && !PRIVSEP(do_pam_account())) + authenticated = 0; +#endif + #ifdef _UNICOS if (authenticated && cray_access_denied(authctxt->user)) { authenticated = 0; diff --git a/monitor.c b/monitor.c index 95fd0cf64..80b1a8fba 100644 --- a/monitor.c +++ b/monitor.c @@ -118,6 +118,7 @@ int mm_answer_sessid(int, Buffer *); #ifdef USE_PAM int mm_answer_pam_start(int, Buffer *); +int mm_answer_pam_account(int, Buffer *); int mm_answer_pam_init_ctx(int, Buffer *); int mm_answer_pam_query(int, Buffer *); int mm_answer_pam_respond(int, Buffer *); @@ -165,6 +166,7 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, @@ -214,6 +216,7 @@ struct mon_table mon_dispatch_proto15[] = { #endif #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, @@ -295,6 +298,18 @@ monitor_child_preauth(struct monitor *pmonitor) if (authctxt->pw->pw_uid == 0 && !auth_root_allowed(auth_method)) authenticated = 0; +#ifdef USE_PAM + /* PAM needs to perform account checks after auth */ + if (options.use_pam) { + Buffer m; + + buffer_init(&m); + mm_request_receive_expect(pmonitor->m_sendfd, + MONITOR_REQ_PAM_ACCOUNT, &m); + authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m); + buffer_free(&m); + } +#endif } if (ent->flags & MON_AUTHDECIDE) { @@ -771,9 +786,28 @@ mm_answer_pam_start(int socket, Buffer *m) xfree(user); + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); + return (0); } +int +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__); + + ret = do_pam_account(); + + buffer_put_int(m, ret); + + mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m); + + return (ret); +} + static void *sshpam_ctxt, *sshpam_authok; extern KbdintDevice sshpam_device; diff --git a/monitor.h b/monitor.h index 13b21aa42..eeac78e03 100644 --- a/monitor.h +++ b/monitor.h @@ -51,6 +51,7 @@ enum monitor_reqtype { MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, MONITOR_REQ_PAM_START, + MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, diff --git a/monitor_wrap.c b/monitor_wrap.c index c7ba86ffc..9e7e6b3c3 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -682,6 +682,30 @@ mm_start_pam(char *user) buffer_free(&m); } +u_int +mm_do_pam_account(void) +{ + Buffer m; + u_int ret; + + debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); + + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_PAM_ACCOUNT, &m); + ret = buffer_get_int(&m); + + buffer_free(&m); + + debug3("%s returning %d", __func__, ret); + + return (ret); +} + void * mm_sshpam_init_ctx(Authctxt *authctxt) { diff --git a/monitor_wrap.h b/monitor_wrap.h index e0dd73bd0..ddd42ee28 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -57,6 +57,7 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); #ifdef USE_PAM void mm_start_pam(char *); +u_int mm_do_pam_account(void); void *mm_sshpam_init_ctx(struct Authctxt *); int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_sshpam_respond(void *, u_int, char **); diff --git a/session.c b/session.c index d3ef89a0c..20c4b8a97 100644 --- a/session.c +++ b/session.c @@ -719,6 +719,7 @@ do_login(Session *s, const char *command) if (options.use_pam && is_pam_password_change_required()) { print_pam_messages(); do_pam_chauthtok(); + /* XXX - signal [net] parent to enable forwardings */ } #endif -- cgit v1.2.3 From 0efd155c3c184f0eaa2e1eb244eaaf066e6906e0 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 26 Aug 2003 11:49:55 +1000 Subject: - markus@cvs.openbsd.org 2003/08/22 10:56:09 [auth2.c auth2-gss.c auth.h compat.c compat.h gss-genr.c gss-serv-krb5.c gss-serv.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h servconf.c servconf.h session.c session.h ssh-gss.h ssh_config.5 sshconnect2.c sshd_config sshd_config.5] support GSS API user authentication; patches from Simon Wilkinson, stripped down and tested by Jakob and myself. --- ChangeLog | 10 +- auth.h | 3 +- auth2-gss.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++ auth2.c | 18 +++- compat.c | 8 +- compat.h | 3 +- gss-genr.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++++ gss-serv-krb5.c | 168 ++++++++++++++++++++++++++++++++ gss-serv.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ monitor.c | 92 +++++++++++++++++- monitor.h | 5 +- monitor_wrap.c | 73 +++++++++++++- monitor_wrap.h | 10 +- readconf.c | 26 ++++- readconf.h | 4 +- servconf.c | 24 ++++- servconf.h | 4 +- session.c | 31 +++++- session.h | 5 +- ssh-gss.h | 109 +++++++++++++++++++++ ssh_config.5 | 14 ++- sshconnect2.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++- sshd_config | 6 +- sshd_config.5 | 15 ++- 24 files changed, 1646 insertions(+), 24 deletions(-) create mode 100644 auth2-gss.c create mode 100644 gss-genr.c create mode 100644 gss-serv-krb5.c create mode 100644 gss-serv.c create mode 100644 ssh-gss.h (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index e8727e2f0..142af1b06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,14 @@ - (djm) Bug #629: Mark ssh_config option "pamauthenticationviakbdint" as deprecated. Remove mention from README.privsep. Patch from aet AT cc.hut.fi + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/22 10:56:09 + [auth2.c auth2-gss.c auth.h compat.c compat.h gss-genr.c gss-serv-krb5.c + gss-serv.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h readconf.c + readconf.h servconf.c servconf.h session.c session.h ssh-gss.h + ssh_config.5 sshconnect2.c sshd_config sshd_config.5] + support GSS API user authentication; patches from Simon Wilkinson, + stripped down and tested by Jakob and myself. 20030825 - (djm) Bug #621: Select OpenSC keys by usage attributes. Patch from @@ -874,4 +882,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2906 2003/08/26 00:48:14 djm Exp $ +$Id: ChangeLog,v 1.2907 2003/08/26 01:49:55 dtucker Exp $ diff --git a/auth.h b/auth.h index 1ed92e018..6beff7cc3 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.43 2003/07/22 13:35:22 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.44 2003/08/22 10:56:08 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -67,6 +67,7 @@ struct Authctxt { krb5_principal krb5_user; char *krb5_ticket_file; #endif + void *methoddata; }; /* * Every authentication method has to handle authentication requests for diff --git a/auth2-gss.c b/auth2-gss.c new file mode 100644 index 000000000..c7651112d --- /dev/null +++ b/auth2-gss.c @@ -0,0 +1,243 @@ +/* $OpenBSD: auth2-gss.c,v 1.1 2003/08/22 10:56:08 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI + +#include "auth.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "log.h" +#include "dispatch.h" +#include "servconf.h" +#include "compat.h" +#include "packet.h" +#include "monitor_wrap.h" + +#include "ssh-gss.h" + +extern ServerOptions options; + +static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_errtok(int, u_int32_t, void *); + +/* + * We only support those mechanisms that we know about (ie ones that we know + * how to check local user kuserok and the like + */ +static int +userauth_gssapi(Authctxt *authctxt) +{ + gss_OID_desc oid = {0, NULL}; + Gssctxt *ctxt = NULL; + int mechs; + gss_OID_set supported; + int present; + OM_uint32 ms; + u_int len; + char *doid = NULL; + + if (!authctxt->valid || authctxt->user == NULL) + return (0); + + mechs = packet_get_int(); + if (mechs == 0) { + debug("Mechanism negotiation is not supported"); + return (0); + } + + ssh_gssapi_supported_oids(&supported); + do { + mechs--; + + if (doid) + xfree(doid); + + doid = packet_get_string(&len); + + if (doid[0] != SSH_GSS_OIDTYPE || doid[1] != len-2) { + logit("Mechanism OID received using the old encoding form"); + oid.elements = doid; + oid.length = len; + } else { + oid.elements = doid + 2; + oid.length = len - 2; + } + gss_test_oid_set_member(&ms, &oid, supported, &present); + } while (mechs > 0 && !present); + + gss_release_oid_set(&ms, &supported); + + if (!present) { + xfree(doid); + return (0); + } + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &oid)))) + return (0); + + authctxt->methoddata=(void *)ctxt; + + packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); + + /* Return OID in same format as we received it*/ + packet_put_string(doid, len); + + packet_send(); + xfree(doid); + + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); + authctxt->postponed = 1; + + return (0); +} + +static void +input_gssapi_token(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 maj_status, min_status; + u_int len; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; /* u_int vs. size_t */ + + packet_check_eom(); + + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, NULL)); + + xfree(recv_tok.value); + + if (GSS_ERROR(maj_status)) { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + } + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + userauth_finish(authctxt, 0, "gssapi"); + } else { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + } + if (maj_status == GSS_S_COMPLETE) { + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, + &input_gssapi_exchange_complete); + } + } + + gss_release_buffer(&min_status, &send_tok); +} + +static void +input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 maj_status; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + recv_tok.value = packet_get_string(&recv_tok.length); + + packet_check_eom(); + + /* Push the error token into GSSAPI to see what it says */ + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, NULL)); + + xfree(recv_tok.value); + + /* We can't return anything to the client, even if we wanted to */ + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + + /* The client will have already moved on to the next auth */ + + gss_release_buffer(&maj_status, &send_tok); +} + +/* + * This is called when the client thinks we've completed authentication. + * It should only be enabled in the dispatch handler by the function above, + * which only enables it once the GSSAPI exchange is complete. + */ + +static void +input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + int authenticated; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + + /* + * We don't need to check the status, because the stored credentials + * which userok uses are only populated once the context init step + * has returned complete. + */ + + packet_check_eom(); + + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); + userauth_finish(authctxt, authenticated, "gssapi"); +} + +Authmethod method_gssapi = { + "gssapi", + userauth_gssapi, + &options.gss_authentication +}; + +#endif /* GSSAPI */ diff --git a/auth2.c b/auth2.c index e6ec8ddcd..4a305a416 100644 --- a/auth2.c +++ b/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.99 2003/06/24 08:23:46 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.100 2003/08/22 10:56:08 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -36,6 +36,10 @@ RCSID("$OpenBSD: auth2.c,v 1.99 2003/06/24 08:23:46 markus Exp $"); #include "pathnames.h" #include "monitor_wrap.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* import */ extern ServerOptions options; extern u_char *session_id2; @@ -53,10 +57,16 @@ extern Authmethod method_hostbased; #ifdef KRB5 extern Authmethod method_kerberos; #endif +#ifdef GSSAPI +extern Authmethod method_gssapi; +#endif Authmethod *authmethods[] = { &method_none, &method_pubkey, +#ifdef GSSAPI + &method_gssapi, +#endif &method_passwd, &method_kbdint, &method_hostbased, @@ -184,6 +194,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) } /* reset state */ auth2_challenge_stop(authctxt); + +#ifdef GSSAPI + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); +#endif + authctxt->postponed = 0; /* try to authenticate user */ diff --git a/compat.c b/compat.c index 63a5d91ff..6bd42a6f5 100644 --- a/compat.c +++ b/compat.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: compat.c,v 1.67 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: compat.c,v 1.68 2003/08/22 10:56:09 markus Exp $"); #include "buffer.h" #include "packet.h" @@ -79,7 +79,11 @@ compat_datafellows(const char *version) { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH_2.*," "OpenSSH_3.0*," - "OpenSSH_3.1*", SSH_BUG_EXTEOF}, + "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_BUG_GSSAPI_BER}, + { "OpenSSH_3.2*," + "OpenSSH_3.3*," + "OpenSSH_3.4*," + "OpenSSH_3.5*", SSH_BUG_GSSAPI_BER}, { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH*", 0 }, { "*MindTerm*", 0 }, diff --git a/compat.h b/compat.h index 881e450d3..a21e473c5 100644 --- a/compat.h +++ b/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.34 2003/04/01 10:31:26 markus Exp $ */ +/* $OpenBSD: compat.h,v 1.35 2003/08/22 10:56:09 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -56,6 +56,7 @@ #define SSH_BUG_K5USER 0x00400000 #define SSH_BUG_PROBE 0x00800000 #define SSH_BUG_FIRSTKEX 0x01000000 +#define SSH_BUG_GSSAPI_BER 0x02000000 void enable_compat13(void); void enable_compat20(void); diff --git a/gss-genr.c b/gss-genr.c new file mode 100644 index 000000000..bda12d6f1 --- /dev/null +++ b/gss-genr.c @@ -0,0 +1,256 @@ +/* $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI + +#include "xmalloc.h" +#include "bufaux.h" +#include "compat.h" +#include "log.h" +#include "monitor_wrap.h" + +#include "ssh-gss.h" + + +/* Check that the OID in a data stream matches that in the context */ +int +ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) +{ + return (ctx != NULL && ctx->oid != GSS_C_NO_OID && + ctx->oid->length == len && + memcmp(ctx->oid->elements, data, len) == 0); +} + +/* Set the contexts OID from a data stream */ +void +ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) +{ + if (ctx->oid != GSS_C_NO_OID) { + xfree(ctx->oid->elements); + xfree(ctx->oid); + } + ctx->oid = xmalloc(sizeof(gss_OID_desc)); + ctx->oid->length = len; + ctx->oid->elements = xmalloc(len); + memcpy(ctx->oid->elements, data, len); +} + +/* Set the contexts OID */ +void +ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) +{ + ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length); +} + +/* All this effort to report an error ... */ +void +ssh_gssapi_error(Gssctxt *ctxt) +{ + debug("%s", ssh_gssapi_last_error(ctxt, NULL, NULL)); +} + +char * +ssh_gssapi_last_error(Gssctxt *ctxt, + OM_uint32 *major_status, OM_uint32 *minor_status) +{ + OM_uint32 lmin; + gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; + OM_uint32 ctx; + Buffer b; + char *ret; + + buffer_init(&b); + + if (major_status != NULL) + *major_status = ctxt->major; + if (minor_status != NULL) + *minor_status = ctxt->minor; + + ctx = 0; + /* The GSSAPI error */ + do { + gss_display_status(&lmin, ctxt->major, + GSS_C_GSS_CODE, GSS_C_NULL_OID, &ctx, &msg); + + buffer_append(&b, msg.value, msg.length); + buffer_put_char(&b, '\n'); + + gss_release_buffer(&lmin, &msg); + } while (ctx != 0); + + /* The mechanism specific error */ + do { + gss_display_status(&lmin, ctxt->minor, + GSS_C_MECH_CODE, GSS_C_NULL_OID, &ctx, &msg); + + buffer_append(&b, msg.value, msg.length); + buffer_put_char(&b, '\n'); + + gss_release_buffer(&lmin, &msg); + } while (ctx != 0); + + buffer_put_char(&b, '\0'); + ret = xmalloc(buffer_len(&b)); + buffer_get(&b, ret, buffer_len(&b)); + buffer_free(&b); + return (ret); +} + +/* + * Initialise our GSSAPI context. We use this opaque structure to contain all + * of the data which both the client and server need to persist across + * {accept,init}_sec_context calls, so that when we do it from the userauth + * stuff life is a little easier + */ +void +ssh_gssapi_build_ctx(Gssctxt **ctx) +{ + *ctx = xmalloc(sizeof (Gssctxt)); + (*ctx)->major = 0; + (*ctx)->minor = 0; + (*ctx)->context = GSS_C_NO_CONTEXT; + (*ctx)->name = GSS_C_NO_NAME; + (*ctx)->oid = GSS_C_NO_OID; + (*ctx)->creds = GSS_C_NO_CREDENTIAL; + (*ctx)->client = GSS_C_NO_NAME; + (*ctx)->client_creds = GSS_C_NO_CREDENTIAL; +} + +/* Delete our context, providing it has been built correctly */ +void +ssh_gssapi_delete_ctx(Gssctxt **ctx) +{ + OM_uint32 ms; + + if ((*ctx) == NULL) + return; + if ((*ctx)->context != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER); + if ((*ctx)->name != GSS_C_NO_NAME) + gss_release_name(&ms, &(*ctx)->name); + if ((*ctx)->oid != GSS_C_NO_OID) { + xfree((*ctx)->oid->elements); + xfree((*ctx)->oid); + (*ctx)->oid = GSS_C_NO_OID; + } + if ((*ctx)->creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->creds); + if ((*ctx)->client != GSS_C_NO_NAME) + gss_release_name(&ms, &(*ctx)->client); + if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->client_creds); + + xfree(*ctx); + *ctx = NULL; +} + +/* + * Wrapper to init_sec_context + * Requires that the context contains: + * oid + * server name (from ssh_gssapi_import_name) + */ +OM_uint32 +ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, + gss_buffer_desc* send_tok, OM_uint32 *flags) +{ + int deleg_flag = 0; + + if (deleg_creds) { + deleg_flag = GSS_C_DELEG_FLAG; + debug("Delegating credentials"); + } + + ctx->major = gss_init_sec_context(&ctx->minor, + GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, + GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, + 0, NULL, recv_tok, NULL, send_tok, flags, NULL); + + if (GSS_ERROR(ctx->major)) + ssh_gssapi_error(ctx); + + return (ctx->major); +} + +/* Create a service name for the given host */ +OM_uint32 +ssh_gssapi_import_name(Gssctxt *ctx, const char *host) +{ + gss_buffer_desc gssbuf; + + gssbuf.length = sizeof("host@") + strlen(host); + gssbuf.value = xmalloc(gssbuf.length); + snprintf(gssbuf.value, gssbuf.length, "host@%s", host); + + if ((ctx->major = gss_import_name(&ctx->minor, + &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) + ssh_gssapi_error(ctx); + + xfree(gssbuf.value); + return (ctx->major); +} + +/* Acquire credentials for a server running on the current host. + * Requires that the context structure contains a valid OID + */ + +/* Returns a GSSAPI error code */ +OM_uint32 +ssh_gssapi_acquire_cred(Gssctxt *ctx) +{ + OM_uint32 status; + char lname[MAXHOSTNAMELEN]; + gss_OID_set oidset; + + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); + + if (gethostname(lname, MAXHOSTNAMELEN)) + return (-1); + + if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) + return (ctx->major); + + if ((ctx->major = gss_acquire_cred(&ctx->minor, + ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) + ssh_gssapi_error(ctx); + + gss_release_oid_set(&status, &oidset); + return (ctx->major); +} + +OM_uint32 +ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) { + if (*ctx) + ssh_gssapi_delete_ctx(ctx); + ssh_gssapi_build_ctx(ctx); + ssh_gssapi_set_oid(*ctx, oid); + return (ssh_gssapi_acquire_cred(*ctx)); +} + +#endif /* GSSAPI */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c new file mode 100644 index 000000000..d86872258 --- /dev/null +++ b/gss-serv-krb5.c @@ -0,0 +1,168 @@ +/* $OpenBSD: gss-serv-krb5.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI +#ifdef KRB5 + +#include "auth.h" +#include "xmalloc.h" +#include "log.h" +#include "servconf.h" + +#include "ssh-gss.h" + +extern ServerOptions options; + +#include + +static krb5_context krb_context = NULL; + +/* Initialise the krb5 library, for the stuff that GSSAPI won't do */ + +static int +ssh_gssapi_krb5_init() +{ + krb5_error_code problem; + + if (krb_context != NULL) + return 1; + + problem = krb5_init_context(&krb_context); + if (problem) { + logit("Cannot initialize krb5 context"); + return 0; + } + krb5_init_ets(krb_context); + + return 1; +} + +/* Check if this user is OK to login. This only works with krb5 - other + * GSSAPI mechanisms will need their own. + * Returns true if the user is OK to log in, otherwise returns 0 + */ + +static int +ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +{ + krb5_principal princ; + int retval; + + if (ssh_gssapi_krb5_init() == 0) + return 0; + + if ((retval = krb5_parse_name(krb_context, client->exportedname.value, + &princ))) { + logit("krb5_parse_name(): %.100s", + krb5_get_err_text(krb_context, retval)); + return 0; + } + if (krb5_kuserok(krb_context, princ, name)) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", + name, (char *)client->displayname.value); + } else + retval = 0; + + krb5_free_principal(krb_context, princ); + return retval; +} + + +/* This writes out any forwarded credentials from the structure populated + * during userauth. Called after we have setuid to the user */ + +static void +ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +{ + krb5_ccache ccache; + krb5_error_code problem; + krb5_principal princ; + OM_uint32 maj_status, min_status; + + if (client->creds == NULL) { + debug("No credentials stored"); + return; + } + + if (ssh_gssapi_krb5_init() == 0) + return; + + if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { + logit("krb5_cc_gen_new(): %.100s", + krb5_get_err_text(krb_context, problem)); + return; + } + + if ((problem = krb5_parse_name(krb_context, + client->exportedname.value, &princ))) { + logit("krb5_parse_name(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_cc_destroy(krb_context, ccache); + return; + } + + if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { + logit("krb5_cc_initialize(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_free_principal(krb_context, princ); + krb5_cc_destroy(krb_context, ccache); + return; + } + + krb5_free_principal(krb_context, princ); + + if ((maj_status = gss_krb5_copy_ccache(&min_status, + client->creds, ccache))) { + logit("gss_krb5_copy_ccache() failed"); + krb5_cc_destroy(krb_context, ccache); + return; + } + + client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); + client->store.envvar = "KRB5CCNAME"; + client->store.envval = xstrdup(client->store.filename); + + krb5_cc_close(krb_context, ccache); + + return; +} + +ssh_gssapi_mech gssapi_kerberos_mech = { + "toWM5Slw5Ew8Mqkay+al2g==", + "Kerberos", + {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, + NULL, + &ssh_gssapi_krb5_userok, + NULL, + &ssh_gssapi_krb5_storecreds +}; + +#endif /* KRB5 */ + +#endif /* GSSAPI */ diff --git a/gss-serv.c b/gss-serv.c new file mode 100644 index 000000000..42718177d --- /dev/null +++ b/gss-serv.c @@ -0,0 +1,291 @@ +/* $OpenBSD: gss-serv.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI + +#include "bufaux.h" +#include "compat.h" +#include "auth.h" +#include "log.h" +#include "channels.h" +#include "session.h" +#include "servconf.h" +#include "monitor_wrap.h" +#include "xmalloc.h" +#include "getput.h" + +#include "ssh-gss.h" + +extern ServerOptions options; + +static ssh_gssapi_client gssapi_client = + { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, + GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}}; + +ssh_gssapi_mech gssapi_null_mech = + { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; + +#ifdef KRB5 +extern ssh_gssapi_mech gssapi_kerberos_mech; +#endif + +ssh_gssapi_mech* supported_mechs[]= { +#ifdef KRB5 + &gssapi_kerberos_mech, +#endif + &gssapi_null_mech, +}; + +/* Unpriviledged */ +void +ssh_gssapi_supported_oids(gss_OID_set *oidset) +{ + int i = 0; + OM_uint32 min_status; + int present; + gss_OID_set supported; + + gss_create_empty_oid_set(&min_status, oidset); + gss_indicate_mechs(&min_status, &supported); + + while (supported_mechs[i]->name != NULL) { + if (GSS_ERROR(gss_test_oid_set_member(&min_status, + &supported_mechs[i]->oid, supported, &present))) + present = 0; + if (present) + gss_add_oid_set_member(&min_status, + &supported_mechs[i]->oid, oidset); + i++; + } +} + + +/* Wrapper around accept_sec_context + * Requires that the context contains: + * oid + * credentials (from ssh_gssapi_acquire_cred) + */ +/* Priviledged */ +OM_uint32 +ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok, + gss_buffer_desc *send_tok, OM_uint32 *flags) +{ + OM_uint32 status; + gss_OID mech; + + ctx->major = gss_accept_sec_context(&ctx->minor, + &ctx->context, ctx->creds, recv_tok, + GSS_C_NO_CHANNEL_BINDINGS, &ctx->client, &mech, + send_tok, flags, NULL, &ctx->client_creds); + + if (GSS_ERROR(ctx->major)) + ssh_gssapi_error(ctx); + + if (ctx->client_creds) + debug("Received some client credentials"); + else + debug("Got no client credentials"); + + status = ctx->major; + + /* Now, if we're complete and we have the right flags, then + * we flag the user as also having been authenticated + */ + + if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) && + (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { + if (ssh_gssapi_getclient(ctx, &gssapi_client)) + fatal("Couldn't convert client name"); + } + + return (status); +} + +/* + * This parses an exported name, extracting the mechanism specific portion + * to use for ACL checking. It verifies that the name belongs the mechanism + * originally selected. + */ +static OM_uint32 +ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) +{ + char *tok; + OM_uint32 offset; + OM_uint32 oidl; + + tok=ename->value; + + /* + * Check that ename is long enough for all of the fixed length + * header, and that the initial ID bytes are correct + */ + + if (ename->length<6 || memcmp(tok,"\x04\x01", 2)!=0) + return GSS_S_FAILURE; + + /* + * Extract the OID, and check it. Here GSSAPI breaks with tradition + * and does use the OID type and length bytes. To confuse things + * there are two lengths - the first including these, and the + * second without. + */ + + oidl = GET_16BIT(tok+2); /* length including next two bytes */ + oidl = oidl-2; /* turn it into the _real_ length of the variable OID */ + + /* + * Check the BER encoding for correct type and length, that the + * string is long enough and that the OID matches that in our context + */ + if (tok[4] != 0x06 || tok[5] != oidl || + ename->length < oidl+6 || + !ssh_gssapi_check_oid(ctx,tok+6,oidl)) + return GSS_S_FAILURE; + + offset = oidl+6; + + if (ename->length < offset+4) + return GSS_S_FAILURE; + + name->length = GET_32BIT(tok+offset); + offset += 4; + + if (ename->length < offset+name->length) + return GSS_S_FAILURE; + + name->value = xmalloc(name->length); + memcpy(name->value,tok+offset,name->length); + + return GSS_S_COMPLETE; +} + +/* Extract the client details from a given context. This can only reliably + * be called once for a context */ + +/* Priviledged (called from accept_secure_ctx) */ +OM_uint32 +ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +{ + int i = 0; + + gss_buffer_desc ename; + + client->mech = NULL; + + while (supported_mechs[i]->name != NULL) { + if (supported_mechs[i]->oid.length == ctx->oid->length && + (memcmp(supported_mechs[i]->oid.elements, + ctx->oid->elements, ctx->oid->length) == 0)) + client->mech = supported_mechs[i]; + i++; + } + + if (client->mech == NULL) + return GSS_S_FAILURE; + + if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, + &client->displayname, NULL))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } + + if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, + &ename))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } + + if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, + &client->exportedname))) { + return (ctx->major); + } + + /* We can't copy this structure, so we just move the pointer to it */ + client->creds = ctx->client_creds; + ctx->client_creds = GSS_C_NO_CREDENTIAL; + return (ctx->major); +} + +/* As user - called through fatal cleanup hook */ +void +ssh_gssapi_cleanup_creds(void *ignored) +{ + if (gssapi_client.store.filename != NULL) { + /* Unlink probably isn't sufficient */ + debug("removing gssapi cred file\"%s\"", gssapi_client.store.filename); + unlink(gssapi_client.store.filename); + } +} + +/* As user */ +void +ssh_gssapi_storecreds(void) +{ + if (gssapi_client.mech && gssapi_client.mech->storecreds) { + (*gssapi_client.mech->storecreds)(&gssapi_client); + if (options.gss_cleanup_creds) + fatal_add_cleanup(ssh_gssapi_cleanup_creds, NULL); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); +} + +/* This allows GSSAPI methods to do things to the childs environment based + * on the passed authentication process and credentials. + */ +/* As user */ +void +ssh_gssapi_do_child(char ***envp, u_int *envsizep) +{ + + if (gssapi_client.store.envvar != NULL && + gssapi_client.store.envval != NULL) { + + debug("Setting %s to %s", gssapi_client.store.envvar, + gssapi_client.store.envval); + child_set_env(envp, envsizep, gssapi_client.store.envvar, + gssapi_client.store.envval); + } +} + +/* Priviledged */ +int +ssh_gssapi_userok(char *user) +{ + if (gssapi_client.exportedname.length == 0 || + gssapi_client.exportedname.value == NULL) { + debug("No suitable client data"); + return 0; + } + if (gssapi_client.mech && gssapi_client.mech->userok) + return ((*gssapi_client.mech->userok)(&gssapi_client, user)); + else + debug("ssh_gssapi_userok: Unknown GSSAPI mechanism"); + return (0); +} + +#endif diff --git a/monitor.c b/monitor.c index 80b1a8fba..f90a90461 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.45 2003/07/22 13:35:22 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.46 2003/08/22 10:56:09 markus Exp $"); #include @@ -59,6 +59,11 @@ RCSID("$OpenBSD: monitor.c,v 1.45 2003/07/22 13:35:22 markus Exp $"); #include "ssh2.h" #include "mpaux.h" +#ifdef GSSAPI +#include "ssh-gss.h" +static Gssctxt *gsscontext = NULL; +#endif + /* Imports */ extern ServerOptions options; extern u_int utmp_len; @@ -128,6 +133,11 @@ int mm_answer_pam_free_ctx(int, Buffer *); #ifdef KRB5 int mm_answer_krb5(int, Buffer *); #endif +#ifdef GSSAPI +int mm_answer_gss_setup_ctx(int, Buffer *); +int mm_answer_gss_accept_ctx(int, Buffer *); +int mm_answer_gss_userok(int, Buffer *); +#endif static Authctxt *authctxt; static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ @@ -184,6 +194,11 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, #ifdef KRB5 {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, +#endif +#ifdef GSSAPI + {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, + {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, + {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, #endif {0, 0, NULL} }; @@ -357,7 +372,6 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); - } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1769,3 +1783,77 @@ monitor_reinit(struct monitor *mon) mon->m_recvfd = pair[0]; mon->m_sendfd = pair[1]; } + +#ifdef GSSAPI +int +mm_answer_gss_setup_ctx(int socket, Buffer *m) +{ + gss_OID_desc oid; + OM_uint32 major; + u_int len; + + oid.elements = buffer_get_string(m, &len); + oid.length = len; + + major = ssh_gssapi_server_ctx(&gsscontext, &oid); + + xfree(oid.elements); + + buffer_clear(m); + buffer_put_int(m, major); + + mm_request_send(socket,MONITOR_ANS_GSSSETUP, m); + + /* Now we have a context, enable the step */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); + + return (0); +} + +int +mm_answer_gss_accept_ctx(int socket, Buffer *m) +{ + gss_buffer_desc in; + gss_buffer_desc out = GSS_C_EMPTY_BUFFER; + OM_uint32 major,minor; + OM_uint32 flags = 0; /* GSI needs this */ + + in.value = buffer_get_string(m, &in.length); + major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); + xfree(in.value); + + buffer_clear(m); + buffer_put_int(m, major); + buffer_put_string(m, out.value, out.length); + buffer_put_int(m, flags); + mm_request_send(socket, MONITOR_ANS_GSSSTEP, m); + + 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); + } + return (0); +} + +int +mm_answer_gss_userok(int socket, Buffer *m) +{ + int authenticated; + + authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + + buffer_clear(m); + buffer_put_int(m, authenticated); + + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m); + + auth_method="gssapi"; + + /* Monitor loop will terminate if authenticated */ + return (authenticated); +} +#endif /* GSSAPI */ diff --git a/monitor.h b/monitor.h index eeac78e03..da33ed613 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.9 2003/07/22 13:35:22 markus Exp $ */ +/* $OpenBSD: monitor.h,v 1.10 2003/08/22 10:56:09 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -50,6 +50,9 @@ enum monitor_reqtype { MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE, MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, + MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP, + MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, + MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, MONITOR_REQ_PAM_START, MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, diff --git a/monitor_wrap.c b/monitor_wrap.c index 9e7e6b3c3..4073905f6 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.28 2003/07/22 13:35:22 markus Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.29 2003/08/22 10:56:09 markus Exp $"); #include #include @@ -53,6 +53,10 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.28 2003/07/22 13:35:22 markus Exp $"); #include "channels.h" #include "session.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* Imports */ extern int compat20; extern Newkeys *newkeys[]; @@ -1100,4 +1104,69 @@ mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) buffer_free(&m); return (success); } -#endif +#endif /* KRB5 */ + +#ifdef GSSAPI +OM_uint32 +mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) +{ + Buffer m; + OM_uint32 major; + + /* Client doesn't get to see the context */ + *ctx = NULL; + + buffer_init(&m); + buffer_put_string(&m, oid->elements, oid->length); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); + + major = buffer_get_int(&m); + + buffer_free(&m); + return (major); +} + +OM_uint32 +mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, + gss_buffer_desc *out, OM_uint32 *flags) +{ + Buffer m; + OM_uint32 major; + + buffer_init(&m); + buffer_put_string(&m, in->value, in->length); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); + + major = buffer_get_int(&m); + out->value = buffer_get_string(&m, &out->length); + if (flags) + *flags = buffer_get_int(&m); + + buffer_free(&m); + + return (major); +} + +int +mm_ssh_gssapi_userok(char *user) +{ + Buffer m; + int authenticated = 0; + + buffer_init(&m); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, + &m); + + authenticated = buffer_get_int(&m); + + buffer_free(&m); + debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); + return (authenticated); +} +#endif /* GSSAPI */ diff --git a/monitor_wrap.h b/monitor_wrap.h index ddd42ee28..c6251924a 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.9 2003/07/22 13:35:22 markus Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.10 2003/08/22 10:56:09 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -55,6 +55,14 @@ int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); BIGNUM *mm_auth_rsa_generate_challenge(Key *); +#ifdef GSSAPI +#include "ssh-gss.h" +OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid); +OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt, + gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags); +int mm_ssh_gssapi_userok(char *user); +#endif + #ifdef USE_PAM void mm_start_pam(char *); u_int mm_do_pam_account(void); diff --git a/readconf.c b/readconf.c index 96ad25a51..9447cb55f 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.117 2003/08/13 09:07:09 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.118 2003/08/22 10:56:09 markus Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -105,7 +105,7 @@ typedef enum { oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, - oAddressFamily, + oAddressFamily, oGssAuthentication, oGssDelegateCreds, oDeprecated, oUnsupported } OpCodes; @@ -140,6 +140,14 @@ static struct { { "kerberostgtpassing", oUnsupported }, #endif { "afstokenpassing", oUnsupported }, +#if defined(GSSAPI) + { "gssapiauthentication", oGssAuthentication }, + { "gssapidelegatecreds", oGssDelegateCreds }, + { "gssapidelegatecredentials", oGssDelegateCreds }, +#else + { "gssapiauthentication", oUnsupported }, + { "gssapidelegatecredentials", oUnsupported }, +#endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, { "identityfile", oIdentityFile }, @@ -389,6 +397,14 @@ parse_flag: intptr = &options->kerberos_tgt_passing; goto parse_flag; + case oGssAuthentication: + intptr = &options->gss_authentication; + goto parse_flag; + + case oGssDelegateCreds: + intptr = &options->gss_deleg_creds; + goto parse_flag; + case oBatchMode: intptr = &options->batch_mode; goto parse_flag; @@ -813,6 +829,8 @@ initialize_options(Options * options) options->challenge_response_authentication = -1; options->kerberos_authentication = -1; options->kerberos_tgt_passing = -1; + options->gss_authentication = -1; + options->gss_deleg_creds = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; @@ -887,6 +905,10 @@ fill_default_options(Options * options) options->kerberos_authentication = 1; if (options->kerberos_tgt_passing == -1) options->kerberos_tgt_passing = 1; + if (options->gss_authentication == -1) + options->gss_authentication = 1; + if (options->gss_deleg_creds == -1) + options->gss_deleg_creds = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) diff --git a/readconf.h b/readconf.h index 6fbf467e5..1100205b8 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.53 2003/08/13 08:46:30 markus Exp $ */ +/* $OpenBSD: readconf.h,v 1.54 2003/08/22 10:56:09 markus Exp $ */ /* * Author: Tatu Ylonen @@ -42,6 +42,8 @@ typedef struct { /* Try S/Key or TIS, authentication. */ int kerberos_authentication; /* Try Kerberos authentication. */ int kerberos_tgt_passing; /* Try Kerberos TGT passing. */ + int gss_authentication; /* Try GSS authentication */ + int gss_deleg_creds; /* Delegate GSS credentials */ int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c index 09fdbf424..e13309388 100644 --- a/servconf.c +++ b/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.124 2003/08/13 08:46:30 markus Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.125 2003/08/22 10:56:09 markus Exp $"); #include "ssh.h" #include "log.h" @@ -73,6 +73,8 @@ initialize_server_options(ServerOptions *options) options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_tgt_passing = -1; + options->gss_authentication=-1; + options->gss_cleanup_creds = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; @@ -182,6 +184,10 @@ fill_default_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = 1; if (options->kerberos_tgt_passing == -1) options->kerberos_tgt_passing = 0; + if (options->gss_authentication == -1) + options->gss_authentication = 0; + if (options->gss_cleanup_creds == -1) + options->gss_cleanup_creds = 1; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -259,6 +265,7 @@ typedef enum { sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, + sGssAuthentication, sGssCleanupCreds, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; @@ -305,6 +312,13 @@ static struct { { "kerberostgtpassing", sUnsupported }, #endif { "afstokenpassing", sUnsupported }, +#ifdef GSSAPI + { "gssapiauthentication", sGssAuthentication }, + { "gssapicleanupcreds", sGssCleanupCreds }, +#else + { "gssapiauthentication", sUnsupported }, + { "gssapicleanupcreds", sUnsupported }, +#endif { "passwordauthentication", sPasswordAuthentication }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, { "challengeresponseauthentication", sChallengeResponseAuthentication }, @@ -623,6 +637,14 @@ parse_flag: intptr = &options->kerberos_tgt_passing; goto parse_flag; + case sGssAuthentication: + intptr = &options->gss_authentication; + goto parse_flag; + + case sGssCleanupCreds: + intptr = &options->gss_cleanup_creds; + goto parse_flag; + case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; diff --git a/servconf.h b/servconf.h index 42bcda757..f86cb2209 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.63 2003/08/13 08:46:30 markus Exp $ */ +/* $OpenBSD: servconf.h,v 1.64 2003/08/22 10:56:09 markus Exp $ */ /* * Author: Tatu Ylonen @@ -82,6 +82,8 @@ typedef struct { * file on logout. */ int kerberos_tgt_passing; /* If true, permit Kerberos TGT * passing. */ + int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c index 20c4b8a97..3593a3ff5 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.160 2003/08/13 08:33:02 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.161 2003/08/22 10:56:09 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -58,6 +58,10 @@ RCSID("$OpenBSD: session.c,v 1.160 2003/08/13 08:33:02 markus Exp $"); #include "session.h" #include "monitor_wrap.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* func */ Session *session_new(void); @@ -424,6 +428,12 @@ do_exec_no_pty(Session *s, const char *command) } #endif /* USE_PAM */ +#ifdef GSSAPI + temporarily_use_uid(s->pw); + ssh_gssapi_storecreds(); + restore_uid(); +#endif + /* Fork the child. */ if ((pid = fork()) == 0) { fatal_remove_all_cleanups(); @@ -550,6 +560,12 @@ do_exec_pty(Session *s, const char *command) } #endif +#ifdef GSSAPI + temporarily_use_uid(s->pw); + ssh_gssapi_storecreds(); + restore_uid(); +#endif + /* Fork the child. */ if ((pid = fork()) == 0) { fatal_remove_all_cleanups(); @@ -807,7 +823,7 @@ check_quietlogin(Session *s, const char *command) * Sets the value of the given variable in the environment. If the variable * already exists, its value is overriden. */ -static void +void child_set_env(char ***envp, u_int *envsizep, const char *name, const char *value) { @@ -934,6 +950,13 @@ do_setup_env(Session *s, const char *shell) copy_environment(environ, &env, &envsize); #endif +#ifdef GSSAPI + /* Allow any GSSAPI methods that we've used to alter + * the childs environment as they see fit + */ + ssh_gssapi_do_child(&env, &envsize); +#endif + if (!options.use_login) { /* Set basic environment. */ child_set_env(&env, &envsize, "USER", pw->pw_name); @@ -2088,4 +2111,8 @@ static void do_authenticated2(Authctxt *authctxt) { server_loop2(authctxt); +#if defined(GSSAPI) + if (options.gss_cleanup_creds) + ssh_gssapi_cleanup_creds(NULL); +#endif } diff --git a/session.h b/session.h index d3ddfab75..525e47f64 100644 --- a/session.h +++ b/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.19 2002/06/30 21:59:45 deraadt Exp $ */ +/* $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -68,4 +68,7 @@ Session *session_new(void); Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); +void child_set_env(char ***envp, u_int *envsizep, const char *name, + const char *value); + #endif diff --git a/ssh-gss.h b/ssh-gss.h new file mode 100644 index 000000000..263e51b94 --- /dev/null +++ b/ssh-gss.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SSH_GSS_H +#define _SSH_GSS_H + +#ifdef GSSAPI + +#include "buffer.h" + +#include + +/* draft-ietf-secsh-gsskeyex-06 */ +#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 +#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 +#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 +#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 +#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 + +#define SSH_GSS_OIDTYPE 0x06 + +typedef struct { + char *filename; + char *envvar; + char *envval; + void *data; +} ssh_gssapi_ccache; + +typedef struct { + gss_buffer_desc displayname; + gss_buffer_desc exportedname; + gss_cred_id_t creds; + struct ssh_gssapi_mech_struct *mech; + ssh_gssapi_ccache store; +} ssh_gssapi_client; + +typedef struct ssh_gssapi_mech_struct { + char *enc_name; + char *name; + gss_OID_desc oid; + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); + void (*storecreds) (ssh_gssapi_client *); +} ssh_gssapi_mech; + +typedef struct { + OM_uint32 major; /* both */ + OM_uint32 minor; /* both */ + gss_ctx_id_t context; /* both */ + gss_name_t name; /* both */ + gss_OID oid; /* client */ + gss_cred_id_t creds; /* server */ + gss_name_t client; /* server */ + gss_cred_id_t client_creds; /* server */ +} Gssctxt; + +extern ssh_gssapi_mech *supported_mechs[]; + +int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len); +void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len); +void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid); +void ssh_gssapi_supported_oids(gss_OID_set *oidset); +ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *ctxt); + +OM_uint32 ssh_gssapi_import_name(Gssctxt *ctx, const char *host); +OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx); +OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, + gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags); +OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, + gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags); +OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *); +void ssh_gssapi_error(Gssctxt *ctx); +char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min); +void ssh_gssapi_build_ctx(Gssctxt **ctx); +void ssh_gssapi_delete_ctx(Gssctxt **ctx); +OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid); + +/* In the server */ +int ssh_gssapi_userok(char *name); + +void ssh_gssapi_do_child(char ***envp, u_int *envsizep); +void ssh_gssapi_cleanup_creds(void *ignored); +void ssh_gssapi_storecreds(void); + +#endif /* GSSAPI */ + +#endif /* _SSH_GSS_H */ diff --git a/ssh_config.5 b/ssh_config.5 index fb341d79b..f99562b96 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.17 2003/08/13 08:46:31 markus Exp $ +.\" $OpenBSD: ssh_config.5,v 1.18 2003/08/22 10:56:09 markus Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -331,6 +331,18 @@ The default is Specifies a file to use for the global host key database instead of .Pa /etc/ssh/ssh_known_hosts . +.It Cm GSSAPIAuthentication +Specifies whether authentication based on GSSAPI may be used, either using +the result of a successful key exchange, or using GSSAPI user +authentication. +The default is +.Dq yes . +Note that this option applies to protocol version 2 only. +.It Cm GSSAPIDelegateCredentials +Forward (delegate) credentials to the server. +The default is +.Dq no . +Note that this option applies to protocol version 2 only. .It Cm HostbasedAuthentication Specifies whether to try rhosts based authentication with public key authentication. diff --git a/sshconnect2.c b/sshconnect2.c index 6a0bd409a..c71ad506b 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.120 2003/06/24 08:23:46 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.121 2003/08/22 10:56:09 markus Exp $"); #ifdef KRB5 #include @@ -57,6 +57,10 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.120 2003/06/24 08:23:46 markus Exp $"); #include "msg.h" #include "pathnames.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* import */ extern char *client_version_string; extern char *server_version_string; @@ -178,6 +182,8 @@ struct Authctxt { Sensitive *sensitive; /* kbd-interactive */ int info_req_seen; + /* generic */ + void *methoddata; }; struct Authmethod { char *name; /* string to compare against server's list */ @@ -201,6 +207,15 @@ int userauth_kbdint(Authctxt *); int userauth_hostbased(Authctxt *); int userauth_kerberos(Authctxt *); +#ifdef GSSAPI +int userauth_gssapi(Authctxt *authctxt); +void input_gssapi_response(int type, u_int32_t, void *); +void input_gssapi_token(int type, u_int32_t, void *); +void input_gssapi_hash(int type, u_int32_t, void *); +void input_gssapi_error(int, u_int32_t, void *); +void input_gssapi_errtok(int, u_int32_t, void *); +#endif + void userauth(Authctxt *, char *); static int sign_and_send_pubkey(Authctxt *, Identity *); @@ -213,6 +228,12 @@ static Authmethod *authmethod_lookup(const char *name); static char *authmethods_get(void); Authmethod authmethods[] = { +#ifdef GSSAPI + {"gssapi", + userauth_gssapi, + &options.gss_authentication, + NULL}, +#endif {"hostbased", userauth_hostbased, &options.hostbased_authentication, @@ -283,6 +304,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, authctxt.success = 0; authctxt.method = authmethod_lookup("none"); authctxt.authlist = NULL; + authctxt.methoddata = NULL; authctxt.sensitive = sensitive; authctxt.info_req_seen = 0; if (authctxt.method == NULL) @@ -306,6 +328,10 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, void userauth(Authctxt *authctxt, char *authlist) { + if (authctxt->methoddata) { + xfree(authctxt->methoddata); + authctxt->methoddata = NULL; + } if (authlist == NULL) { authlist = authctxt->authlist; } else { @@ -361,6 +387,8 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt) fatal("input_userauth_success: no authentication context"); if (authctxt->authlist) xfree(authctxt->authlist); + if (authctxt->methoddata) + xfree(authctxt->methoddata); authctxt->success = 1; /* break out */ } @@ -449,6 +477,228 @@ done: userauth(authctxt, NULL); } +#ifdef GSSAPI +int +userauth_gssapi(Authctxt *authctxt) +{ + Gssctxt *gssctxt = NULL; + static gss_OID_set supported = NULL; + static int mech = 0; + OM_uint32 min; + int ok = 0; + + /* Try one GSSAPI method at a time, rather than sending them all at + * once. */ + + if (supported == NULL) + gss_indicate_mechs(&min, &supported); + + /* Check to see if the mechanism is usable before we offer it */ + while (mechcount && !ok) { + if (gssctxt) + ssh_gssapi_delete_ctx(&gssctxt); + ssh_gssapi_build_ctx(&gssctxt); + ssh_gssapi_set_oid(gssctxt, &supported->elements[mech]); + + /* My DER encoding requires length<128 */ + if (supported->elements[mech].length < 128 && + !GSS_ERROR(ssh_gssapi_import_name(gssctxt, + authctxt->host))) { + ok = 1; /* Mechanism works */ + } else { + mech++; + } + } + + if (!ok) return 0; + + authctxt->methoddata=(void *)gssctxt; + + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + + packet_put_int(1); + + /* Some servers encode the OID incorrectly (as we used to) */ + if (datafellows & SSH_BUG_GSSAPI_BER) { + packet_put_string(supported->elements[mech].elements, + supported->elements[mech].length); + } else { + packet_put_int((supported->elements[mech].length)+2); + packet_put_char(SSH_GSS_OIDTYPE); + packet_put_char(supported->elements[mech].length); + packet_put_raw(supported->elements[mech].elements, + supported->elements[mech].length); + } + + packet_send(); + + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); + + mech++; /* Move along to next candidate */ + + return 1; +} + +void +input_gssapi_response(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + OM_uint32 status, ms; + int oidlen; + char *oidv; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + + if (authctxt == NULL) + fatal("input_gssapi_response: no authentication context"); + gssctxt = authctxt->methoddata; + + /* Setup our OID */ + oidv = packet_get_string(&oidlen); + + if (datafellows & SSH_BUG_GSSAPI_BER) { + if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen)) + fatal("Server returned different OID than expected"); + } else { + if(oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen-2) { + debug("Badly encoded mechanism OID received"); + userauth(authctxt, NULL); + xfree(oidv); + return; + } + if (!ssh_gssapi_check_oid(gssctxt, oidv+2, oidlen-2)) + fatal("Server returned different OID than expected"); + } + + packet_check_eom(); + + xfree(oidv); + + status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, + GSS_C_NO_BUFFER, &send_tok, NULL); + if (GSS_ERROR(status)) { + if (send_tok.length > 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); + } + /* Start again with next method on list */ + debug("Trying to start again"); + userauth(authctxt, NULL); + return; + } + + /* We must have data to send */ + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); +} + +void +input_gssapi_token(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 status, ms; + u_int slen; + + if (authctxt == NULL) + fatal("input_gssapi_response: no authentication context"); + gssctxt = authctxt->methoddata; + + recv_tok.value = packet_get_string(&slen); + recv_tok.length = slen; /* safe typecast */ + + packet_check_eom(); + + status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, + &recv_tok, &send_tok, NULL); + + xfree(recv_tok.value); + + if (GSS_ERROR(status)) { + if (send_tok.length > 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); + } + /* Start again with the next method in the list */ + userauth(authctxt, NULL); + return; + } + + if (send_tok.length > 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); + } + + if (status == GSS_S_COMPLETE) { + /* If that succeeded, send a exchange complete message */ + packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); + packet_send(); + } +} + +void +input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 status, ms; + + if (authctxt == NULL) + fatal("input_gssapi_response: no authentication context"); + gssctxt = authctxt->methoddata; + + recv_tok.value = packet_get_string(&recv_tok.length); + + packet_check_eom(); + + /* Stick it into GSSAPI and see what it says */ + status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, + &recv_tok, &send_tok, NULL); + + xfree(recv_tok.value); + gss_release_buffer(&ms, &send_tok); + + /* Server will be returning a failed packet after this one */ +} + +void +input_gssapi_error(int type, u_int32_t plen, void *ctxt) +{ + OM_uint32 maj, min; + char *msg; + char *lang; + + maj=packet_get_int(); + min=packet_get_int(); + msg=packet_get_string(NULL); + lang=packet_get_string(NULL); + + packet_check_eom(); + + debug("Server GSSAPI Error:\n%s\n", msg); + xfree(msg); + xfree(lang); +} +#endif /* GSSAPI */ + int userauth_none(Authctxt *authctxt) { diff --git a/sshd_config b/sshd_config index a2bd2ff60..294539096 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.63 2003/08/13 08:46:31 markus Exp $ +# $OpenBSD: sshd_config,v 1.64 2003/08/22 10:56:09 markus Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -63,6 +63,10 @@ #KerberosTicketCleanup yes #KerberosTgtPassing no +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCreds yes + # Set this to 'yes' to enable PAM authentication (via challenge-response) # and session processing. Depending on your PAM configuration, this may # bypass the setting of 'PasswordAuthentication' diff --git a/sshd_config.5 b/sshd_config.5 index 3d920cc80..8857c673d 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.22 2003/08/13 08:46:31 markus Exp $ +.\" $OpenBSD: sshd_config.5,v 1.23 2003/08/22 10:56:09 markus Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -225,6 +225,19 @@ or .Dq no . The default is .Dq no . +.It Cm GSSAPIAuthentication +Specifies whether authentication based on GSSAPI may be used, either using +the result of a successful key exchange, or using GSSAPI user +authentication. +The default is +.Dq no . +Note that this option applies to protocol version 2 only. +.It Cm GSSAPICleanupCredentials +Specifies whether to automatically destroy the user's credentials cache +on logout. +The default is +.Dq yes . +Note that this option applies to protocol version 2 only. .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed -- cgit v1.2.3 From 600ad8de76e12820ed1ff0db71946b4e03d5349c Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 26 Aug 2003 12:10:48 +1000 Subject: - deraadt@cvs.openbsd.org 2003/08/24 17:36:52 [monitor.c monitor_wrap.c sshconnect2.c] 64 bit cleanups; markus ok --- ChangeLog | 5 ++++- monitor.c | 6 ++++-- monitor_wrap.c | 6 ++++-- sshconnect2.c | 6 ++++-- 4 files changed, 16 insertions(+), 7 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index e10a3c425..ba3e56d8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,9 @@ - markus@cvs.openbsd.org 2003/08/22 20:55:06 [LICENCE] add Simon Wilkinson + - deraadt@cvs.openbsd.org 2003/08/24 17:36:52 + [monitor.c monitor_wrap.c sshconnect2.c] + 64 bit cleanups; markus ok - (dtucker) [Makefile.in acconfig.h auth-krb5.c auth-pam.c auth-pam.h configure.ac defines.h gss-serv-krb5.c session.c ssh-gss.h sshconnect1.c sshconnect2.c] Add Portable GSSAPI support, patch by Simon Wilkinson. @@ -894,4 +897,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2911 2003/08/26 02:09:53 dtucker Exp $ +$Id: ChangeLog,v 1.2912 2003/08/26 02:10:48 dtucker Exp $ diff --git a/monitor.c b/monitor.c index f90a90461..e08181f74 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.46 2003/08/22 10:56:09 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.47 2003/08/24 17:36:52 deraadt Exp $"); #include @@ -1817,8 +1817,10 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m) gss_buffer_desc out = GSS_C_EMPTY_BUFFER; OM_uint32 major,minor; OM_uint32 flags = 0; /* GSI needs this */ + u_int len; - in.value = buffer_get_string(m, &in.length); + in.value = buffer_get_string(m, &len); + in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); xfree(in.value); diff --git a/monitor_wrap.c b/monitor_wrap.c index 4073905f6..82649a7cc 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.29 2003/08/22 10:56:09 markus Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.30 2003/08/24 17:36:52 deraadt Exp $"); #include #include @@ -1134,6 +1134,7 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, { Buffer m; OM_uint32 major; + u_int len; buffer_init(&m); buffer_put_string(&m, in->value, in->length); @@ -1142,7 +1143,8 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); major = buffer_get_int(&m); - out->value = buffer_get_string(&m, &out->length); + out->value = buffer_get_string(&m, &len); + out->length = len; if (flags) *flags = buffer_get_int(&m); diff --git a/sshconnect2.c b/sshconnect2.c index 558a0a749..22795395e 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.122 2003/08/22 13:20:03 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.123 2003/08/24 17:36:52 deraadt Exp $"); #include "openbsd-compat/sys-queue.h" @@ -647,12 +647,14 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; OM_uint32 status, ms; + u_int len; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; - recv_tok.value = packet_get_string(&recv_tok.length); + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; packet_check_eom(); -- cgit v1.2.3 From 1a0c0b96219b037865d624079a81ab7d88bbccc1 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 2 Sep 2003 22:51:17 +1000 Subject: - markus@cvs.openbsd.org 2003/08/28 12:54:34 [auth-krb5.c auth.h auth1.c monitor.c monitor.h monitor_wrap.c] [monitor_wrap.h readconf.c servconf.c session.c ssh_config.5] [sshconnect1.c sshd.c sshd_config sshd_config.5] remove kerberos support from ssh1, since it has been replaced with GSSAPI; but keep kerberos passwd auth for ssh1 and 2; ok djm, hin, henning, ... --- ChangeLog | 8 +- auth-krb5.c | 194 +---------------------------------------- auth.h | 3 +- auth1.c | 57 +------------ monitor.c | 50 +---------- monitor.h | 3 +- monitor_wrap.c | 37 +------- monitor_wrap.h | 9 +- readconf.c | 7 +- servconf.c | 5 +- session.c | 26 +----- ssh_config.5 | 14 +-- sshconnect1.c | 265 +-------------------------------------------------------- sshd.c | 16 +--- sshd_config | 3 +- sshd_config.5 | 12 +-- 16 files changed, 25 insertions(+), 684 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index 91e727198..b6cc55337 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,12 @@ - deraadt@cvs.openbsd.org 2003/08/24 17:36:51 [auth2-gss.c] 64 bit cleanups; markus ok + - markus@cvs.openbsd.org 2003/08/28 12:54:34 + [auth-krb5.c auth.h auth1.c monitor.c monitor.h monitor_wrap.c] + [monitor_wrap.h readconf.c servconf.c session.c ssh_config.5] + [sshconnect1.c sshd.c sshd_config sshd_config.5] + remove kerberos support from ssh1, since it has been replaced with GSSAPI; + but keep kerberos passwd auth for ssh1 and 2; ok djm, hin, henning, ... 20030829 - (bal) openbsd-compat/ clean up. Considate headers, add in Id on our @@ -918,4 +924,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2920 2003/09/02 12:14:07 djm Exp $ +$Id: ChangeLog,v 1.2921 2003/09/02 12:51:17 djm Exp $ diff --git a/auth-krb5.c b/auth-krb5.c index b9eeb5ba6..0aa5195b8 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -28,7 +28,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-krb5.c,v 1.11 2003/07/16 15:02:06 markus Exp $"); +RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -65,193 +65,6 @@ krb5_init(void *context) return (0); } -/* - * Try krb5 authentication. server_user is passed for logging purposes - * only, in auth is received ticket, in client is returned principal - * from the ticket - */ -int -auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply) -{ - krb5_error_code problem; - krb5_principal server; - krb5_ticket *ticket; - int fd, ret; - - ret = 0; - server = NULL; - ticket = NULL; - reply->length = 0; - - problem = krb5_init(authctxt); - if (problem) - goto err; - - problem = krb5_auth_con_init(authctxt->krb5_ctx, - &authctxt->krb5_auth_ctx); - if (problem) - goto err; - - fd = packet_get_connection_in(); -#ifdef HEIMDAL - problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx, &fd); -#else - problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx,fd, - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); -#endif - if (problem) - goto err; - - problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL, - KRB5_NT_SRV_HST, &server); - if (problem) - goto err; - - problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx, - auth, server, NULL, NULL, &ticket); - if (problem) - goto err; - -#ifdef HEIMDAL - problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client, - &authctxt->krb5_user); -#else - problem = krb5_copy_principal(authctxt->krb5_ctx, - ticket->enc_part2->client, - &authctxt->krb5_user); -#endif - if (problem) - goto err; - - /* if client wants mutual auth */ - problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - reply); - if (problem) - goto err; - - /* Check .k5login authorization now. */ - if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, - authctxt->pw->pw_name)) - goto err; - - if (client) - krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user, - client); - - ret = 1; - err: - if (server) - krb5_free_principal(authctxt->krb5_ctx, server); - if (ticket) - krb5_free_ticket(authctxt->krb5_ctx, ticket); - if (!ret && reply->length) { - xfree(reply->data); - memset(reply, 0, sizeof(*reply)); - } - - if (problem) { - if (authctxt->krb5_ctx != NULL) - debug("Kerberos v5 authentication failed: %s", - krb5_get_err_text(authctxt->krb5_ctx, problem)); - else - debug("Kerberos v5 authentication failed: %d", - problem); - } - - return (ret); -} - -int -auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt) -{ - krb5_error_code problem; - krb5_ccache ccache = NULL; - char *pname; - krb5_creds **creds; - - if (authctxt->pw == NULL || authctxt->krb5_user == NULL) - return (0); - - temporarily_use_uid(authctxt->pw); - -#ifdef HEIMDAL - problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache); -#else -{ - char ccname[40]; - int tmpfd; - - snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); - - if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { - logit("mkstemp(): %.100s", strerror(errno)); - problem = errno; - goto fail; - } - if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { - logit("fchmod(): %.100s", strerror(errno)); - close(tmpfd); - problem = errno; - goto fail; - } - close(tmpfd); - problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache); -} -#endif - if (problem) - goto fail; - - problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache, - authctxt->krb5_user); - if (problem) - goto fail; - -#ifdef HEIMDAL - problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - ccache, tgt); - if (problem) - goto fail; -#else - problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - tgt, &creds, NULL); - if (problem) - goto fail; - problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds); - if (problem) - goto fail; -#endif - - authctxt->krb5_fwd_ccache = ccache; - ccache = NULL; - - authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); - - problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user, - &pname); - if (problem) - goto fail; - - debug("Kerberos v5 TGT accepted (%s)", pname); - - restore_uid(); - - return (1); - - fail: - if (problem) - debug("Kerberos v5 TGT passing failed: %s", - krb5_get_err_text(authctxt->krb5_ctx, problem)); - if (ccache) - krb5_cc_destroy(authctxt->krb5_ctx, ccache); - - restore_uid(); - - return (0); -} - int auth_krb5_password(Authctxt *authctxt, const char *password) { @@ -405,11 +218,6 @@ krb5_cleanup_proc(void *context) krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; } - if (authctxt->krb5_auth_ctx) { - krb5_auth_con_free(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx); - authctxt->krb5_auth_ctx = NULL; - } if (authctxt->krb5_ctx) { krb5_free_context(authctxt->krb5_ctx); authctxt->krb5_ctx = NULL; diff --git a/auth.h b/auth.h index 6beff7cc3..358f26b7e 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.44 2003/08/22 10:56:08 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -62,7 +62,6 @@ struct Authctxt { #endif #ifdef KRB5 krb5_context krb5_ctx; - krb5_auth_context krb5_auth_ctx; krb5_ccache krb5_fwd_ccache; krb5_principal krb5_user; char *krb5_ticket_file; diff --git a/auth1.c b/auth1.c index d8b5836ba..5b1922a11 100644 --- a/auth1.c +++ b/auth1.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.50 2003/08/13 08:46:30 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -49,10 +49,6 @@ get_authname(int type) case SSH_CMSG_AUTH_TIS: case SSH_CMSG_AUTH_TIS_RESPONSE: return "challenge-response"; -#ifdef KRB5 - case SSH_CMSG_AUTH_KERBEROS: - return "kerberos"; -#endif } snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); return buf; @@ -119,47 +115,6 @@ do_authloop(Authctxt *authctxt) /* Process the packet. */ switch (type) { - -#ifdef KRB5 - case SSH_CMSG_AUTH_KERBEROS: - if (!options.kerberos_authentication) { - verbose("Kerberos authentication disabled."); - } else { - char *kdata = packet_get_string(&dlen); - packet_check_eom(); - - if (kdata[0] != 4) { /* KRB_PROT_VERSION */ - krb5_data tkt, reply; - tkt.length = dlen; - tkt.data = kdata; - - if (PRIVSEP(auth_krb5(authctxt, &tkt, - &client_user, &reply))) { - authenticated = 1; - snprintf(info, sizeof(info), - " tktuser %.100s", - client_user); - - /* Send response to client */ - packet_start( - SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) - reply.data, reply.length); - packet_send(); - packet_write_wait(); - - if (reply.length) - xfree(reply.data); - } - } - xfree(kdata); - } - break; - case SSH_CMSG_HAVE_KERBEROS_TGT: - packet_send_debug("Kerberos TGT passing disabled before authentication."); - break; -#endif - case SSH_CMSG_AUTH_RHOSTS_RSA: if (!options.rhosts_rsa_authentication) { verbose("Rhosts with RSA authentication disabled."); @@ -337,16 +292,6 @@ do_authentication(void) if ((style = strchr(user, ':')) != NULL) *style++ = '\0'; -#ifdef KRB5 - /* XXX - SSH.com Kerberos v5 braindeath. */ - if ((datafellows & SSH_BUG_K5USER) && - options.kerberos_authentication) { - char *p; - if ((p = strchr(user, '@')) != NULL) - *p = '\0'; - } -#endif - authctxt = authctxt_new(); authctxt->user = user; authctxt->style = style; diff --git a/monitor.c b/monitor.c index e08181f74..9ea7b93b9 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.47 2003/08/24 17:36:52 deraadt Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $"); #include @@ -130,9 +130,6 @@ int mm_answer_pam_respond(int, Buffer *); int mm_answer_pam_free_ctx(int, Buffer *); #endif -#ifdef KRB5 -int mm_answer_krb5(int, Buffer *); -#endif #ifdef GSSAPI int mm_answer_gss_setup_ctx(int, Buffer *); int mm_answer_gss_accept_ctx(int, Buffer *); @@ -192,9 +189,6 @@ struct mon_table mon_dispatch_proto20[] = { #endif {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, -#ifdef KRB5 - {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, -#endif #ifdef GSSAPI {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, @@ -236,9 +230,6 @@ struct mon_table mon_dispatch_proto15[] = { {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, -#endif -#ifdef KRB5 - {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, #endif {0, 0, NULL} }; @@ -1470,45 +1461,6 @@ mm_answer_rsa_response(int socket, Buffer *m) return (success); } -#ifdef KRB5 -int -mm_answer_krb5(int socket, Buffer *m) -{ - krb5_data tkt, reply; - char *client_user; - u_int len; - int success; - - /* use temporary var to avoid size issues on 64bit arch */ - tkt.data = buffer_get_string(m, &len); - tkt.length = len; - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb5(authctxt, &tkt, &client_user, &reply); - - if (tkt.length) - xfree(tkt.data); - - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client_user); - buffer_put_string(m, reply.data, reply.length); - if (client_user) - xfree(client_user); - if (reply.length) - xfree(reply.data); - } - mm_request_send(socket, MONITOR_ANS_KRB5, m); - - auth_method = "kerberos"; - - return success; -} -#endif - int mm_answer_term(int socket, Buffer *req) { diff --git a/monitor.h b/monitor.h index da33ed613..2461156c7 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.10 2003/08/22 10:56:09 markus Exp $ */ +/* $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -49,7 +49,6 @@ enum monitor_reqtype { MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED, MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE, MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, - MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP, MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, diff --git a/monitor_wrap.c b/monitor_wrap.c index 82649a7cc..4034d569c 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.30 2003/08/24 17:36:52 deraadt Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $"); #include #include @@ -1071,41 +1071,6 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) return (success); } -#ifdef KRB5 -int -mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) -{ - krb5_data *tkt, *reply; - Buffer m; - int success; - - debug3("%s entering", __func__); - tkt = (krb5_data *) argp; - reply = (krb5_data *) resp; - - buffer_init(&m); - buffer_put_string(&m, tkt->data, tkt->length); - - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m); - mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m); - - success = buffer_get_int(&m); - if (success) { - u_int len; - - *userp = buffer_get_string(&m, NULL); - reply->data = buffer_get_string(&m, &len); - reply->length = len; - } else { - memset(reply, 0, sizeof(*reply)); - *userp = NULL; - } - - buffer_free(&m); - return (success); -} -#endif /* KRB5 */ - #ifdef GSSAPI OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) diff --git a/monitor_wrap.h b/monitor_wrap.h index c6251924a..5e0334588 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.10 2003/08/22 10:56:09 markus Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -96,13 +96,6 @@ int mm_bsdauth_respond(void *, u_int, char **); int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); -/* auth_krb */ -#ifdef KRB5 -/* auth and reply are really krb5_data objects, but we don't want to - * include all of the krb5 headers here */ -int mm_auth_krb5(void *authctxt, void *auth, char **client, void *reply); -#endif - /* zlib allocation hooks */ void *mm_zalloc(struct mm_master *, u_int, u_int); diff --git a/readconf.c b/readconf.c index 9447cb55f..281b66872 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.118 2003/08/22 10:56:09 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.119 2003/08/28 12:54:34 markus Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -132,13 +132,8 @@ static struct { { "challengeresponseauthentication", oChallengeResponseAuthentication }, { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ -#ifdef KRB5 - { "kerberosauthentication", oKerberosAuthentication }, - { "kerberostgtpassing", oKerberosTgtPassing }, -#else { "kerberosauthentication", oUnsupported }, { "kerberostgtpassing", oUnsupported }, -#endif { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, diff --git a/servconf.c b/servconf.c index e13309388..6051918c2 100644 --- a/servconf.c +++ b/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.125 2003/08/22 10:56:09 markus Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.126 2003/08/28 12:54:34 markus Exp $"); #include "ssh.h" #include "log.h" @@ -304,13 +304,12 @@ static struct { { "kerberosauthentication", sKerberosAuthentication }, { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, { "kerberosticketcleanup", sKerberosTicketCleanup }, - { "kerberostgtpassing", sKerberosTgtPassing }, #else { "kerberosauthentication", sUnsupported }, { "kerberosorlocalpasswd", sUnsupported }, { "kerberosticketcleanup", sUnsupported }, - { "kerberostgtpassing", sUnsupported }, #endif + { "kerberostgtpassing", sUnsupported }, { "afstokenpassing", sUnsupported }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication }, diff --git a/session.c b/session.c index 6ba0233e5..351b40c13 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.161 2003/08/22 10:56:09 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.162 2003/08/28 12:54:34 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -332,30 +332,6 @@ do_authenticated1(Authctxt *authctxt) success = 1; break; -#ifdef KRB5 - case SSH_CMSG_HAVE_KERBEROS_TGT: - if (!options.kerberos_tgt_passing) { - verbose("Kerberos TGT passing disabled."); - } else { - char *kdata = packet_get_string(&dlen); - packet_check_eom(); - - /* XXX - 0x41, used for AFS */ - if (kdata[0] != 0x41) { - krb5_data tgt; - tgt.data = kdata; - tgt.length = dlen; - - if (auth_krb5_tgt(s->authctxt, &tgt)) - success = 1; - else - verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user); - } - xfree(kdata); - } - break; -#endif - case SSH_CMSG_EXEC_SHELL: case SSH_CMSG_EXEC_CMD: if (type == SSH_CMSG_EXEC_CMD) { diff --git a/ssh_config.5 b/ssh_config.5 index f99562b96..b20452ce2 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.18 2003/08/22 10:56:09 markus Exp $ +.\" $OpenBSD: ssh_config.5,v 1.19 2003/08/28 12:54:34 markus Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -407,18 +407,6 @@ This is important in scripts, and many users want it too. .Pp To disable keepalives, the value should be set to .Dq no . -.It Cm KerberosAuthentication -Specifies whether Kerberos authentication will be used. -The argument to this keyword must be -.Dq yes -or -.Dq no . -.It Cm KerberosTgtPassing -Specifies whether a Kerberos TGT will be forwarded to the server. -The argument to this keyword must be -.Dq yes -or -.Dq no . .It Cm LocalForward Specifies that a TCP/IP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine. diff --git a/sshconnect1.c b/sshconnect1.c index 5935e8b77..2f89964ec 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -13,15 +13,11 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.55 2003/08/13 08:46:31 markus Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.56 2003/08/28 12:54:34 markus Exp $"); #include #include -#ifdef KRB5 -#include -#endif - #include "ssh.h" #include "ssh1.h" #include "xmalloc.h" @@ -370,233 +366,6 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key) return 0; } -#ifdef KRB5 -static int -try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) -{ - krb5_error_code problem; - const char *tkfile; - struct stat buf; - krb5_ccache ccache = NULL; - const char *remotehost; - krb5_data ap; - int type; - krb5_ap_rep_enc_part *reply = NULL; - int ret; - - memset(&ap, 0, sizeof(ap)); - - problem = krb5_init_context(context); - if (problem) { - debug("Kerberos v5: krb5_init_context failed"); - ret = 0; - goto out; - } - - problem = krb5_auth_con_init(*context, auth_context); - if (problem) { - debug("Kerberos v5: krb5_auth_con_init failed"); - ret = 0; - goto out; - } - -#ifndef HEIMDAL - problem = krb5_auth_con_setflags(*context, *auth_context, - KRB5_AUTH_CONTEXT_RET_TIME); - if (problem) { - debug("Keberos v5: krb5_auth_con_setflags failed"); - ret = 0; - goto out; - } -#endif - - tkfile = krb5_cc_default_name(*context); - if (strncmp(tkfile, "FILE:", 5) == 0) - tkfile += 5; - - if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) { - debug("Kerberos v5: could not get default ccache (permission denied)."); - ret = 0; - goto out; - } - - problem = krb5_cc_default(*context, &ccache); - if (problem) { - debug("Kerberos v5: krb5_cc_default failed: %s", - krb5_get_err_text(*context, problem)); - ret = 0; - goto out; - } - - remotehost = get_canonical_hostname(1); - - problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED, - "host", remotehost, NULL, ccache, &ap); - if (problem) { - debug("Kerberos v5: krb5_mk_req failed: %s", - krb5_get_err_text(*context, problem)); - ret = 0; - goto out; - } - - packet_start(SSH_CMSG_AUTH_KERBEROS); - packet_put_string((char *) ap.data, ap.length); - packet_send(); - packet_write_wait(); - - xfree(ap.data); - ap.length = 0; - - type = packet_read(); - switch (type) { - case SSH_SMSG_FAILURE: - /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ - debug("Kerberos v5 authentication failed."); - ret = 0; - break; - - case SSH_SMSG_AUTH_KERBEROS_RESPONSE: - /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ - debug("Kerberos v5 authentication accepted."); - - /* Get server's response. */ - ap.data = packet_get_string((unsigned int *) &ap.length); - packet_check_eom(); - /* XXX je to dobre? */ - - problem = krb5_rd_rep(*context, *auth_context, &ap, &reply); - if (problem) { - ret = 0; - } - ret = 1; - break; - - default: - packet_disconnect("Protocol error on Kerberos v5 response: %d", - type); - ret = 0; - break; - - } - - out: - if (ccache != NULL) - krb5_cc_close(*context, ccache); - if (reply != NULL) - krb5_free_ap_rep_enc_part(*context, reply); - if (ap.length > 0) -#ifdef HEIMDAL - krb5_data_free(&ap); -#else - krb5_free_data_contents(*context, &ap); -#endif - - return (ret); -} - -static void -send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) -{ - int fd, type; - krb5_error_code problem; - krb5_data outbuf; - krb5_ccache ccache = NULL; - krb5_creds creds; -#ifdef HEIMDAL - krb5_kdc_flags flags; -#else - int forwardable; -#endif - const char *remotehost; - - memset(&creds, 0, sizeof(creds)); - memset(&outbuf, 0, sizeof(outbuf)); - - fd = packet_get_connection_in(); - -#ifdef HEIMDAL - problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd); -#else - problem = krb5_auth_con_genaddrs(context, auth_context, fd, - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); -#endif - if (problem) - goto out; - - problem = krb5_cc_default(context, &ccache); - if (problem) - goto out; - - problem = krb5_cc_get_principal(context, ccache, &creds.client); - if (problem) - goto out; - - remotehost = get_canonical_hostname(1); - -#ifdef HEIMDAL - problem = krb5_build_principal(context, &creds.server, - strlen(creds.client->realm), creds.client->realm, - "krbtgt", creds.client->realm, NULL); -#else - problem = krb5_build_principal(context, &creds.server, - creds.client->realm.length, creds.client->realm.data, - "host", remotehost, NULL); -#endif - if (problem) - goto out; - - creds.times.endtime = 0; - -#ifdef HEIMDAL - flags.i = 0; - flags.b.forwarded = 1; - flags.b.forwardable = krb5_config_get_bool(context, NULL, - "libdefaults", "forwardable", NULL); - problem = krb5_get_forwarded_creds(context, auth_context, - ccache, flags.i, remotehost, &creds, &outbuf); -#else - forwardable = 1; - problem = krb5_fwd_tgt_creds(context, auth_context, remotehost, - creds.client, creds.server, ccache, forwardable, &outbuf); -#endif - - if (problem) - goto out; - - packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); - packet_put_string((char *)outbuf.data, outbuf.length); - packet_send(); - packet_write_wait(); - - type = packet_read(); - - if (type == SSH_SMSG_SUCCESS) { - char *pname; - - krb5_unparse_name(context, creds.client, &pname); - debug("Kerberos v5 TGT forwarded (%s).", pname); - xfree(pname); - } else - debug("Kerberos v5 TGT forwarding failed."); - - return; - - out: - if (problem) - debug("Kerberos v5 TGT forwarding failed: %s", - krb5_get_err_text(context, problem)); - if (creds.client) - krb5_free_principal(context, creds.client); - if (creds.server) - krb5_free_principal(context, creds.server); - if (ccache) - krb5_cc_close(context, ccache); - if (outbuf.data) - xfree(outbuf.data); -} -#endif /* KRB5 */ - /* * Tries to authenticate with any string-based challenge/response system. * Note that the client code is not tied to s/key or TIS. @@ -885,10 +654,6 @@ void ssh_userauth1(const char *local_user, const char *server_user, char *host, Sensitive *sensitive) { -#ifdef KRB5 - krb5_context context = NULL; - krb5_auth_context auth_context = NULL; -#endif int i, type; if (supported_authentications == 0) @@ -913,21 +678,6 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type); -#ifdef KRB5 - if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && - options.kerberos_authentication) { - debug("Trying Kerberos v5 authentication."); - - if (try_krb5_authentication(&context, &auth_context)) { - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type); - } - } -#endif /* KRB5 */ - /* * Try .rhosts or /etc/hosts.equiv authentication with RSA host * authentication. @@ -981,18 +731,5 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, /* NOTREACHED */ success: -#ifdef KRB5 - /* Try Kerberos v5 TGT passing. */ - if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && - options.kerberos_tgt_passing && context && auth_context) { - if (options.cipher == SSH_CIPHER_NONE) - logit("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - send_krb5_tgt(context, auth_context); - } - if (auth_context) - krb5_auth_con_free(context, auth_context); - if (context) - krb5_free_context(context); -#endif return; /* need statement after label */ } diff --git a/sshd.c b/sshd.c index 8d04f6a74..47df9caf1 100644 --- a/sshd.c +++ b/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.275 2003/08/13 08:46:31 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.276 2003/08/28 12:54:34 markus Exp $"); #include #include @@ -1463,14 +1463,6 @@ main(int ac, char **av) sshd_exchange_identification(sock_in, sock_out); -#ifdef KRB5 - if (!packet_connection_is_ipv4() && - options.kerberos_authentication) { - debug("Kerberos Authentication disabled, only available for IPv4."); - options.kerberos_authentication = 0; - } -#endif - packet_set_nonblocking(); /* prepare buffers to collect authentication messages */ @@ -1634,12 +1626,6 @@ do_ssh1_kex(void) auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; if (options.rsa_authentication) auth_mask |= 1 << SSH_AUTH_RSA; -#ifdef KRB5 - if (options.kerberos_authentication) - auth_mask |= 1 << SSH_AUTH_KERBEROS; - if (options.kerberos_tgt_passing) - auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; -#endif if (options.challenge_response_authentication == 1) auth_mask |= 1 << SSH_AUTH_TIS; if (options.password_authentication) diff --git a/sshd_config b/sshd_config index 294539096..dd53f1057 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.64 2003/08/22 10:56:09 markus Exp $ +# $OpenBSD: sshd_config,v 1.65 2003/08/28 12:54:34 markus Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -61,7 +61,6 @@ #KerberosAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes -#KerberosTgtPassing no # GSSAPI options #GSSAPIAuthentication no diff --git a/sshd_config.5 b/sshd_config.5 index 8857c673d..577605f3e 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.23 2003/08/22 10:56:09 markus Exp $ +.\" $OpenBSD: sshd_config.5,v 1.24 2003/08/28 12:54:34 markus Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -316,11 +316,9 @@ This avoids infinitely hanging sessions. To disable keepalives, the value should be set to .Dq no . .It Cm KerberosAuthentication -Specifies whether Kerberos authentication is allowed. -This can be in the form of a Kerberos ticket, or if +Specifies whether the password provided by the user for .Cm PasswordAuthentication -is yes, the password provided by the user will be validated through -the Kerberos KDC. +will be validated through the Kerberos KDC. To use this option, the server needs a Kerberos servtab which allows the verification of the KDC's identity. Default is @@ -332,10 +330,6 @@ such as .Pa /etc/passwd . Default is .Dq yes . -.It Cm KerberosTgtPassing -Specifies whether a Kerberos TGT may be forwarded to the server. -Default is -.Dq no . .It Cm KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket cache file on logout. -- cgit v1.2.3 From 856f0be66908352828bb595f7ad5213623c0c610 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 3 Sep 2003 07:32:45 +1000 Subject: - markus@cvs.openbsd.org 2003/08/26 09:58:43 [auth-passwd.c auth.c auth.h auth1.c auth2-none.c auth2-passwd.c] [auth2.c monitor.c] fix passwd auth for 'username leaks via timing'; with djm@, original patches from solar --- ChangeLog | 10 +++++++++- auth-passwd.c | 44 ++++++++++++++++++++++---------------------- auth.c | 23 ++++++++++++++++++++++- auth.h | 4 +++- auth1.c | 4 +++- auth2-none.c | 4 ++-- auth2-passwd.c | 4 ++-- auth2.c | 3 ++- monitor.c | 2 +- 9 files changed, 66 insertions(+), 32 deletions(-) (limited to 'monitor.c') diff --git a/ChangeLog b/ChangeLog index ea6aaedb1..f91e452d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +20030903 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/26 09:58:43 + [auth-passwd.c auth.c auth.h auth1.c auth2-none.c auth2-passwd.c] + [auth2.c monitor.c] + fix passwd auth for 'username leaks via timing'; with djm@, original + patches from solar + 20030902 - (djm) OpenBSD CVS Sync - deraadt@cvs.openbsd.org 2003/08/24 17:36:51 @@ -968,4 +976,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2937 2003/09/02 13:33:42 djm Exp $ +$Id: ChangeLog,v 1.2938 2003/09/02 21:32:45 djm Exp $ diff --git a/auth-passwd.c b/auth-passwd.c index a5d23b6bf..57a2d3620 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-passwd.c,v 1.28 2003/07/22 13:35:22 markus Exp $"); +RCSID("$OpenBSD: auth-passwd.c,v 1.29 2003/08/26 09:58:43 markus Exp $"); #include "packet.h" #include "log.h" @@ -62,25 +62,22 @@ auth_password(Authctxt *authctxt, const char *password) /* deny if no user. */ if (pw == NULL) - ok = 0; + return 0; #ifndef HAVE_CYGWIN if (pw && pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) ok = 0; #endif if (*password == '\0' && options.permit_empty_passwd == 0) - ok = 0; - - if (!ok) return 0; #if defined(HAVE_OSF_SIA) - return auth_sia_password(authctxt, password); + return auth_sia_password(authctxt, password) && ok; #else # ifdef KRB5 if (options.kerberos_authentication == 1) { int ret = auth_krb5_password(authctxt, password); if (ret == 1 || ret == 0) - return ret; + return ret && ok; /* Fall back to ordinary passwd authentication. */ } # endif @@ -89,30 +86,32 @@ auth_password(Authctxt *authctxt, const char *password) HANDLE hToken = cygwin_logon_user(pw, password); if (hToken == INVALID_HANDLE_VALUE) - return (0); + return 0; cygwin_set_impersonation_token(hToken); - return (1); + return ok; } # endif # ifdef WITH_AIXAUTHENTICATE { - char *authmsg; + char *authmsg = NULL; int reenter = 1; - int authsuccess = (authenticate(pw->pw_name, password, - &reenter, &authmsg) == 0); - aix_remove_embedded_newlines(authmsg); + int authsuccess = 0; - if (authsuccess) { + if (authenticate(pw->pw_name, password, &reenter, + &authmsg) == 0 && ok) { char *msg; char *host = (char *)get_canonical_hostname(options.use_dns); + authsuccess = 1; + aix_remove_embedded_newlines(authmsg); + debug3("AIX/authenticate succeeded for user %s: %.100s", pw->pw_name, authmsg); /* No pty yet, so just label the line as "ssh" */ if (loginsuccess(authctxt->user, host, "ssh", - &msg) == 0){ + &msg) == 0) { if (msg != NULL) { debug("%s: msg %s", __func__, msg); buffer_append(&loginmsg, msg, @@ -120,14 +119,15 @@ auth_password(Authctxt *authctxt, const char *password) xfree(msg); } } - } else + } else { debug3("AIX/authenticate failed for user %s: %.100s", pw->pw_name, authmsg); + } if (authmsg != NULL) xfree(authmsg); - return (authsuccess); + return authsuccess; } # endif # ifdef BSD_AUTH @@ -135,15 +135,15 @@ auth_password(Authctxt *authctxt, const char *password) (char *)password) == 0) return 0; else - return 1; + return ok; # else { - char *pw_password = shadow_pw(pw); + /* Just use the supplied fake password if authctxt is invalid */ + char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; /* Check for users with no password. */ - /* XXX Reverted back to OpenBSD, why was this changed again? */ if (strcmp(pw_password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) - return 1; + return ok; else { /* Encrypt the candidate password using the proper salt. */ char *encrypted_password = xcrypt(password, @@ -153,7 +153,7 @@ auth_password(Authctxt *authctxt, const char *password) * Authentication is accepted if the encrypted passwords * are identical. */ - return (strcmp(encrypted_password, pw_password) == 0); + return (strcmp(encrypted_password, pw_password) == 0) && ok; } } diff --git a/auth.c b/auth.c index f645cc112..46e495adf 100644 --- a/auth.c +++ b/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.48 2003/06/02 09:17:34 markus Exp $"); +RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $"); #ifdef HAVE_LOGIN_H #include @@ -589,3 +589,24 @@ auth_debug_reset(void) auth_debug_init = 1; } } + +struct passwd * +fakepw(void) +{ + static struct passwd fake; + + memset(&fake, 0, sizeof(fake)); + fake.pw_name = "NOUSER"; + fake.pw_passwd = + "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; + fake.pw_gecos = "NOUSER"; + fake.pw_uid = -1; + fake.pw_gid = -1; +#ifdef HAVE_PW_CLASS_IN_PASSWD + fake.pw_class = ""; +#endif + fake.pw_dir = "/nonexist"; + fake.pw_shell = "/nonexist"; + + return (&fake); +} diff --git a/auth.h b/auth.h index 358f26b7e..130a27da7 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.45 2003/08/26 09:58:43 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -173,6 +173,8 @@ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); void auth_debug_send(void); void auth_debug_reset(void); +struct passwd *fakepw(void); + #define AUTH_FAIL_MAX 6 #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) #define AUTH_FAIL_MSG "Too many authentication failures for %.100s" diff --git a/auth1.c b/auth1.c index 5b1922a11..dfe944dd1 100644 --- a/auth1.c +++ b/auth1.c @@ -299,8 +299,10 @@ do_authentication(void) /* Verify that the user is a valid user. */ if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) authctxt->valid = 1; - else + else { debug("do_authentication: illegal user %s", user); + authctxt->pw = fakepw(); + } setproctitle("%s%s", authctxt->pw ? user : "unknown", use_privsep ? " [net]" : ""); diff --git a/auth2-none.c b/auth2-none.c index 3332f4f83..c342addec 100644 --- a/auth2-none.c +++ b/auth2-none.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-none.c,v 1.5 2003/07/31 09:21:02 markus Exp $"); +RCSID("$OpenBSD: auth2-none.c,v 1.6 2003/08/26 09:58:43 markus Exp $"); #include "auth.h" #include "xmalloc.h" @@ -100,7 +100,7 @@ userauth_none(Authctxt *authctxt) if (check_nt_auth(1, authctxt->pw) == 0) return(0); #endif - if (options.password_authentication && authctxt->valid) + if (options.password_authentication) return (PRIVSEP(auth_password(authctxt, ""))); return (0); } diff --git a/auth2-passwd.c b/auth2-passwd.c index 8eb18f2e3..67fb4c921 100644 --- a/auth2-passwd.c +++ b/auth2-passwd.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-passwd.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); +RCSID("$OpenBSD: auth2-passwd.c,v 1.4 2003/08/26 09:58:43 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -47,7 +47,7 @@ userauth_passwd(Authctxt *authctxt) logit("password change not supported"); password = packet_get_string(&len); packet_check_eom(); - if (PRIVSEP(auth_password(authctxt, password)) == 1 && authctxt->valid + if (PRIVSEP(auth_password(authctxt, password)) == 1 #ifdef HAVE_CYGWIN && check_nt_auth(1, authctxt->pw) #endif diff --git a/auth2.c b/auth2.c index efff03a52..41e77efdc 100644 --- a/auth2.c +++ b/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.101 2003/08/22 13:22:27 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -168,6 +168,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) #endif } else { logit("input_userauth_request: illegal user %s", user); + authctxt->pw = fakepw(); #ifdef USE_PAM if (options.use_pam) PRIVSEP(start_pam(user)); diff --git a/monitor.c b/monitor.c index 9ea7b93b9..e5656470d 100644 --- a/monitor.c +++ b/monitor.c @@ -649,7 +649,7 @@ mm_answer_authpassword(int socket, Buffer *m) passwd = buffer_get_string(m, &plen); /* Only authenticate if the context is valid */ authenticated = options.password_authentication && - auth_password(authctxt, passwd) && authctxt->valid; + auth_password(authctxt, passwd); memset(passwd, 0, strlen(passwd)); xfree(passwd); -- cgit v1.2.3