chiark / gitweb /
Properly log fatal errors encountered after program startup.
[yaid] / yaid.h
CommitLineData
9da480be
MW
1/* -*-c-*-
2 *
3 * Common definitions for YAID
4 *
5 * (c) 2012 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Yet Another Ident Daemon (YAID).
11 *
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.
16 *
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.
21 *
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.
25 */
26
27#ifndef YAID_H
28#define YAID_H
29
30#ifdef __cplusplus
31 extern "C" {
32#endif
33
34/*----- Header files ------------------------------------------------------*/
35
bf4d9761
MW
36#include "config.h"
37
9da480be
MW
38#include <assert.h>
39#include <ctype.h>
40#include <errno.h>
41#include <limits.h>
42#include <stdarg.h>
43#include <stdio.h>
44#include <string.h>
45#include <string.h>
4f8fdcc1 46#include <time.h>
9da480be
MW
47
48#include <sys/types.h>
4f8fdcc1 49#include <sys/time.h>
9da480be
MW
50#include <unistd.h>
51#include <fcntl.h>
52
74716d82 53#include <grp.h>
9da480be
MW
54#include <pwd.h>
55
56#include <sys/socket.h>
57#include <netinet/in.h>
58#include <arpa/inet.h>
74716d82 59#include <netdb.h>
9da480be 60
9da480be
MW
61#include <syslog.h>
62
63#include <mLib/bits.h>
64#include <mLib/conn.h>
74716d82 65#include <mLib/daemonize.h>
9da480be
MW
66#include <mLib/darray.h>
67#include <mLib/dstr.h>
bf4d9761 68#include <mLib/fdflags.h>
9da480be 69#include <mLib/fwatch.h>
bc23d2c7 70#include <mLib/macros.h>
74716d82 71#include <mLib/mdwopt.h>
9da480be
MW
72#include <mLib/quis.h>
73#include <mLib/report.h>
74#include <mLib/sel.h>
75#include <mLib/selbuf.h>
74716d82 76#include <mLib/sig.h>
9da480be 77
c3794524 78/*----- Address family handling -------------------------------------------*/
bf4d9761 79
c3794524
MW
80/* The maximum length of an address formatted as a text string, including the
81 * terminating null byte.
82 */
83#define ADDRLEN 64
bf4d9761 84
c3794524
MW
85/* A list of address types. */
86#define ADDRTYPES(_) \
87 _(ipv4, IPV4) \
88 _(ipv6, IPV6)
9da480be 89
c3794524
MW
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
9da480be 94
c3794524 95/* A union of address types. */
9da480be 96union addr {
c3794524
MW
97#define UMEMB(ty, TY) TYPE_##TY ty;
98 ADDRTYPES(UMEMB)
99#undef UMEMB
9da480be
MW
100};
101
c3794524 102/* A socket holds an address and a port number. */
9da480be 103struct socket {
c3794524
MW
104 union addr addr; /* The address */
105 unsigned port; /* The port, in /host/ byte order */
9da480be
MW
106};
107
c3794524
MW
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.
110 */
bf4d9761 111struct addrpat {
c3794524
MW
112 union addr addr; /* The base address */
113 unsigned len; /* The prefix length */
bf4d9761
MW
114};
115
c3794524
MW
116/* A port pattern matches a port if the port is within the stated (inclusive)
117 * bounds.
118 */
bf4d9761
MW
119struct portpat {
120 unsigned lo, hi;
121};
122
c3794524
MW
123/* A socket pattern consists simply of an address pattern and a port pattern:
124 * it matches a socket componentwise.
125 */
bf4d9761
MW
126struct sockpat {
127 struct addrpat addr;
128 struct portpat port;
129};
130
c3794524
MW
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
133 * details.
134 */
bf4d9761 135struct addrops {
c3794524
MW
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 */
141
bf4d9761 142 int (*addreq)(const union addr *, const union addr *);
c3794524
MW
143 /* Return nonzero if the two addresses are equal. */
144
bf4d9761 145 int (*match_addrpat)(const struct addrpat *, const union addr *);
c3794524
MW
146 /* Return nonzero if the pattern matches the address. */
147
bf4d9761 148 void (*socket_to_sockaddr)(const struct socket *s, void *, size_t *);
c3794524
MW
149 /* Convert a socket structure to a `struct sockaddr', and return the
150 * size of the latter.
151 */
152
bf4d9761 153 void (*sockaddr_to_addr)(const void *, union addr *);
c3794524
MW
154 /* Extract the address from a `struct sockaddr'. */
155
bf4d9761 156 int (*init_listen_socket)(int);
c3794524
MW
157 /* Perform any necessary extra operations on a socket which is going
158 * to be used to listen for incoming connections.
159 */
bf4d9761
MW
160};
161
c3794524
MW
162/* A handy constant for each address family. These are more useful than the
163 * AF_* constants in that they form a dense sequence.
164 */
bf4d9761 165enum {
3b1bed1d 166#define DEFADDR(ty, TY) ADDR_##TY,
bf4d9761
MW
167 ADDRTYPES(DEFADDR)
168#undef DEFADDR
169 ADDR_LIMIT
170};
171
c3794524
MW
172/* The table of address operations, indexed by the ADDR_* constants defined
173 * just above.
174 */
bf4d9761 175extern const struct addrops addroptab[];
c3794524
MW
176
177/* System-specific operations, provided by the system-specific code for its
178 * own purposes.
179 */
180#define OPS_SYS(ty, TY) \
bf4d9761
MW
181 extern const struct addrops_sys addrops_sys_##ty;
182ADDRTYPES(OPS_SYS)
183#undef OPS_SYS
184
c3794524
MW
185/* Answer whether the sockets SA and SB are equal. */
186extern int sockeq(const struct addrops */*ao*/,
187 const struct socket */*sa*/, const struct socket */*sb*/);
188
189/* Write a textual description of S to the string D. */
190extern void dputsock(dstr */*d*/, const struct addrops */*ao*/,
191 const struct socket */*s*/);
192
193/*----- Queries and responses ---------------------------------------------*/
194
195/* Constants for describing the `L'ocal and `R'emote ends of a connection. */
9da480be
MW
196enum { L, R, NDIR };
197
c3794524 198/* Response types, and the data needed to represent any associated data. A
1e00cfaa 199 * U_(MEMB, TYPE) constructs a union member; an N_ means no associated data.
c3794524 200 */
9da480be 201#define RESPONSE(_) \
1e00cfaa
MW
202 _(ERROR, U_(error, unsigned)) \
203 _(UID, U_(uid, uid_t)) \
204 _(NAT, U_(nat, struct socket))
9da480be 205
c3794524
MW
206enum {
207#define DEFENUM(what, branch) R_##what,
208 RESPONSE(DEFENUM)
209#undef DEFENUM
210 R_LIMIT
211};
212
213/* Protocol error tokens. */
9da480be
MW
214#define ERROR(_) \
215 _(INVPORT, "INVALID-PORT") \
216 _(NOUSER, "NO-USER") \
217 _(HIDDEN, "HIDDEN-USER") \
218 _(UNKNOWN, "UNKNOWN-ERROR")
9da480be
MW
219
220enum {
221#define DEFENUM(err, tok) E_##err,
222 ERROR(DEFENUM)
223#undef DEFENUM
224 E_LIMIT
225};
226
c3794524 227extern const char *const errtok[];
9da480be 228
c3794524
MW
229/* The query structure keeps together the parameters to the client's query
230 * and our response to it.
231 */
9da480be 232struct query {
c3794524
MW
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 */
9da480be 237#define DEFBRANCH(WHAT, branch) branch
1e00cfaa
MW
238#define U_(memb, ty) ty memb;
239#define N_
9da480be 240 RESPONSE(DEFBRANCH)
1e00cfaa
MW
241#undef U_
242#undef N_
9da480be
MW
243#undef DEFBRANCH
244 } u;
245} query;
246
c3794524
MW
247/*----- Common utility functions ------------------------------------------*/
248
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.
251 */
bc23d2c7
MW
252extern void PRINTF_LIKE(3, 4)
253 logmsg(const struct query */*q*/, int /*prio*/, const char */*msg*/, ...);
9da480be 254
429dcd8d
MW
255/* Format and report MSG as a fatal error, and exit. */
256extern void PRINTF_LIKE(1, 2) fatal(const char */*msg*/, ...);
257
c3794524
MW
258/*----- System-specific connection identification code --------------------*/
259
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
262 * structure.
263 */
264extern void identify(struct query */*q*/);
265
56e93c83
MW
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
268 * utility.
269 */
270extern void fill_random(void */*p*/, size_t /*sz*/);
271
c3794524
MW
272/* Initialize the system-specific code. */
273extern void init_sys(void);
274
275/*----- Policy management -------------------------------------------------*/
276
277/* The possible policy actions and their names. */
9da480be
MW
278#define ACTIONS(_) \
279 _(USER, "user") \
280 _(TOKEN, "token") \
281 _(NAME, "name") \
282 _(DENY, "deny") \
283 _(HIDE, "hide") \
284 _(LIE, "lie")
285
286enum {
287#define DEFENUM(tag, word) A_##tag,
288 ACTIONS(DEFENUM)
289#undef DEFENUM
290 A_LIMIT
291};
292
c3794524 293/* A policy action. */
9da480be
MW
294struct action {
295 unsigned act;
296 union {
c3794524
MW
297 unsigned user; /* Bitmask of permitted actions */
298 char *lie; /* The user name to impersonate */
9da480be
MW
299 } u;
300};
301
c039c936
MW
302/* A user pattern matches a user if the uid is within the given bounds. */
303struct userpat {
304 unsigned lo, hi;
305};
306
c3794524
MW
307/* A policy rule: if the query matches the pattern, then perform the
308 * action.
309 */
9da480be 310struct policy {
bf4d9761 311 const struct addrops *ao;
9da480be 312 struct sockpat sp[NDIR];
c039c936 313 struct userpat up;
9da480be
MW
314 struct action act;
315};
c3794524
MW
316#define POLICY_INIT(a) { .act.act = a }
317DA_DECL(policy_v, struct policy);
9da480be 318
c3794524
MW
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').
322 */
323extern void init_policy(struct policy */*p*/);
9da480be 324
c3794524
MW
325/* Free a policy structure, resetting it to its freshly-initialized state.
326 * This function is idempotent.
327 */
328extern void free_policy(struct policy */*p*/);
329
330/* Print a policy rule to standard output. */
331extern void print_policy(const struct policy */*p*/);
332
333/* Return true if the query matches the patterns in the policy rule. */
334extern int match_policy(const struct policy */*p*/,
335 const struct query */*q*/);
336
337/*----- Parsing policy files ----------------------------------------------*/
9da480be 338
c3794524
MW
339/* Possible results from a parse. */
340enum {
341 T_OK, /* Successful: results returned */
342 T_EOL, /* End-of-line found immediately */
b9eb1a36
MW
343 T_ERROR, /* Some kind of error occurred */
344 T_EOF /* End-of-file found immediately */
c3794524 345};
9da480be 346
c3794524
MW
347/* A context for parsing a policy file. */
348struct 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 */
356};
bf4d9761 357
c3794524
MW
358/* Open a policy file by NAME. The description WHAT and query Q are used for
359 * formatting error messages for the log.
7164a50b
MW
360 *
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.
c3794524
MW
365 */
366extern int open_policy_file(struct policy_file */*pf*/, const char */*name*/,
17272ab8
MW
367 const char */*what*/, const struct query */*q*/,
368 unsigned /*f*/);
369#define OPF_NOENTOK 1u /* Don't complain if file missing */
9da480be 370
c3794524
MW
371/* Read a policy rule from the file, storing it in PF->p. Return one of the
372 * T_* codes.
373 */
374extern int read_policy_file(struct policy_file */*pf*/);
375
376/* Close a policy file. It doesn't matter whether the file was completely
377 * read.
378 */
379extern void close_policy_file(struct policy_file */*pf*/);
9da480be 380
c3794524
MW
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.
383 */
384extern int load_policy_file(const char */*file*/, policy_v */*pv*/);
9da480be
MW
385
386/*----- That's all, folks -------------------------------------------------*/
387
388#ifdef __cplusplus
389 }
390#endif
391
392#endif