diff options
Diffstat (limited to 'libmailutils/server/acl.c')
-rw-r--r-- | libmailutils/server/acl.c | 366 |
1 files changed, 90 insertions, 276 deletions
diff --git a/libmailutils/server/acl.c b/libmailutils/server/acl.c index 0b7a507e0..ba1a4b86b 100644 --- a/libmailutils/server/acl.c +++ b/libmailutils/server/acl.c | |||
@@ -40,14 +40,20 @@ | |||
40 | #include <mailutils/kwd.h> | 40 | #include <mailutils/kwd.h> |
41 | #include <mailutils/io.h> | 41 | #include <mailutils/io.h> |
42 | #include <mailutils/util.h> | 42 | #include <mailutils/util.h> |
43 | #include <mailutils/sockaddr.h> | ||
44 | #include <mailutils/cidr.h> | ||
45 | #include <mailutils/stream.h> | ||
46 | #include <mailutils/stdstream.h> | ||
47 | |||
48 | #ifndef MU_INADDR_BYTES | ||
49 | #define MU_INADDR_BYTES 16 | ||
50 | #endif | ||
43 | 51 | ||
44 | struct _mu_acl_entry | 52 | struct _mu_acl_entry |
45 | { | 53 | { |
46 | mu_acl_action_t action; | 54 | mu_acl_action_t action; |
47 | void *arg; | 55 | void *arg; |
48 | unsigned netmask; | 56 | struct mu_cidr cidr; |
49 | int salen; | ||
50 | struct sockaddr sa[1]; | ||
51 | }; | 57 | }; |
52 | 58 | ||
53 | struct _mu_acl | 59 | struct _mu_acl |
@@ -64,52 +70,19 @@ _destroy_acl_entry (void *item) | |||
64 | /* FIXME: free arg? */ | 70 | /* FIXME: free arg? */ |
65 | } | 71 | } |
66 | 72 | ||
67 | static size_t | ||
68 | mu_acl_entry_size (int salen) | ||
69 | { | ||
70 | return sizeof (struct _mu_acl_entry) + salen - sizeof (struct sockaddr); | ||
71 | } | ||
72 | |||
73 | static int | ||
74 | prepare_sa (struct sockaddr *sa) | ||
75 | { | ||
76 | switch (sa->sa_family) | ||
77 | { | ||
78 | case AF_INET: | ||
79 | { | ||
80 | struct sockaddr_in *s_in = (struct sockaddr_in *)sa; | ||
81 | s_in->sin_addr.s_addr = ntohl (s_in->sin_addr.s_addr); | ||
82 | break; | ||
83 | } | ||
84 | |||
85 | case AF_UNIX: | ||
86 | break; | ||
87 | |||
88 | default: | ||
89 | return 1; | ||
90 | } | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | int | 73 | int |
95 | mu_acl_entry_create (struct _mu_acl_entry **pent, | 74 | mu_acl_entry_create (struct _mu_acl_entry **pent, |
96 | mu_acl_action_t action, void *data, | 75 | mu_acl_action_t action, void *data, |
97 | struct sockaddr *sa, int salen, unsigned long netmask) | 76 | struct mu_cidr *cidr) |
98 | { | 77 | { |
99 | struct _mu_acl_entry *p = malloc (mu_acl_entry_size (salen)); | 78 | struct _mu_acl_entry *p = malloc (sizeof (*p)); |
100 | if (!p) | 79 | if (!p) |
101 | return EINVAL; | 80 | return EINVAL; |
102 | 81 | ||
103 | p->action = action; | 82 | p->action = action; |
104 | p->arg = data; | 83 | p->arg = data; |
105 | p->netmask = ntohl (netmask); | 84 | memcpy (&p->cidr, cidr, sizeof (p->cidr)); |
106 | p->salen = salen; | 85 | |
107 | memcpy (p->sa, sa, salen); | ||
108 | if (prepare_sa (p->sa)) | ||
109 | { | ||
110 | free (p); | ||
111 | return EINVAL; | ||
112 | } | ||
113 | *pent = p; | 86 | *pent = p; |
114 | return 0; | 87 | return 0; |
115 | } | 88 | } |
@@ -165,15 +138,14 @@ mu_acl_get_iterator (mu_acl_t acl, mu_iterator_t *pitr) | |||
165 | 138 | ||
166 | int | 139 | int |
167 | mu_acl_append (mu_acl_t acl, mu_acl_action_t act, | 140 | mu_acl_append (mu_acl_t acl, mu_acl_action_t act, |
168 | void *data, struct sockaddr *sa, int salen, | 141 | void *data, struct mu_cidr *cidr) |
169 | unsigned long netmask) | ||
170 | { | 142 | { |
171 | int rc; | 143 | int rc; |
172 | struct _mu_acl_entry *ent; | 144 | struct _mu_acl_entry *ent; |
173 | 145 | ||
174 | if (!acl) | 146 | if (!acl) |
175 | return EINVAL; | 147 | return EINVAL; |
176 | rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); | 148 | rc = mu_acl_entry_create (&ent, act, data, cidr); |
177 | if (rc) | 149 | if (rc) |
178 | { | 150 | { |
179 | mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, | 151 | mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, |
@@ -193,14 +165,14 @@ mu_acl_append (mu_acl_t acl, mu_acl_action_t act, | |||
193 | 165 | ||
194 | int | 166 | int |
195 | mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data, | 167 | mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data, |
196 | struct sockaddr *sa, int salen, unsigned long netmask) | 168 | struct mu_cidr *cidr) |
197 | { | 169 | { |
198 | int rc; | 170 | int rc; |
199 | struct _mu_acl_entry *ent; | 171 | struct _mu_acl_entry *ent; |
200 | 172 | ||
201 | if (!acl) | 173 | if (!acl) |
202 | return EINVAL; | 174 | return EINVAL; |
203 | rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); | 175 | rc = mu_acl_entry_create (&ent, act, data, cidr); |
204 | if (rc) | 176 | if (rc) |
205 | { | 177 | { |
206 | mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, | 178 | mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, |
@@ -219,8 +191,7 @@ mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data, | |||
219 | 191 | ||
220 | int | 192 | int |
221 | mu_acl_insert (mu_acl_t acl, size_t pos, int before, | 193 | mu_acl_insert (mu_acl_t acl, size_t pos, int before, |
222 | mu_acl_action_t act, void *data, | 194 | mu_acl_action_t act, void *data, struct mu_cidr *cidr) |
223 | struct sockaddr *sa, int salen, unsigned long netmask) | ||
224 | { | 195 | { |
225 | int rc; | 196 | int rc; |
226 | void *ptr; | 197 | void *ptr; |
@@ -236,7 +207,7 @@ mu_acl_insert (mu_acl_t acl, size_t pos, int before, | |||
236 | ("No such entry %lu", (unsigned long) pos)); | 207 | ("No such entry %lu", (unsigned long) pos)); |
237 | return rc; | 208 | return rc; |
238 | } | 209 | } |
239 | rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); | 210 | rc = mu_acl_entry_create (&ent, act, data, cidr); |
240 | if (!ent) | 211 | if (!ent) |
241 | { | 212 | { |
242 | mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, | 213 | mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, |
@@ -279,124 +250,19 @@ mu_acl_string_to_action (const char *str, mu_acl_action_t *pres) | |||
279 | return rc; | 250 | return rc; |
280 | } | 251 | } |
281 | 252 | ||
282 | #define MU_S_UN_NAME(sa, salen) \ | 253 | struct run_closure |
283 | ((salen < mu_offsetof (struct sockaddr_un,sun_path)) ? "" : (sa)->sun_path) | ||
284 | |||
285 | static void | ||
286 | debug_sockaddr (struct sockaddr *sa, int salen) | ||
287 | { | ||
288 | switch (sa->sa_family) | ||
289 | { | ||
290 | case AF_INET: | ||
291 | { | ||
292 | struct sockaddr_in s_in = *(struct sockaddr_in *)sa; | ||
293 | s_in.sin_addr.s_addr = htonl (s_in.sin_addr.s_addr); | ||
294 | mu_debug_log_cont ("{AF_INET %s:%d}", | ||
295 | inet_ntoa (s_in.sin_addr), ntohs (s_in.sin_port)); | ||
296 | break; | ||
297 | } | ||
298 | |||
299 | case AF_UNIX: | ||
300 | { | ||
301 | struct sockaddr_un *s_un = (struct sockaddr_un *)sa; | ||
302 | if (MU_S_UN_NAME(s_un, salen)[0] == 0) | ||
303 | mu_debug_log_cont ("{AF_UNIX}"); | ||
304 | else | ||
305 | mu_debug_log_cont ("{AF_UNIX %s}", s_un->sun_path); | ||
306 | break; | ||
307 | } | ||
308 | |||
309 | default: | ||
310 | mu_debug_log_cont ("{Unsupported family: %d}", sa->sa_family); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | size_t | ||
315 | mu_stpcpy (char **pbuf, size_t *psize, const char *src) | ||
316 | { | ||
317 | size_t slen = strlen (src); | ||
318 | if (pbuf == NULL || *pbuf == NULL) | ||
319 | return slen; | ||
320 | else | ||
321 | { | ||
322 | char *buf = *pbuf; | ||
323 | size_t size = *psize; | ||
324 | if (size > slen) | ||
325 | size = slen; | ||
326 | memcpy (buf, src, size); | ||
327 | *psize -= size; | ||
328 | *pbuf += size; | ||
329 | if (*psize) | ||
330 | **pbuf = 0; | ||
331 | else | ||
332 | (*pbuf)[-1] = 0; | ||
333 | return size; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | void | ||
338 | mu_sockaddr_to_str (const struct sockaddr *sa, int salen, | ||
339 | char *bufptr, size_t buflen, | ||
340 | size_t *plen) | ||
341 | { | 254 | { |
342 | char *nbuf; | 255 | unsigned idx; |
343 | size_t len = 0; | 256 | struct mu_cidr addr; |