1 /* source: xio.h */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
4 
5 #ifndef __xio_h_included
6 #define __xio_h_included 1
7 
8 #if 1 /*!*/
9 #include "mytypes.h"
10 #include "sysutils.h"
11 #endif
12 
13 #define XIO_MAXSOCK 2
14 
15 /* Linux 2.2.10 */
16 #define HAVE_STRUCT_LINGER 1
17 
18 #define LINETERM_RAW 0
19 #define LINETERM_CR 1
20 #define LINETERM_CRNL 2
21 
22 struct addrdesc;
23 struct opt;
24 
25 /* the flags argument of xioopen */
26 #define XIO_RDONLY  O_RDONLY /* asserted to be 0 */
27 #define XIO_WRONLY  O_WRONLY /* asserted to be 1 */
28 #define XIO_RDWR    O_RDWR   /* asserted to be 2 */
29 #define XIO_ACCMODE (XIO_RDONLY|XIO_WRONLY|XIO_RDWR)	/* must be 3 */
30 #define XIO_MAYFORK     4 /* address is allowed to fork the program (fork) */
31 #define XIO_MAYCHILD    8 /* address is allowed to fork off a child (exec)*/
32 #define XIO_MAYEXEC    16 /* address is allowed to exec a prog (exec+nofork) */
33 #define XIO_MAYCONVERT 32 /* address is allowed to perform modifications on the
34 			     stream data, e.g. SSL, REALDINE; CRLF */
35 
36 /* the status flags of xiofile_t */
37 #define XIO_DOESFORK    XIO_MAYFORK
38 #define XIO_DOESCHILD   XIO_MAYCHILD
39 #define XIO_DOESEXEC    XIO_MAYEXEC
40 #define XIO_DOESCONVERT XIO_MAYCONVERT
41 
42 
43 /* methods for reading and writing, and for related checks */
44 #define XIODATA_READMASK	0xf000	/* mask for basic r/w method */
45 #define XIOREAD_STREAM		0x1000	/* read() (default) */
46 #define XIOREAD_RECV		0x2000	/* recvfrom() */
47 #define XIOREAD_PTY		0x4000	/* handle EIO */
48 #define XIOREAD_READLINE	0x5000	/* ... */
49 #define XIOREAD_OPENSSL		0x6000	/* SSL_read() */
50 #define XIODATA_WRITEMASK	0x0f00	/* mask for basic r/w method */
51 #define XIOWRITE_STREAM		0x0100	/* write() (default) */
52 #define XIOWRITE_SENDTO		0x0200	/* sendto() */
53 #define XIOWRITE_PIPE		0x0300	/* write() to alternate (pipe) Fd */
54 #define XIOWRITE_2PIPE		0x0400	/* write() to alternate (2pipe) Fd */
55 #define XIOWRITE_READLINE	0x0500	/* check for prompt */
56 #define XIOWRITE_OPENSSL	0x0600	/* SSL_write() */
57 /* modifiers to XIODATA_READ_RECV */
58 #define XIOREAD_RECV_CHECKPORT	0x0001	/* recv, check peer port */
59 #define XIOREAD_RECV_CHECKADDR	0x0002	/* recv, check peer address */
60 #define XIOREAD_RECV_CHECKRANGE	0x0004	/* recv, check if peer addr in range */
61 #define XIOREAD_RECV_ONESHOT	0x0008	/* give EOF after first packet */
62 #define XIOREAD_RECV_SKIPIP	0x0010	/* recv, skip IPv4 header */
63 #define XIOREAD_RECV_FROM	0x0020	/* remember peer for replying */
64 
65 /* combinations */
66 #define XIODATA_MASK		(XIODATA_READMASK|XIODATA_WRITEMASK)
67 #define XIODATA_STREAM		(XIOREAD_STREAM|XIOWRITE_STREAM)
68 #define XIODATA_RECVFROM	(XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKPORT|XIOREAD_RECV_CHECKADDR|XIOREAD_RECV_FROM)
69 #define XIODATA_RECVFROM_SKIPIP	(XIODATA_RECVFROM|XIOREAD_RECV_SKIPIP)
70 #define XIODATA_RECVFROM_ONE	(XIODATA_RECVFROM|XIOREAD_RECV_ONESHOT)
71 #define XIODATA_RECVFROM_SKIPIP_ONE	(XIODATA_RECVFROM_SKIPIP|XIOREAD_RECV_ONESHOT)
72 #define XIODATA_RECV		(XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKRANGE)
73 #define XIODATA_RECV_SKIPIP	(XIODATA_RECV|XIOREAD_RECV_SKIPIP)
74 #define XIODATA_PIPE		(XIOREAD_STREAM|XIOWRITE_PIPE)
75 #define XIODATA_2PIPE		(XIOREAD_STREAM|XIOWRITE_2PIPE)
76 #define XIODATA_PTY		(XIOREAD_PTY|XIOWRITE_STREAM)
77 #define XIODATA_READLINE	(XIOREAD_READLINE|XIOWRITE_STREAM)
78 #define XIODATA_OPENSSL		(XIOREAD_OPENSSL|XIOWRITE_OPENSSL)
79 
80 
81 /* these are the values allowed for the "enum xiotag  tag" flag of the "struct
82    single" and "union bipipe" (xiofile_t) structures. */
83 enum xiotag {
84    XIO_TAG_INVALID,	/* the record is not in use */
85    XIO_TAG_RDONLY,	/* this is a single read-only stream */
86    XIO_TAG_WRONLY,	/* this is a single write-only stream */
87    XIO_TAG_RDWR,	/* this is a single read-write stream */
88    XIO_TAG_DUAL		/* this is a dual stream, consisting of two single
89 			   streams */
90 } ;
91 
92 /* global XIO options/parameters */
93 typedef struct {
94    bool strictopts;
95    const char *pipesep;
96    const char *paramsep;
97    const char *optionsep;
98    char ip4portsep;
99    char ip6portsep;	/* do not change, might be hardcoded somewhere! */
100    char logopt;	/* 'm' means "switch to syslog when entering daemon mode" */
101    const char *syslogfac;	/* syslog facility (only with mixed mode) */
102    char default_ip;	/* default prot.fam for IP based listen ('4' or '6') */
103    char preferred_ip;	/* preferred prot.fam. for name resolution ('0' for
104 			   unspecified, '4', or '6') */
105 } xioopts_t;
106 
107 /* pack the description of a lock file */
108 typedef struct {
109    const char     *lockfile;	/* name of lockfile; NULL if no locking */
110    bool            waitlock;	/* dont't exit when already locked */
111    struct timespec intervall;	/* polling intervall */
112 } xiolock_t;
113 
114 extern xioopts_t xioopts;
115 
116 #define MAXARGV 8
117 
118 #if _WITH_IP4 || _WITH_IP6
119 struct para_ip {
120 	unsigned int res_opts[2];	/* bits to be set in _res.options are
121 					   at [0], bits to be cleared are at [1] */
122 	bool     dosourceport; 	/* check the source port of incoming connection or packets */
123 	uint16_t sourceport;		/* host byte order */
124 	bool     lowport;
125 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
126 	bool   dolibwrap;
127 	char    *libwrapname;
128 	char    *tcpwrap_etc;
129 	char    *hosts_allow_table;
130 	char    *hosts_deny_table;
131 #endif
132 } ;
133 #endif /* _WITH_IP4 || _WITH_IP6 */
134 
135 /* a non-dual file descriptor */
136 typedef struct single {
137    enum xiotag tag;	/* see  enum xiotag  */
138    const struct addrdesc *addr;
139    int    flags;
140    /* until here, keep consistent with bipipe.common !!! */
141 #if WITH_RETRY
142    unsigned int retry;	/* retry opening this many times */
143    bool forever;	/* retry opening forever */
144    struct timespec intervall;	/* wait so long between retries */
145 #endif /* WITH_RETRY */
146    bool   ignoreeof;	/* option ignoreeof; do not pass eof condition to app*/
147    int    eof;		/* 1..exec'd child has died, but no explicit eof
148 			   occurred
149 			   2..fd0 has reached EOF, but check for ignoreeof
150 			   3..fd0 has reached EOF (definitely; never with
151 			   ignoreeof! */
152    size_t wsize;	/* write always this size; 0..all available */
153    size_t readbytes;	/* read only so many bytes; 0...unlimited */
154    size_t actbytes;	/* so many bytes still to be read (when readbytes!=0)*/
155    xiolock_t lock;	/* parameters of lockfile */
156    bool      havelock;	/* we are happy owner of the above lock */
157    bool	     cool_write;	/* downlevel EPIPE, ECONNRESET to notice */
158    /* until here, keep consistent with bipipe.dual ! */
159    int argc;		/* number of fields in argv */
160    const char *argv[MAXARGV];	/* address keyword, required args */
161    struct opt *opts;	/* the options of this address */
162    int    lineterm;	/* 0..dont touch; 1..CR; 2..CRNL on extern data */
163    int    fd;
164    bool   opt_unlink_close;	/* option unlink_close */
165    char  *unlink_close;	/* name of a symlink or unix socket to be removed */
166    int dtype;
167    enum {
168       XIOSHUT_UNSPEC,	/* standard (address dependent) behaviour */
169       XIOSHUT_NONE,	/* do nothing on shutdown */
170       XIOSHUT_CLOSE,	/* close the FD */
171       XIOSHUT_DOWN,	/* shutdown() */
172       XIOSHUT_NULL	/* send an empty packet (dgram socket) */
173    } howtoshut;
174    enum {
175       END_UNSPEC,	/* after init, when no end-close... option */
176       END_NONE,		/* no action */
177       END_CLOSE,	/* close() */
178       END_SHUTDOWN,	/* shutdown() */
179       END_KILL,		/* has subprocess */
180       END_CLOSE_KILL,	/* first close fd, then kill subprocess */
181       END_SHUTDOWN_KILL	/* first shutdown fd, then kill subprocess */
182    } howtoend;
183 #if _WITH_SOCKET
184    union sockaddr_union peersa;
185    socklen_t salen;
186 #endif /* _WITH_SOCKET */
187 #if WITH_TERMIOS
188    bool ttyvalid;		/* the following struct is valid */
189    struct termios savetty;	/* save orig tty settings for later restore */
190 #endif /* WITH_TERMIOS */
191    int (*sigchild)(struct single *);	/* callback after sigchild */
192    pid_t ppid;			/* parent pid, only if we send it signals */
193    int escape;			/* escape character; -1 for no escape */
194    bool actescape;		/* escape character found in input data */
195    union {
196       struct {
197 	 int fdout;		/* use fd for output */
198       } bipipe;
199 #if _WITH_SOCKET
200       struct {
201 	 /* keep a consistent copy in openssl part !!! */
202 	 struct timeval connect_timeout; /* how long to hang in connect() */
203 #if WITH_LISTEN
204 	 struct timeval accept_timeout;  /* how long to wait for incoming connection */
205 #endif
206 	 union sockaddr_union la;	/* local socket address */
207 	 bool null_eof;		/* with dgram: empty packet means EOF */
208 	 bool dorange;
209 	 struct xiorange range;	/* restrictions for peer address */
210 #if _WITH_IP4 || _WITH_IP6
211 	 struct para_ip ip;
212 #endif /* _WITH_IP4 || _WITH_IP6 */
213 	 /* up to here, keep consistent copy in openssl part !!! */
214 #if WITH_UNIX
215 	 struct {
216 	    bool     tight;
217 	 } un;
218 #endif /* WITH_UNIX */
219       } socket;
220 #endif /* _WITH_SOCKET */
221       struct {
222 	 pid_t pid;		/* child PID, with EXEC: */
223 	 int fdout;		/* use fd for output if two pipes */
224       } exec;
225 #if WITH_READLINE
226       struct {
227 	 char *history_file;
228 	 char *prompt;		/* static prompt, passed to readline() */
229 	 size_t dynbytes;	/* length of buffer for dynamic prompt */
230 	 char *dynprompt;	/* the dynamic prompt */
231 	 char *dynend;		/* current end of dynamic prompt */
232 #if HAVE_REGEX_H
233 	 bool    hasnoecho;	/* following regex is set */
234 	 regex_t noecho;	/* if it matches the prompt, input is silent */
235 #endif
236       } readline;
237 #endif /* WITH_READLINE */
238 #if WITH_OPENSSL
239       struct {
240 	 /* copy of the para.socket structure without un !!! */
241 	 struct timeval connect_timeout; /* how long to hang in connect() */
242 #if WITH_LISTEN
243 	 struct timeval accept_timeout;  /* how long to wait for incoming connection */
244 #endif
245 	 union sockaddr_union la;	/* local socket address */
246 	 bool null_eof;		/* with dgram: empty packet means EOF */
247 	 bool dorange;
248 	 struct xiorange range;	/* restrictions for peer address */
249 #if _WITH_IP4 || _WITH_IP6
250 	 struct para_ip ip;
251 #endif /* _WITH_IP4 || _WITH_IP6 */
252 	 /* end of the para.socket structure copy */
253 	 SSL_CTX* ctx; 	/* for freeing on close */
254 	 SSL *ssl;
255 #if HAVE_SSL_CTX_set_min_proto_version || defined(SSL_CTX_set_min_proto_version)
256 	 char *min_proto_version;
257 #endif
258 #if HAVE_SSL_CTX_set_max_proto_version || defined(SSL_CTX_set_max_proto_version)
259 	 char *max_proto_version;
260 #endif
261       } openssl;
262 #endif /* WITH_OPENSSL */
263 #if WITH_TUN
264       struct {
265 	 short iff_opts[2];	/* ifr flags, using OFUNC_OFFSET_MASKS */
266       } tun;
267 #endif /* WITH_TUN */
268    } para;
269 } xiosingle_t;
270 
271 /* rw: 0..read, 1..write, 2..r/w */
272 /* when implementing a new address type take care of following topics:
273    . be aware that xioopen_single is used for O_RDONLY, O_WRONLY, and O_RDWR data
274    . which options are allowed (option groups)
275    . implement application of all these options
276    . set FD_CLOEXEC on new file descriptors BEFORE the cloexec option might be
277      applied
278    .
279 */
280 
281 typedef union bipipe {
282    enum xiotag    tag;
283    struct {
284       enum xiotag tag;
285       const struct addrdesc *addr;
286       int         flags;
287    } common;
288    struct single  stream;
289    struct {
290       enum xiotag tag;
291       const struct addrdesc *addr;
292       int         flags;	/* compatible to fcntl(.., F_GETFL, ..) */
293 #if WITH_RETRY
294       unsigned retry;	/* retry opening this many times */
295       bool forever;	/* retry opening forever */
296       struct timespec intervall;	/* wait so long between retries */
297 #endif /* WITH_RETRY */
298       bool        ignoreeof;
299       int         eof;		/* fd0 has reached EOF */
300       size_t      wsize;	/* write always this size; 0..all available */
301       size_t readbytes;	/* read only so many bytes; 0...unlimited */
302       size_t actbytes;	/* so many bytes still to be read */
303       xiolock_t lock;	/* parameters of lockfile */
304       bool      havelock;	/* we are happy owner of the above lock */
305       xiosingle_t *stream[2];	/* input stream, output stream */
306    } dual;
307 } xiofile_t;
308 
309 
310 struct addrdesc {
311    const char *defname;	/* main (canonical) name of address */
312    int directions;	/* 1..read, 2..write, 3..both */
313    int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, unsigned groups,
314 	       int arg1, int arg2, int arg3);
315    unsigned groups;
316    int arg1;
317    int arg2;
318    int arg3;
319 #if WITH_HELP
320    const char *syntax;
321 #endif
322 } ;
323 
324 #define XIO_WRITABLE(s) (((s)->common.flags+1)&2)
325 #define XIO_READABLE(s) (((s)->common.flags+1)&1)
326 #define XIO_RDSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]:&(s)->stream)
327 #define XIO_WRSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]:&(s)->stream)
328 #define XIO_GETRDFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]->fd:(s)->stream.fd)
329 #define XIO_GETWRFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]->fd:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_2PIPE)?(s)->stream.para.exec.fdout:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_PIPE)?(s)->stream.para.bipipe.fdout:(s)->stream.fd)
330 #define XIO_EOF(s) (XIO_RDSTREAM(s)->eof && !XIO_RDSTREAM(s)->ignoreeof)
331 
332 typedef unsigned long flags_t;
333 
334 union integral {
335    bool           u_bool;
336    uint8_t        u_byte;
337    gid_t          u_gidt;
338    int	          u_int;
339    long           u_long;
340 #if HAVE_TYPE_LONGLONG
341    long long      u_longlong;
342 #endif
343    double         u_double;
344    mode_t         u_modet;
345    short          u_short;
346    size_t         u_sizet;
347    char          *u_string;
348    uid_t          u_uidt;
349    unsigned int   u_uint;
350    unsigned long  u_ulong;
351    unsigned short u_ushort;
352    uint16_t       u_2bytes;
353    void          *u_ptr;
354    flags_t        u_flag;
355    struct {
356       uint8_t    *b_data;
357       size_t      b_len;
358    }              u_bin;
359    struct timeval u_timeval;
360 #if HAVE_STRUCT_LINGER
361    struct linger  u_linger;
362 #endif /* HAVE_STRUCT_LINGER */
363 #if HAVE_STRUCT_TIMESPEC
364    struct timespec u_timespec;
365 #endif /* HAVE_STRUCT_TIMESPEC */
366 #if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN
367    struct {
368       char *multiaddr;
369       char *param2;	/* address, interface */
370 #if HAVE_STRUCT_IP_MREQN
371       char ifindex[IF_NAMESIZE+1];
372 #endif
373    } u_ip_mreq;
374 #endif
375 #if HAVE_STRUCT_IP_MREQ_SOURCE
376    struct {
377       char *mcaddr;
378       char *ifaddr;	/* address, interface */
379       char *srcaddr;	/* source address */
380    } u_ip_mreq_source;
381 #endif
382 #if WITH_IP4
383    struct in_addr  u_ip4addr;
384 #endif
385 } ;
386 
387 /* some aliases */
388 
389 #if HAVE_BASIC_OFF_T==3
390 #  define u_off u_int
391 #elif HAVE_BASIC_OFF_T==5
392 #  define u_off u_long
393 #elif HAVE_BASIC_OFF_T==7
394 #  define u_off u_longlong
395 #else
396 #  error "unexpected size of off_t, please report this as bug"
397 #endif
398 
399 #if defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T
400 #  if HAVE_BASIC_OFF64_T==5
401 #     define u_off64 u_long
402 #  elif HAVE_BASIC_OFF64_T==7
403 #     define u_off64 u_longlong
404 #  else
405 #     error "unexpected size of off64_t, please report this as bug"
406 #  endif
407 #endif /* defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T */
408 
409 
410 /* this handles option instances, for communication between subroutines */
411 struct opt {
412    const struct optdesc *desc;
413    union integral value;
414    union integral value2;
415    union integral value3;
416 } ;
417 
418 extern const char *PIPESEP;
419 extern xiofile_t *sock[XIO_MAXSOCK];
420 
421 extern int num_child;
422 
423 /* return values of xioopensingle */
424 #define STAT_OK		0
425 #define STAT_WARNING	1
426 #define STAT_EXIT	2
427 #define STAT_NOACTION	3	/* by retropt_* when option not applied */
428 #define STAT_RETRYNOW	-1	/* only after timeouts useful ? */
429 #define STAT_RETRYLATER	-2	/* address cannot be opened, but user might
430 				   change something in the filesystem etc. to
431 				   make this process succeed later. */
432 #define STAT_NORETRY	-3	/* address syntax error, not implemented etc;
433 				   not even by external changes correctable */
434 
435 extern int xioinitialize(void);
436 extern int xioinitialize2(void);
437 extern pid_t xio_fork(bool subchild, int level);
438 extern int xio_forked_inchild(void);
439 extern int xiosetopt(char what, const char *arg);
440 extern int xioinqopt(char what, char *arg, size_t n);
441 extern xiofile_t *xioopen(const char *args, int flags);
442 extern int xioopensingle(char *addr, struct single *xfd, int xioflags);
443 extern int xioopenhelp(FILE *of, int level);
444 
445 /* must be outside function for use by childdied handler */
446 extern xiofile_t *sock1, *sock2;
447 #define NUMUNKNOWN 4
448 extern pid_t diedunknown[NUMUNKNOWN];	/* child died before it is registered */
449 #define diedunknown1 (diedunknown[0])
450 #define diedunknown2 (diedunknown[1])
451 #define diedunknown3 (diedunknown[2])
452 #define diedunknown4 (diedunknown[3])
453 extern int   statunknown[NUMUNKNOWN]; 	/* exit state of unknown dead child */
454 
455 extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *));
456 extern int xiosetchilddied(void);
457 extern int xio_opt_signal(pid_t pid, int signum);
458 extern void childdied(int signum);
459 
460 extern ssize_t xioread(xiofile_t *sock1, void *buff, size_t bufsiz);
461 extern ssize_t xiopending(xiofile_t *sock1);
462 extern ssize_t xiowrite(xiofile_t *sock1, const void *buff, size_t bufsiz);
463 extern int xioshutdown(xiofile_t *sock, int how);
464 
465 extern int xioclose(xiofile_t *sock);
466 extern void xioexit(void);
467 
468 extern int (*xiohook_newchild)(void);	/* xio calls this function from a new child process */
469 
470 #endif /* !defined(__xio_h_included) */
471