summaryrefslogtreecommitdiffstats
path: root/crypto/telnet/libtelnet
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/telnet/libtelnet')
-rw-r--r--crypto/telnet/libtelnet/Makefile19
-rw-r--r--crypto/telnet/libtelnet/auth-proto.h8
-rw-r--r--crypto/telnet/libtelnet/auth.c10
-rw-r--r--crypto/telnet/libtelnet/enc-proto.h2
-rw-r--r--crypto/telnet/libtelnet/encrypt.c15
-rw-r--r--crypto/telnet/libtelnet/encrypt.h5
-rw-r--r--crypto/telnet/libtelnet/pk.c266
-rw-r--r--crypto/telnet/libtelnet/pk.h41
-rw-r--r--crypto/telnet/libtelnet/sra.c478
9 files changed, 840 insertions, 4 deletions
diff --git a/crypto/telnet/libtelnet/Makefile b/crypto/telnet/libtelnet/Makefile
new file mode 100644
index 0000000..3ef7f94
--- /dev/null
+++ b/crypto/telnet/libtelnet/Makefile
@@ -0,0 +1,19 @@
+# From: @(#)Makefile 8.2 (Berkeley) 12/15/93
+# $Id: Makefile,v 1.1.1.1.6.5 1996/06/30 12:50:37 markm Exp $
+
+INTERNALSTATICLIB= YES
+
+LIB= telnet
+SRCS= encrypt.c genget.c getent.c misc.c
+
+# SRA Authentication & DES Encryption
+CFLAGS+= -I.. -DHAS_CGETENT -DENCRYPTION -DAUTHENTICATION -DSRA
+CFLAGS+= -DDES_ENCRYPTION
+LDADD+= -ldes -lmp
+SRCS+= auth.c enc_des.c sra.c pk.c
+
+#don't bother to install
+install:
+ /usr/bin/true
+
+.include <bsd.lib.mk>
diff --git a/crypto/telnet/libtelnet/auth-proto.h b/crypto/telnet/libtelnet/auth-proto.h
index a1e9aa4..c62fe5f 100644
--- a/crypto/telnet/libtelnet/auth-proto.h
+++ b/crypto/telnet/libtelnet/auth-proto.h
@@ -97,4 +97,12 @@ void kerberos5_reply P((Authenticator *, unsigned char *, int));
int kerberos5_status P((Authenticator *, char *, int));
void kerberos5_printsub P((unsigned char *, int, unsigned char *, int));
#endif
+#ifdef SRA
+int sra_init P((Authenticator *, int));
+int sra_send P((Authenticator *));
+void sra_is P((Authenticator *, unsigned char *, int));
+void sra_reply P((Authenticator *, unsigned char *, int));
+int sra_status P((Authenticator *, char *, int));
+void sra_printsub P((unsigned char *, int, unsigned char *, int));
+#endif
#endif
diff --git a/crypto/telnet/libtelnet/auth.c b/crypto/telnet/libtelnet/auth.c
index 4262b55..d574b1e 100644
--- a/crypto/telnet/libtelnet/auth.c
+++ b/crypto/telnet/libtelnet/auth.c
@@ -185,6 +185,16 @@ Authenticator authenticators[] = {
rsaencpwd_status,
rsaencpwd_printsub },
#endif
+#ifdef SRA
+ { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
+ sra_init,
+ sra_send,
+ sra_is,
+ sra_reply,
+ sra_status,
+ sra_printsub },
+
+#endif
{ 0, },
};
diff --git a/crypto/telnet/libtelnet/enc-proto.h b/crypto/telnet/libtelnet/enc-proto.h
index 8e15ffd..8cec406 100644
--- a/crypto/telnet/libtelnet/enc-proto.h
+++ b/crypto/telnet/libtelnet/enc-proto.h
@@ -94,6 +94,7 @@ int encrypt_cmd P((int, char **));
void encrypt_display P((void));
#endif
+#ifdef DES_ENCRYPTION
void krbdes_encrypt P((unsigned char *, int));
int krbdes_decrypt P((int));
int krbdes_is P((unsigned char *, int));
@@ -122,5 +123,6 @@ int ofb64_reply P((unsigned char *, int));
void ofb64_session P((Session_Key *, int));
int ofb64_keyid P((int, unsigned char *, int *));
void ofb64_printsub P((unsigned char *, int, unsigned char *, int));
+#endif /* DES_ENCRYPTION */
#endif /* ENCRYPTION */
diff --git a/crypto/telnet/libtelnet/encrypt.c b/crypto/telnet/libtelnet/encrypt.c
index 41dd5cc..e1ac1c4 100644
--- a/crypto/telnet/libtelnet/encrypt.c
+++ b/crypto/telnet/libtelnet/encrypt.c
@@ -104,10 +104,17 @@ static char *Name = "Noname";
#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0)
-static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64)
- | typemask(ENCTYPE_DES_OFB64);
-static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64)
- | typemask(ENCTYPE_DES_OFB64);
+static long i_support_encrypt = 0
+#ifdef DES_ENCRYPTION
+ | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64)
+#endif
+ |0;
+static long i_support_decrypt = 0
+#ifdef DES_ENCRYPTION
+ | typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64)
+#endif
+ |0;
+
static long i_wont_support_encrypt = 0;
static long i_wont_support_decrypt = 0;
#define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt)
diff --git a/crypto/telnet/libtelnet/encrypt.h b/crypto/telnet/libtelnet/encrypt.h
index 1c942dc..14be826 100644
--- a/crypto/telnet/libtelnet/encrypt.h
+++ b/crypto/telnet/libtelnet/encrypt.h
@@ -60,9 +60,14 @@
#define DIR_DECRYPT 1
#define DIR_ENCRYPT 2
+#include <des.h>
typedef unsigned char Block[8];
typedef unsigned char *BlockT;
+#if 0
typedef struct { Block __; } Schedule[16];
+#else
+#define Schedule des_key_schedule
+#endif
#define VALIDKEY(key) ( key[0] | key[1] | key[2] | key[3] | \
key[4] | key[5] | key[6] | key[7])
diff --git a/crypto/telnet/libtelnet/pk.c b/crypto/telnet/libtelnet/pk.c
new file mode 100644
index 0000000..78e474f
--- /dev/null
+++ b/crypto/telnet/libtelnet/pk.c
@@ -0,0 +1,266 @@
+/* public key routines */
+/* functions:
+ genkeys(char *public, char *secret)
+ common_key(char *secret, char *public, desData *deskey)
+ pk_encode(char *in, *out, DesData *deskey);
+ pk_decode(char *in, *out, DesData *deskey);
+ where
+ char public[HEXKEYBYTES + 1];
+ char secret[HEXKEYBYTES + 1];
+ */
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <string.h>
+#include <fcntl.h>
+#include <des.h>
+#include "mp.h"
+#include "pk.h"
+#if defined(SOLARIS2) || defined(LINUX)
+#include <stdlib.h>
+#endif
+
+/*
+ * Choose top 128 bits of the common key to use as our idea key.
+ */
+static
+extractideakey(ck, ideakey)
+ MINT *ck;
+ IdeaData *ideakey;
+{
+ MINT *a;
+ MINT *z;
+ short r;
+ int i;
+ short base = (1 << 8);
+ char *k;
+
+ z = itom(0);
+ a = itom(0);
+ madd(ck, z, a);
+ for (i = 0; i < ((KEYSIZE - 128) / 8); i++) {
+ sdiv(a, base, a, &r);
+ }
+ k = (char *)ideakey;
+ for (i = 0; i < 16; i++) {
+ sdiv(a, base, a, &r);
+ *k++ = r;
+ }
+ mfree(z);
+ mfree(a);
+}
+
+/*
+ * Choose middle 64 bits of the common key to use as our des key, possibly
+ * overwriting the lower order bits by setting parity.
+ */
+static
+extractdeskey(ck, deskey)
+ MINT *ck;
+ DesData *deskey;
+{
+ MINT *a;
+ MINT *z;
+ short r;
+ int i;
+ short base = (1 << 8);
+ char *k;
+
+ z = itom(0);
+ a = itom(0);
+ madd(ck, z, a);
+ for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {
+ sdiv(a, base, a, &r);
+ }
+ k = (char *)deskey;
+ for (i = 0; i < 8; i++) {
+ sdiv(a, base, a, &r);
+ *k++ = r;
+ }
+ mfree(z);
+ mfree(a);
+}
+
+/*
+ * get common key from my secret key and his public key
+ */
+void common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey)
+{
+ MINT *public;
+ MINT *secret;
+ MINT *common;
+ MINT *modulus = xtom(HEXMODULUS);
+
+ public = xtom(xpublic);
+ secret = xtom(xsecret);
+ common = itom(0);
+ pow(public, secret, modulus, common);
+ extractdeskey(common, deskey);
+ extractideakey(common, ideakey);
+#if DES_OSTHOLM
+ des_fixup_key_parity(deskey);
+#else
+ des_set_odd_parity(deskey);
+#endif
+ mfree(common);
+ mfree(secret);
+ mfree(public);
+ mfree(modulus);
+}
+
+
+/*
+ * Generate a seed
+ */
+void getseed(seed, seedsize)
+ char *seed;
+ int seedsize;
+{
+ int i,f;
+ int rseed;
+ struct timeval tv;
+ long devrand;
+
+ (void)gettimeofday(&tv, (struct timezone *)NULL);
+ rseed = tv.tv_sec + tv.tv_usec;
+/* XXX What the hell is this?! */
+ for (i = 0; i < 8; i++) {
+ rseed ^= (rseed << 8);
+ }
+
+ f=open("/dev/random",O_NONBLOCK|O_RDONLY);
+ if (f>=0)
+ {
+ read(f,&devrand,sizeof(devrand));
+ close(f);
+ }
+ srand48((long)rseed^devrand);
+
+ for (i = 0; i < seedsize; i++) {
+ seed[i] = (lrand48() & 0xff);
+ }
+}
+
+
+/*
+ * Generate a random public/secret key pair
+ */
+void genkeys(public, secret)
+ char *public;
+ char *secret;
+{
+ int i;
+
+# define BASEBITS (8*sizeof(short) - 1)
+# define BASE (1 << BASEBITS)
+
+ MINT *pk = itom(0);
+ MINT *sk = itom(0);
+ MINT *tmp;
+ MINT *base = itom(BASE);
+ MINT *root = itom(PROOT);
+ MINT *modulus = xtom(HEXMODULUS);
+ short r;
+ unsigned short seed[KEYSIZE/BASEBITS + 1];
+ char *xkey;
+
+ getseed((char *)seed, sizeof(seed));
+ for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
+ r = seed[i] % BASE;
+ tmp = itom(r);
+ mult(sk, base, sk);
+ madd(sk, tmp, sk);
+ mfree(tmp);
+ }
+ tmp = itom(0);
+ mdiv(sk, modulus, tmp, sk);
+ mfree(tmp);
+ pow(root, sk, modulus, pk);
+ xkey = mtox(sk);
+ adjust(secret, xkey);
+ xkey = mtox(pk);
+ adjust(public, xkey);
+ mfree(sk);
+ mfree(base);
+ mfree(pk);
+ mfree(root);
+ mfree(modulus);
+}
+
+/*
+ * Adjust the input key so that it is 0-filled on the left
+ */
+adjust(keyout, keyin)
+ char keyout[HEXKEYBYTES+1];
+ char *keyin;
+{
+ char *p;
+ char *s;
+
+ for (p = keyin; *p; p++)
+ ;
+ for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
+ *s = *p;
+ }
+ while (s >= keyout) {
+ *s-- = '0';
+ }
+}
+
+static char hextab[17] = "0123456789ABCDEF";
+
+/* given a DES key, cbc encrypt and translate input to terminated hex */
+void pk_encode(in, out, key)
+char *in,*out;
+DesData *key;
+{
+ char buf[256];
+ DesData i;
+ des_key_schedule k;
+ int l,op,deslen;
+
+ memset(&i,0,sizeof(i));
+ memset(buf,0,sizeof(buf));
+ deslen = ((strlen(in) + 7)/8)*8;
+ des_key_sched(key, k);
+ des_cbc_encrypt((des_cblock *)in,(des_cblock *)buf,deslen,
+ k,&i,DES_ENCRYPT);
+ for (l=0,op=0;l<deslen;l++) {
+ out[op++] = hextab[(buf[l] & 0xf0) >> 4];
+ out[op++] = hextab[(buf[l] & 0x0f)];
+ }
+ out[op] = '\0';
+}
+
+/* given a DES key, translate input from hex and decrypt */
+void pk_decode(in, out, key)
+char *in,*out;
+DesData *key;
+{
+ char buf[256];
+ DesData i;
+ des_key_schedule k;
+ int l,n1,n2,op;
+
+ memset(&i,0,sizeof(i));
+ memset(buf,0,sizeof(buf));
+ for (l=0,op=0;l<strlen(in)/2;l++,op+=2) {
+ if(in[op] == '0' && in[op+1] == '0') {
+ buf[l] = '\0';
+ break;
+ }
+ if (in[op] > '9')
+ n1 = in[op] - 'A' + 10;
+ else
+ n1 = in[op] - '0';
+ if (in[op+1] > '9')
+ n2 = in[op+1] - 'A' + 10;
+ else
+ n2 = in[op+1] - '0';
+ buf[l] = n1*16 +n2;
+ }
+ des_key_sched(key, k);
+ des_cbc_encrypt((des_cblock *)buf,(des_cblock *)out,strlen(in)/2,
+ k,&i,DES_DECRYPT);
+ out[strlen(in)/2] = '\0';
+}
diff --git a/crypto/telnet/libtelnet/pk.h b/crypto/telnet/libtelnet/pk.h
new file mode 100644
index 0000000..b41bba5
--- /dev/null
+++ b/crypto/telnet/libtelnet/pk.h
@@ -0,0 +1,41 @@
+/* header for the des routines that we will use */
+
+typedef unsigned char byte, DesData[ 8], IdeaData[16];
+#if 0
+typedef unsigned long word, DesKeys[32];
+#else
+#define DesKeys des_key_schedule
+#endif
+
+#define DES_DECRYPT 0
+#define DES_ENCRYPT 1
+
+#if 0
+extern void des_fixup_key_parity(); /* (DesData *key) */
+extern int des_key_sched(); /* (DesData *key, DesKeys *m) */
+extern int des_ecb_encrypt(); /* (DesData *src, *dst, DesKeys *m, int mode) */
+extern int des_cbc_encrypt(); /* (char *src, *dst, int length,
+ DesKeys *m, DesData *init, int mode) */
+#endif
+
+/* public key routines */
+/* functions:
+ genkeys(char *public, char *secret)
+ common_key(char *secret, char *public, desData *deskey)
+ where
+ char public[HEXKEYBYTES + 1];
+ char secret[HEXKEYBYTES + 1];
+ */
+
+#define HEXMODULUS "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
+#define HEXKEYBYTES 48
+#define KEYSIZE 192
+#define KEYBYTES 24
+#define PROOT 3
+
+extern void genkeys(char *public, char *secret);
+extern void common_key(char *secret, char *public, IdeaData *common,
+ DesData *deskey);
+extern void pk_encode(char *in, char *out, DesData *deskey);
+extern void pk_decode(char *in, char *out, DesData *deskey);
+
diff --git a/crypto/telnet/libtelnet/sra.c b/crypto/telnet/libtelnet/sra.c
new file mode 100644
index 0000000..44a26f2
--- /dev/null
+++ b/crypto/telnet/libtelnet/sra.c
@@ -0,0 +1,478 @@
+#ifdef SRA
+#include <sys/types.h>
+#include <arpa/telnet.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#ifdef NO_STRING_H
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+
+#include "auth.h"
+#include "misc.h"
+#include "encrypt.h"
+#include "pk.h"
+
+char pka[HEXKEYBYTES+1], ska[HEXKEYBYTES+1], pkb[HEXKEYBYTES+1];
+char *user,*pass,*xuser,*xpass;
+DesData ck;
+IdeaData ik;
+
+extern int auth_debug_mode;
+static sra_valid = 0;
+static passwd_sent = 0;
+
+static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
+ AUTHTYPE_SRA, };
+
+#define SRA_KEY 0
+#define SRA_USER 1
+#define SRA_CONTINUE 2
+#define SRA_PASS 3
+#define SRA_ACCEPT 4
+#define SRA_REJECT 5
+
+/* support routine to send out authentication message */
+static int Data(ap, type, d, c)
+Authenticator *ap;
+int type;
+void *d;
+int c;
+{
+ unsigned char *p = str_data + 4;
+ unsigned char *cd = (unsigned char *)d;
+
+ if (c == -1)
+ c = strlen((char *)cd);
+
+ if (auth_debug_mode) {
+ printf("%s:%d: [%d] (%d)",
+ str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
+ str_data[3],
+ type, c);
+ printd(d, c);
+ printf("\r\n");
+ }
+ *p++ = ap->type;
+ *p++ = ap->way;
+ *p++ = type;
+ while (c-- > 0) {
+ if ((*p++ = *cd++) == IAC)
+ *p++ = IAC;
+ }
+ *p++ = IAC;
+ *p++ = SE;
+ if (str_data[3] == TELQUAL_IS)
+ printsub('>', &str_data[2], p - (&str_data[2]));
+ return(net_write(str_data, p - str_data));
+}
+
+int sra_init(ap, server)
+Authenticator *ap;
+int server;
+{
+ if (server)
+ str_data[3] = TELQUAL_REPLY;
+ else
+ str_data[3] = TELQUAL_IS;
+
+ user = (char *)malloc(256);
+ xuser = (char *)malloc(512);
+ pass = (char *)malloc(256);
+ xpass = (char *)malloc(512);
+ passwd_sent = 0;
+
+ genkeys(pka,ska);
+ return(1);
+}
+
+/* client received a go-ahead for sra */
+int sra_send(ap)
+Authenticator *ap;
+{
+ /* send PKA */
+
+ if (auth_debug_mode)
+ printf("Sent PKA to server.\r\n" );
+ printf("Trying SRA secure login:\r\n");
+ if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) {
+ if (auth_debug_mode)
+ printf("Not enough room for authentication data\r\n");
+ return(0);
+ }
+
+ return(1);
+}
+
+/* server received an IS -- could be SRA KEY, USER, or PASS */
+void sra_is(ap, data, cnt)
+Authenticator *ap;
+unsigned char *data;
+int cnt;
+{
+ int valid;
+ Session_Key skey;
+
+ if (cnt-- < 1)
+ return;
+ switch (*data++) {
+
+ case SRA_KEY:
+ if (cnt < HEXKEYBYTES) {
+ Data(ap, SRA_REJECT, (void *)0, 0);
+ auth_finished(ap, AUTH_USER);
+ if (auth_debug_mode) {
+ printf("SRA user rejected for bad PKB\r\n");
+ }
+ return;
+ }
+ if (auth_debug_mode)
+ printf("Sent pka\r\n");
+ if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) {
+ if (auth_debug_mode)
+ printf("Not enough room\r\n");
+ return;
+ }
+ memcpy(pkb,data,HEXKEYBYTES);
+ pkb[HEXKEYBYTES] = '\0';
+ common_key(ska,pkb,&ik,&ck);
+ break;
+
+ case SRA_USER:
+ /* decode KAB(u) */
+ memcpy(xuser,data,cnt);
+ xuser[cnt] = '\0';
+ pk_decode(xuser,user,&ck);
+ auth_encrypt_user(user);
+ Data(ap, SRA_CONTINUE, (void *)0, 0);
+
+ break;
+
+ case SRA_PASS:
+ /* decode KAB(P) */
+ memcpy(xpass,data,cnt);
+ xpass[cnt] = '\0';
+ pk_decode(xpass,pass,&ck);
+
+ /* check user's password */
+ valid = check_user(user,pass);
+
+ if(valid) {
+ Data(ap, SRA_ACCEPT, (void *)0, 0);
+#ifdef DES_ENCRYPTION
+ skey.data = ck;
+ skey.type = SK_DES;
+ skey.length = 8;
+ encrypt_session_key(&skey, 1);
+#endif
+
+ sra_valid = 1;
+ auth_finished(ap, AUTH_VALID);
+ if (auth_debug_mode) {
+ printf("SRA user accepted\r\n");
+ }
+ }
+ else {
+ Data(ap, SRA_CONTINUE, (void *)0, 0);
+/*
+ Data(ap, SRA_REJECT, (void *)0, 0);
+ sra_valid = 0;
+ auth_finished(ap, AUTH_REJECT);
+*/
+ if (auth_debug_mode) {
+ printf("SRA user failed\r\n");
+ }
+ }
+ break;
+
+ default:
+ if (auth_debug_mode)
+ printf("Unknown SRA option %d\r\n", data[-1]);
+ Data(ap, SRA_REJECT, 0, 0);
+ sra_valid = 0;
+ auth_finished(ap, AUTH_REJECT);
+ break;
+ }
+}
+
+extern char *getpass();
+
+/* client received REPLY -- could be SRA KEY, CONTINUE, ACCEPT, or REJECT */
+void sra_reply(ap, data, cnt)
+Authenticator *ap;
+unsigned char *data;
+int cnt;
+{
+ extern char *telnet_gets();
+ char uprompt[256],tuser[256];
+ Session_Key skey;
+ int i;
+
+ if (cnt-- < 1)
+ return;
+ switch (*data++) {
+
+ case SRA_KEY:
+ /* calculate common key */
+ if (cnt < HEXKEYBYTES) {
+ if (auth_debug_mode) {
+ printf("SRA user rejected for bad PKB\r\n");
+ }
+ return;
+ }
+ memcpy(pkb,data,HEXKEYBYTES);
+ pkb[HEXKEYBYTES] = '\0';
+
+ common_key(ska,pkb,&ik,&ck);
+
+ enc_user:
+
+ /* encode user */
+ memset(tuser,0,sizeof(tuser));
+ sprintf(uprompt,"User (%s): ",UserNameRequested);
+ telnet_gets(uprompt,tuser,255,1);
+ if (tuser[0] == '\n' || tuser[0] == '\r' )
+ strcpy(user,UserNameRequested);
+ else {
+ /* telnet_gets leaves the newline on */
+ for(i=0;i<sizeof(tuser);i++) {
+ if (tuser[i] == '\n') {
+ tuser[i] = '\0';
+ break;
+ }
+ }
+ strcpy(user,tuser);
+ }
+ pk_encode(user,xuser,&ck);
+
+ /* send it off */
+ if (auth_debug_mode)
+ printf("Sent KAB(U)\r\n");
+ if (!Data(ap, SRA_USER, (void *)xuser, strlen(xuser))) {
+ if (auth_debug_mode)
+ printf("Not enough room\r\n");
+ return;
+ }
+ break;
+
+ case SRA_CONTINUE:
+ if (passwd_sent) {
+ passwd_sent = 0;
+ printf("[ SRA login failed ]\r\n");
+ goto enc_user;
+ }
+ /* encode password */
+ memset(pass,0,sizeof(pass));
+ telnet_gets("Password: ",pass,255,0);
+ pk_encode(pass,xpass,&ck);
+ /* send it off */
+ if (auth_debug_mode)
+ printf("Sent KAB(P)\r\n");
+ if (!Data(ap, SRA_PASS, (void *)xpass, strlen(xpass))) {
+ if (auth_debug_mode)
+ printf("Not enough room\r\n");
+ return;
+ }
+ passwd_sent = 1;
+ break;
+
+ case SRA_REJECT:
+ printf("[ SRA refuses authentication ]\r\n");
+ printf("Trying plaintext login:\r\n");
+ auth_finished(0,AUTH_REJECT);
+ return;
+
+ case SRA_ACCEPT:
+ printf("[ SRA accepts you ]\r\n");
+#ifdef DES_ENCRYPTION
+ skey.data = ck;
+ skey.type = SK_DES;
+ skey.length = 8;
+ encrypt_session_key(&skey, 0);
+#endif
+
+ auth_finished(ap, AUTH_VALID);
+ return;
+ default:
+ if (auth_debug_mode)
+ printf("Unknown SRA option %d\r\n", data[-1]);
+ return;
+ }
+}
+
+int sra_status(ap, name, level)
+Authenticator *ap;
+char *name;
+int level;
+{
+ if (level < AUTH_USER)
+ return(level);
+ if (UserNameRequested && sra_valid) {
+ strcpy(name, UserNameRequested);
+ return(AUTH_VALID);
+ } else
+ return(AUTH_USER);
+}
+
+#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
+#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
+
+void sra_printsub(data, cnt, buf, buflen)
+unsigned char *data, *buf;
+int cnt, buflen;
+{
+ char lbuf[32];
+ register int i;
+
+ buf[buflen-1] = '\0'; /* make sure its NULL terminated */
+ buflen -= 1;
+
+ switch(data[3]) {
+
+ case SRA_CONTINUE:
+ strncpy((char *)buf, " CONTINUE ", buflen);
+ goto common;
+
+ case SRA_REJECT: /* Rejected (reason might follow) */
+ strncpy((char *)buf, " REJECT ", buflen);
+ goto common;
+
+ case SRA_ACCEPT: /* Accepted (name might follow) */
+ strncpy((char *)buf, " ACCEPT ", buflen);
+
+ common:
+ BUMP(buf, buflen);
+ if (cnt <= 4)
+ break;
+ ADDC(buf, buflen, '"');
+ for (i = 4; i < cnt; i++)
+ ADDC(buf, buflen, data[i]);
+ ADDC(buf, buflen, '"');
+ ADDC(buf, buflen, '\0');
+ break;
+
+ case SRA_KEY: /* Authentication data follows */
+ strncpy((char *)buf, " KEY ", buflen);
+ goto common2;
+
+ case SRA_USER:
+ strncpy((char *)buf, " USER ", buflen);
+ goto common2;
+
+ case SRA_PASS:
+ strncpy((char *)buf, " PASS ", buflen);
+ goto common2;
+
+ default:
+ sprintf(lbuf, " %d (unknown)", data[3]);
+ strncpy((char *)buf, lbuf, buflen);
+ common2:
+ BUMP(buf, buflen);
+ for (i = 4; i < cnt; i++) {
+ sprintf(lbuf, " %d", data[i]);
+ strncpy((char *)buf, lbuf, buflen);
+ BUMP(buf, buflen);
+ }
+ break;
+ }
+}
+
+struct passwd *pw;
+
+/*
+ * Helper function for sgetpwnam().
+ */
+char *
+sgetsave(s)
+ char *s;
+{
+ char *new = malloc((unsigned) strlen(s) + 1);
+
+ if (new == NULL) {
+ return(NULL);
+ }
+ (void) strcpy(new, s);
+ return (new);
+}
+
+#include <pwd.h>
+#include <syslog.h>
+#ifdef USE_SHADOW
+#include <shadow.h>
+#endif
+
+
+struct passwd *
+sgetpwnam(name)
+ char *name;
+{
+ static struct passwd save;
+ register struct passwd *p;
+ char *sgetsave();
+
+ if ((p = getpwnam(name)) == NULL)
+ return (p);
+ if (save.pw_name) {
+ free(save.pw_name);
+ free(save.pw_passwd);
+ free(save.pw_gecos);
+ free(save.pw_dir);
+ free(save.pw_shell);
+ }
+ save = *p;
+ save.pw_name = sgetsave(p->pw_name);
+ save.pw_passwd = sgetsave(p->pw_passwd);
+ save.pw_gecos = sgetsave(p->pw_gecos);
+ save.pw_dir = sgetsave(p->pw_dir);
+ save.pw_shell = sgetsave(p->pw_shell);
+#if 0
+syslog(LOG_WARNING,"%s\n",save.pw_name);
+syslog(LOG_WARNING,"%s\n",save.pw_passwd);
+syslog(LOG_WARNING,"%s\n",save.pw_gecos);
+syslog(LOG_WARNING,"%s\n",save.pw_dir);
+#endif
+#ifdef USE_SHADOW
+ {
+ struct spwd *sp;
+ sp = getspnam(name);
+ free(save.pw_passwd);
+ save.pw_passwd = sgetsave(sp->sp_pwdp);
+ }
+#endif
+ return (&save);
+}
+
+char *crypt();
+
+int check_user(name, pass)
+char *name;
+char *pass;
+{
+ register char *cp;
+ char *xpasswd, *salt;
+
+ if (pw = sgetpwnam(name)) {
+ if (pw->pw_shell == NULL) {
+ pw = (struct passwd *) NULL;
+ return(0);
+ }
+
+ salt = pw->pw_passwd;
+ xpasswd = crypt(pass, salt);
+ /* The strcmp does not catch null passwords! */
+ if (pw == NULL || *pw->pw_passwd == '\0' ||
+ strcmp(xpasswd, pw->pw_passwd)) {
+ pw = (struct passwd *) NULL;
+ return(0);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+
+#endif
+
OpenPOWER on IntegriCloud