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