mirror of
https://github.com/sheumann/telnetd.git
synced 2024-11-22 01:31:54 +00:00
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
This commit is contained in:
parent
1549f66b7a
commit
0f2c0f75fe
4
Makefile
Normal file
4
Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
SUBDIR= libtelnet telnetd telnet
|
||||
|
||||
.include <bsd.subdir.mk>
|
@ -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
|
||||
|
19
libtelnet/Makefile
Normal file
19
libtelnet/Makefile
Normal file
@ -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>
|
@ -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
|
||||
|
@ -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, },
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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])
|
||||
|
266
libtelnet/pk.c
Normal file
266
libtelnet/pk.c
Normal file
@ -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';
|
||||
}
|
41
libtelnet/pk.h
Normal file
41
libtelnet/pk.h
Normal file
@ -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);
|
||||
|
478
libtelnet/sra.c
Normal file
478
libtelnet/sra.c
Normal file
@ -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
|
||||
|
52
telnet/Makefile
Normal file
52
telnet/Makefile
Normal file
@ -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 <bsd.prog.mk>
|
||||
|
24
telnetd/Makefile
Normal file
24
telnetd/Makefile
Normal file
@ -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 <bsd.prog.mk>
|
Loading…
Reference in New Issue
Block a user