summaryrefslogtreecommitdiffstats
path: root/lib/libskey/skeysubr.c
blob: e144202a765536065dbcf45ffb10e94437ec3ce2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef	__MSDOS__
#include <dos.h>
#endif
#ifdef unix
#include <fcntl.h>
#include <termios.h>
#include <signal.h>
#endif

#include "skey.h"
#include "mdx.h"

/* Crunch a key:
 * concatenate the seed and the password, run through MD4 and
 * collapse to 64 bits. This is defined as the user's starting key.
 */
int
keycrunch(result,seed,passwd)
char *result;   /* 8-byte result */
char *seed;     /* Seed, any length */
char *passwd;   /* Password, any length */
{
	char *buf;
	MDX_CTX md;
	u_long results[4];
	unsigned int buflen;
	
	buflen = strlen(seed) + strlen(passwd);
	if((buf = malloc(buflen+1)) == NULL)
		return -1;
	strcpy(buf,seed);
	strcat(buf,passwd);

	/* Crunch the key through MD[45] */
	sevenbit(buf);
	MDXInit(&md);
	MDXUpdate(&md,(unsigned char *)buf,buflen);
	MDXFinal((unsigned char *)results,&md);
	free(buf);

	results[0] ^= results[2];
	results[1] ^= results[3];

	memcpy(result,(char *)results,8);

	return 0;
}

/* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */
void
f(x)
char *x;
{
	MDX_CTX md;
	u_long results[4];

	MDXInit(&md);
	MDXUpdate(&md,(unsigned char *)x,8);
	MDXFinal((unsigned char *)results,&md);
	/* Fold 128 to 64 bits */
	results[0] ^= results[2];
	results[1] ^= results[3];

	/* Only works on byte-addressed little-endian machines!! */
	memcpy(x,(char *)results,8);
}

/* Strip trailing cr/lf from a line of text */
void
rip(buf)
char *buf;
{
	char *cp;

	if((cp = strchr(buf,'\r')) != NULL)
		*cp = '\0';

	if((cp = strchr(buf,'\n')) != NULL)
		*cp = '\0';
}
/************************/
#ifdef	__MSDOS__
char *
readpass(buf,n)
char *buf;
int n;
{
	int i;
	char *cp;

	for(cp=buf,i = 0; i < n ; i++)
		if ((*cp++ = bdos(7,0,0)) == '\r')
			break;
	*cp = '\0';
	printf("\n");
	rip(buf);
	return buf;
}
#else
static struct termios saved_ttymode;

static void interrupt()
{
	tcsetattr(0, TCSANOW, &saved_ttymode);
	exit(1);
}

char *
readpass(buf,n)
char *buf;
int n;
{
	struct termios noecho_ttymode;
	void (*oldsig)();

	/* Save normal line editing modes */
	tcgetattr(0, &saved_ttymode);
	if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN)
		signal(SIGINT, interrupt);

	/* Turn off echoing */
	tcgetattr(0, &noecho_ttymode);
	noecho_ttymode.c_lflag &= ~ECHO;
	tcsetattr(0, TCSANOW, &noecho_ttymode);
	fgets(buf,n,stdin);
	rip(buf);

	/* Restore previous tty modes */
	tcsetattr(0, TCSANOW, &saved_ttymode);
	if (oldsig != SIG_IGN)
		signal(SIGINT, oldsig);

	/*
	after the secret key is taken from the keyboard, the line feed is
	written to standard error instead of standard output.  That means that
	anyone using the program from a terminal won't notice, but capturing
	standard output will get the key words without a newline in front of
	them. 
	*/
        fprintf(stderr, "\n");
        fflush(stderr);
	sevenbit(buf);

	return buf;
}

#endif

sevenbit(s)
char *s;
{
	/* make sure there are only 7 bit code in the line*/
	while(*s){
		*s = 0x7f & ( *s);
		s++;
	}
}
OpenPOWER on IntegriCloud