2 rxpd_connection.c - regex policy daemon
5 2007, Christian Thaeter <ct@pipapo.org>
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.
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.
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.
24 struct rxpd_connection
*
25 rxpd_connection_new (struct rxpd_socket
* socket
, int fd
)
27 struct rxpd_connection
* self
;
28 self
= rxpd_malloc (sizeof (struct rxpd_connection
));
31 self
->socket
= socket
;
34 llist_init (&self
->tmp_list
);
36 rxpd_buffer_init (&self
->in
, fd
);
37 rxpd_buffer_init (&self
->out
, fd
);
39 self
->connecter
= NULL
;
45 rxpd_connection_delete (struct rxpd_connection
* self
)
51 LLIST_WHILE_HEAD (&self
->tmp_list
, n
)
53 struct rxpd_rule
* node
= (struct rxpd_rule
*)n
;
54 rxpd_rule_delete (node
);
60 struct rxpd_connection
*
61 rxpd_connection_spawn (struct rxpd_connection
* self
)
66 rxpd_die ("connection thread already spawned\n");
68 pth_attr_t attr
= pth_attr_new ();
70 pth_attr_set (attr
, PTH_ATTR_JOINABLE
, FALSE
);
72 self
->connecter
= pth_spawn (attr
, rxpd_connection_parse_cmd
, self
);
75 rxpd_die ("failed spawning thread\n");
81 rxpd_connection_check_policy (struct rxpd_connection
* self
, char* line
)
83 struct rxpd_base
* base
= self
->socket
->base
;
89 if (!self
->socket
->rxpd_socket_addr (self
, buf
, line
, 256))
91 rxpd_log (base
, LOG_ERR
, "policy line too long\n");
96 LLIST_FOREACH (&base
->policy
->rules
, n
)
98 struct rxpd_rule
* rule
= (struct rxpd_rule
*)n
;
99 if (rule
->string
[0] != '#')
101 if (regexec (&rule
->rx
, buf
, 0, NULL
, 0) == 0)
103 match
= rule
->string
;
109 if (!match
|| !RXPD_PREFIXCMP (match
, "ACCEPT:"))
111 rxpd_log (base
, LOG_WARNING
, "policy check: access denied '%s'\n", buf
);
114 rxpd_log (base
, LOG_NOTICE
, "policy check: permitted '%s'\n", buf
);
120 rxpd_connection_parse_cmd (void* ptr
)
122 struct rxpd_connection
* self
= (struct rxpd_connection
*) ptr
;
123 struct rxpd_base
* base
= self
->socket
->base
;
126 line
= rxpd_buffer_readline (&self
->in
);
130 rxpd_log (base
, LOG_ERR
, "no data\n");
131 rxpd_buffer_printf (&self
->out
, "#ERROR: no data\n");
136 rxpd_log (base
, LOG_DEBUG
, "parse command '%s'\n", line
);
138 static const struct cmd_table
145 #define RXPD_CMD(cmd, _) {RXPD_CMD_##cmd, #cmd":", sizeof (#cmd)},
151 const struct cmd_table
* i
;
152 for (i
= cmds
; i
->cmd
; ++i
)
153 if (strncmp (line
, i
->cmd
, i
->sz
) == 0)
158 rxpd_log (base
, LOG_ERR
, "no command\n");
159 rxpd_buffer_printf (&self
->out
, "#ERROR: no command\n");
160 rxpd_connection_delete (self
);
164 if (!rxpd_connection_check_policy (self
, line
))
166 rxpd_buffer_printf (&self
->out
, "#ERROR: access denied\n");
167 rxpd_connection_delete (self
);
174 self
->file
= (struct rxpd_file
*) psplay_find (&base
->files
, &line
[i
->sz
]);
178 self
->file
= rxpd_file_new (base
, &line
[i
->sz
]);
181 rxpd_log (base
, LOG_ERR
, "illeagal filename\n");
182 rxpd_buffer_printf (&self
->out
, "#ERROR: illegal filename\n");
183 rxpd_connection_delete (self
);
192 #define RXPD_CMD(cmd, _) \
193 case RXPD_CMD_##cmd: \
194 rxpd_connection_cmd_##cmd (self); \
195 rxpd_connection_delete (self); \