/[pkg-mixmaster]/trunk/Mix2.0/Src/server.c
ViewVC logotype

Contents of /trunk/Mix2.0/Src/server.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 200 - (hide annotations) (download)
Wed Aug 28 20:06:48 2002 UTC (10 years, 9 months ago) by rabbi
File MIME type: text/plain
File size: 7736 byte(s)
Initial revision
1 rabbi 200
2     /* $Id: server.c,v 1.1 2002/08/28 20:06:50 rabbi Exp $
3     * $Log: server.c,v $
4     * Revision 1.1 2002/08/28 20:06:50 rabbi
5     * Initial revision
6     *
7     * Revision 2.4 1998/08/21 13:26:08 um
8     * *** empty log message ***
9     *
10     * Revision 2.3 1998/04/13 23:22:29 um
11     * re-indented.
12     *
13     * Revision 2.2 1998/02/26 02:25:32 um
14     * Changes for BSAFEeay.
15     *
16     *
17     * server.c 1997-11-08 um
18     * simple socket protocol completed.
19     *
20     * server.c (from Anonymous)
21     */
22    
23     #include <string.h>
24     #include <signal.h>
25     #include <stdlib.h>
26     #include <sys/wait.h>
27     #include "mix.h"
28     #include "inet.h"
29    
30     R_DH_PARAMS DH_params;
31     unsigned char prime[DH_PRIME_LEN (1024)], generator[DH_PRIME_LEN (1024)];
32     unsigned char your_publicDH[DH_PRIME_LEN (1024)];
33     unsigned char my_publicDH[DH_PRIME_LEN (1024)];
34     unsigned char my_privateDH[DH_PRIME_LEN (1024)];
35     unsigned char agreedKey[DH_PRIME_LEN (1024)];
36     unsigned char RND1[16], RND2[16];
37     int server_privateDH_len = 700;
38     R_ENVELOPE_CTX rsa_context;
39     R_RSA_PRIVATE_KEY privKey;
40     R_RSA_PUBLIC_KEY pubKey;
41     R_DIGEST_CTX digest_context;
42     unsigned int numPubKeys, keylen;
43    
44    
45     /* send greeting message to client program */
46     int
47     send_greeting (int fd)
48     {
49     char line[1024];
50    
51     sprintf (line, "200-Mixmaster Version %s\n200 Welcome to %s!\n",
52     VERSION, REMAILERNAME);
53     return (writestr (fd, line));
54     }
55    
56     int
57     get_key_request (int fd)
58     {
59     char line[1024], *ptr;
60     int i, error;
61     int t[16];
62     byte ID[16];
63     FILE *fptr;
64    
65     readline (fd, line, sizeof (line));
66     if (strileft (line, "Quit"))
67     return (0);
68     if (strileft (line, "SendKey "))
69     {
70     ptr = line + strlen ("SendKey ");
71     sscanf (ptr, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
72     t, t + 1, t + 2, t + 3, t + 4, t + 5, t + 6, t + 7, t + 8, t + 9,
73     t + 10, t + 11, t + 12, t + 13, t + 14, t + 15);
74     for (i = 0; i < 16; i++)
75     ID[i] = t[i];
76     error = get_priv_key (ID, &privKey);
77     error += get_pub_key (ID, &pubKey);
78     if (error)
79     {
80     writestr (fd, "400 not found\n");
81     return (0);
82     }
83     else
84     {
85     writestr (fd, "210 Sending key\n");
86     /* start sending the keyring */
87     if ((fptr = open_mix_file ("pubring.mix", "r")) == NULL)
88     {
89     writestr (fd, "500 Internal error: no key file\n");
90     return (0);
91     }
92     while (fgets (line, 1024, fptr) != NULL)
93     writestr (fd, line);
94     fclose (fptr);
95     writestr (fd, "\n-----End Key File-----\n");
96     return (1);
97     }
98     }
99     else if (strileft (line, "ConfirmKey "))
100     {
101     ptr = line + strlen ("ConfirmKey ");
102     sscanf (ptr, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
103     t, t + 1, t + 2, t + 3, t + 4, t + 5, t + 6, t + 7, t + 8, t + 9,
104     t + 10, t + 11, t + 12, t + 13, t + 14, t + 15);
105     for (i = 0; i < 16; i++)
106     ID[i] = t[i];
107     error = get_priv_key (ID, &privKey);
108     error += get_pub_key (ID, &pubKey);
109     if (error)
110     {
111     writestr (fd, "400 not found\n");
112     return (0);
113     }
114     else
115     {
116     writestr (fd, "100 Confirm key available\n");
117     return (1);
118     }
119     }
120     writestr (fd, "400 Command unrecognized\n");
121     return (0); /* I don't know what he said */
122     }
123    
124     /* Get the DH parameters to generate the shared key */
125     int
126     get_DH_params (int fd)
127     {
128     unsigned char *ptr;
129     BUFFER *buf;
130    
131     DH_params.prime = prime;
132     DH_params.generator = generator;
133     buf = new_buffer ();
134     readbuf (fd, buf);
135     ptr = buf->message;
136    
137     DH_params.primeLen = *ptr;
138     ptr++;
139     R_memcpy (DH_params.prime, ptr, DH_PRIME_LEN (1024));
140     ptr += DH_PRIME_LEN (1024);
141     DH_params.generatorLen = *ptr;
142     ptr++;
143     R_memcpy (DH_params.generator, ptr, DH_PRIME_LEN (1024));
144     return (1);
145     }
146    
147     /* Send server keyhalf for DH exchange */
148     int
149     send_server_keyhalf (int fd)
150     {
151     /* Calculate DH key half, and agreed key using other half */
152     if (R_SetupDHAgreement (my_publicDH, my_privateDH, server_privateDH_len,
153     &DH_params, random_obj))
154     return (0);
155    
156     writen (fd, my_publicDH, DH_PRIME_LEN (1024));
157     return (1);
158     }
159    
160     /* Get keyhalf from client. It is encrypted to us */
161     int
162     get_client_keyhalf (int fd)
163     {
164     int len, olen, keylen;
165     unsigned char key[MAX_ENCRYPTED_KEY_LEN];
166     unsigned char *ptr, iv[8];
167     BUFFER *buf;
168    
169     buf = new_buffer ();
170     readbuf (fd, buf);
171     ptr = buf->message;
172     len = buf->length;
173    
174     memcpy (iv, ptr, 8);
175     ptr += 8;
176     len -= 8;
177     keylen = *ptr++; /* length of encrypted key */
178     len--;
179     memcpy (key, ptr, keylen);
180     ptr += keylen;
181     len -= keylen;
182     if (R_OpenInit (&rsa_context, EA_DES_EDE3_CBC, key, keylen, iv, &privKey))
183     return (0);
184     R_OpenUpdate (&rsa_context, your_publicDH, &olen, ptr, len);
185     if (R_OpenFinal (&rsa_context, your_publicDH + olen, &olen))
186     return (0);
187     else
188     return (1);
189     }
190    
191     /* Get the message from the client */
192     int
193     get_message (int fd)
194     {
195     BUFFER *msg;
196     unsigned char iv[9];
197    
198     if (R_ComputeDHAgreedKey (agreedKey, your_publicDH, my_privateDH,
199     server_privateDH_len, &DH_params))
200     return (0);
201    
202     msg = new_buffer ();
203    
204     /* Ok, now we get the message */
205     readn (fd, iv, 8);
206     readbuf (fd, msg);
207     crypt_in_buffer (agreedKey, iv, msg, 0);
208    
209     if (type2_dec (msg, msg->message + msg->length - 16) == 0)
210     {
211     stats (FL_MESSAGE | FL_NEW, NULL); /* count one type 2 message */
212     return (1);
213     }
214     else
215     return (0);
216     }
217    
218     int
219     send_fail (int fd)
220     {
221     return (writestr (fd, "400 Message Corrupted\n"));
222     }
223    
224    
225     int
226     send_confirmation (int fd)
227     {
228     return (writestr (fd, "200 Message Valid\n"));
229     }
230    
231     int
232     get_quit (int fd)
233     {
234     char line[256];
235    
236     readline (fd, line, sizeof (line));
237     if (strileft (line, "quit"))
238     return (1);
239     else
240     return (0);
241     }
242    
243     int
244     protocol (int fd)
245     {
246    
247     int ok;
248    
249     ok = send_greeting (fd);
250     if (!ok)
251     return (ok);
252    
253     ok = get_key_request (fd);
254     if (!ok)
255     return (ok);
256    
257     ok = get_DH_params (fd);
258     if (!ok)
259     return (ok);
260    
261     ok = get_client_keyhalf (fd);
262     if (!ok)
263     return (ok);
264    
265     ok = send_server_keyhalf (fd);
266     if (!ok)
267     return (ok);
268    
269     ok = get_message (fd);
270     if (!ok)
271     {
272     send_fail (fd);
273     return (ok);
274     }
275    
276     ok = send_confirmation (fd);
277     if (!ok)
278     return (ok);
279    
280     ok = get_quit (fd);
281     return (ok);
282     }
283    
284     int
285     mix_server (int dofork)
286     {
287     int sockfd, newsockfd, clilen, childpid = 0;
288     struct sockaddr_in cli_addr, serv_addr;
289    
290     /*
291     * Open a TCP socket (an Internet stream socket).
292     */
293    
294     if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
295     {
296     fprintf (errlog, "server: can't open stream socket\n");
297     return (1);
298     }
299     /*
300     * Bind our local address so that the client can send to us
301     */
302    
303     bzero ((char *) &serv_addr, sizeof (serv_addr));
304     serv_addr.sin_family = AF_INET;
305     serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
306     serv_addr.sin_port = htons (SERV_TCP_PORT);
307    
308     if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
309     {
310     fprintf (errlog, "server: can't bind local address\n");
311     return (2);
312     }
313    
314     if (listen (sockfd, 5) < 0)
315     {
316     fprintf (errlog, "server: listen failed\n");
317     return (3);
318     }
319    
320     signal (SIGCHLD, server_chld);/* this eliminates zombies */
321     signal (SIGPIPE, server_close);
322    
323     for (;;)
324     {
325     /*
326     * Wait for a connection from a client process.
327     */
328    
329     clilen = sizeof (cli_addr);
330     newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen);
331    
332     if (newsockfd < 0)
333     fprintf (errlog, "server: accept error\n");
334    
335     if (dofork == 1)
336     if ((childpid = fork ()) < 0)
337     {
338     fprintf (errlog, "server: fork error\n");
339     return (4);
340     }
341    
342     if (childpid == 0)
343     { /* child process */
344     close (sockfd); /* close original socket */
345     protocol (newsockfd);
346     server_close (0);
347     }
348    
349     close (newsockfd); /* parent process */
350     }
351     }
352    
353     void
354     server_close (int sig)
355     {
356     close_our_random ();
357     exit (0);
358     }
359    
360     void
361     server_chld (int sig)
362     {
363     while (waitpid (-1, NULL, WNOHANG) > 0)
364     ;
365     }

  ViewVC Help
Powered by ViewVC 1.1.5