1 /*++
2 /* NAME
3 /* ehlo_mask 3
4 /* SUMMARY
5 /* map EHLO keywords to bit mask
6 /* SYNOPSIS
7 /* #include <ehlo_mask.h>
8 /*
9 /* #define EHLO_MASK_8BITMIME (1<<0)
10 /* #define EHLO_MASK_PIPELINING (1<<1)
11 /* #define EHLO_MASK_SIZE (1<<2)
12 /* #define EHLO_MASK_VRFY (1<<3)
13 /* #define EHLO_MASK_ETRN (1<<4)
14 /* #define EHLO_MASK_AUTH (1<<5)
15 /* #define EHLO_MASK_VERP (1<<6)
16 /* #define EHLO_MASK_STARTTLS (1<<7)
17 /* #define EHLO_MASK_XCLIENT (1<<8)
18 /* #define EHLO_MASK_XFORWARD (1<<9)
19 /* #define EHLO_MASK_ENHANCEDSTATUSCODES (1<<10)
20 /* #define EHLO_MASK_DSN (1<<11)
21 /* #define EHLO_MASK_SMTPUTF8 (1<<12)
22 /* #define EHLO_MASK_CHUNKING (1<<13)
23 /* #define EHLO_MASK_SILENT (1<<15)
24 /*
25 /* int ehlo_mask(keyword_list)
26 /* const char *keyword_list;
27 /*
28 /* const char *str_ehlo_mask(bitmask)
29 /* int bitmask;
30 /* DESCRIPTION
31 /* ehlo_mask() computes the bit-wise OR of the masks that correspond
32 /* to the names listed in the \fIkeyword_list\fR argument, separated by
33 /* comma and/or whitespace characters. Undefined names are silently
34 /* ignored.
35 /*
36 /* str_ehlo_mask() translates a mask into its equivalent names.
37 /* The result is written to a static buffer that is overwritten
38 /* upon each call. Undefined bits cause a fatal run-time error.
39 /* DIAGNOSTICS
40 /* Fatal: str_ehlo_mask() found an undefined bit.
41 /* LICENSE
42 /* .ad
43 /* .fi
44 /* The Secure Mailer license must be distributed with this software.
45 /* AUTHOR(S)
46 /* Wietse Venema
47 /* IBM T.J. Watson Research
48 /* P.O. Box 704
49 /* Yorktown Heights, NY 10598, USA
50 /*
51 /* Wietse Venema
52 /* Google, Inc.
53 /* 111 8th Avenue
54 /* New York, NY 10011, USA
55 /*--*/
56
57 /* System library.*/
58
59 #include <sys_defs.h>
60
61 /* Utility library. */
62
63 #include <name_mask.h>
64
65 /* Global library. */
66
67 #include <ehlo_mask.h>
68
69 /*
70 * The lookup table.
71 */
72 static const NAME_MASK ehlo_mask_table[] = {
73 "8BITMIME", EHLO_MASK_8BITMIME,
74 "AUTH", EHLO_MASK_AUTH,
75 "ETRN", EHLO_MASK_ETRN,
76 "PIPELINING", EHLO_MASK_PIPELINING,
77 "SIZE", EHLO_MASK_SIZE,
78 "VERP", EHLO_MASK_VERP,
79 "VRFY", EHLO_MASK_VRFY,
80 "XCLIENT", EHLO_MASK_XCLIENT,
81 "XFORWARD", EHLO_MASK_XFORWARD,
82 "STARTTLS", EHLO_MASK_STARTTLS,
83 "ENHANCEDSTATUSCODES", EHLO_MASK_ENHANCEDSTATUSCODES,
84 "DSN", EHLO_MASK_DSN,
85 "EHLO_MASK_SMTPUTF8", EHLO_MASK_SMTPUTF8,
86 "SMTPUTF8", EHLO_MASK_SMTPUTF8,
87 "CHUNKING", EHLO_MASK_CHUNKING,
88 "SILENT-DISCARD", EHLO_MASK_SILENT, /* XXX In-band signaling */
89 0,
90 };
91
92 /* ehlo_mask - string to bit mask */
93
ehlo_mask(const char * mask_str)94 int ehlo_mask(const char *mask_str)
95 {
96
97 /*
98 * We allow "STARTTLS" besides "starttls, because EHLO keywords are often
99 * spelled in uppercase. We ignore non-existent EHLO keywords so people
100 * can switch between Postfix versions without trouble.
101 */
102 return (name_mask_opt("ehlo string mask", ehlo_mask_table,
103 mask_str, NAME_MASK_ANY_CASE | NAME_MASK_IGNORE));
104 }
105
106 /* str_ehlo_mask - mask to string */
107
str_ehlo_mask(int mask_bits)108 const char *str_ehlo_mask(int mask_bits)
109 {
110
111 /*
112 * We don't allow non-existent bits. Doing so makes no sense at this
113 * time.
114 */
115 return (str_name_mask("ehlo bitmask", ehlo_mask_table, mask_bits));
116 }
117
118 #ifdef TEST
119
120 /*
121 * Stand-alone test program.
122 */
123 #include <stdlib.h>
124 #include <vstream.h>
125 #include <vstring.h>
126 #include <vstring_vstream.h>
127
main(int unused_argc,char ** unused_argv)128 int main(int unused_argc, char **unused_argv)
129 {
130 int mask_bits;
131 VSTRING *buf = vstring_alloc(1);
132 const char *mask_string;
133
134 while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
135 mask_bits = ehlo_mask(vstring_str(buf));
136 mask_string = str_ehlo_mask(mask_bits);
137 vstream_printf("%s -> 0x%x -> %s\n", vstring_str(buf), mask_bits,
138 mask_string);
139 vstream_fflush(VSTREAM_OUT);
140 }
141 vstring_free(buf);
142 exit(0);
143 }
144
145 #endif
146