creating connections
[rxpd] / rxpd.c
1 /*
2     rxpd.c - regex policy daemon
3
4   Copyright (C)
5     2007,               Christian Thaeter <ct@pipapo.org>
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "rxpd.h"
23
24 static struct rxpd_base global_base = {NULL};
25
26 struct rxpd_base*
27 rxpd_init (char* rulesdir)
28 {
29   if (global_base.rulesdir)
30     return NULL;
31
32   global_base.rulesdir = strdup (rulesdir);
33   if (!global_base.rulesdir) abort();
34
35   psplay_init_root (&global_base.files, rxpd_file_cmp, rxpd_file_delete);
36
37   llist_init (&global_base.sockets_pending);
38   llist_init (&global_base.sockets_active);
39   llist_init (&global_base.connections_pending);
40   llist_init (&global_base.connections_active);
41
42   return &global_base;
43 }
44
45 void
46 rxpd_destroy (void)
47 {
48   if (global_base.rulesdir)
49     {
50       free (global_base.rulesdir);
51       psplay_destroy_root (&global_base.files);
52       LLIST_WHILE_HEAD (&global_base.sockets_pending, n)
53         {
54           struct rxpd_socket* socket = (struct rxpd_socket*)n;
55           rxpd_socket_delete (socket);
56         }
57       LLIST_WHILE_HEAD (&global_base.sockets_active, n)
58         {
59           struct rxpd_socket* socket = (struct rxpd_socket*)n;
60           rxpd_socket_delete (socket);
61         }
62       LLIST_WHILE_HEAD (&global_base.connections_pending, n)
63         {
64           struct rxpd_connection* connection = (struct rxpd_connection*)n;
65           rxpd_connection_delete (connection);
66         }
67       LLIST_WHILE_HEAD (&global_base.connections_active, n)
68         {
69           struct rxpd_connection* connection = (struct rxpd_connection*)n;
70           rxpd_connection_delete (connection);
71         }
72     }
73 }
74
75
76 //
77 struct rxpd_rule*
78 rxpd_rule_new (const char* buf)
79 {
80   struct rxpd_rule* self = malloc (sizeof (struct rxpd_rule));
81   if (self)
82     {
83       llist_init (&self->node);
84
85       if (*buf != '#')
86         {
87           int err;
88           char* rxstart = strchr (buf, ':') + 1;
89
90           err = regcomp (&self->rx, rxstart, REG_EXTENDED|REG_ICASE|REG_NOSUB);
91
92           if (!err)
93             {
94               self->string = strdup (buf);
95               if (!self->string) abort();
96             }
97           else
98             {
99               regfree (&self->rx);
100               char ebuf[256];
101               size_t len = regerror (err, NULL, ebuf, 256);
102               self->string = malloc(len + strlen(buf) + 9);
103               if (!self->string) abort();
104               strcpy (self->string, "# ");
105               strcat (self->string, ebuf);
106               strcat (self->string, " in '");
107               strcat (self->string, buf);
108               strcat (self->string, "'");
109             }
110         }
111       else
112         {
113           self->string = strdup (buf);
114           if (!self->string) abort();
115         }
116     }
117   return self;
118 }
119
120 void
121 rxpd_rule_delete (struct rxpd_rule* rule)
122 {
123   if (rule)
124     {
125       llist_unlink (&rule->node);
126       if (rule->string[0] != '#')
127         regfree (&rule->rx);
128       free (rule->string);
129       free(rule);
130     }
131 }
132
133 //
134
135
136 int
137 rxpd_file_load (struct rxpd_base* base, const char* filename)
138 {
139   char buf[2048];
140
141   // TODO better filenname validation / error handling
142   if (!filename ||
143       strchr (filename, '/') ||
144       strlen (filename) + strlen (base->rulesdir) > 2047)
145     abort();
146
147   strcpy (buf, base->rulesdir);
148   strcat (buf, filename);
149   filename = strdup (buf);
150
151   struct rxpd_file* file = malloc (sizeof (struct rxpd_file));
152   if (!file || !filename) abort();
153
154   psplay_init (&file->node, filename);
155   llist_init (&file->rules);
156   
157   FILE* f = fopen (filename, "r");
158   // TODO error handling
159   if (!f) abort();
160
161   // TODO test excess line length = error
162   while (fgets (buf, 2048, f))
163     {
164       size_t last = strlen(buf);
165       if (buf[last-1] == '\n')
166         buf[last-1] = '\0';
167
168       struct rxpd_rule* rule;
169       rule = rxpd_rule_new (buf);
170       if (!rule)
171         abort();
172
173
174       printf("%s\n", rule->string);
175
176       llist_insert_tail (&file->rules, &rule->node);
177     }
178
179   fclose (f);
180
181   psplay_insert (&base->files, &file->node);
182
183   return 0;
184 }
185
186 void
187 rxpd_file_delete (PSplay f)
188 {
189   if (f)
190     {
191       struct rxpd_file* file = (struct rxpd_file*)f;
192       LLIST_WHILE_HEAD (&file->rules, n)
193         {
194           struct rxpd_rule* node = (struct rxpd_rule*)n;
195           rxpd_rule_delete (node);
196         }
197       free ((void*)file->node.key);
198       free (f);
199     }
200 }
201
202 int
203 rxpd_file_cmp (const void* A, const void* B)
204 {
205   return strcmp (A, B);
206 }
207
208
209 //
210
211 struct rxpd_socket*
212 rxpd_socket_new_tcp4 (struct rxpd_base* base, const char* addr, unsigned short port)
213 {
214   struct rxpd_socket* self = malloc (sizeof (struct rxpd_socket));
215   if (!self)
216     abort();
217
218   self->base = base;
219
220   llist_init (&self->node);
221
222   self->fd = socket (PF_INET, SOCK_STREAM, 0);
223   if (self->fd == -1)
224     abort ();
225
226   struct sockaddr_in listen_addr;
227   memset (&listen_addr, 0, sizeof (listen_addr));
228
229   listen_addr.sin_family = AF_INET;
230   if (inet_aton (addr?addr:"0.0.0.0", &listen_addr.sin_addr) == 0)
231     abort();
232   listen_addr.sin_port = htons(port);
233
234   if (bind (self->fd, (struct sockaddr*)&listen_addr, sizeof (listen_addr)) == -1)
235     abort();
236
237   static int yes=1;
238   if (setsockopt (self->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
239     abort ();
240
241   if (listen (self->fd, 20) == -1)
242     abort ();
243
244   event_set (&self->ev, self->fd, EV_READ, rxpd_socket_accept, self);
245   llist_insert_tail (&base->sockets_pending, &self->node);
246   return self;
247 }
248
249
250 void
251 rxpd_socket_delete (struct rxpd_socket* self)
252 {
253   if (self)
254     {
255       event_del (&self->ev);
256       llist_unlink (&self->node);
257       close (self->fd);
258     }
259   free (self);
260 }
261
262 struct rxpd_socket*
263 rxpd_socket_activate (struct rxpd_socket* self)
264 {
265   if (self)
266     {
267       llist_insert_tail (&self->base->sockets_active, &self->node);
268       event_add (&self->ev, NULL);
269     }
270   return self;
271 }
272
273 struct rxpd_socket*
274 rxpd_socket_suspend (struct rxpd_socket* self)
275 {
276   if (self)
277     {
278       event_del (&self->ev);
279       llist_insert_tail (&self->base->sockets_pending, &self->node);
280     }
281   return self;
282 }
283
284 void
285 rxpd_socket_accept (int fd, short event, void* ptr)
286 {
287   printf ("incoming connection\n");
288
289   struct rxpd_socket* sock = ptr;
290
291   struct rxpd_connection* conn =
292     rxpd_connection_new (sock->base, fd);
293
294   rxpd_connection_activate (conn);
295 }
296
297 ///
298
299 struct rxpd_connection*
300 rxpd_connection_new (struct rxpd_base* base, int fd)
301 {
302   struct rxpd_connection* self = malloc (sizeof (struct rxpd_connection));
303   if (!self)
304     abort();
305
306   llist_init (&self->node);
307
308   socklen_t addr_sz = sizeof (self->peer_addr); 
309   self->fd = accept (fd, (struct sockaddr*)&self->peer_addr, &addr_sz);
310   if (self->fd == -1)
311     abort ();
312
313   self->base = base;
314   self->file = NULL;
315
316   self->eol = self->eob = self->buffer;
317   
318   event_set (&self->ev, self->fd, EV_READ, rxpd_connection_parse_cmd, self);
319
320   llist_insert_tail (&base->connections_pending, &self->node);
321
322   return self;
323 }
324
325 void
326 rxpd_connection_delete (struct rxpd_connection* self)
327 {
328   if (self)
329     {
330       event_del (&self->ev);
331       llist_unlink (&self->node);
332       close (self->fd);
333     }
334   free (self);
335 }
336
337 struct rxpd_connection*
338 rxpd_connection_activate (struct rxpd_connection* self)
339 {
340   if (self)
341     {
342       llist_insert_tail (&self->base->connections_active, &self->node);
343       event_add (&self->ev, NULL);
344     }
345   return self;
346 }
347
348 struct rxpd_connection*
349 rxpd_connection_suspend (struct rxpd_connection* self)
350 {
351   if (self)
352     {
353       event_del (&self->ev);
354       llist_insert_tail (&self->base->connections_pending, &self->node);
355     }
356   return self;
357 }
358
359
360
361
362 int
363 rxpd_connection_readline (struct rxpd_connection* self)
364 {
365 }
366
367 void
368 rxpd_connection_parse_cmd (int sock, short event, void* ptr)
369 {
370   printf ("parse cmd\n");
371   // TODO policy check
372 }
373
374 void
375 rxpd_connection_cmd_CHECK (int sock, short event, void* ptr)
376 {
377 }
378
379 void
380 rxpd_connection_cmd_APPEND (int sock, short event, void* ptr)
381 {
382 }
383
384 void
385 rxpd_connection_cmd_PREPEND (int sock, short event, void* ptr)
386 {
387 }
388
389 void
390 rxpd_connection_cmd_REMOVE (int sock, short event, void* ptr)
391 {
392 }
393
394 void
395 rxpd_connection_cmd_REPLACE (int sock, short event, void* ptr)
396 {
397 }
398
399 void
400 rxpd_connection_cmd_LOAD (int sock, short event, void* ptr)
401 {
402 }
403
404 void
405 rxpd_connection_cmd_SAVE (int sock, short event, void* ptr)
406 {
407 }
408
409 void
410 rxpd_connection_cmd_DUMP (int sock, short event, void* ptr)
411 {
412 }
413
414 void
415 rxpd_connection_cmd_LIST (int sock, short event, void* ptr)
416 {
417 }
418
419 void
420 rxpd_connection_cmd_END (int sock, short event, void* ptr)
421 {
422 }
423
424