3 * Common definitions for YAID
5 * (c) 2012 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Yet Another Ident Daemon (YAID).
12 * YAID is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * YAID is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with YAID; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 /*----- Header files ------------------------------------------------------*/
48 #include <sys/types.h>
56 #include <sys/socket.h>
57 #include <netinet/in.h>
58 #include <arpa/inet.h>
63 #include <mLib/bits.h>
64 #include <mLib/conn.h>
65 #include <mLib/daemonize.h>
66 #include <mLib/darray.h>
67 #include <mLib/dstr.h>
68 #include <mLib/fdflags.h>
69 #include <mLib/fwatch.h>
70 #include <mLib/macros.h>
71 #include <mLib/mdwopt.h>
72 #include <mLib/quis.h>
73 #include <mLib/report.h>
75 #include <mLib/selbuf.h>
78 /*----- Address family handling -------------------------------------------*/
80 /* The maximum length of an address formatted as a text string, including the
81 * terminating null byte.
85 /* A list of address types. */
86 #define ADDRTYPES(_) \
90 /* Address types for the various families, in the form acceptable to
91 * inet_ntop(3) and inet_pton(3). */
92 #define TYPE_IPV4 struct in_addr
93 #define TYPE_IPV6 struct in6_addr
95 /* A union of address types. */
97 #define UMEMB(ty, TY) TYPE_##TY ty;
102 /* A socket holds an address and a port number. */
104 union addr addr
; /* The address */
105 unsigned port
; /* The port, in /host/ byte order */
108 /* An address pattern consists of an address and a prefix length: the
109 * pattern matches an address if they agree in the first LEN bits.
112 union addr addr
; /* The base address */
113 unsigned len
; /* The prefix length */
116 /* A port pattern matches a port if the port is within the stated (inclusive)
123 /* A socket pattern consists simply of an address pattern and a port pattern:
124 * it matches a socket componentwise.
131 /* The table of address-type operations. Each address family has one of
132 * these, so that most of the program doesn't need to worry about these
136 int af
; /* The AF_* constant */
137 const char *name
; /* Name of the protocol, for logs */
138 unsigned len
; /* Length of an address, in bits */
139 const union addr
*any
; /* A wildcard address */
140 const struct addrops_sys
*sys
; /* Pointer to system-specific ops */
142 int (*addreq
)(const union addr
*, const union addr
*);
143 /* Return nonzero if the two addresses are equal. */
145 int (*match_addrpat
)(const struct addrpat
*, const union addr
*);
146 /* Return nonzero if the pattern matches the address. */
148 void (*socket_to_sockaddr
)(const struct socket
*s
, void *, size_t *);
149 /* Convert a socket structure to a `struct sockaddr', and return the
150 * size of the latter.
153 void (*sockaddr_to_addr
)(const void *, union addr
*);
154 /* Extract the address from a `struct sockaddr'. */
156 int (*init_listen_socket
)(int);
157 /* Perform any necessary extra operations on a socket which is going
158 * to be used to listen for incoming connections.
162 /* A handy constant for each address family. These are more useful than the
163 * AF_* constants in that they form a dense sequence.
166 #define DEFADDR(ty, TY) ADDR_##TY,
172 /* The table of address operations, indexed by the ADDR_* constants defined
175 extern const struct addrops addroptab
[];
177 /* System-specific operations, provided by the system-specific code for its
180 #define OPS_SYS(ty, TY) \
181 extern const struct addrops_sys addrops_sys_##ty;
185 /* Answer whether the sockets SA and SB are equal. */
186 extern int sockeq(const struct addrops */
*ao*/
,
187 const struct socket */
*sa*/
, const struct socket */
*sb*/
);
189 /* Write a textual description of S to the string D. */
190 extern void dputsock(dstr */
*d*/
, const struct addrops */
*ao*/
,
191 const struct socket */
*s*/
);
193 /*----- Queries and responses ---------------------------------------------*/
195 /* Constants for describing the `L'ocal and `R'emote ends of a connection. */
198 /* Response types, and the data needed to represent any associated data. A
199 * U_(MEMB, TYPE) constructs a union member; an N_ means no associated data.
201 #define RESPONSE(_) \
202 _(ERROR, U_(error, unsigned)) \
203 _(UID, U_(uid, uid_t)) \
204 _(NAT, U_(nat, struct socket))
207 #define DEFENUM(what, branch) R_##what,
213 /* Protocol error tokens. */
215 _(INVPORT, "INVALID-PORT") \
216 _(NOUSER, "NO-USER") \
217 _(HIDDEN, "HIDDEN-USER") \
218 _(UNKNOWN, "UNKNOWN-ERROR")
221 #define DEFENUM(err, tok) E_##err,
227 extern const char *const errtok
[];
229 /* The query structure keeps together the parameters to the client's query
230 * and our response to it.
233 const struct addrops
*ao
; /* Address family operations */
234 struct socket s
[NDIR
]; /* The local and remote ends */
235 unsigned resp
; /* Our response type */
236 union { /* A union of response data */
237 #define DEFBRANCH(WHAT, branch) branch
238 #define U_(memb, ty) ty memb;
247 /*----- Common utility functions ------------------------------------------*/
249 /* Format and log MSG somewhere sensible, at the syslog(3) priority PRIO.
250 * Prefix it with a description of the query Q, if non-null.
252 extern void PRINTF_LIKE(3, 4)
253 logmsg(const struct query */
*q*/
, int /*prio*/, const char */
*msg*/
, ...);
255 /* Format and report MSG as a fatal error, and exit. */
256 extern void PRINTF_LIKE(1, 2) fatal(const char */
*msg*/
, ...);
258 /*----- System-specific connection identification code --------------------*/
260 /* Find out who is responsible for the connection described in the query Q.
261 * Write the answer to Q. Errors are logged and reported via the query
264 extern void identify(struct query */
*q*/
);
266 /* Fill the buffer at P with SZ random bytes. The buffer will be moderately
267 * large: this is intended to be a low-level interface, not a general-purpose
270 extern void fill_random(void */
*p*/
, size_t /*sz*/);
272 /* Initialize the system-specific code. */
273 extern void init_sys(void);
275 /*----- Policy management -------------------------------------------------*/
277 /* The possible policy actions and their names. */
287 #define DEFENUM(tag, word) A_##tag,
293 /* A policy action. */
297 unsigned user
; /* Bitmask of permitted actions */
298 char *lie
; /* The user name to impersonate */
302 /* A user pattern matches a user if the uid is within the given bounds. */
307 /* A policy rule: if the query matches the pattern, then perform the
311 const struct addrops
*ao
;
312 struct sockpat sp
[NDIR
];
316 #define POLICY_INIT(a) { .act.act = a }
317 DA_DECL(policy_v
, struct policy
);
319 /* Initialize a policy structure. In this state, it doesn't actually have
320 * any resources allocated (so can be simply discarded) but it's safe to free
321 * (using `free_policy').
323 extern void init_policy(struct policy */
*p*/
);
325 /* Free a policy structure, resetting it to its freshly-initialized state.
326 * This function is idempotent.
328 extern void free_policy(struct policy */
*p*/
);
330 /* Print a policy rule to standard output. */
331 extern void print_policy(const struct policy */
*p*/
);
333 /* Return true if the query matches the patterns in the policy rule. */
334 extern int match_policy(const struct policy */
*p*/
,
335 const struct query */
*q*/
);
337 /*----- Parsing policy files ----------------------------------------------*/
339 /* Possible results from a parse. */
341 T_OK
, /* Successful: results returned */
342 T_EOL
, /* End-of-line found immediately */
343 T_ERROR
, /* Some kind of error occurred */
344 T_EOF
/* End-of-file found immediately */
347 /* A context for parsing a policy file. */
349 FILE *fp
; /* The file to read from */
350 const struct query
*q
; /* A query to use for logging */
351 const char *name
; /* The name of the file */
352 const char *what
; /* A description of the file */
353 int err
; /* Have there been any errors? */
354 int lno
; /* The current line number */
355 struct policy p
; /* Parsed policy rule goes here */
358 /* Open a policy file by NAME. The description WHAT and query Q are used for
359 * formatting error messages for the log.
361 * This function is somewhat careful only to read from actual regular files,
362 * though (if the filesystem object identified by NAME is a symlink, say) it
363 * might open a device node or other exotic thing without reading it. This
364 * is likely harmless, since we're running as an unprivileged user anyway.
366 extern int open_policy_file(struct policy_file */
*pf*/
, const char */
*name*/
,
367 const char */
*what*/
, const struct query */
*q*/
,
369 #define OPF_NOENTOK 1u /* Don't complain if file missing */
371 /* Read a policy rule from the file, storing it in PF->p. Return one of the
374 extern int read_policy_file(struct policy_file */
*pf*/
);
376 /* Close a policy file. It doesn't matter whether the file was completely
379 extern void close_policy_file(struct policy_file */
*pf*/
);
381 /* Load a policy file, writing a vector of records into PV. If the policy
382 * file has errors, then leave PV unchanged and return nonzero.
384 extern int load_policy_file(const char */
*file*/
, policy_v */
*pv*/
);
386 /*----- That's all, folks -------------------------------------------------*/