masqmail-0.2

view src/masqmail.h @ 162:52c82d755215

replaced the MD5 implementation with the one of Solar Designer Until now, the sample code of RFC 1321 was used. It had an ugly license. Now we use the implementation of Solar Designer, which is in the Public Domain. http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
author meillo@marmaro.de
date Sun, 18 Jul 2010 22:01:04 +0200
parents c678d0342451
children 349518b940db
line source
1 /* MasqMail
2 Copyright (C) 1999-2001 Oliver Kurth
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #include <config.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <unistd.h>
27 #include <pwd.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <time.h>
32 #include <sys/time.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <netdb.h>
36 #include <syslog.h>
37 #include <signal.h>
38 #include <fcntl.h>
40 #include <glib.h>
42 #ifdef ENABLE_IDENT
43 #include "libident/ident.h"
44 #endif
46 #include "lookup.h"
48 typedef struct _interface {
49 gchar *address;
50 gint port;
51 } interface;
53 #define ADDR_FLAG_DELIVERED 0x01
54 #define ADDR_FLAG_DEFERED 0x02
55 #define ADDR_FLAG_FAILED 0x04
56 #define ADDR_FLAG_LAST_ROUTE 0x40
57 #define ADDR_FLAG_NOEXPAND 0x80
59 typedef struct _address {
60 gchar *address;
61 gchar *local_part;
62 gchar *domain;
63 gint flags;
64 GList *children;
65 struct _address *parent;
66 } address;
68 #define addr_mark_delivered(addr) { addr->flags |= ADDR_FLAG_DELIVERED; }
69 #define addr_unmark_delivered(addr) { addr->flags &= ~ADDR_FLAG_DELIVERED; }
70 #define addr_is_delivered(addr) ((addr->flags & ADDR_FLAG_DELIVERED) != 0 )
72 #define addr_mark_defered(addr) { addr->flags |= ADDR_FLAG_DEFERED; }
73 #define addr_unmark_defered(addr) { addr->flags &= ~ADDR_FLAG_DEFERED; }
74 #define addr_is_defered(addr) ((addr->flags & ADDR_FLAG_DEFERED) != 0 )
76 #define addr_mark_failed(addr) { addr->flags |= ADDR_FLAG_FAILED; }
77 #define addr_unmark_failed(addr) { addr->flags &= ~ADDR_FLAG_FAILED; }
78 #define addr_is_failed(addr) ((addr->flags & ADDR_FLAG_FAILED) != 0 )
80 typedef struct _connect_route {
81 gchar *name;
82 gchar *filename;
84 gchar *protocol;
86 gboolean is_local_net;
87 gboolean last_route;
89 GList *allowed_return_paths;
90 GList *not_allowed_return_paths;
91 GList *allowed_mail_locals;
92 GList *not_allowed_mail_locals;
93 GList *allowed_rcpt_domains;
94 GList *not_allowed_rcpt_domains;
96 interface *mail_host;
97 gchar *wrapper;
98 gboolean connect_error_fail;
100 gchar *helo_name;
101 gboolean do_correct_helo;
102 gboolean do_pipelining;
104 gchar *set_h_from_domain;
105 gchar *set_h_reply_to_domain;
106 gchar *set_return_path_domain;
108 GList *map_h_from_addresses;
109 GList *map_h_reply_to_addresses;
110 GList *map_h_mail_followup_to_addresses;
111 GList *map_return_path_addresses;
113 gboolean expand_h_sender_domain;
114 gboolean expand_h_sender_address;
116 GList *resolve_list;
118 gchar *auth_name;
119 gchar *auth_login;
120 gchar *auth_secret;
122 gchar *pop3_login;
124 gchar *pipe;
126 gboolean pipe_fromline;
127 gboolean pipe_fromhack;
128 } connect_route;
130 typedef struct _get_conf {
131 gchar *protocol;
132 gchar *server_name;
133 guint server_port;
134 gchar *wrapper;
135 gchar *login_user;
136 gchar *login_pass;
137 address *address;
138 address *return_path;
139 gboolean do_keep;
140 gboolean do_uidl;
141 gboolean do_uidl_dele;
142 gint max_size;
143 gboolean max_size_delete;
144 gint max_count;
146 GList *resolve_list;
148 } get_conf;
150 typedef struct _masqmail_conf {
151 gint mail_uid;
152 gint mail_gid;
154 gint orig_uid;
155 gint orig_gid;
157 gboolean run_as_user;
159 gchar *mail_dir;
160 gchar *lock_dir;
161 gchar *spool_dir;
162 gchar *log_dir;
164 gint debug_level;
165 gboolean use_syslog;
166 guint log_max_pri;
168 gchar *host_name;
169 GList *local_hosts;
170 GList *local_addresses;
171 GList *not_local_addresses;
172 GList *local_nets;
173 GList *listen_addresses;
175 guint remote_port;
177 /* ANSI C defines unsigned long to be at least 32bit
178 i.e. ca. 4GB max; that should be enough. */
179 gulong max_msg_size;
181 gboolean do_save_envelope_to;
183 gboolean defer_all;
184 gboolean do_relay;
186 GList *ident_trusted_nets;
188 gboolean do_queue;
190 gboolean do_verbose;
192 gchar *mbox_default;
193 GList *mbox_users;
194 GList *mda_users;
195 GList *maildir_users;
197 gchar *mda;
198 gboolean mda_fromline;
199 gboolean mda_fromhack;
201 gboolean pipe_fromline;
202 gboolean pipe_fromhack;
204 gchar *alias_file;
205 int (*alias_local_cmp) (const char *, const char *);
207 GList *local_net_routes;
208 GList *connect_routes; /* list of pairs which point to lists */
210 gchar *online_detect;
211 gchar *online_file;
212 gchar *online_pipe;
213 interface *mserver_iface;
215 GList *get_names;
216 GList *online_gets; /* list of pairs which point to lists */
218 gchar *errmsg_file;
219 gchar *warnmsg_file;
220 GList *warn_intervals;
221 gint max_defer_time;
223 gchar *log_user;
224 } masqmail_conf;
226 extern masqmail_conf conf;
228 typedef struct _table_pair {
229 gchar *key;
230 gpointer *value;
231 } table_pair;
234 typedef enum _prot_id {
235 PROT_LOCAL = 0,
236 PROT_BSMTP,
237 PROT_SMTP,
238 PROT_ESMTP,
239 PROT_POP3,
240 PROT_APOP,
241 PROT_NUM
242 } prot_id;
244 extern gchar *prot_names[];
246 typedef enum _header_id {
247 HEAD_FROM = 0,
248 HEAD_SENDER,
249 HEAD_TO,
250 HEAD_CC,
251 HEAD_BCC,
252 HEAD_DATE,
253 HEAD_MESSAGE_ID,
254 HEAD_REPLY_TO,
255 HEAD_SUBJECT,
256 HEAD_RETURN_PATH,
257 HEAD_ENVELOPE_TO,
258 HEAD_RECEIVED,
259 HEAD_NUM_IDS,
260 HEAD_STATUS,
261 HEAD_UNKNOWN = HEAD_NUM_IDS,
262 HEAD_NONE = -1,
263 } header_id;
265 typedef struct _header_name {
266 gchar *header;
267 header_id id;
268 } header_name;
270 typedef struct _header {
271 header_id id;
272 gchar *header;
273 gchar *value;
274 } header;
277 typedef struct _message {
278 gchar *uid;
280 gchar *received_host;
281 prot_id received_prot;
282 gchar *ident;
283 gint transfer_id; /* for multiple messages per transfer */
285 address *return_path;
286 GList *rcpt_list;
287 GList *non_rcpt_list;
289 GList *hdr_list;
290 GList *data_list;
292 gint data_size;
293 time_t received_time;
294 time_t warned_time;
296 gchar *full_sender_name;
297 } message;
299 typedef struct _msg_out {
300 message *msg;
302 address *return_path;
303 GList *rcpt_list;
305 GList *hdr_list;
306 GList *xtra_hdr_list;
307 } msg_out;
309 typedef struct _msgout_perhost {
310 gchar *host;
311 GList *msgout_list;
312 } msgout_perhost;
314 /* flags for accept() */
315 #define ACC_DEL_RCPTS 0x02 /* -t option, delete rcpts that were given as cmd args */
316 #define ACC_RCPT_FROM_HEAD 0x08 /* -t option, get rcpts from headers */
317 #define ACC_DOT_IGNORE 0x10 /* a dot on a line itself does not end the message (-oi option) */
318 #define ACC_MAIL_FROM_HEAD 0x40 /* get return path from header */
319 #define ACC_NODOT_RELAX 0x80 /* do not be picky if message ist not terminated by a dot on a line */
320 #define ACC_SAVE_ENVELOPE_TO 0x0100 /* save an existent Envelope-to header as X-Orig-Envelope-to */
322 #define DLVR_LOCAL 0x01
323 #define DLVR_LAN 0x02
324 #define DLVR_ONLINE 0x04
325 #define DLVR_ALL (DLVR_LOCAL|DLVR_LAN|DLVR_ONLINE)
327 /* transport flags */
328 #define MSGSTR_FROMLINE 0x01
329 #define MSGSTR_FROMHACK 0x02
331 typedef enum _accept_error {
332 AERR_OK = 0,
333 AERR_TIMEOUT,
334 AERR_EOF,
335 AERR_OVERFLOW,
336 AERR_SYNTAX,
337 AERR_NOSPOOL,
338 AERR_NORCPT,
339 AERR_SIZE, /* max msg size exeeded (SMTP SIZE) */
340 AERR_UNKNOWN
341 } accept_error;
343 #define BUF_LEN 1024
344 #define MAX_ADDRESS 256
345 #define MAX_DATALINE 4096
347 typedef enum _smtp_cmd_id {
348 SMTP_HELO = 0,
349 SMTP_EHLO,
350 SMTP_MAIL_FROM,
351 SMTP_RCPT_TO,
352 SMTP_DATA,
353 SMTP_QUIT,
354 SMTP_RSET,
355 SMTP_NOOP,
356 SMTP_HELP,
357 SMTP_NUM_IDS,
358 SMTP_EOF = -1,
359 SMTP_ERROR = -2,
360 } smtp_cmd_id;
362 typedef struct _smtp_cmd {
363 smtp_cmd_id id;
364 gchar *cmd;
365 } smtp_cmd;
367 typedef struct _smtp_connection {
368 gchar *remote_host;
370 prot_id prot;
371 gint next_id;
373 gboolean helo_seen;
374 gboolean from_seen;
375 gboolean rcpt_seen;
377 message *msg;
378 } smtp_connection;
380 /* alias.c*/
381 gboolean addr_is_local(address * addr);
382 GList *alias_expand(GList * alias_table, GList * rcpt_list, GList * non_rcpt_list);
384 /* child.c */
385 int child(const char *command);
387 /* conf.c */
388 void init_conf();
389 gboolean read_conf(gchar * filename);
390 connect_route *read_route(gchar * filename, gboolean is_local_net);
391 GList *read_route_list(GList * rf_list, gboolean is_local_net);
392 void destroy_route(connect_route * r);
393 void destroy_route_list(GList * list);
394 get_conf *read_get_conf(gchar * filename);
395 void destroy_get_conf(get_conf * gc);
396 connect_route *create_local_route();
398 /* expand.c */
399 GList *var_table_rcpt(GList * var_table, address * rcpt);
400 GList *var_table_msg(GList * var_table, message * msg);
401 GList *var_table_conf(GList * var_table);
402 gint expand(GList * var_list, gchar * format, gchar * result, gint result_len);
404 /* message.c */
405 message *create_message(void);
406 void destroy_message(message * msg);
407 void destroy_msg_list(GList * msg_list);
408 void msg_free_data(message * msg);
409 gint msg_calc_size(message * msg, gboolean is_smtp);
411 msg_out *create_msg_out(message * msg);
412 msg_out *clone_msg_out(msg_out * msgout_orig);
413 GList *create_msg_out_list(GList * msg_list);
414 void destroy_msg_out(msg_out * msgout);
415 void destroy_msg_out_list(GList * msgout_list);
417 /* address.c */
418 address *create_address(gchar * path, gboolean is_rfc821);
419 address *create_address_qualified(gchar * path, gboolean is_rfc821, gchar * domain);
420 address *create_address_pipe(gchar * path);
421 void destroy_address(address * addr);
422 address *copy_modify_address(const address * orig, gchar * l_part, gchar * dom);
423 #define copy_address(addr) copy_modify_address(addr, NULL, NULL)
424 gboolean addr_isequal(address * addr1, address * addr2);
425 gboolean addr_isequal_parent(address * addr1, address * addr2);
426 address *addr_find_ancestor(address * addr);
427 gboolean addr_is_delivered_children(address * addr);
428 gboolean addr_is_finished_children(address * addr);
429 gchar *addr_string(address * addr);
430 gint addr_match(address * addr1, address * addr2);
432 /* accept.c */
433 accept_error accept_message(FILE * in, message * msg, guint flags);
434 accept_error accept_message_prepare(message * msg, guint flags);
436 /* header.c */
437 gchar *rec_timestamp();
438 GList *find_header(GList * hdr_list, header_id id, gchar * hdr_str);
439 void header_unfold(header * hdr);
440 void header_fold(header * hdr);
441 header *create_header(header_id id, gchar * fmt, ...);
442 void destroy_header(header * hdr);
443 header *copy_header(header * hdr);
444 header *get_header(gchar * line);
446 /* smtp_in.c */
447 void smtp_in(FILE * in, FILE * out, gchar * remote_host, gchar * ident);
449 /* listen.c */
450 void listen_port(GList * addr_list, gint qival, char *argv[]);
452 /* parse.c */
453 gboolean split_address(const gchar * path, gchar ** local_part, gchar ** domain, gboolean is_rfc821);
454 gboolean parse_address_rfc822(gchar * string, gchar ** local_begin, gchar ** local_end, gchar ** domain_begin, gchar ** domain_end, gchar ** address_end);
455 gboolean parse_address_rfc821(gchar * string, gchar ** local_begin, gchar ** local_end, gchar ** domain_begin, gchar ** domain_end, gchar ** address_end);
456 address *_create_address(gchar * string, gchar ** end, gboolean is_rfc821);
457 address *create_address_rfc821(gchar * string, gchar ** end);
458 address *create_address_rfc822(gchar * string, gchar ** end);
459 GList *addr_list_append_rfc822(GList * addr_list, gchar * string, gchar * domain);
460 gboolean addr_isequal(address * addr1, address * addr2);
462 /* connect.c */
463 mxip_addr *connect_hostlist(int *psockfd, gchar * host, guint port, GList * addr_list);
464 mxip_addr *connect_resolvelist(int *psockfd, gchar * host, guint port, GList * res_funcs);
466 /* deliver.c */
467 void msg_rcptlist_local(GList * rcpt_list, GList **, GList **);
468 gboolean deliver_local(msg_out * msgout);
469 gboolean deliver_msglist_host(connect_route * route, GList * msg_list, gchar * host, GList * res_list);
470 gboolean deliver_route_msgout_list(connect_route * route, GList * msgout_list);
471 gboolean deliver_route_msg_list(connect_route * route, GList * msgout_list);
472 gboolean deliver_finish(msg_out * msgout);
473 gboolean deliver_finish_list(GList * msgout_list);
474 gboolean deliver_msg_list(GList * msg_list, guint flags);
475 gboolean deliver(message * msg);
477 /* fail_msg.c */
478 gboolean fail_msg(message * msg, gchar * template, GList * failed_rcpts, gchar * err_fmt, va_list args);
479 gboolean warn_msg(message * msg, gchar * template, GList * failed_rcpts, gchar * err_fmt, va_list args);
481 /* get.c */
482 gboolean get_from_file(gchar * fname);
483 gboolean get_from_name(gchar * name);
484 gboolean get_all(void);
485 void get_online(void);
486 void get_daemon(gint gival, char *argv[]);
487 gboolean pop_before_smtp(gchar * fname);
489 /* interface.c */
490 gboolean init_sockaddr(struct sockaddr_in *name, interface * iface);
491 int make_server_socket(interface * iface);
493 /* local.c */
494 gboolean append_file(message * msg, GList * hdr_list, gchar * user);
495 gboolean maildir_out(message * msg, GList * hdr_list, gchar * user, guint flags);
496 gboolean pipe_out(message * msg, GList * hdr_list, address * rcpt, gchar * cmd, guint flags);
498 /* log.c */
499 gchar *ext_strerror(int err);
500 gboolean logopen(void);
501 void logclose(void);
502 void vlogwrite(int pri, const char *fmt, va_list args);
503 void logwrite(int pri, const char *fmt, ...);
504 void debugf(const char *fmt, ...);
505 void vdebugf(const char *fmt, va_list args);
506 void maillog(const char *fmt, ...);
508 /* spool.c */
509 gboolean spool_read_data(message * msg);
510 gboolean spool_read_data(message * msg);
511 message *msg_spool_read(gchar * uid, gboolean do_readdata);
512 gboolean spool_write(message * msg, gboolean do_writedata);
513 gboolean spool_lock(gchar * uid);
514 gboolean spool_unlock(gchar * uid);
515 gboolean spool_delete_all(message * msg);
517 /* queue.c */
518 GList *read_queue(gboolean do_readdata);
519 gboolean queue_run(void);
520 gboolean queue_run_online(void);
521 void queue_list(void);
522 gboolean queue_delete(gchar * uid);
524 /* online.c */
525 gchar *detect_online();
526 void set_online_name(gchar * name);
528 /* permissions.c */
529 gboolean is_ingroup(uid_t uid, gid_t gid);
530 void set_euidgid(gint uid, gint gid, uid_t * old_uid, gid_t * old_gid);
531 void set_identity(uid_t old_uid, gchar * task_name);
533 /* rewrite.c */
534 gboolean set_address_header_domain(header * hdr, gchar * domain);
535 gboolean map_address_header(header * hdr, GList * table);
537 /* route.c */
538 msgout_perhost *create_msgout_perhost(gchar * host);
539 void destroy_msgout_perhost(msgout_perhost * mo_ph);
540 void rewrite_headers(msg_out * msgout, connect_route * route);
541 void rcptlist_with_one_of_hostlist(GList * rcpt_list, GList * host_list, GList **, GList **);
542 void rcptlist_with_addr_is_local(GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list);
543 gboolean route_strip_msgout(connect_route * route, msg_out * msgout);
544 msg_out *route_prepare_msgout(connect_route * route, msg_out * msgout);
545 GList *route_msgout_list(connect_route * route, GList * msgout_list);
546 gboolean route_is_allowed_return_path(connect_route * route, address * ret_path);
547 gboolean route_is_allowed_mail_local(connect_route * route, address * ret_path);
548 void msg_rcptlist_route(connect_route * route, GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list);
550 /* tables.c */
551 table_pair *create_pair(gchar * key, gpointer value);
552 table_pair *create_pair_string(gchar * key, gpointer value);
553 table_pair *parse_table_pair(gchar * line, char delim);
554 gpointer *table_find_func(GList * table_list, gchar * key, int (*cmp_func) (const char *, const char *));
555 gpointer *table_find(GList * table_list, gchar * key);
556 gpointer *table_find_case(GList * table_list, gchar * key);
557 gpointer *table_find_fnmatch(GList * table_list, gchar * key);
558 GList *table_read(gchar * fname, gchar delim);
559 void destroy_table(GList * table);
561 /* timeival.c */
562 gint time_interval(gchar * str, gint * pos);
564 /* permissions.c */
565 gboolean is_privileged_user(uid_t uid);
567 /* other things */
569 #define foreach(list, node)\
570 for((node) = g_list_first(list);\
571 (node);\
572 (node) = g_list_next(node))
574 #ifdef ENABLE_DEBUG
575 #define DEBUG(level) if(level <= conf.debug_level)
576 #else
577 /* hopefully the compiler optmizes this away... */
578 #define DEBUG(level) if(0)
579 #endif
581 #define LOG_VERBOSE 0x100
583 #ifndef HAVE_GETLINE
584 #define getline(buf, size, file) getdelim(buf, size, '\n', file)
585 #endif
587 #ifndef HAVE_FDATASYNC
588 #define fdatasync(fd) fsync(fd)
589 #endif
591 #ifndef CONF_DIR
592 #define CONF_DIR "/etc/masqmail"
593 #endif
595 #define CONF_FILE CONF_DIR"/masqmail.conf"
597 #define PIDFILEDIR "/var/run/masqmail/"
599 #ifndef va_copy
600 #ifdef __va_copy
601 #define va_copy(ap1, ap2) __va_copy(ap1, ap2)
602 #else
603 #define va_copy(ap1, ap2) G_VA_COPY(ap1, ap2)
604 #endif
605 #endif
607 /* *BSD needs this: */
608 extern char **environ;