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