summaryrefslogtreecommitdiffstats
path: root/src/global/header_opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/global/header_opts.c')
-rw-r--r--src/global/header_opts.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/global/header_opts.c b/src/global/header_opts.c
new file mode 100644
index 0000000..c0c4d5c
--- /dev/null
+++ b/src/global/header_opts.c
@@ -0,0 +1,179 @@
+/*++
+/* NAME
+/* header_opts 3
+/* SUMMARY
+/* message header classification
+/* SYNOPSIS
+/* #include <header_opts.h>
+/*
+/* const HEADER_OPTS *header_opts_find(string)
+/* const char *string;
+/* DESCRIPTION
+/* header_opts_find() takes a message header line and looks up control
+/* information for the corresponding header type.
+/* DIAGNOSTICS
+/* Panic: input is not a valid header line. The result is a pointer
+/* to HEADER_OPTS in case of success, a null pointer when the header
+/* label was not recognized.
+/* SEE ALSO
+/* header_opts(3h) the gory details
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <ctype.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <htable.h>
+#include <vstring.h>
+#include <stringops.h>
+#include <argv.h>
+#include <mymalloc.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <header_opts.h>
+
+ /*
+ * Header names are given in the preferred capitalization. The lookups are
+ * case-insensitive.
+ *
+ * XXX Removing Return-Path: headers should probably be done only with mail
+ * that enters via a non-SMTP channel. Changing this now could break other
+ * software. See also comments in bounce_notify_util.c.
+ */
+static HEADER_OPTS header_opts[] = {
+ "Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP,
+ "Bcc", HDR_BCC, HDR_OPT_XRECIP,
+ "Cc", HDR_CC, HDR_OPT_XRECIP,
+ "Content-Description", HDR_CONTENT_DESCRIPTION, HDR_OPT_MIME,
+ "Content-Disposition", HDR_CONTENT_DISPOSITION, HDR_OPT_MIME,
+ "Content-ID", HDR_CONTENT_ID, HDR_OPT_MIME,
+ "Content-Length", HDR_CONTENT_LENGTH, 0,
+ "Content-Transfer-Encoding", HDR_CONTENT_TRANSFER_ENCODING, HDR_OPT_MIME,
+ "Content-Type", HDR_CONTENT_TYPE, HDR_OPT_MIME,
+ "Delivered-To", HDR_DELIVERED_TO, 0,
+ "Disposition-Notification-To", HDR_DISP_NOTIFICATION, HDR_OPT_SENDER,
+ "Date", HDR_DATE, 0,
+ "Errors-To", HDR_ERRORS_TO, HDR_OPT_SENDER,
+ "From", HDR_FROM, HDR_OPT_SENDER,
+ "Mail-Followup-To", HDR_MAIL_FOLLOWUP_TO, HDR_OPT_SENDER,
+ "Message-Id", HDR_MESSAGE_ID, 0,
+ "MIME-Version", HDR_MIME_VERSION, HDR_OPT_MIME,
+ "Received", HDR_RECEIVED, 0,
+ "Reply-To", HDR_REPLY_TO, HDR_OPT_SENDER,
+ "Resent-Bcc", HDR_RESENT_BCC, HDR_OPT_XRECIP | HDR_OPT_RR,
+ "Resent-Cc", HDR_RESENT_CC, HDR_OPT_XRECIP | HDR_OPT_RR,
+ "Resent-Date", HDR_RESENT_DATE, HDR_OPT_RR,
+ "Resent-From", HDR_RESENT_FROM, HDR_OPT_SENDER | HDR_OPT_RR,
+ "Resent-Message-Id", HDR_RESENT_MESSAGE_ID, HDR_OPT_RR,
+ "Resent-Reply-To", HDR_RESENT_REPLY_TO, HDR_OPT_RECIP | HDR_OPT_RR,
+ "Resent-Sender", HDR_RESENT_SENDER, HDR_OPT_SENDER | HDR_OPT_RR,
+ "Resent-To", HDR_RESENT_TO, HDR_OPT_XRECIP | HDR_OPT_RR,
+ "Return-Path", HDR_RETURN_PATH, HDR_OPT_SENDER,
+ "Return-Receipt-To", HDR_RETURN_RECEIPT_TO, HDR_OPT_SENDER,
+ "Sender", HDR_SENDER, HDR_OPT_SENDER,
+ "To", HDR_TO, HDR_OPT_XRECIP,
+};
+
+#define HEADER_OPTS_SIZE (sizeof(header_opts) / sizeof(header_opts[0]))
+
+static HTABLE *header_hash; /* quick lookup */
+static VSTRING *header_key;
+
+/* header_opts_init - initialize */
+
+static void header_opts_init(void)
+{
+ const HEADER_OPTS *hp;
+ const char *cp;
+
+ /*
+ * Build a hash table for quick lookup, and allocate memory for
+ * lower-casing the lookup key.
+ */
+ header_key = vstring_alloc(10);
+ header_hash = htable_create(HEADER_OPTS_SIZE);
+ for (hp = header_opts; hp < header_opts + HEADER_OPTS_SIZE; hp++) {
+ VSTRING_RESET(header_key);
+ for (cp = hp->name; *cp; cp++)
+ VSTRING_ADDCH(header_key, TOLOWER(*cp));
+ VSTRING_TERMINATE(header_key);
+ htable_enter(header_hash, vstring_str(header_key), (void *) hp);
+ }
+}
+
+/* header_drop_init - initialize "header drop" flags */
+
+static void header_drop_init(void)
+{
+ ARGV *hdr_drop_list;
+ char **cpp;
+ HTABLE_INFO *ht;
+ HEADER_OPTS *hp;
+
+ /*
+ * Having one main.cf parameter for the "drop" header flag does not
+ * generalize to the "sender", "extract", etc., flags. Flags would need
+ * to be grouped by header name, but that would be unwieldy, too:
+ *
+ * message_header_flags = { apparently-to = recipient }, { bcc = recipient,
+ * extract, drop }, { from = sender }, ...
+ *
+ * Thus, it is unlikely that all header flags will become configurable.
+ */
+ hdr_drop_list = argv_split(var_drop_hdrs, CHARS_COMMA_SP);
+ for (cpp = hdr_drop_list->argv; *cpp; cpp++) {
+ lowercase(*cpp);
+ if ((ht = htable_locate(header_hash, *cpp)) == 0) {
+ hp = (HEADER_OPTS *) mymalloc(sizeof(*hp));
+ hp->type = HDR_OTHER;
+ hp->flags = HDR_OPT_DROP;
+ ht = htable_enter(header_hash, *cpp, (void *) hp);
+ hp->name = ht->key;
+ } else
+ hp = (HEADER_OPTS *) ht->value;
+ hp->flags |= HDR_OPT_DROP;
+ }
+ argv_free(hdr_drop_list);
+}
+
+/* header_opts_find - look up header options */
+
+const HEADER_OPTS *header_opts_find(const char *string)
+{
+ const char *cp;
+
+ if (header_hash == 0) {
+ header_opts_init();
+ header_drop_init();
+ }
+
+ /*
+ * Look up the lower-cased version of the header name.
+ */
+ VSTRING_RESET(header_key);
+ for (cp = string; *cp != ':'; cp++) {
+ if (*cp == 0)
+ msg_panic("header_opts_find: no colon in header: %.30s", string);
+ VSTRING_ADDCH(header_key, TOLOWER(*cp));
+ }
+ vstring_truncate(header_key,
+ trimblanks(vstring_str(header_key), cp - string)
+ - vstring_str(header_key));
+ VSTRING_TERMINATE(header_key);
+ return ((const HEADER_OPTS *) htable_find(header_hash, vstring_str(header_key)));
+}