1/*	$NetBSD: split_addr.c,v 1.3 2020/03/18 19:05:16 christos Exp $	*/
2
3/*++
4/* NAME
5/*	split_addr 3
6/* SUMMARY
7/*	recipient localpart address splitter
8/* SYNOPSIS
9/*	#include <split_addr.h>
10/*
11/*	char	*split_addr_internal(localpart, delimiter_set)
12/*	char	*localpart;
13/*	const char *delimiter_set;
14/* LEGACY SUPPORT
15/*	char	*split_addr(localpart, delimiter_set)
16/*	char	*localpart;
17/*	const char *delimiter_set;
18/* DESCRIPTION
19/*	split_addr*() null-terminates \fIlocalpart\fR at the first
20/*	occurrence of the \fIdelimiter\fR character(s) found, and
21/*	returns a pointer to the remainder.
22/*
23/*	With split_addr_internal(), the address must be in internal
24/*	(unquoted) form.
25/*
26/*	split_addr() is a backwards-compatible form for legacy code.
27/*
28/*	Reserved addresses are not split: postmaster, mailer-daemon,
29/*	double-bounce. Addresses that begin with owner-, or addresses
30/*	that end in -request are not split when the owner_request_special
31/*	parameter is set.
32/* LICENSE
33/* .ad
34/* .fi
35/*	The Secure Mailer license must be distributed with this software.
36/* AUTHOR(S)
37/*	Wietse Venema
38/*	IBM T.J. Watson Research
39/*	P.O. Box 704
40/*	Yorktown Heights, NY 10598, USA
41/*
42/*	Wietse Venema
43/*	Google, Inc.
44/*	111 8th Avenue
45/*	New York, NY 10011, USA
46/*--*/
47
48/* System library. */
49
50#include <sys_defs.h>
51#include <string.h>
52
53#ifdef STRCASECMP_IN_STRINGS_H
54#include <strings.h>
55#endif
56
57/* Utility library. */
58
59#include <split_at.h>
60#include <stringops.h>
61
62/* Global library. */
63
64#include <mail_params.h>
65#include <mail_addr.h>
66#include <split_addr.h>
67
68/* split_addr_internal - split address with extreme prejudice */
69
70char   *split_addr_internal(char *localpart, const char *delimiter_set)
71{
72    ssize_t len;
73
74    /*
75     * Don't split these, regardless of what the delimiter is.
76     */
77    if (strcasecmp(localpart, MAIL_ADDR_POSTMASTER) == 0)
78	return (0);
79    if (strcasecmp(localpart, MAIL_ADDR_MAIL_DAEMON) == 0)
80	return (0);
81    if (strcasecmp_utf8(localpart, var_double_bounce_sender) == 0)
82	return (0);
83
84    /*
85     * Backwards compatibility: don't split owner-foo or foo-request.
86     */
87    if (strchr(delimiter_set, '-') != 0 && var_ownreq_special != 0) {
88	if (strncasecmp(localpart, "owner-", 6) == 0)
89	    return (0);
90	if ((len = strlen(localpart) - 8) > 0
91	    && strcasecmp(localpart + len, "-request") == 0)
92	    return (0);
93    }
94
95    /*
96     * Safe to split this address. Do not split the address if the result
97     * would have a null localpart.
98     */
99    if ((len = strcspn(localpart, delimiter_set)) == 0 || localpart[len] == 0) {
100	return (0);
101    } else {
102	localpart[len] = 0;
103	return (localpart + len + 1);
104    }
105}
106