1 /*
2  * mavis.h
3  * (C)1998-2015 by Marc Huber <Marc.Huber@web.de>
4  * All rights reserved.
5  *
6  * $Id: mavis.h,v 1.82 2019/03/31 09:14:22 marc Exp marc $
7  *
8  */
9 
10 #ifndef __MAVIS_H_
11 #define __MAVIS_H_
12 #include <sys/types.h>
13 #include <unistd.h>
14 #include <sys/time.h>
15 #include <sys/poll.h>
16 #include <sys/types.h>
17 #include <stdarg.h>
18 #include <setjmp.h>
19 
20 #include "misc/sysconf.h"
21 
22 #include "scm.h"
23 #include "debug.h"
24 #include "token.h"
25 
26 #include "misc/io_sched.h"
27 #include "misc/io_child.h"
28 #include "misc/pid_write.h"
29 #include "misc/rb.h"
30 
31 /* Response codes for MAVIS modules */
32 
33 /* External + internal interface: */
34 #define MAVIS_FINAL	0	/* response available */
35 #define MAVIS_DEFERRED	1	/* response deferred */
36 #define MAVIS_IGNORE	2	/* ignore response */
37 #define MAVIS_TIMEOUT	3	/* query timed out */
38 
39 /* Internal interface: */
40 #define MAVIS_DOWN	16	/* pass request to lower module */
41 
42 /* Module configuration return codes: */
43 #define MAVIS_CONF_OK	0	/* configuration succeeded */
44 #define MAVIS_CONF_ERR	1	/* configuration failed */
45 
46 /* Initialization return codes: */
47 #define MAVIS_INIT_OK	0	/* initialization succeeded */
48 #define MAVIS_INIT_ERR	1	/* initialization failed */
49 
50 #define BUFSIZE_MAVIS 65000
51 
52 #ifdef __MAVIS_MAIN__
53 #define AV_CHAR_START char *av_char[] = {
54 AV_CHAR_START
55 #undef AV_CHAR_START
56 #define AV_CHAR(A,B) A,B
57 #else
58 #define AV_CHAR(A,B)
59 #endif
60 
61 
62 #define AV_A_TYPE               0
63 AV_CHAR("TYPE",)
64 #define AV_A_DIGEST_MD5_USER	1
65     AV_CHAR("DIGEST_MD5_USER",)
66 #define AV_A_UDATA		2
67     AV_CHAR("UDATA",)
68 #define AV_A_TIMESTAMP		3
69 #define AV_A_DIGEST_MD5_NONCE	AV_A_TIMESTAMP
70     AV_CHAR("TIMESTAMP",)
71 #define AV_A_USER		4
72     AV_CHAR("USER",)
73 #define AV_A_DIGEST             5
74     AV_CHAR("DIGEST",)
75 #define AV_A_RESULT             6
76     AV_CHAR("RESULT",)
77 #define AV_A_PATH               7
78     AV_CHAR("PATH",)
79 #define AV_A_PASSWORD           8
80     AV_CHAR("PASSWORD",)
81 #define AV_A_UID                9
82     AV_CHAR("UID",)
83 #define AV_A_GID                10
84     AV_CHAR("GID",)
85 #define AV_A_LIMIT		11
86     AV_CHAR("LIMIT",)
87 #define AV_A_TRANSPORT		12
88     AV_CHAR("TRANSPORT",)
89 #define AV_A_TRAFFICSHAPING	13
90     AV_CHAR("TRAFFICSHAPING",)
91 #define AV_A_IPADDR             14
92     AV_CHAR("IPADDR",)
93 #define AV_A_QUOTA_LIMIT        15
94     AV_CHAR("QUOTA_LIMIT",)
95 #define AV_A_QUOTA_PATH         16
96     AV_CHAR("QUOTA_PATH",)
97 #define AV_A_COMMENT            17
98     AV_CHAR("COMMENT",)
99 #define AV_A_DIGEST_MD5_CNONCE	18
100     AV_CHAR("CNONCE",)
101 #define AV_A_HOME               19
102     AV_CHAR("HOME",)
103 #define AV_A_ROOT               20
104     AV_CHAR("ROOT",)
105 #define AV_A_SERIAL             21
106     AV_CHAR("SERIAL",)
107 #define AV_A_FTP_ANONYMOUS	22
108     AV_CHAR("FTP_ANONYMOUS",)
109 #define AV_A_EMAIL		23
110     AV_CHAR("EMAIL",)
111 #define AV_A_GIDS		24	/* supplemental groups */
112     AV_CHAR("GIDS",)
113 #define AV_A_SERVERIP		25
114     AV_CHAR("SERVERIP",)
115 #define AV_A_TARIFF		26
116     AV_CHAR("TARIFF",)
117 #define AV_A_REALM		27
118     AV_CHAR("REALM",)
119 #define AV_A_DIGEST_MD5_URI	28
120     AV_CHAR("DIGEST_URI",)
121 #define AV_A_ANON_INCOMING	29
122     AV_CHAR("ANON_INCOMING",)
123 #define AV_A_VHOST		30
124     AV_CHAR("VHOST",)
125 #define AV_A_UMASK		31
126     AV_CHAR("UMASK",)
127 #define AV_A_USER_RESPONSE	32
128     AV_CHAR("USER_RESPONSE",)
129 #define AV_A_AUTH_METHOD	33
130     AV_CHAR("AUTH_METHOD",)
131 #define AV_A_CLASS		34
132     AV_CHAR("CLASS",)
133 #define AV_A_DIGEST_MD5_RSPAUTH	35
134     AV_CHAR("DIGEST_MD5_RESPONSE",)
135 #define AV_A_DBPASSWORD		36
136     AV_CHAR("DBPASSWORD",)
137 #define AV_A_SCRAM_CLIENT_CHALLENGE	37
138     AV_CHAR("SCRAM_CLIENT_CHALLENGE",)
139 #define AV_A_SCRAM_SERVER_CHALLENGE	38
140     AV_CHAR("SCRAM_SERVER_CHALLENGE",)
141 #define AV_A_SCRAM_SERVER_PROOF		39
142     AV_CHAR("SCRAM_SERVER_PROOF",)
143 #define AV_A_SCRAM_CLIENT_PROOF		40
144     AV_CHAR("SCRAM_CLIENT_PROOF",)
145 #define AV_A_MAILCHECK_POST		41
146     AV_CHAR("MAILCHECK_POST",)
147 #define AV_A_MAILCHECK_PRE		42
148     AV_CHAR("MAILCHECK_PRE",)
149 #define AV_A_TUNNEL			43
150     AV_CHAR("TUNNEL",)
151 #define AV_A_CERTSUBJ			44
152     AV_CHAR("CERTSUBJ",)
153 #define AV_A_DBCERTSUBJ			45
154     AV_CHAR("DBCERTSUBJ",)
155 #define AV_A_TACCLIENT			46
156     AV_CHAR("TACCLIENT",)
157 #define AV_A_TACMEMBER			47
158     AV_CHAR("TACMEMBER",)
159 #define AV_A_TACPROFILE			48
160     AV_CHAR("TACPROFILE",)
161 #define AV_A_TACTYPE			49
162     AV_CHAR("TACTYPE",)
163 #define AV_A_PASSWORD_NEW		50
164     AV_CHAR("PASSWDNEW",)
165 #define AV_A_CHALLENGE			51
166     AV_CHAR("CHALLENGE",)
167 #define AV_A_PASSWORD_ONESHOT		52
168     AV_CHAR("PASSWORD_ONESHOT",)
169 #define AV_A_PASSWORD_MUSTCHANGE	53
170     AV_CHAR("PASSWORD_MUSTCHANGE",)
171 #define AV_A_SHELL			54
172     AV_CHAR("SHELL",)
173 #define AV_A_ARRAYSIZE          	55
174 #ifdef __MAVIS_MAIN__
175 #define AV_CHAR_END };
176     AV_CHAR_END
177 #undef AV_CHAR_END
178 #endif
179 #define AV_V_TYPE_WWW           	"WWW"
180 #define AV_V_TYPE_FTP           	"FTP"
181 #define AV_V_TYPE_POP3          	"POP3"
182 #define AV_V_TYPE_POP3PATH		"POP3PATH"
183 #define AV_V_TYPE_LOGIN         	"LOGIN"
184 #define AV_V_TYPE_CANONICAL		"CANONICAL"
185 #define AV_V_TYPE_TRANSPORT		"TRANSPORT"
186 #define AV_V_TYPE_VIRTUAL		"VIRTUAL"
187 #define AV_V_TYPE_RADIUS		"RADIUS"
188 #define AV_V_TYPE_TACPLUS		"TACPLUS"
189 /* private query types/commands, may not be used in client queries */
190 #define AV_V_TYPE_PRIVATE_PREFIX	"PRIV_"
191 #define AV_V_TYPE_PRIVATE_PREFIX_LEN	5
192 #define AV_V_TYPE_LOGSTATS		"PRIV_LOGSTATS"
193 #define AV_V_BOOL_TRUE          	"TRUE"
194 #define AV_V_BOOL_FALSE         	"FALSE"
195 #define AV_V_RESULT_OK          	"ACK"
196 #define AV_V_RESULT_FAIL        	"NAK"
197 #define AV_V_RESULT_ERROR       	"ERR"
198 #define AV_V_RESULT_NOTFOUND    	"NFD"
199 #define AV_V_TACTYPE_AUTH		"AUTH"
200 #define AV_V_TACTYPE_INFO		"INFO"
201 #define AV_V_TACTYPE_CHPW		"CHPW"
202 #define AV_V_TACTYPE_CHAL		"CHAL"
203 #define AV_V_AUTH_METHOD_APOP		"APOP"
204 #define AV_V_AUTH_METHOD_USER		"USER"
205 #define AV_V_AUTH_METHOD_CRAM_MD5	"CRAM-MD5"
206 #define AV_V_AUTH_METHOD_SCRAM_MD5	"SCRAM-MD5"
207 #define AV_V_AUTH_METHOD_DIGEST_MD5	"DIGEST-MD5"
208 #define AV_V_TRANSPORT_POP3		"pop3"
209 #define AV_V_TRANSPORT_QUOTA_TEMP	"quota-t"
210 #define AV_V_TRANSPORT_QUOTA_PERM	"quota-p"
211 #define AV_V_TRANSPORT_BOUNCE		"bounce"
212 #define AV_V_TRANSPORT_DEFER		"defer"
213 #define AV_V_TRANSPORT_FORWARD		"forward"
214 #define AV_V_TRANSPORT_LIST		"list"
215 typedef struct av_ctx av_ctx;
216 
217 struct av_ctx {
218     char *arr[AV_A_ARRAYSIZE];
219     void *app_cb;
220     void *app_ctx;
221 };
222 
223 typedef struct mavis_ctx mavis_ctx;
224 struct sym;
225 struct mavis_action;
226 
227 struct mavis_ctx {
228     void *handle;
229     int (*append) (mavis_ctx *, void *);
230     int (*init) (mavis_ctx *);
231     int (*parse) (mavis_ctx *, struct sym *, char *);
232     int (*send) (mavis_ctx *, av_ctx **);
233     int (*recv) (mavis_ctx *, av_ctx **, void *);
234     int (*cancel) (mavis_ctx *, void *);
235     void *(*drop) (mavis_ctx *);
236     mavis_ctx *down;
237     av_ctx *ac_bak;
238     int ac_bak_required;
239     struct mavis_action *script_in;
240     struct mavis_action *script_out;
241     struct io_context *io;
242 #ifdef MAVIS_CTX_PRIVATE
243      MAVIS_CTX_PRIVATE
244 #endif
245     char identifier[1];
246 };
247 
248 /* Module handling: */
249 int mavis_method_add(mavis_ctx **, struct io_context *ctx, char *, char *);
250 int mavis_init(mavis_ctx *, char *);
251 int mavis_cancel(mavis_ctx *, void *);
252 int mavis_drop(mavis_ctx *);
253 int mavis_send(mavis_ctx *, av_ctx **);
254 int mavis_recv(mavis_ctx *, av_ctx **, void *);
255 int mavis_parse(mavis_ctx *, struct sym *, char *);
256 
257 int get_syslog_level(char *);
258 int get_syslog_facility(char *);
259 
260 /* Attribute-value handling: */
261 av_ctx *av_new(void *, void *);
262 void av_setcb(av_ctx *, void *, void *);
263 void av_free(av_ctx *);
264 char *av_get(av_ctx *, int);
265 void av_set(av_ctx *, int, char *);
266 void av_setf(av_ctx *, int, char *, ...)
267     __attribute__ ((format(printf, 3, 4)));
268 #define av_unset(A,B) av_set(A,B, NULL)
269 void av_clear(av_ctx *);
270 void av_dump(av_ctx *);
271 void av_move(av_ctx *, av_ctx *);
272 void av_merge(av_ctx *, av_ctx *);
273 void av_copy(av_ctx *, av_ctx *);
274 int av_array_to_char(av_ctx *, char *, size_t, fd_set *);
275 int av_char_to_array(av_ctx *, char *, fd_set *);
276 int av_attribute_to_i(char *);
277 
278 char *av_addserial(av_ctx *);
279 
280 #define MAX_INPUT_LINE_LEN 4096
281 
282 struct token_chain;
283 
284 struct sym {
285     char *filename;
286     char buf[MAX_INPUT_LINE_LEN];	/* parse buffer */
287     char *start;
288     char *raw;
289     int pos;			/* current place in buf */
290     u_int line:30;		/* current line number for parsing */
291     u_int flag_parse_pcre:1;
292     u_int flag_prohibit_include:1;
293     char ch[4];			/* current parse character */
294     char chlen;			/* current parse character length */
295     enum token code;		/* parser output */
296     char *in;			/* input buffer start */
297     int len;			/* input buffer length */
298     char *tin;			/* pointer to remaining input buffer */
299     int tlen;			/* length of remaining input buffer */
300     jmp_buf env;		/* saved stack context for parse errors */
301     struct token_chain *token_chain;
302     struct sym *next;
303 };
304 
305 void parse_error(struct sym *, char *, ...);
306 void parse_error_expect(struct sym *, enum token, ...);
307 enum token parse_permission(struct sym *);
308 int parse_bool(struct sym *);
309 void parse(struct sym *, enum token);
310 void getsym(struct sym *);
311 void buf_add(struct sym *, char);
312 void sym_get(struct sym *);
313 enum token sym_peek(struct sym *);
314 void cfg_read_config(char *, void (*)(struct sym *), char *);
315 enum token keycode(char *);
316 int parse_int(struct sym *);
317 int parse_seconds(struct sym *);
318 void sym_init(struct sym *);
319 void report_cfg_error(int, int, char *, ...)
320     __attribute__ ((format(printf, 3, 4)));
321 void parse_debug(struct sym *, u_int *);
322 int parse_comma(struct sym *);
323 
324 void parse_userid(struct sym *, uid_t *, gid_t *);
325 void parse_groupid(struct sym *, gid_t *);
326 void parse_umask(struct sym *, mode_t *);
327 
328 void parse_mavispath(struct sym *);
329 int parse_mavismodule(mavis_ctx **, struct io_context *, struct sym *);
330 
331 struct common_data {
332     struct io_context *io;
333     char *progname;
334     char *progpath;
335     char *version;
336     u_int version_only;
337     u_int parse_only;
338     u_int debug;
339     u_int debug_redirected;
340     int syslog_level;
341     int syslog_facility;
342     u_int syslog_dflt:1;
343     unsigned long long regex_match_case;
344 #if defined(WITH_PCRE) || defined(WITH_PCRE2)
345     int regex_pcre_flags;
346 #endif
347     int regex_posix_flags;
348     char *syslog_ident;
349     char *proctitle;
350     char *coredumpdir;
351     char *gcorepath;
352     char *debug_cmd;
353     int debugtty;
354     pid_t pid;
355     int users_min;
356     int users_max;
357     int users_cur;
358     int users_max_total;
359     int servers_min;
360     int servers_max;
361     int servers_cur;
362     char *font_black;
363     char *font_red;
364     char *font_green;
365     char *font_yellow;
366     char *font_blue;
367     char *font_magenta;
368     char *font_cyan;
369     char *font_white;
370     char *font_plain;
371     char *font_bold;
372     u_long ipc_key;
373     char *ipc_url;
374     char **argv;
375     char **envp;
376     struct pidfile *pidfile;
377     int singleprocess;
378     char *conffile;
379     char *id;
380     int (*scm_send_msg) (int, struct scm_data *, int);
381     int (*scm_recv_msg) (int, struct scm_data_accept *, size_t, int *);
382     void (*scm_accept) (int, struct scm_data_accept *);
383 };
384 
385 extern struct common_data common_data;
386 
387 #define case_CC_Tokens \
388         case S_trace:\
389         case S_debug:\
390         case S_syslog:\
391         case S_proctitle:\
392         case S_coredump: parse_common(sym); continue
393 
394 void init_common_data(void);
395 void parse_common(struct sym *);
396 void common_usage(void);
397 
398 void mavis_script_parse(mavis_ctx *, struct sym *);
399 enum token mavis_script_eval(mavis_ctx *, av_ctx *, struct mavis_action *);
400 void mavis_script_drop(struct mavis_action **);
401 
402 struct mavis_tm {
403     struct mavis_tm *next;
404     char *string;
405     unsigned long long min;	/* minute, 0-59 */
406     unsigned long hour;		/* hour, 0-23 */
407     unsigned long mday;		/* day of month, 1-31 */
408     unsigned long mon;		/* month, 1-12 */
409     unsigned long wday;		/* day of week, 1-7 */
410 };
411 
412 struct mavis_timespec {
413     struct mavis_tm *tm;
414     char *string;
415     int matched;		/* 0 == no match */
416     time_t valid_until;
417     char name[1];
418 };
419 
420 int eval_timespec(struct mavis_timespec *, char **);
421 
422 int parse_cron(struct mavis_tm *, char *);
423 void parse_timespec(struct sym *);
424 struct mavis_timespec *find_timespec(char *);
425 void init_timespec(void);
426 
427 int cfg_open_and_read(char *, char **, int *);
428 int cfg_close(char *, char *, int);
429 int ipc_create(char *, int);
430 void ipc_delete(void);
431 
432 int mavis_check_version(char *);
433 
434 void mavis_detach(void);
435 
436 #endif				/* __MAVIS_H_ */
437