1/*++
2/* NAME
3/*	verp_sender 3
4/* SUMMARY
5/*	quote local part of mailbox
6/* SYNOPSIS
7/*	#include <verp_sender.h>
8/*
9/*	VSTRING	*verp_sender(dst, delims, sender, recipient)
10/*	VSTRING	*dst;
11/*	const char *delims;
12/*	const char *sender;
13/*	const RECIPIENT *recipient;
14/*
15/*	const char *verp_delims_verify(delims)
16/*	const char *delims;
17/* DESCRIPTION
18/*	verp_sender() encodes the recipient address in the sender
19/*	address, using the specified delimiters. For example,
20/*	with delims +=, sender \fIprefix@origin\fR, and
21/*	recipient \fIuser@domain\fR the result is
22/*	\fIprefix+user=domain@origin\fR.
23/*
24/*	verp_delims_verify() determines if the specified VERP delimiters
25/*	have reasonable values. What is reasonable is configured with
26/*	the verp_delimiter_filter configuration parameter. The result
27/*	is null in case of success, a description of the problem in
28/*	case of error.
29/*
30/*	Arguments:
31/* .IP dst
32/*	The result. The buffer is null terminated.
33/* .IP delims
34/*	VERP formatting characters.
35/* .IP sender
36/*	Sender envelope address.
37/* .IP recipient
38/*	Recipient envelope address.
39/* LICENSE
40/* .ad
41/* .fi
42/*	The Secure Mailer license must be distributed with this software.
43/* AUTHOR(S)
44/*	Wietse Venema
45/*	IBM T.J. Watson Research
46/*	P.O. Box 704
47/*	Yorktown Heights, NY 10598, USA
48/*--*/
49
50/* System library. */
51
52#include <sys_defs.h>
53#include <string.h>
54
55/* Utility library. */
56
57#include <vstring.h>
58
59/* Global library. */
60
61#include <mail_params.h>
62#include <recipient_list.h>
63#include <verp_sender.h>
64
65/* verp_sender - encode recipient into envelope sender address */
66
67VSTRING *verp_sender(VSTRING *buf, const char *delimiters,
68		             const char *sender, const RECIPIENT *rcpt_info)
69{
70    ssize_t send_local_len;
71    ssize_t rcpt_local_len;
72    const char *recipient;
73    const char *cp;
74
75    /*
76     * Change prefix@origin into prefix+user=domain@origin.
77     *
78     * Fix 20090115: Use the Postfix original recipient, because that is what
79     * the VERP consumer expects.
80     */
81    send_local_len = ((cp = strrchr(sender, '@')) != 0 ?
82		      cp - sender : strlen(sender));
83    recipient = (rcpt_info->orig_addr[0] ?
84		 rcpt_info->orig_addr : rcpt_info->address);
85    rcpt_local_len = ((cp = strrchr(recipient, '@')) != 0 ?
86		      cp - recipient : strlen(recipient));
87    vstring_strncpy(buf, sender, send_local_len);
88    VSTRING_ADDCH(buf, delimiters[0] & 0xff);
89    vstring_strncat(buf, recipient, rcpt_local_len);
90    if (recipient[rcpt_local_len] && recipient[rcpt_local_len + 1]) {
91	VSTRING_ADDCH(buf, delimiters[1] & 0xff);
92	vstring_strcat(buf, recipient + rcpt_local_len + 1);
93    }
94    if (sender[send_local_len] && sender[send_local_len + 1]) {
95	VSTRING_ADDCH(buf, '@');
96	vstring_strcat(buf, sender + send_local_len + 1);
97    }
98    VSTRING_TERMINATE(buf);
99    return (buf);
100}
101
102/* verp_delims_verify - sanitize VERP delimiters */
103
104const char *verp_delims_verify(const char *delims)
105{
106    if (strlen(delims) != 2)
107	return ("bad VERP delimiter character count");
108    if (strchr(var_verp_filter, delims[0]) == 0)
109	return ("bad first VERP delimiter character");
110    if (strchr(var_verp_filter, delims[1]) == 0)
111	return ("bad second VERP delimiter character");
112    return (0);
113}
114