1 /* 2 ** MasqMail 3 ** Copyright (C) 1999-2001 Oliver Kurth 4 ** Copyright (C) 2010 markus schnalke <meillo@marmaro.de> 5 ** 6 ** This program is free software; you can redistribute it and/or modify 7 ** it under the terms of the GNU General Public License as published by 8 ** the Free Software Foundation; either version 2 of the License, or 9 ** (at your option) any later version. 10 ** 11 ** This program is distributed in the hope that it will be useful, 12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 ** GNU General Public License for more details. 15 ** 16 ** You should have received a copy of the GNU General Public License 17 ** along with this program; if not, write to the Free Software 18 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 #include <config.h> 21 22 #include <stdio.h> 23 #include <stdarg.h> 24 #include <errno.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <ctype.h> 28 #include <unistd.h> 29 #include <pwd.h> 30 #include <sys/types.h> 31 #include <sys/socket.h> 32 #include <netinet/in.h> 33 #include <time.h> 34 #include <sys/time.h> 35 #include <netinet/in.h> 36 #include <arpa/inet.h> 37 #include <netdb.h> 38 #include <syslog.h> 39 #include <signal.h> 40 #include <fcntl.h> 41 42 #include <glib.h> 43 44 #include "lookup.h" 45 46 typedef struct _interface { 47 gchar *address; 48 gint port; 49 } interface; 50 51 #define ADDR_FLAG_DELIVERED 0x01 52 #define ADDR_FLAG_DEFERED 0x02 53 #define ADDR_FLAG_FAILED 0x04 54 #define ADDR_FLAG_LAST_ROUTE 0x40 55 56 typedef struct _address { 57 gchar *address; /* full addr string: `markus <meillo@marmaro.de>' */ 58 gchar *local_part; /* in this example: `meillo' */ 59 gchar *domain; /* in this example: `marmaro.de' */ 60 gint flags; 61 GList *children; 62 struct _address *parent; 63 } address; 64 65 #define addr_mark_delivered(addr) { addr->flags |= ADDR_FLAG_DELIVERED; } 66 #define addr_unmark_delivered(addr) { addr->flags &= ~ADDR_FLAG_DELIVERED; } 67 #define addr_is_delivered(addr) ((addr->flags & ADDR_FLAG_DELIVERED) != 0 ) 68 69 #define addr_mark_defered(addr) { addr->flags |= ADDR_FLAG_DEFERED; } 70 #define addr_unmark_defered(addr) { addr->flags &= ~ADDR_FLAG_DEFERED; } 71 #define addr_is_defered(addr) ((addr->flags & ADDR_FLAG_DEFERED) != 0 ) 72 73 #define addr_mark_failed(addr) { addr->flags |= ADDR_FLAG_FAILED; } 74 #define addr_unmark_failed(addr) { addr->flags &= ~ADDR_FLAG_FAILED; } 75 #define addr_is_failed(addr) ((addr->flags & ADDR_FLAG_FAILED) != 0 ) 76 77 typedef struct _connect_route { 78 gchar *name; 79 gchar *filename; 80 81 gboolean is_perma; 82 gboolean last_route; 83 84 GList *allowed_senders; 85 GList *denied_senders; 86 GList *allowed_recipients; 87 GList *denied_recipients; 88 GList *allowed_from_hdrs; 89 GList *denied_from_hdrs; 90 91 interface *mail_host; 92 gboolean connect_error_fail; 93 GList *resolve_list; 94 gchar *helo_name; 95 gboolean do_correct_helo; 96 gboolean instant_helo; 97 gboolean do_pipelining; 98 gchar *auth_name; 99 gchar *auth_login; 100 gchar *auth_secret; 101 gchar *wrapper; 102 103 gchar *set_h_from_domain; 104 gchar *set_h_reply_to_domain; 105 gchar *set_return_path_domain; 106 GList *map_h_from_addresses; 107 GList *map_h_reply_to_addresses; 108 GList *map_h_mail_followup_to_addresses; 109 GList *map_return_path_addresses; 110 gboolean expand_h_sender_domain; 111 gboolean expand_h_sender_address; 112 113 gchar *pipe; 114 gboolean pipe_fromline; 115 gboolean pipe_fromhack; 116 } connect_route; 117 118 typedef struct _masqmail_conf { 119 gint mail_uid; 120 gint mail_gid; 121 122 gint orig_uid; 123 gint orig_gid; 124 125 gboolean run_as_user; 126 127 gchar *mail_dir; 128 gchar *lock_dir; 129 gchar *spool_dir; 130 gchar *log_dir; 131 132 gint debug_level; 133 gboolean use_syslog; 134 135 gchar *host_name; 136 GList *local_hosts; 137 GList *local_addresses; 138 GList *not_local_addresses; 139 GList *listen_addresses; 140 141 /* 142 ** ANSI C defines unsigned long to be at least 32bit 143 ** i.e. ca. 4GB max; that should be enough. 144 */ 145 gulong max_msg_size; 146 147 gboolean do_save_envelope_to; 148 149 gboolean defer_all; 150 gboolean do_relay; 151 152 gboolean do_queue; 153 154 gboolean do_verbose; 155 156 gchar *mbox_default; 157 GList *mbox_users; 158 GList *mda_users; 159 160 gchar *mda; 161 gboolean mda_fromline; 162 gboolean mda_fromhack; 163 164 gboolean pipe_fromline; 165 gboolean pipe_fromhack; 166 167 gchar *alias_file; 168 int (*localpartcmp) (const char *, const char *); 169 gchar *globalias_file; 170 171 GList *perma_routes; 172 GList *query_routes; /* list of pairs which point to lists */ 173 174 gchar *online_query; 175 176 gchar *errmsg_file; 177 gchar *warnmsg_file; 178 GList *warn_intervals; 179 gint max_defer_time; 180 181 gchar *log_user; 182 } masqmail_conf; 183 184 extern masqmail_conf conf; 185 186 typedef struct _table_pair { 187 gchar *key; 188 gpointer *value; 189 } table_pair; 190 191 192 /* must match the contents of prot_names[] in accept.c */ 193 typedef enum _prot_id { 194 PROT_LOCAL = 0, 195 PROT_SMTP, 196 PROT_ESMTP, 197 PROT_NUM 198 } prot_id; 199 200 extern gchar *prot_names[]; 201 202 typedef enum _header_id { 203 HEAD_FROM = 0, 204 HEAD_SENDER, 205 HEAD_TO, 206 HEAD_CC, 207 HEAD_BCC, 208 HEAD_DATE, 209 HEAD_MESSAGE_ID, 210 HEAD_REPLY_TO, 211 HEAD_SUBJECT, 212 HEAD_RETURN_PATH, 213 HEAD_ENVELOPE_TO, 214 HEAD_RECEIVED, 215 HEAD_NUM_IDS, 216 HEAD_STATUS, 217 HEAD_UNKNOWN = HEAD_NUM_IDS, 218 HEAD_NONE = -1, 219 } header_id; 220 221 typedef struct _header_name { 222 gchar *header; 223 header_id id; 224 } header_name; 225 226 typedef struct _header { 227 header_id id; 228 gchar *header; 229 gchar *value; 230 } header; 231 232 233 typedef struct _message { 234 gchar *uid; 235 236 gchar *received_host; 237 prot_id received_prot; 238 gchar *ident; 239 gint transfer_id; /* for multiple messages per transfer */ 240 241 address *return_path; 242 GList *rcpt_list; 243 GList *non_rcpt_list; 244 245 GList *hdr_list; 246 GList *data_list; 247 248 gint data_size; 249 time_t received_time; 250 time_t warned_time; 251 252 gchar *full_sender_name; 253 } message; 254 255 typedef struct _msg_out { 256 message *msg; 257 258 address *return_path; 259 GList *rcpt_list; 260 261 GList *hdr_list; 262 GList *xtra_hdr_list; /* rewritten headers */ 263 } msg_out; 264 265 typedef struct _msgout_perhost { 266 gchar *host; 267 GList *msgout_list; 268 } msgout_perhost; 269 270 /* flags for accept() */ 271 #define ACC_RCPT_FROM_HEAD 0x08 /* -t option, get rcpts from headers */ 272 #define ACC_DOT_IGNORE 0x10 /* a dot on a line itself does not end the message (-oi option) */ 273 #define ACC_MAIL_FROM_HEAD 0x40 /* get return path from header */ 274 #define ACC_NODOT_RELAX 0x80 /* do not be picky if message ist not terminated by a dot on a line */ 275 #define ACC_SAVE_ENVELOPE_TO 0x0100 /* save an existent Envelope-to header as X-Orig-Envelope-to */ 276 277 #define DLVR_LOCAL 0x01 278 #define DLVR_ONLINE 0x02 279 #define DLVR_ALL (DLVR_LOCAL|DLVR_ONLINE) 280 281 /* transport flags */ 282 #define MSGSTR_FROMLINE 0x01 283 #define MSGSTR_FROMHACK 0x02 284 285 typedef enum _accept_error { 286 AERR_OK = 0, 287 AERR_TIMEOUT, 288 AERR_EOF, 289 AERR_OVERFLOW, 290 AERR_SYNTAX, 291 AERR_NOSPOOL, 292 AERR_NORCPT, 293 AERR_SIZE, /* max msg size exeeded (SMTP SIZE) */ 294 AERR_UNKNOWN 295 } accept_error; 296 297 #define BUF_LEN 1024 298 #define MAX_ADDRESS 256 299 #define MAX_DATALINE 4096 300 301 typedef enum _smtp_cmd_id { 302 SMTP_HELO = 0, 303 SMTP_EHLO, 304 SMTP_MAIL_FROM, 305 SMTP_RCPT_TO, 306 SMTP_DATA, 307 SMTP_QUIT, 308 SMTP_RSET, 309 SMTP_NOOP, 310 SMTP_HELP, 311 SMTP_NUM_IDS, 312 SMTP_EOF = -1, 313 SMTP_ERROR = -2, 314 } smtp_cmd_id; 315 316 typedef struct _smtp_cmd { 317 smtp_cmd_id id; 318 gchar *cmd; 319 } smtp_cmd; 320 321 typedef struct _smtp_connection { 322 gchar *remote_host; 323 324 prot_id prot; 325 gint next_id; 326 327 gboolean helo_seen; 328 gboolean from_seen; 329 gboolean rcpt_seen; 330 331 message *msg; 332 } smtp_connection; 333 334 /* alias.c*/ 335 gboolean addr_is_local(address *addr); 336 GList *alias_expand(GList *alias_table, GList *rcpt_list, GList *non_rcpt_list, 337 int doglob); 338 339 /* child.c */ 340 int child(const char *command); 341 342 /* conf.c */ 343 void init_conf(); 344 gboolean read_conf(gchar *filename); 345 connect_route *read_route(gchar *filename, gboolean is_perma); 346 GList *read_route_list(GList *rf_list, gboolean is_perma); 347 void destroy_route(connect_route *r); 348 void destroy_route_list(GList *list); 349 350 /* expand.c */ 351 GList *var_table_rcpt(GList *var_table, address *rcpt); 352 GList *var_table_msg(GList *var_table, message *msg); 353 GList *var_table_conf(GList *var_table); 354 gint expand(GList *var_list, gchar *format, gchar *result, gint result_len); 355 356 /* message.c */ 357 message *create_message(void); 358 void destroy_message(message *msg); 359 void destroy_msg_list(GList *msg_list); 360 void msg_free_data(message *msg); 361 gint msg_calc_size(message *msg, gboolean is_smtp); 362 363 msg_out *create_msg_out(message *msg); 364 msg_out *clone_msg_out(msg_out *msgout_orig); 365 void destroy_msg_out(msg_out *msgout); 366 void destroy_msg_out_list(GList *msgout_list); 367 368 /* address.c */ 369 address *create_address(gchar *path, gboolean is_rfc821); 370 address *create_address_qualified(gchar *path, gboolean is_rfc821, gchar *domain); 371 address *create_address_pipe(gchar *path); 372 void destroy_address(address *addr); 373 address *copy_modify_address(const address *orig, gchar *l_part, gchar *dom); 374 #define copy_address(addr) copy_modify_address(addr, NULL, NULL) 375 gboolean addr_isequal(address *addr1, address *addr2, int (*cmpfunc) (const char*, const char*)); 376 gboolean addr_isequal_parent(address *addr1, address *addr2, int (*cmpfunc) (const char*, const char*)); 377 address *addr_find_ancestor(address *addr); 378 gboolean addr_is_delivered_children(address *addr); 379 gboolean addr_is_finished_children(address *addr); 380 gchar *addr_string(address *addr); 381 382 /* accept.c */ 383 accept_error accept_message(FILE *in, message *msg, guint flags); 384 accept_error accept_message_prepare(message *msg, guint flags); 385 386 /* header.c */ 387 gchar *rec_timestamp(); 388 GList *find_header(GList *hdr_list, header_id id, gchar *hdr_str); 389 void header_unfold(header *hdr); 390 void header_fold(header *hdr, unsigned int maxlen); 391 header *create_header(header_id id, gchar *fmt, ...); 392 void destroy_header(header *hdr); 393 header *copy_header(header *hdr); 394 header *get_header(gchar *line); 395 396 /* smtp_in.c */ 397 void smtp_in(FILE *in, FILE *out, gchar *remote_host, gchar *ident); 398 399 /* listen.c */ 400 void listen_port(GList *addr_list, gint qival, char *argv[]); 401 402 /* parse.c */ 403 gboolean split_address(const gchar *path, gchar **local_part, gchar **domain, gboolean is_rfc821); 404 gboolean parse_address_rfc822(gchar *string, gchar **local_begin, gchar **local_end, gchar **domain_begin, gchar **domain_end, gchar **address_end); 405 gboolean parse_address_rfc821(gchar *string, gchar **local_begin, gchar **local_end, gchar **domain_begin, gchar **domain_end, gchar **address_end); 406 address *_create_address(gchar *string, gchar **end, gboolean is_rfc821); 407 address *create_address_rfc821(gchar *string, gchar **end); 408 address *create_address_rfc822(gchar *string, gchar **end); 409 GList *addr_list_append_rfc822(GList *addr_list, gchar *string, gchar *domain); 410 411 /* connect.c */ 412 mxip_addr *connect_hostlist(int *psockfd, gchar *host, guint port, GList *addr_list); 413 mxip_addr *connect_resolvelist(int *psockfd, gchar *host, guint port, GList *res_funcs); 414 415 /* deliver.c */ 416 void msg_rcptlist_local(GList *rcpt_list, GList **, GList **); 417 gboolean deliver_local(msg_out *msgout); 418 gboolean deliver_msglist_host(connect_route *route, GList *msg_list, gchar *host, GList *res_list); 419 gboolean deliver_route_msgout_list(connect_route *route, GList *msgout_list); 420 gboolean deliver_route_msg_list(connect_route *route, GList *msgout_list); 421 gboolean deliver_finish(msg_out *msgout); 422 gboolean deliver_msg_list(GList *msg_list, guint flags); 423 gboolean deliver(message *msg); 424 425 /* fail_msg.c */ 426 gboolean fail_msg(message *msg, gchar *template, GList *failed_rcpts, gchar *err_fmt, va_list args); 427 gboolean warn_msg(message *msg, gchar *template, GList *failed_rcpts, gchar *err_fmt, va_list args); 428 429 /* interface.c */ 430 gboolean init_sockaddr(struct sockaddr_in *name, interface *iface); 431 int make_server_socket(interface *iface); 432 433 /* local.c */ 434 gboolean append_file(message *msg, GList *hdr_list, gchar *user); 435 gboolean pipe_out(message *msg, GList *hdr_list, address *rcpt, gchar *cmd, guint flags); 436 437 /* log.c */ 438 gchar *ext_strerror(int err); 439 gboolean logopen(void); 440 void logclose(void); 441 void vlogwrite(int pri, const char *fmt, va_list args); 442 void logwrite(int pri, const char *fmt, ...); 443 void debugf(const char *fmt, ...); 444 void vdebugf(const char *fmt, va_list args); 445 void maillog(const char *fmt, ...); 446 447 /* spool.c */ 448 gboolean spool_read_data(message *msg); 449 message *msg_spool_read(gchar *uid); 450 gboolean spool_write(message *msg, gboolean do_writedata); 451 gboolean spool_lock(gchar *uid); 452 gboolean spool_unlock(gchar *uid); 453 gboolean spool_delete_all(message *msg); 454 455 /* queue.c */ 456 GList *read_queue(void); 457 gboolean queue_run(void); 458 gboolean queue_run_online(void); 459 void queue_list(void); 460 gboolean queue_delete(gchar *uid); 461 462 /* online.c */ 463 gchar *online_query(); 464 465 /* permissions.c */ 466 gboolean is_ingroup(uid_t uid, gid_t gid); 467 void set_euidgid(gint uid, gint gid, uid_t *old_uid, gid_t *old_gid); 468 void set_identity(uid_t old_uid, gchar *task_name); 469 470 /* rewrite.c */ 471 gboolean set_address_header_domain(header *hdr, gchar *domain); 472 gboolean map_address_header(header *hdr, GList *table); 473 474 /* route.c */ 475 msgout_perhost *create_msgout_perhost(gchar *host); 476 void destroy_msgout_perhost(msgout_perhost *mo_ph); 477 void rewrite_headers(msg_out *msgout, connect_route *route); 478 void split_rcpts(GList *rcpt_list, GList *localnets, GList **rl_local, GList **rl_localnet, GList **rl_others); 479 GList *local_rcpts(GList *rcpt_list); 480 GList *remote_rcpts(GList *rcpt_list); 481 gboolean route_strip_msgout(connect_route *route, msg_out *msgout); 482 msg_out *route_prepare_msgout(connect_route *route, msg_out *msgout); 483 GList *route_msgout_list(connect_route *route, GList *msgout_list); 484 gboolean route_sender_is_allowed(connect_route *route, address *ret_path); 485 void route_split_rcpts(connect_route *route, GList *rcpt_list, GList **p_rcpt_list, GList **p_non_rcpt_list); 486 487 /* tables.c */ 488 table_pair *create_pair(gchar *key, gpointer value); 489 table_pair *create_pair_string(gchar *key, gpointer value); 490 table_pair *parse_table_pair(gchar *line, char delim); 491 gpointer *table_find_func(GList *table_list, gchar *key, int (*cmp_func) (const char *, const char *)); 492 gpointer *table_find(GList *table_list, gchar *key); 493 gpointer *table_find_case(GList *table_list, gchar *key); 494 gpointer *table_find_fnmatch(GList *table_list, gchar *key); 495 GList *table_read(gchar *fname, gchar delim); 496 void destroy_table(GList *table); 497 498 /* timeival.c */ 499 gint time_interval(gchar *str); 500 501 /* permissions.c */ 502 gboolean is_privileged_user(uid_t uid); 503 504 /* other things */ 505 506 #define foreach(list, node)\ 507 for((node) = g_list_first(list);\ 508 (node);\ 509 (node) = g_list_next(node)) 510 511 #ifdef ENABLE_DEBUG 512 #define DEBUG(level) if(level <= conf.debug_level) 513 #else 514 /* hopefully the compiler optmizes this away... */ 515 #define DEBUG(level) if(0) 516 #endif 517 518 #define LOG_VERBOSE 0x100 519 520 #ifndef HAVE_GETLINE 521 #define getline(buf, size, file) getdelim(buf, size, '\n', file) 522 #endif 523 524 #ifndef HAVE_FDATASYNC 525 #define fdatasync(fd) fsync(fd) 526 #endif 527 528 #ifndef CONF_DIR 529 #define CONF_DIR "/etc/masqmail" 530 #endif 531 532 #define CONF_FILE CONF_DIR"/masqmail.conf" 533 534 #ifndef PID_DIR 535 #define PID_DIR "/var/run" 536 #endif 537 538 #ifndef va_copy 539 #ifdef __va_copy 540 #define va_copy(ap1, ap2) __va_copy(ap1, ap2) 541 #else 542 #define va_copy(ap1, ap2) G_VA_COPY(ap1, ap2) 543 #endif 544 #endif 545 546 /* *BSD needs this: */ 547 extern char **environ; 548