Bugzilla – Attachment 1452 Details for
Bug 1438
Adds an out-of-band challenge (OBC) authentication method (via kbdint)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Adds an out-of-band challenge (obc) device to kbdint
openssh-4.7p1-kbdint-obc.patch (text/plain), 32.08 KB, created by
Paul Sery
on 2008-02-06 16:39:46 AEDT
(
hide
)
Description:
Adds an out-of-band challenge (obc) device to kbdint
Filename:
MIME Type:
Creator:
Paul Sery
Created:
2008-02-06 16:39:46 AEDT
Size:
32.08 KB
patch
obsolete
>--- openssh-4.7p1/Makefile.in 2007-06-10 22:01:42.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/Makefile.in 2008-02-05 22:05:58.000000000 -0700 >@@ -79,10 +79,11 @@ > SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ > sshpty.o sshlogin.o servconf.o serverloop.o \ > auth.o auth1.o auth2.o auth-options.o session.o \ > auth-chall.o auth2-chall.o groupaccess.o \ > auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ >+ auth-obc.o \ > auth2-none.o auth2-passwd.o auth2-pubkey.o \ > monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ > auth-krb5.o \ > auth2-gss.o gss-serv.o gss-serv-krb5.o \ > loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ >--- openssh-4.7p1/config.h.in 2007-09-04 00:50:04.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/config.h.in 2008-02-05 22:05:58.000000000 -0700 >@@ -1222,10 +1222,13 @@ > #undef SIZEOF_SHORT_INT > > /* Define if you want S/Key support */ > #undef SKEY > >+/* Define if you want OBC support */ >+#undef USE_OBC >+ > /* Define if your skeychallenge() function takes 4 arguments (NetBSD) */ > #undef SKEYCHALLENGE_4ARG > > /* Define if you want smartcard support */ > #undef SMARTCARD >--- openssh-4.7p1/configure.ac 2007-08-09 22:36:12.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/configure.ac 2008-02-05 22:05:58.000000000 -0700 >@@ -1091,10 +1091,25 @@ > ) > fi > ] > ) > >+# Check whether user wants OBC support >+OBC_MSG="no" >+AC_ARG_WITH(obc, >+ [ --with-obc Enable out-of-band challenge support], >+ [ >+ if test "x$withval" != "xno" ; then >+ >+ AC_DEFINE(USE_OBC, 1, [Define if you want OBC support]) >+ OBC_MSG="yes" >+ >+ AC_MSG_CHECKING([for out-of-band (obc) support]) >+ fi >+ ] >+) >+ > # Check whether user wants TCP wrappers support > TCPW_MSG="no" > AC_ARG_WITH(tcp-wrappers, > [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)], > [ >@@ -4029,10 +4044,11 @@ > echo " OSF SIA support: $SIA_MSG" > echo " KerberosV support: $KRB5_MSG" > echo " SELinux support: $SELINUX_MSG" > echo " Smartcard support: $SCARD_MSG" > echo " S/KEY support: $SKEY_MSG" >+echo " OBC support: $OBC_MSG" > echo " TCP Wrappers support: $TCPW_MSG" > echo " MD5 password support: $MD5_MSG" > echo " libedit support: $LIBEDIT_MSG" > echo " Solaris process contract support: $SPC_MSG" > echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" >--- openssh-4.7p1/auth2-chall.c 2007-01-04 22:30:16.000000000 -0700 >+++ openssh-4.7p1-kbdint-obc/auth2-chall.c 2008-02-05 22:05:58.000000000 -0700 >@@ -57,10 +57,13 @@ > extern KbdintDevice sshpam_device; > #endif > #ifdef SKEY > extern KbdintDevice skey_device; > #endif >+#ifdef USE_OBC >+extern KbdintDevice obc_device; >+#endif > #endif > > KbdintDevice *devices[] = { > #ifdef BSD_AUTH > &bsdauth_device, >@@ -69,10 +72,13 @@ > &sshpam_device, > #endif > #ifdef SKEY > &skey_device, > #endif >+#ifdef USE_OBC >+ &obc_device, >+#endif > #endif > NULL > }; > > typedef struct KbdintAuthctxt KbdintAuthctxt; >@@ -88,11 +94,10 @@ > void > remove_kbdint_device(const char *devname) > { > int i, j; > >- for (i = 0; devices[i] != NULL; i++) > if (strcmp(devices[i]->name, devname) == 0) { > for (j = i; devices[j] != NULL; j++) > devices[j] = devices[j+1]; > i--; > } >@@ -104,10 +109,11 @@ > { > KbdintAuthctxt *kbdintctxt; > Buffer b; > int i; > >+ > #ifdef USE_PAM > if (!options.use_pam) > remove_kbdint_device("pam"); > #endif > >@@ -193,11 +199,11 @@ > authctxt->user ? authctxt->user : "<nouser>", > devs ? devs : "<no devs>"); > > if (authctxt->user == NULL || !devs) > return 0; >- if (authctxt->kbdintctxt == NULL) >+ if (authctxt->kbdintctxt == NULL) > authctxt->kbdintctxt = kbdint_alloc(devs); > return auth2_challenge_start(authctxt); > } > > /* unregister kbd-int callbacks and context */ >@@ -350,11 +356,11 @@ > } > > void > privsep_challenge_enable(void) > { >-#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY) >+#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY) || defined(USE_OBC) > int n = 0; > #endif > #ifdef BSD_AUTH > extern KbdintDevice mm_bsdauth_device; > #endif >@@ -362,17 +368,23 @@ > extern KbdintDevice mm_sshpam_device; > #endif > #ifdef SKEY > extern KbdintDevice mm_skey_device; > #endif >+#ifdef USE_OBC >+ extern KbdintDevice mm_obc_device; >+#endif > > #ifdef BSD_AUTH > devices[n++] = &mm_bsdauth_device; > #else > #ifdef USE_PAM > devices[n++] = &mm_sshpam_device; > #endif > #ifdef SKEY > devices[n++] = &mm_skey_device; > #endif >+#ifdef USE_OBC >+ devices[n++] = &mm_obc_device; >+#endif > #endif > } >--- openssh-4.7p1/auth.h 2006-08-18 08:32:46.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/auth.h 2008-02-05 22:05:58.000000000 -0700 >@@ -69,10 +69,11 @@ > char *krb5_ticket_file; > char *krb5_ccname; > #endif > Buffer *loginmsg; > void *methoddata; >+ char *obc; > }; > /* > * Every authentication method has to handle authentication requests for > * non-existing users, or for users that are not allowed to login. In this > * case 'valid' is set to 0, but 'user' points to the username requested by >@@ -153,10 +154,13 @@ > void auth2_challenge_stop(Authctxt *); > int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); > int bsdauth_respond(void *, u_int, char **); > int skey_query(void *, char **, char **, u_int *, char ***, u_int **); > int skey_respond(void *, u_int, char **); >+int obc_challenge(Authctxt *); >+int obc_auth(Authctxt *); >+int obc_send(char *, char *, char *); > > int allowed_user(struct passwd *); > struct passwd * getpwnamallow(const char *user); > > char *get_challenge(Authctxt *); >--- openssh-4.7p1/auth-obc.c 1969-12-31 17:00:00.000000000 -0700 >+++ openssh-4.7p1-kbdint-obc/auth-obc.c 2008-02-05 22:05:58.000000000 -0700 >@@ -0,0 +1,370 @@ >+/* $OpenBSD: auth-obc.c,v 0.5 2008/02/04 07:55:00 pgsery Exp $ */ >+/* >+ * Copyright (c) 2008 Paul Sery. 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. >+ */ >+ >+/* This code was derived from Markus Friedl's auth-skey.c and >+ Daniel B. Cid's Ossec/sendmail.c */ >+ >+#include "includes.h" >+ >+#include <sys/types.h> >+ >+#include <string.h> >+#include <stdarg.h> >+ >+#include "xmalloc.h" >+#include "packet.h" >+#include "log.h" >+#include "key.h" >+#include "hostfile.h" >+#include "auth.h" >+#include "buffer.h" >+#ifdef GSSAPI >+#include "ssh-gss.h" >+#endif >+#include "monitor_wrap.h" >+#include "servconf.h" >+#include "uidswap.h" >+ >+#include <netinet/in.h> >+#include <netdb.h> >+#include <arpa/inet.h> >+#include <sys/socket.h> >+#include <sys/types.h> >+#include <string.h> >+#include <stdarg.h> >+#include <unistd.h> >+#include "includes.h" >+#include "log.h" >+ >+/* import */ >+extern ServerOptions options; >+ >+#define OS_SIZE_1024 1024 >+ >+#define OS_SUCCESS 0 /* Success */ >+#define OS_INVALID -1 /* Invalid entry */ >+#define OS_NOTFOUND -2 /* Entry not found */ >+#define OS_FILERR -3 /* Error in the file */ >+#define OS_SIZELIM -4 /* Size limit problem */ >+#define OS_CFGERR -5 /* Configuration error */ >+#define OS_SOCKTERR -6 /* Socket error */ >+#define OS_MISVALUE -7 /* There are values missing */ >+#define OS_CONNERR -8 /* Connection failed */ >+#define OS_UNDEF -9 /* Uknown error */ >+#define OS_MEMERR -10 /* Memory Error */ >+#define OS_SOCKBUSY -11 /* Busy socket -- try again */ >+ >+#define OS_ENDFILE -20 /* End of file */ >+#define OS_FINISH -21 /* Finished this task */ >+ >+ >+/* Return codes (from SMTP server) */ >+#define VALIDBANNER "220" >+#define VALIDMAIL "250" >+#define VALIDDATA "354" >+ >+/* Default values use to connect */ >+#define SMTP_DEFAULT_PORT "25" >+#define HELOMSG "Helo openssh\r\n" >+#define MAILFROM "Mail From: <%s>\r\n" >+#define RCPTTO "Rcpt To: <%s>\r\n" >+#define DATAMSG "DATA\r\n" >+#define FROM "From: <%s>\r\n" >+#define TO "To: <%s>\r\n" >+#define CC "Cc: <%s>\r\n" >+#define SUBJECT "Subject: %s\r\n" >+#define ENDDATA "\r\n.\r\n" >+#define QUITMSG "QUIT\r\n" >+ >+void >+display_ip(struct addrinfo *ip) >+{ >+ struct sockaddr_in *sa = (struct sockaddr_in *) ip->ai_addr; >+ struct in_addr *inadr = (struct in_addr *) &sa->sin_addr.s_addr; >+ debug3("challenge smtp server ip: %-16s", inet_ntoa(*inadr)); >+ if (ip->ai_canonname && *ip->ai_canonname) >+ debug3("canonical name: %s", ip->ai_canonname); >+} >+ >+char * >+obc_recv_tcp(int socket, int sizet) >+{ >+ char *ret; >+ int retsize=0; >+ >+ ret = (char *) calloc((sizet), sizeof(char)); >+ if(ret == NULL) >+ return(NULL); >+ >+ if((retsize = recv(socket, ret, sizet-1,0)) <= 0) >+ return(NULL); >+ >+ return(ret); >+} >+ >+void >+obc_send_tcp(int socket, char *type, char *msg, int size) >+{ >+ int result; >+ char snd_msg[128]; >+ >+ if (size) { >+ memset(snd_msg,'\0',size); >+ snprintf(snd_msg,size+1, type, msg); >+ result = send(socket, snd_msg, strlen(snd_msg),0); >+ } else { >+ result = send(socket, type, strlen(type),0); >+ } >+ >+ if (result == -1) >+ error("obc send tcp: %d",OS_SOCKTERR); >+} >+ >+int >+obc_connect_smtp(char *smtp_server, char *port) >+{ >+ int err, sock, result; >+ struct addrinfo hints, *ip_info, *ip; >+ >+ memset(&hints, 0, sizeof(struct addrinfo)); >+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ >+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ >+ hints.ai_flags = 0; >+ hints.ai_protocol = 0; /* Any protocol */ >+ >+ if ( (err = getaddrinfo(smtp_server, "25", &hints, &ip_info) != 0) ) { >+ debug3("%s: getaddrinfo %s\n", __func__, gai_strerror(err)); >+ return(-1); >+ } >+ >+ for (ip = ip_info; ip != NULL; ip = ip->ai_next) { >+ display_ip(ip); >+ if ( (sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0) { >+ debug3("%s: can't open socket %d", __func__, sock); >+ close(sock); >+ continue; >+ } >+ if ( (result = connect(sock, ip->ai_addr, ip->ai_addrlen)) < 0) >+ debug3("%s: %s", __func__, gai_strerror(result)); >+ else >+ break; >+ } >+ >+ if (ip == NULL) { >+ debug3("%s: Could not connect",__func__); >+ return(-1); >+ } >+ >+ return(sock); >+} >+ >+void >+check_msg(int socket,char *msg,char *type, char *res) >+{ >+ if((msg == NULL)||(!strcmp(res, msg))) >+ { >+ if(msg) >+ free(msg); >+ close(socket); >+ } >+ free(msg); >+} >+ >+int >+obc_send(char *obc, char *email_addr, char *smtp_server) >+{ >+ int socket; >+ char *msg; >+ char final_to[512]; >+ >+ if(obc == NULL) >+ debug3("%s: no message to send",__func__); >+ >+ /* Connecting to the smtp server */ >+ socket = obc_connect_smtp(smtp_server, SMTP_DEFAULT_PORT); >+ if(socket < 0) >+ return(socket); >+ >+ msg = obc_recv_tcp(socket, OS_SIZE_1024); >+ check_msg(socket,msg,"returned banner",VALIDBANNER); >+ >+ obc_send_tcp(socket,HELOMSG,NULL,0); >+ msg = obc_recv_tcp(socket, OS_SIZE_1024); >+ check_msg(socket,msg,HELOMSG,VALIDMAIL); >+ >+ obc_send_tcp(socket, MAILFROM, email_addr, 128); >+ msg = obc_recv_tcp(socket, OS_SIZE_1024); >+ check_msg(socket,msg,MAILFROM,VALIDMAIL); >+ >+ obc_send_tcp(socket,RCPTTO,email_addr,128); >+ msg = obc_recv_tcp(socket, OS_SIZE_1024); >+ check_msg(socket,msg,RCPTTO,VALIDMAIL); >+ >+ obc_send_tcp(socket,DATAMSG,NULL,0); >+ msg = obc_recv_tcp(socket, OS_SIZE_1024); >+ check_msg(socket,msg,DATAMSG,VALIDMAIL); >+ >+ /* Building "From" and "To" in the e-mail header */ >+ final_to[0] = '\0'; >+ obc_send_tcp(socket,final_to,NULL,0); >+ obc_send_tcp(socket, TO,email_addr,128); >+ obc_send_tcp(socket, FROM, email_addr, 128); >+ obc_send_tcp(socket, SUBJECT,"Out-of-band challenge",128); >+ obc_send_tcp(socket, obc, NULL, 0); >+ >+ /* Sending end of data \r\n.\r\n */ >+ obc_send_tcp(socket,ENDDATA,NULL,0); >+ msg = obc_recv_tcp(socket, OS_SIZE_1024); >+ >+ /* quitting and closing socket */ >+ obc_send_tcp(socket,QUITMSG,NULL,0); >+ msg = obc_recv_tcp(socket, OS_SIZE_1024); >+ >+ /* Returning 0 (success) */ >+ close(socket); >+ >+ return(0); >+} >+ >+int >+obc_gen(struct Authctxt *authctxt) >+{ >+ int i,ran,obc_length=4; >+ char *obc,cpool[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; >+ size_t nchars = sizeof(cpool) - 1; >+ >+ /* generate out-of-bound challenge (obc) */ >+ obc=malloc(obc_length+1); >+ if (obc == NULL) >+ exit(-1); >+ >+ for (i=0;i<obc_length;i++) { >+ ran = arc4random(); >+ obc[i] = cpool[ran%nchars]; >+ } >+ obc[obc_length] = '\0'; >+ >+ authctxt->obc = obc; >+ >+ return 1; >+} >+ >+int >+obc_challenge(Authctxt *authctxt) >+{ >+ int i, result=0; >+ char *alias=NULL,*email_addr=NULL; >+ >+ for (i=0; options.challenge_users[i] != NULL; i++) { >+ alias=strtok(options.challenge_users[i],":"); >+ email_addr=strtok(NULL,":"); >+ if (strcmp(authctxt->user,alias) == 0) >+ obc_gen(authctxt); >+ result = obc_send(authctxt->obc,email_addr, >+ options.challengesmtpserver); >+ } >+ debug2("%s: challenge sent to %s at %s via %s", >+ __func__, alias ,email_addr,options.challengesmtpserver); >+ >+ return(result); >+} >+ >+int >+obc_haskey(char *pw_name) >+{ >+ if (pw_name != NULL) >+ return 0; >+ else >+ return 1; >+} >+ >+int >+obc_passcheck(char *obc_local, char *obc_remote) >+{ >+ if (strcmp(obc_local, obc_remote) == 0) >+ return 1; >+ >+ return 0; >+} >+ >+static void * >+obc_init_ctx(Authctxt *authctxt) >+{ >+ int result; >+ result=obc_challenge(authctxt); >+ return authctxt; >+} >+ >+int >+obc_query(void *ctx, char **name, char **infotxt, >+ u_int* numprompts, char ***prompts, u_int **echo_on) >+{ >+ *name = xstrdup(""); >+ *infotxt = xstrdup(""); >+ *numprompts = 1; >+ *prompts = xcalloc(*numprompts, sizeof(char *)); >+ *echo_on = xcalloc(*numprompts, sizeof(u_int)); >+ >+ xasprintf(*prompts, "Enter out-of-band challenge:"); >+ >+ return 0; >+} >+ >+int >+obc_respond(void *ctx, u_int numresponses, char **responses) >+{ >+ Authctxt *authctxt = ctx; >+ >+ if (authctxt->valid && >+ numresponses == 1 && >+ obc_haskey(authctxt->obc) == 0 && >+ obc_passcheck(authctxt->obc, responses[0]) == 1) >+ return 0; >+ return -1; >+} >+ >+static void >+obc_free_ctx(void *ctx) >+{ >+ Authctxt *authctx = ctx; >+ >+ authctx->obc = NULL; >+} >+ >+KbdintDevice obc_device = { >+ "obc", >+ obc_init_ctx, >+ obc_query, >+ obc_respond, >+ obc_free_ctx >+}; >+ >+KbdintDevice mm_obc_device = { >+ "obc", >+ obc_init_ctx, >+ mm_obc_query, >+ mm_obc_respond, >+ obc_free_ctx >+}; >--- openssh-4.7p1/monitor.c 2007-05-19 23:10:16.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/monitor.c 2008-02-05 22:05:58.000000000 -0700 >@@ -156,10 +156,15 @@ > int mm_answer_pam_query(int, Buffer *); > int mm_answer_pam_respond(int, Buffer *); > int mm_answer_pam_free_ctx(int, Buffer *); > #endif > >+#ifdef USE_OBC >+int mm_answer_obc_query(int, Buffer *); >+int mm_answer_obc_respond(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 *); > int mm_answer_gss_checkmic(int, Buffer *); >@@ -223,10 +228,14 @@ > #endif > #ifdef SKEY > {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, > {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, > #endif >+#ifdef USE_OBC >+ {MONITOR_REQ_OBCQUERY, MON_ISAUTH, mm_answer_obc_query}, >+ {MONITOR_REQ_OBCRESPOND, MON_AUTH, mm_answer_obc_respond}, >+#endif > {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, > {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, > #ifdef GSSAPI > {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, > {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, >@@ -264,10 +273,14 @@ > #endif > #ifdef SKEY > {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, > {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, > #endif >+#ifdef USE_OBC >+ {MONITOR_REQ_OBCQUERY, MON_ISAUTH, mm_answer_obc_query}, >+ {MONITOR_REQ_OBCRESPOND, MON_AUTH, mm_answer_obc_respond}, >+#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}, >@@ -810,33 +823,48 @@ > debug3("%s: sending challenge success: %u", __func__, success); > mm_request_send(sock, MONITOR_ANS_SKEYQUERY, m); > > return (0); > } >+#endif > >+#ifdef USE_OBC > int >-mm_answer_skeyrespond(int sock, Buffer *m) >+mm_answer_obc_query(int sock, Buffer *m) >+{ >+ char challenge[1024]; >+ u_int success=1; >+ >+ buffer_clear(m); >+ buffer_put_int(m, success); >+ if (success) >+ buffer_put_cstring(m, challenge); >+ >+ debug3("%s: sending challenge success: %u", __func__, success); >+ >+ mm_request_send(sock, MONITOR_ANS_OBCQUERY, m); >+ >+ return (0); >+} >+ >+int >+mm_answer_obc_respond(int sock, Buffer *m) > { > char *response; > int authok; > > response = buffer_get_string(m, NULL); > >- authok = (options.challenge_response_authentication && >- authctxt->valid && >- skey_haskey(authctxt->pw->pw_name) == 0 && >- skey_passcheck(authctxt->pw->pw_name, response) != -1); >- > xfree(response); > > buffer_clear(m); > buffer_put_int(m, authok); > > debug3("%s: sending authenticated: %d", __func__, authok); >- mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); >+ mm_request_send(sock, MONITOR_ANS_OBCRESPOND, m); > >- auth_method = "skey"; >+ auth_method = "obc"; > > return (authok != 0); > } > #endif > >--- openssh-4.7p1/monitor.h 2006-03-25 20:30:02.000000000 -0700 >+++ openssh-4.7p1-kbdint-obc/monitor.h 2008-02-05 22:05:58.000000000 -0700 >@@ -37,10 +37,12 @@ > MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD, > MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY, > MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND, > MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY, > MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND, >+ MONITOR_REQ_OBCQUERY, MONITOR_ANS_OBCQUERY, >+ MONITOR_REQ_OBCRESPOND, MONITOR_ANS_OBCRESPOND, > MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED, > MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY, > MONITOR_REQ_KEYEXPORT, > MONITOR_REQ_PTY, MONITOR_ANS_PTY, > MONITOR_REQ_PTYCLEANUP, >--- openssh-4.7p1/monitor_wrap.c 2007-06-10 22:01:42.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/monitor_wrap.c 2008-02-05 22:05:58.000000000 -0700 >@@ -817,20 +817,20 @@ > { > Buffer m; > u_int i; > int ret; > >- debug3("%s", __func__); >+ debug2("%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__); >+ debug2("%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); >+ debug2("%s: pam_respond returned %d", __func__, ret); > buffer_free(&m); > return (ret); > } > > void >@@ -1007,10 +1007,78 @@ > > return ((authok == 0) ? -1 : 0); > } > #endif /* SKEY */ > >+#ifdef USE_OBC >+int >+mm_obc_query(void *ctx, char **name, char **infotxt, >+ u_int *numprompts, char ***prompts, u_int **echo_on) >+{ >+ Buffer m; >+ u_int success; >+ char *challenge; >+ >+ buffer_init(&m); >+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_OBCQUERY, &m); >+ >+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_OBCQUERY, >+ &m); >+ success = buffer_get_int(&m); >+ if (success == 0) { >+ debug3("%s: no challenge", __func__); >+ buffer_free(&m); >+ return (-1); >+ } >+ >+ /* Get the challenge, and format the response */ >+ challenge = buffer_get_string(&m, NULL); >+ buffer_free(&m); >+ >+ debug2("%s: received challenge: %s", __func__, challenge); >+ >+ mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); >+ >+ xasprintf(*prompts, "%s%s", challenge, "Out-of-band challenge: "); >+ xfree(challenge); >+ >+ return (0); >+} >+ >+int >+mm_obc_respond(void *ctx, u_int numresponses, char **responses) >+{ >+ Buffer m; >+ int authok; >+ Authctxt *authctxt = ctx; >+ >+ debug3("%s entering", __func__); >+ if (numresponses != 1) >+ return (-1); >+ >+ buffer_init(&m); >+ buffer_put_cstring(&m, responses[0]); >+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_OBCRESPOND, &m); >+ >+ mm_request_receive_expect(pmonitor->m_recvfd, >+ MONITOR_ANS_OBCRESPOND, &m); >+ >+ authok = buffer_get_int(&m); >+ buffer_free(&m); >+ authctxt->postponed = 0; >+ >+ if (authctxt->valid && >+ numresponses == 1 && >+ obc_haskey(authctxt->obc) == 0 && >+ obc_passcheck(authctxt->obc, responses[0]) == 1) { >+ return 0; >+ } >+ return -1; >+} >+#endif /* USE_OBC */ >+ >+ > void > mm_ssh1_session_id(u_char session_id[16]) > { > Buffer m; > int i; >@@ -1235,5 +1303,48 @@ > buffer_free(&m); > debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); > return (authenticated); > } > #endif /* GSSAPI */ >+ >+#ifdef USE_OBC >+int >+mm_obc_connect_smtp(char *smtp_server, char *port) >+{ >+ int err, sock, result; >+ struct addrinfo hints, *ip_info, *ip; >+ >+ debug3("[obc_connect] host %s, port %s",smtp_server,port); >+ >+ memset(&hints, 0, sizeof(struct addrinfo)); >+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ >+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ >+ hints.ai_flags = 0; >+ hints.ai_protocol = 0; /* Any protocol */ >+ >+ if ( (err = getaddrinfo(smtp_server, "25", &hints, &ip_info) != 0) ) { >+/* if ( (err = getaddrinfo("76.96.30.117", "25", &hints, &ip_info) != 0) ) {*/ >+ debug3("[obc_connect]getaddrinfo: %s\n", gai_strerror(err)); >+ return(-1); >+ } >+ >+ for (ip = ip_info; ip != NULL; ip = ip->ai_next) { >+ display_ip(ip); >+ if ( (sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0) { >+ debug3("[obc_connect] can't open socket %d", sock); >+ close(sock); >+ continue; >+ } >+ if ( (result = connect(sock, ip->ai_addr, ip->ai_addrlen)) < 0) >+ debug3("[obc_connect] %s", gai_strerror(result)); >+ else >+ break; >+ } >+ >+ if (ip == NULL) { >+ debug3("[obc_connect]Could not connect"); >+ return(-1); >+ } >+ >+ return(sock); >+} >+#endif >--- openssh-4.7p1/monitor_wrap.h 2006-08-04 20:39:40.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/monitor_wrap.h 2008-02-05 22:05:58.000000000 -0700 >@@ -99,10 +99,14 @@ > > /* skey */ > int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); > int mm_skey_respond(void *, u_int, char **); > >+/* obc */ >+int mm_obc_query(void *, char **, char **, u_int *, char ***, u_int **); >+int mm_obc_respond(void *, u_int, char **); >+ > /* zlib allocation hooks */ > > void *mm_zalloc(struct mm_master *, u_int, u_int); > void mm_zfree(struct mm_master *, void *); > void mm_init_compression(struct mm_master *); >--- openssh-4.7p1/servconf.c 2007-05-19 23:03:16.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/servconf.c 2008-02-05 22:05:58.000000000 -0700 >@@ -120,10 +120,12 @@ > options->authorized_keys_file2 = NULL; > options->num_accept_env = 0; > options->permit_tun = -1; > options->num_permitted_opens = -1; > options->adm_forced_command = NULL; >+ options->obc_authentication = -1; >+ options->max_challenge_users = 0; > } > > void > fill_default_server_options(ServerOptions *options) > { >@@ -261,10 +263,13 @@ > error("Compression disabled"); > options->compression = 0; > } > #endif > >+ if (options->obc_authentication == -1) >+ options->obc_authentication = 1; >+ > } > > /* Keyword tokens. */ > typedef enum { > sBadOption, /* == unknown option */ >@@ -290,12 +295,13 @@ > sBanner, sUseDNS, sHostbasedAuthentication, > sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, > sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, > sMatch, sPermitOpen, sForceCommand, >- sUsePrivilegeSeparation, >+ sUsePrivilegeSeparation, sChallengeUsers, sChallengeSMTPServer, > sDeprecated, sUnsupported >+ > } ServerOpCodes; > > #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ > #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ > #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) >@@ -401,10 +407,12 @@ > { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, > { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL }, > { "match", sMatch, SSHCFG_ALL }, > { "permitopen", sPermitOpen, SSHCFG_ALL }, > { "forcecommand", sForceCommand, SSHCFG_ALL }, >+ { "challengeusers", sChallengeUsers, SSHCFG_GLOBAL }, >+ { "challengesmtpserver", sChallengeSMTPServer, SSHCFG_GLOBAL }, > { NULL, sBadOption, 0 } > }; > > /* > * Returns the number of the token pointed to by cp or sBadOption. >@@ -1265,10 +1273,30 @@ > filename, linenum, arg); > while (arg) > arg = strdelim(&cp); > break; > >+ case sChallengeUsers: >+ while ((arg = strdelim(&cp)) && *arg != '\0') { >+ if (options->max_challenge_users >= MAX_CHALLENGE_USERS) >+ fatal("%s line %d: too many challenge users.", >+ filename, linenum); >+ options->challenge_users[options->max_challenge_users++] = >+ xstrdup(arg); >+ } >+ break; >+ >+ case sChallengeSMTPServer: >+ while ((arg = strdelim(&cp)) && *arg != '\0') { >+ if (options->challengesmtpserver >= 1) >+ fatal("%s line %d: too many challenge smtp servers.", >+ filename, linenum); >+ options->challengesmtpserver = >+ xstrdup(arg); >+ } >+ break; >+ > default: > fatal("%s line %d: Missing handler for opcode %s (%d)", > filename, linenum, arg, opcode); > } > if ((arg = strdelim(&cp)) != NULL && *arg != '\0') >--- openssh-4.7p1/servconf.h 2007-02-19 04:25:38.000000000 -0700 >+++ openssh-4.7p1-kbdint-obc/servconf.h 2008-02-05 22:05:58.000000000 -0700 >@@ -24,10 +24,11 @@ > #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ > #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ > #define MAX_HOSTKEYS 256 /* Max # hostkeys. */ > #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ > #define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */ >+#define MAX_CHALLENGE_USERS 256 /* Max # of groups for Match. */ > > /* permit_root_login */ > #define PERMIT_NOT_SET -1 > #define PERMIT_NO 0 > #define PERMIT_FORCED_ONLY 1 >@@ -139,10 +140,15 @@ > int use_pam; /* Enable auth via PAM */ > > int permit_tun; > > int num_permitted_opens; >+ >+ int obc_authentication; /* Permit out-of-band challenge if true */ >+ int max_challenge_users; >+ char *challenge_users[MAX_CHALLENGE_USERS]; >+ char *challengesmtpserver; > } ServerOptions; > > void initialize_server_options(ServerOptions *); > void fill_default_server_options(ServerOptions *); > int process_server_config_line(ServerOptions *, char *, const char *, int, >--- openssh-4.7p1/sshd_config 2007-03-21 03:42:25.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/sshd_config 2008-02-05 22:05:58.000000000 -0700 >@@ -61,10 +61,16 @@ > #PermitEmptyPasswords no > > # Change to no to disable s/key passwords > #ChallengeResponseAuthentication yes > >+# Configure the smtp server for sending out-of-band (obc) challenges >+#ChallengeSMTPServer host.some.domain >+ >+# Configure user to receive out-of-band (obc) challenges >+#ChallengeUsers alias:user@some.domain >+ > # Kerberos options > #KerberosAuthentication no > #KerberosOrLocalPasswd yes > #KerberosTicketCleanup yes > #KerberosGetAFSToken no >--- openssh-4.7p1/sshd_config.5 2007-06-10 22:07:13.000000000 -0600 >+++ openssh-4.7p1-kbdint-obc/sshd_config.5 2008-02-05 22:05:58.000000000 -0700 >@@ -170,10 +170,30 @@ > All authentication styles from > .Xr login.conf 5 > are supported. > The default is > .Dq yes . >+.It Cm ChallengeSMTPServer >+Specifies the SMTP server to send OBC challenges through. Use the format: >+ >+ChallengeSMTPServer name/IP address >+ >+You can specify the domain name or IP address; specify an IP address when >+using privilege separation. You can also specify localhost if your computer >+is configured to configured to send mail. >+ >+.It Cm ChallengeUsers >+Specifies the user(s) and their e-mail addresses who can receive out-of-band >+challenges (OBC). OBC provides server-side authentication by generating and >+e-mailing a random password. The user is authenticated by correctly entering >+the challenge when prompted. >+ >+Use the format: >+ >+ChallengeUsers alias:user@someaddr >+ >+ChallengeResponseAuthentication must be set for ChallengeUsers to work. > .It Cm Ciphers > Specifies the ciphers allowed for protocol version 2. > Multiple ciphers must be comma-separated. > The supported ciphers are > .Dq 3des-cbc , >--- openssh-4.7p1/README.obc 1969-12-31 17:00:00.000000000 -0700 >+++ openssh-4.7p1-kbdint-obc/README.obc 2008-02-05 22:32:26.000000000 -0700 >@@ -0,0 +1,35 @@ >+How to authenticate using an Out-of-Band Challenge (OBC) >+ >+Overview: >+ >+The out-of-band challenge (OBC) patch adds a new kbdint device that provides a challenge-based authentication mechanism. The server generates and emails you a random string when you attempt to login. You're authenticated if you can correctly answer the challenge. >+ >+You can use a regular email account, a pager, cell phone or other email capable device to receive the challenge. However, by using a physical device you can completely separate your authentication credential from your workstation. >+ >+OBC can be used in conjunction with the "Multiauth" patch (https://bugzilla.mindrot.org/show_bug.cgi?id=1435), which allows you to require two or more authentications for a successful login. By combining OBC with Multiauth, you can create two physically separate authentication factors equivalent to a commercial token. For instance, combine public key and OBC authentications. >+ >+Configuration: >+ >+The user's OBC email address is stored in the sshd_config file using the format username:emailaddr@somedomain. For instance, if your user name and email address are paul and paul@swcp.com, add the following line to sshd_config: >+ >+ChallengeUsers paul:paul@swcp.com >+ >+If your alias is paul and email address is pgsery@swcp.com, then add the line: >+ >+ChallengeUsers paul:pgsery@swcp.com >+ >+You must also specify the outgoing SMTP email server to use. If your SMTP server is mail.swcp.com and you're not using privilege separation, add the line: >+ >+ChallengeSMTPServer mail.swcp.com >+ >+OBC currently doesn't perform DNS name resolution with privilege separation. When using privilege separation, you must specify your SMTP server's IP address: >+ >+ChallengeSMTPServer 216.184.2.128 >+ >+Compilation: >+ >+Install and compile the OBC patch: >+ >+authconf >+./configure --with-obc >+make install
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1438
: 1452