Hi,
We at BalaBit IT Security Ltd developed a patch against openssh 2.3.0p1 to
support TIS authserv authentication. TIS authserv uses a simple protocol,
and supports CryptoCard, SKey, password etc. authentication.
The commercial versions of SSH support this protocol, OpenSSH implemented
SKey on its own using the protocol primitives originally invented for TIS
authentication.
Our patch is an alternative to S/Key support in OpenSSH, the two cannot be
compiled in at the same time.
Inclusion of this patch in openssh would be welcome and appreciated.
--
Bazsi
PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E C82C 8EB1
url: http://www.balabit.hu/pgpkey.txt
-------------- next part --------------
diff -urN openssh-2.3.0p1/Makefile.in openssh-2.3.0p1-tis/Makefile.in
--- openssh-2.3.0p1/Makefile.in Sun Nov 5 22:13:45 2000
+++ openssh-2.3.0p1-tis/Makefile.in Thu Dec 7 18:38:42 2000
@@ -41,7 +41,7 @@
SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o
clientloop.o
-SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-skey.o auth2-skey.o auth-rhosts.o
auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o
dh.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o
session.o
+SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-skey.o auth2-skey.o auth-rhosts.o
auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o
dh.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o
session.o tisauth.o
TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 sftp-server.8
CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 sftp-server.0
diff -urN openssh-2.3.0p1/acconfig.h openssh-2.3.0p1-tis/acconfig.h
--- openssh-2.3.0p1/acconfig.h Wed Oct 18 15:11:44 2000
+++ openssh-2.3.0p1-tis/acconfig.h Thu Dec 7 18:38:42 2000
@@ -276,6 +276,8 @@
/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */
#undef IPV4_IN_IPV6
+#undef TIS_AUTH
+
@BOTTOM@
/* ******************* Shouldn't need to edit below this line
************** */
diff -urN openssh-2.3.0p1/auth1.c openssh-2.3.0p1-tis/auth1.c
--- openssh-2.3.0p1/auth1.c Sat Oct 14 07:23:11 2000
+++ openssh-2.3.0p1-tis/auth1.c Thu Dec 7 18:38:42 2000
@@ -12,6 +12,10 @@
#include "includes.h"
RCSID("$OpenBSD: auth1.c,v 1.6 2000/10/11 20:27:23 markus Exp $");
+#ifdef TIS_AUTH
+#include "tisauth.h"
+#endif
+
#ifdef HAVE_OSF_SIA
# include <sia.h>
# include <siad.h>
@@ -40,6 +44,10 @@
extern char **saved_argv;
#endif /* HAVE_OSF_SIA */
+#if defined(SKEY) && defined(TIS_AUTH)
+#error "S/Key and TIS authentication is not supported at the same
time"
+#endif
+
/*
* convert ssh auth msg type into description
*/
@@ -60,6 +68,10 @@
case SSH_CMSG_AUTH_KERBEROS:
return "kerberos";
#endif
+#ifdef TIS_AUTH
+ case SSH_CMSG_AUTH_TIS_RESPONSE:
+ return "tis";
+#endif
#ifdef SKEY
case SSH_CMSG_AUTH_TIS_RESPONSE:
return "s/key";
@@ -91,6 +103,9 @@
unsigned int ulen;
int type = 0;
void (*authlog) (const char *fmt,...) = verbose;
+#ifdef TIS_AUTH
+ struct tis_context *tis = NULL;
+#endif
/* Indicate that authentication is needed. */
packet_start(SSH_SMSG_FAILURE);
@@ -267,7 +282,54 @@
xfree(password);
break;
-#ifdef SKEY
+#ifdef TIS_AUTH
+ case SSH_CMSG_AUTH_TIS:
+ debug("rcvd SSH_CMSG_AUTH_TIS");
+ if (options.tis_authentication == 1) {
+ char *challenge = NULL;
+
+ if (pw) {
+ tis_free(tis);
+ tis = tis_connect_multi(options.authserv_addrs);
+ if (tis) {
+ challenge = tis_authenticate(tis, pw->pw_name);
+ }
+ else {
+ log("Error connecting TIS authserv");
+ }
+ else {
+ challenge = tis_fake_challenge();
+ }
+ if (!challenge) {
+ break;
+ }
+ if (challenge != NULL) {
+ debug("sending challenge '%s'", challenge);
+ packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
+ packet_put_string(challenge, strlen(challenge) - 1);
+ packet_send();
+ packet_write_wait();
+ xfree(challenge);
+ continue;
+ }
+ }
+ break;
+ case SSH_CMSG_AUTH_TIS_RESPONSE:
+ if (options.tis_authentication == 1 && tis && pw) {
+ char *response = packet_get_string(&dlen);
+
+ debug("tis response == '%s'", response);
+ packet_integrity_check(plen, 4 + dlen, type);
+ authenticated = tis_response(tis, response);
+ tis_free(tis);
+ tis = NULL;
+
+ /* allow only one attempt */
+ attempt = AUTH_FAIL_MAX + 1;
+ xfree(response);
+ }
+ break;
+#elif SKEY
case SSH_CMSG_AUTH_TIS:
debug("rcvd SSH_CMSG_AUTH_TIS");
if (options.skey_authentication == 1) {
diff -urN openssh-2.3.0p1/config.h.in openssh-2.3.0p1-tis/config.h.in
--- openssh-2.3.0p1/config.h.in Mon Nov 6 04:25:18 2000
+++ openssh-2.3.0p1-tis/config.h.in Thu Dec 7 18:38:42 2000
@@ -269,6 +269,8 @@
/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */
#undef IPV4_IN_IPV6
+#undef TIS_AUTH
+
/* The number of bytes in a char. */
#undef SIZEOF_CHAR
@@ -601,6 +603,9 @@
/* Define if you have the <vis.h> header file. */
#undef HAVE_VIS_H
+
+/* Define if you have the crypt library (-lcrypt). */
+#undef HAVE_LIBCRYPT
/* Define if you have the dl library (-ldl). */
#undef HAVE_LIBDL
diff -urN openssh-2.3.0p1/configure.in openssh-2.3.0p1-tis/configure.in
--- openssh-2.3.0p1/configure.in Sun Nov 5 10:08:45 2000
+++ openssh-2.3.0p1-tis/configure.in Thu Dec 7 18:38:42 2000
@@ -263,10 +263,10 @@
]
)
-
# Checks for libraries.
AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first
***]))
AC_CHECK_LIB(util, login, AC_DEFINE(HAVE_LIBUTIL_LOGIN) LIBS="$LIBS
-lutil")
+AC_CHECK_LIB(crypt, crypt)
AC_CHECK_FUNC(regcomp,
[],
@@ -1116,6 +1116,18 @@
]
)
+# Check whether user wants S/Key support
+TIS_MSG="no"
+AC_ARG_WITH(tis,
+ [ --with-tis Enable TIS authsrv support, may not be used with
--with-skey],
+ [
+ if test "x$withval" != "xno" ; then
+ AC_DEFINE(TIS_AUTH)
+ TIS_MSG="yes"
+ fi
+ ]
+)
+
# Check whether user wants TCP wrappers support
TCPW_MSG="no"
AC_ARG_WITH(tcp-wrappers,
@@ -1566,6 +1578,7 @@
echo " KerberosIV support: $KRB4_MSG"
echo " AFS support: $AFS_MSG"
echo " S/KEY support: $SKEY_MSG"
+echo " TIS authsrv support: $TIS_MSG"
echo " TCP Wrappers support: $TCPW_MSG"
echo " MD5 password support: $MD5_MSG"
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
diff -urN openssh-2.3.0p1/readconf.c openssh-2.3.0p1-tis/readconf.c
--- openssh-2.3.0p1/readconf.c Sat Oct 14 07:23:12 2000
+++ openssh-2.3.0p1-tis/readconf.c Thu Dec 7 18:38:42 2000
@@ -313,7 +313,7 @@
goto parse_flag;
case oTISAuthentication:
- /* fallthrough, there is no difference on the client side */
+ /* fallthrough */
case oSkeyAuthentication:
intptr = &options->skey_authentication;
goto parse_flag;
diff -urN openssh-2.3.0p1/servconf.c openssh-2.3.0p1-tis/servconf.c
--- openssh-2.3.0p1/servconf.c Mon Oct 16 03:14:42 2000
+++ openssh-2.3.0p1-tis/servconf.c Thu Dec 7 18:41:00 2000
@@ -64,6 +64,9 @@
options->kbd_interactive_authentication = -1;
#ifdef SKEY
options->skey_authentication = -1;
+#elif TIS_AUTH
+ options->tis_authentication = -1;
+ options->authserv_addrs = NULL;
#endif
options->permit_empty_passwd = -1;
options->use_login = -1;
@@ -155,6 +158,9 @@
#ifdef SKEY
if (options->skey_authentication == -1)
options->skey_authentication = 1;
+#elif TIS_AUTH
+ if (options->tis_authentication == -1)
+ options->tis_authentication = 1;
#endif
if (options->permit_empty_passwd == -1)
options->permit_empty_passwd = 0;
@@ -188,6 +194,9 @@
#endif
#ifdef SKEY
sSkeyAuthentication,
+#elif TIS_AUTH
+ sTISAuthentication,
+ sAuthservAddress,
#endif
sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
@@ -230,6 +239,9 @@
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
#ifdef SKEY
{ "skeyauthentication", sSkeyAuthentication },
+#elif TIS_AUTH
+ { "tisauthentication", sTISAuthentication },
+ { "authservaddress", sAuthservAddress },
#endif
{ "checkmail", sCheckMail },
{ "listenaddress", sListenAddress },
@@ -277,6 +289,35 @@
return sBadOption;
}
+#ifdef TIS_AUTH
+void
+add_authserv_addr(ServerOptions *options, char **addr)
+{
+ extern int IPv4or6;
+ struct addrinfo hints, *ai, *aitop;
+ char *host, *service;
+ int gaierr;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = IPv4or6;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
+
+ host = strdelim(addr);
+ service = strdelim(addr);
+
+ if ((gaierr = getaddrinfo(host, service, &hints, &aitop)) != 0)
+ fatal("bad addr or host: %s (%s)\n",
+ host ? host : "<NULL>",
+ gai_strerror(gaierr));
+ for (ai = aitop; ai->ai_next; ai = ai->ai_next)
+ ;
+ ai->ai_next = options->authserv_addrs;
+ options->authserv_addrs = aitop;
+
+}
+#endif
+
/*
* add listen address
*/
@@ -518,6 +559,14 @@
case sSkeyAuthentication:
intptr = &options->skey_authentication;
goto parse_flag;
+#elif TIS_AUTH
+ case sTISAuthentication:
+ intptr = &options->tis_authentication;
+ goto parse_flag;
+
+ case sAuthservAddress:
+ add_authserv_addr(options, &cp);
+ break;
#endif
case sPrintMotd:
diff -urN openssh-2.3.0p1/servconf.h openssh-2.3.0p1-tis/servconf.h
--- openssh-2.3.0p1/servconf.h Mon Oct 16 03:14:43 2000
+++ openssh-2.3.0p1-tis/servconf.h Thu Dec 7 18:38:42 2000
@@ -83,6 +83,10 @@
int skey_authentication; /* If true, permit s/key
* authentication. */
#endif
+#ifdef TIS_AUTH
+ struct addrinfo *authserv_addrs; /* Addresses where a TIS authserv can be
found. */
+ int tis_authentication; /* if true, permit TIS authsrv authentication */
+#endif
int permit_empty_passwd; /* If false, do not permit empty
* passwords. */
int use_login; /* If true, login(1) is used */
diff -urN openssh-2.3.0p1/sshd.c openssh-2.3.0p1-tis/sshd.c
--- openssh-2.3.0p1/sshd.c Sat Oct 14 07:23:13 2000
+++ openssh-2.3.0p1-tis/sshd.c Thu Dec 7 18:38:42 2000
@@ -1182,6 +1182,11 @@
if (options.skey_authentication == 1)
auth_mask |= 1 << SSH_AUTH_TIS;
#endif
+#ifdef TIS_AUTH
+ if (options.tis_authentication == 1)
+ auth_mask |= 1 << SSH_AUTH_TIS;
+#endif
+
if (options.password_authentication)
auth_mask |= 1 << SSH_AUTH_PASSWORD;
packet_put_int(auth_mask);
diff -urN openssh-2.3.0p1/tisauth.c openssh-2.3.0p1-tis/tisauth.c
--- openssh-2.3.0p1/tisauth.c Thu Jan 1 01:00:00 1970
+++ openssh-2.3.0p1-tis/tisauth.c Thu Dec 7 18:44:26 2000
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2000 BalaBit IT Ltd.
+ * All rights reserved
+ *
+ * Authors: Bal?zs Scheidler, Attila Szalay
+ *
+ * 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 "ssh.h"
+
+#ifdef TIS_AUTH
+
+struct tis_context {
+ int connfd;
+};
+
+struct tis_context *tis_connect(struct sockaddr *addr, int addrlen)
+{
+ struct tis_context *ctx;
+ char line[128];
+ int fd;
+
+ fd = socket(addr->sa_family, SOCK_STREAM, 0);
+ if (fd < 0)
+ return NULL;
+
+ if (connect(fd, addr, addrlen) < 0) {
+ close(fd);
+ return NULL;
+ }
+
+ /* grab greeting line */
+ if (read(fd, line, sizeof(line)) < 0) {
+ close(fd);
+ return NULL;
+ }
+ ctx = malloc(sizeof(struct tis_context));
+ ctx->connfd = fd;
+ return ctx;
+}
+
+struct tis_context *tis_connect_multi(struct addrinfo *addrs)
+{
+ struct addrinfo *p;
+ struct tis_context *tis;
+
+ for (p = addrs; p; p = p->ai_next) {
+ tis = tis_connect(p->ai_addr, p->ai_addrlen);
+ if (tis)
+ return tis;
+ }
+ return NULL;
+}
+
+void tis_free(struct tis_context *ctx)
+{
+ if (ctx) {
+ close(ctx->connfd);
+ free(ctx);
+ }
+}
+
+char *tis_authenticate(struct tis_context *ctx, char *user)
+{
+ char line[128];
+ int length;
+
+ snprintf(line, 120, "authenticate \"%.32s\"\n", user);
+ if (send(ctx->connfd,line,strlen(line),0) < 0) {
+ return NULL;
+ }
+ if ((length = recv(ctx->connfd, line, sizeof(line) - 1, 0)) < 0)
+ return NULL;
+ line[length] = 0;
+ if (strncmp(line, "challenge", 9) != 0)
+ return NULL;
+ return strdup(line + 10);
+}
+
+int tis_response(struct tis_context *ctx, char *response)
+{
+ char line[128];
+ int length;
+
+ snprintf(line, 120, "response \"%.64s\"\n", response) ;
+ if (send(ctx->connfd, line, strlen(line), 0) < 0)
+ return 0;
+ if ((length = recv(ctx->connfd, line, sizeof(line) - 1, 0)) < 0)
+ return 0;
+ line[length] = 0;
+ if (strncmp(line, "ok", 2) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+char *tis_fake_challenge(void)
+{
+ char challenge[9];
+ unsigned long rnd;
+
+ rnd = time(NULL) ^ getpid();
+ snprintf(challenge, sizeof(challenge), "%ld", rnd);
+ return strdup(challenge);
+}
+
+#endif
diff -urN openssh-2.3.0p1/tisauth.h openssh-2.3.0p1-tis/tisauth.h
--- openssh-2.3.0p1/tisauth.h Thu Jan 1 01:00:00 1970
+++ openssh-2.3.0p1-tis/tisauth.h Thu Dec 7 18:44:53 2000
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2000 BalaBit IT Ltd.
+ * All rights reserved
+ *
+ * Authors: Bal?zs Scheidler, Attila Szalay
+ *
+ * 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 _TISAUTH_H_INCLUDED
+#define _TISAUTH_H_INCLUDED
+
+struct tis_context;
+
+struct tis_context *tis_connect(struct sockaddr *addr, int addrlen);
+struct tis_context *tis_connect_multi(struct addrinfo *addrs);
+void tis_free(struct tis_context *ctx);
+char *tis_authenticate(struct tis_context *ctx, char *user);
+int tis_response(struct tis_context *ctx, char *response);
+char *tis_fake_challenge(void);
+
+#endif
+