From 0f2c0f75feb1302063fa8edce3ffa8874d4fc00a Mon Sep 17 00:00:00 2001 From: nsayer Date: Mon, 16 Aug 1999 11:24:29 +0000 Subject: [PATCH] Add SRA authentication to src/crypto/telnet. SRA does a Diffie-Hellmen exchange and then DES-encrypts the authentication data. If the authentication is successful, it also sets up a session key for DES encryption. SRA was originally developed at Texas A&M University. This code is probably export restricted (despite the fact that I originally found it at a University in Germany). SRA is not perfect. It is vulnerable to monkey-in-the-middle attacks and does not use tremendously large DH constants (and thus an individual exchange probably could be factored in a few days on modern CPU horsepower). It does not, however, require any changes in user or administrative behavior and foils session hijacking and sniffing. The goal of this commit is that telnet and telnetd end up in the DES distribution and that therefore an encrypted session telnet becomes standard issue for FreeBSD. git-svn-id: http://svn0.us-east.freebsd.org/base/head/contrib/telnet@49887 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- Makefile | 4 + arpa/telnet.h | 5 +- libtelnet/Makefile | 19 ++ libtelnet/auth-proto.h | 8 + libtelnet/auth.c | 10 + libtelnet/enc-proto.h | 2 + libtelnet/encrypt.c | 15 +- libtelnet/encrypt.h | 5 + libtelnet/pk.c | 266 +++++++++++++++++++++++ libtelnet/pk.h | 41 ++++ libtelnet/sra.c | 478 +++++++++++++++++++++++++++++++++++++++++ telnet/Makefile | 52 +++++ telnetd/Makefile | 24 +++ 13 files changed, 923 insertions(+), 6 deletions(-) create mode 100644 Makefile create mode 100644 libtelnet/Makefile create mode 100644 libtelnet/pk.c create mode 100644 libtelnet/pk.h create mode 100644 libtelnet/sra.c create mode 100644 telnet/Makefile create mode 100644 telnetd/Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..079eb0b --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ + +SUBDIR= libtelnet telnetd telnet + +.include diff --git a/arpa/telnet.h b/arpa/telnet.h index 01601f1..8a17ff1 100644 --- a/arpa/telnet.h +++ b/arpa/telnet.h @@ -280,13 +280,14 @@ extern char *slc_names[]; #define AUTHTYPE_KERBEROS_V5 2 #define AUTHTYPE_SPX 3 #define AUTHTYPE_MINK 4 -#define AUTHTYPE_CNT 5 +#define AUTHTYPE_SRA 6 +#define AUTHTYPE_CNT 7 #define AUTHTYPE_TEST 99 #ifdef AUTH_NAMES char *authtype_names[] = { - "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", NULL, "SRA", 0 }; #else diff --git a/libtelnet/Makefile b/libtelnet/Makefile new file mode 100644 index 0000000..3ef7f94 --- /dev/null +++ b/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 diff --git a/libtelnet/auth-proto.h b/libtelnet/auth-proto.h index a1e9aa4..c62fe5f 100644 --- a/libtelnet/auth-proto.h +++ b/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/libtelnet/auth.c b/libtelnet/auth.c index 4262b55..d574b1e 100644 --- a/libtelnet/auth.c +++ b/libtelnet/auth.c @@ -184,6 +184,16 @@ Authenticator authenticators[] = { rsaencpwd_reply, 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/libtelnet/enc-proto.h b/libtelnet/enc-proto.h index 8e15ffd..8cec406 100644 --- a/libtelnet/enc-proto.h +++ b/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/libtelnet/encrypt.c b/libtelnet/encrypt.c index 41dd5cc..e1ac1c4 100644 --- a/libtelnet/encrypt.c +++ b/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/libtelnet/encrypt.h b/libtelnet/encrypt.h index 1c942dc..14be826 100644 --- a/libtelnet/encrypt.h +++ b/libtelnet/encrypt.h @@ -60,9 +60,14 @@ #define DIR_DECRYPT 1 #define DIR_ENCRYPT 2 +#include 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/libtelnet/pk.c b/libtelnet/pk.c new file mode 100644 index 0000000..78e474f --- /dev/null +++ b/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 +#include +#include +#include +#include +#include "mp.h" +#include "pk.h" +#if defined(SOLARIS2) || defined(LINUX) +#include +#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> 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 '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/libtelnet/pk.h b/libtelnet/pk.h new file mode 100644 index 0000000..b41bba5 --- /dev/null +++ b/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/libtelnet/sra.c b/libtelnet/sra.c new file mode 100644 index 0000000..44a26f2 --- /dev/null +++ b/libtelnet/sra.c @@ -0,0 +1,478 @@ +#ifdef SRA +#include +#include +#include +#ifdef __STDC__ +#include +#endif +#ifdef NO_STRING_H +#include +#else +#include +#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 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 +#include +#ifdef USE_SHADOW +#include +#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 + diff --git a/telnet/Makefile b/telnet/Makefile new file mode 100644 index 0000000..2996a67 --- /dev/null +++ b/telnet/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (c) 1990 The Regents of the University of California. +# 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. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +# +# @(#)Makefile 8.1 (Berkeley) 6/6/93 +# $Id: Makefile,v 1.16 1996/11/07 14:42:39 markm dead $ +# + +DISTRIBUTION= des + +PROG= telnet +BINDIR= /usr/bin + +SRCS= authenc.c commands.c main.c network.c ring.c sys_bsd.c telnet.c \ + terminal.c tn3270.c utilities.c + +CFLAGS+=-DTERMCAP -DKLUDGELINEMODE -DUSE_TERMIO -DENV_HACK -DENCRYPTION +CFLAGS+=-DAUTHENTICATION +CFLAGS+=-I${.CURDIR}/.. +LDADD+= -L${.CURDIR}/../libtelnet -ltermcap -ltelnet -ldes -lmp -lcrypt +DPADD+= ${.CURDIR}/../libtelnet.a ${LIBTERMCAP} ${LIBDES} ${LIBMP} ${LIBCRYPT} + +.include + diff --git a/telnetd/Makefile b/telnetd/Makefile new file mode 100644 index 0000000..4cda186 --- /dev/null +++ b/telnetd/Makefile @@ -0,0 +1,24 @@ +# @(#)Makefile 8.2 (Berkeley) 12/15/93 +# $Id: Makefile,v 1.2.6.6 1996/06/30 12:50:55 markm Exp $ + +# Do not define -DKLUDGELINEMODE, as it does not interact well with many +# telnet implementations. + +DISTRIBUTION= des + +PROG= telnetd +MAN8= telnetd.8 + +BINDIR= /usr/libexec + +SRCS= authenc.c global.c slc.c state.c sys_term.c telnetd.c \ + termstat.c utility.c + +DPADD= ${.CURDIR}/../libtelnet.a ${LIBUTIL} ${LIBTERMCAP} ${LIBDES} ${LIBMP} +DPADD+= ${LIBCRYPT} +LDADD= -L${.CURDIR}/../libtelnet -lutil -ltermcap -ltelnet -ldes -lmp -lcrypt + +CFLAGS+= -DLINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK +CFLAGS+= -DENCRYPTION -DAUTHENTICATION -I${.CURDIR}/../ + +.include