Collapse gd_astpending and gd_reqpri together into gd_reqflags. gd_reqflags
[dragonfly.git] / lib / libskey / skeysubr.c
1 /* $FreeBSD: src/lib/libskey/skeysubr.c,v 1.9.6.1 2000/07/20 20:13:42 obrien Exp $ */
2 /* $DragonFly: src/lib/libskey/skeysubr.c,v 1.2 2003/06/17 04:26:51 dillon Exp $ */
3
4 #include <err.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <fcntl.h>
9 #include <termios.h>
10 #include <signal.h>
11
12 #include "skey.h"
13 #include "mdx.h"
14
15 /* Crunch a key:
16  * concatenate the seed and the password, run through MDX and
17  * collapse to 64 bits. This is defined as the user's starting key.
18  */
19 int
20 keycrunch(result,seed,passwd)
21 char *result;   /* 8-byte result */
22 const char *seed;     /* Seed, any length */
23 const char *passwd;   /* Password, any length */
24 {
25         char *buf;
26         MDX_CTX md;
27         u_int32_t results[4];
28         unsigned int buflen;
29
30         buflen = strlen(seed) + strlen(passwd);
31         if((buf = malloc(buflen+1)) == NULL)
32                 return -1;
33         strcpy(buf,seed);
34         strcat(buf,passwd);
35
36         /* Crunch the key through MD[45] */
37         sevenbit(buf);
38         MDXInit(&md);
39         MDXUpdate(&md,(unsigned char *)buf,buflen);
40         MDXFinal((unsigned char *)results,&md);
41         free(buf);
42
43         results[0] ^= results[2];
44         results[1] ^= results[3];
45
46         memcpy(result,(char *)results,8);
47
48         return 0;
49 }
50
51 /* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */
52 void
53 f(x)
54 char *x;
55 {
56         MDX_CTX md;
57         u_int32_t results[4];
58
59         MDXInit(&md);
60         MDXUpdate(&md,(unsigned char *)x,8);
61         MDXFinal((unsigned char *)results,&md);
62         /* Fold 128 to 64 bits */
63         results[0] ^= results[2];
64         results[1] ^= results[3];
65
66         memcpy(x,(char *)results,8);
67 }
68
69 /* Strip trailing cr/lf from a line of text */
70 void
71 rip(buf)
72 char *buf;
73 {
74         buf[strcspn(buf, "\r\n")] = 0;
75 }
76
77 static struct termios saved_ttymode;
78
79 static void interrupt __P((int));
80
81 static void interrupt(sig)
82 int sig;
83 {
84         tcsetattr(0, TCSANOW, &saved_ttymode);
85         err(1, "interrupted by signal %s", sys_siglist[sig]);
86 }
87
88 char *
89 readpass(buf,n)
90 char *buf;
91 int n;
92 {
93         struct termios noecho_ttymode;
94         void (*oldsig) __P((int));
95
96         /* Save normal line editing modes */
97         tcgetattr(0, &saved_ttymode);
98         if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN)
99                 signal(SIGINT, interrupt);
100
101         /* Turn off echoing */
102         tcgetattr(0, &noecho_ttymode);
103         noecho_ttymode.c_lflag &= ~ECHO;
104         tcsetattr(0, TCSANOW, &noecho_ttymode);
105         fgets(buf,n,stdin);
106         rip(buf);
107
108         /* Restore previous tty modes */
109         tcsetattr(0, TCSANOW, &saved_ttymode);
110         if (oldsig != SIG_IGN)
111                 signal(SIGINT, oldsig);
112
113         /*
114         after the secret key is taken from the keyboard, the line feed is
115         written to standard error instead of standard output.  That means that
116         anyone using the program from a terminal won't notice, but capturing
117         standard output will get the key words without a newline in front of
118         them.
119         */
120         fprintf(stderr, "\n");
121         fflush(stderr);
122         sevenbit(buf);
123
124         return buf;
125 }
126
127 void
128 sevenbit(s)
129 char *s;
130 {
131         /* make sure there are only 7 bit code in the line*/
132         while(*s){
133                 *s &= 0x7f;
134                 s++;
135         }
136 }