Commit | Line | Data |
---|---|---|
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> |
74716d82 | 70 | #include <mLib/mdwopt.h> |
9da480be MW |
71 | #include <mLib/quis.h> |
72 | #include <mLib/report.h> | |
73 | #include <mLib/sel.h> | |
74 | #include <mLib/selbuf.h> | |
74716d82 | 75 | #include <mLib/sig.h> |
9da480be | 76 | |
c3794524 | 77 | /*----- Address family handling -------------------------------------------*/ |
bf4d9761 | 78 | |
c3794524 MW |
79 | /* The maximum length of an address formatted as a text string, including the |
80 | * terminating null byte. | |
81 | */ | |
82 | #define ADDRLEN 64 | |
bf4d9761 | 83 | |
c3794524 MW |
84 | /* A list of address types. */ |
85 | #define ADDRTYPES(_) \ | |
86 | _(ipv4, IPV4) \ | |
87 | _(ipv6, IPV6) | |
9da480be | 88 | |
c3794524 MW |
89 | /* Address types for the various families, in the form acceptable to |
90 | * inet_ntop(3) and inet_pton(3). */ | |
91 | #define TYPE_IPV4 struct in_addr | |
92 | #define TYPE_IPV6 struct in6_addr | |
9da480be | 93 | |
c3794524 | 94 | /* A union of address types. */ |
9da480be | 95 | union addr { |
c3794524 MW |
96 | #define UMEMB(ty, TY) TYPE_##TY ty; |
97 | ADDRTYPES(UMEMB) | |
98 | #undef UMEMB | |
9da480be MW |
99 | }; |
100 | ||
c3794524 | 101 | /* A socket holds an address and a port number. */ |
9da480be | 102 | struct socket { |
c3794524 MW |
103 | union addr addr; /* The address */ |
104 | unsigned port; /* The port, in /host/ byte order */ | |
9da480be MW |
105 | }; |
106 | ||
c3794524 MW |
107 | /* An address pattern consists of an address and a prefix length: the |
108 | * pattern matches an address if they agree in the first LEN bits. | |
109 | */ | |
bf4d9761 | 110 | struct addrpat { |
c3794524 MW |
111 | union addr addr; /* The base address */ |
112 | unsigned len; /* The prefix length */ | |
bf4d9761 MW |
113 | }; |
114 | ||
c3794524 MW |
115 | /* A port pattern matches a port if the port is within the stated (inclusive) |
116 | * bounds. | |
117 | */ | |
bf4d9761 MW |
118 | struct portpat { |
119 | unsigned lo, hi; | |
120 | }; | |
121 | ||
c3794524 MW |
122 | /* A socket pattern consists simply of an address pattern and a port pattern: |
123 | * it matches a socket componentwise. | |
124 | */ | |
bf4d9761 MW |
125 | struct sockpat { |
126 | struct addrpat addr; | |
127 | struct portpat port; | |
128 | }; | |
129 | ||
c3794524 MW |
130 | /* The table of address-type operations. Each address family has one of |
131 | * these, so that most of the program doesn't need to worry about these | |
132 | * details. | |
133 | */ | |
bf4d9761 | 134 | struct addrops { |
c3794524 MW |
135 | int af; /* The AF_* constant */ |
136 | const char *name; /* Name of the protocol, for logs */ | |
137 | unsigned len; /* Length of an address, in bits */ | |
138 | const union addr *any; /* A wildcard address */ | |
139 | const struct addrops_sys *sys; /* Pointer to system-specific ops */ | |
140 | ||
bf4d9761 | 141 | int (*addreq)(const union addr *, const union addr *); |
c3794524 MW |
142 | /* Return nonzero if the two addresses are equal. */ |
143 | ||
bf4d9761 | 144 | int (*match_addrpat)(const struct addrpat *, const union addr *); |
c3794524 MW |
145 | /* Return nonzero if the pattern matches the address. */ |
146 | ||
bf4d9761 | 147 | void (*socket_to_sockaddr)(const struct socket *s, void *, size_t *); |
c3794524 MW |
148 | /* Convert a socket structure to a `struct sockaddr', and return the |
149 | * size of the latter. | |
150 | */ | |
151 | ||
bf4d9761 | 152 | void (*sockaddr_to_addr)(const void *, union addr *); |
c3794524 MW |
153 | /* Extract the address from a `struct sockaddr'. */ |
154 | ||
bf4d9761 | 155 | int (*init_listen_socket)(int); |
c3794524 MW |
156 | /* Perform any necessary extra operations on a socket which is going |
157 | * to be used to listen for incoming connections. | |
158 | */ | |
bf4d9761 MW |
159 | }; |
160 | ||
c3794524 MW |
161 | /* A handy constant for each address family. These are more useful than the |
162 | * AF_* constants in that they form a dense sequence. | |
163 | */ | |
bf4d9761 | 164 | enum { |
3b1bed1d | 165 | #define DEFADDR(ty, TY) ADDR_##TY, |
bf4d9761 MW |
166 | ADDRTYPES(DEFADDR) |
167 | #undef DEFADDR | |
168 | ADDR_LIMIT | |
169 | }; | |
170 | ||
c3794524 MW |
171 | /* The table of address operations, indexed by the ADDR_* constants defined |
172 | * just above. | |
173 | */ | |
bf4d9761 | 174 | extern const struct addrops addroptab[]; |
c3794524 MW |
175 | |
176 | /* System-specific operations, provided by the system-specific code for its | |
177 | * own purposes. | |
178 | */ | |
179 | #define OPS_SYS(ty, TY) \ | |
bf4d9761 MW |
180 | extern const struct addrops_sys addrops_sys_##ty; |
181 | ADDRTYPES(OPS_SYS) | |
182 | #undef OPS_SYS | |
183 | ||
c3794524 MW |
184 | /* Answer whether the sockets SA and SB are equal. */ |
185 | extern int sockeq(const struct addrops */*ao*/, | |
186 | const struct socket */*sa*/, const struct socket */*sb*/); | |
187 | ||
188 | /* Write a textual description of S to the string D. */ | |
189 | extern void dputsock(dstr */*d*/, const struct addrops */*ao*/, | |
190 | const struct socket */*s*/); | |
191 | ||
192 | /*----- Queries and responses ---------------------------------------------*/ | |
193 | ||
194 | /* Constants for describing the `L'ocal and `R'emote ends of a connection. */ | |
9da480be MW |
195 | enum { L, R, NDIR }; |
196 | ||
c3794524 | 197 | /* Response types, and the data needed to represent any associated data. A |
1e00cfaa | 198 | * U_(MEMB, TYPE) constructs a union member; an N_ means no associated data. |
c3794524 | 199 | */ |
9da480be | 200 | #define RESPONSE(_) \ |
1e00cfaa MW |
201 | _(ERROR, U_(error, unsigned)) \ |
202 | _(UID, U_(uid, uid_t)) \ | |
203 | _(NAT, U_(nat, struct socket)) | |
9da480be | 204 | |
c3794524 MW |
205 | enum { |
206 | #define DEFENUM(what, branch) R_##what, | |
207 | RESPONSE(DEFENUM) | |
208 | #undef DEFENUM | |
209 | R_LIMIT | |
210 | }; | |
211 | ||
212 | /* Protocol error tokens. */ | |
9da480be MW |
213 | #define ERROR(_) \ |
214 | _(INVPORT, "INVALID-PORT") \ | |
215 | _(NOUSER, "NO-USER") \ | |
216 | _(HIDDEN, "HIDDEN-USER") \ | |
217 | _(UNKNOWN, "UNKNOWN-ERROR") | |
9da480be MW |
218 | |
219 | enum { | |
220 | #define DEFENUM(err, tok) E_##err, | |
221 | ERROR(DEFENUM) | |
222 | #undef DEFENUM | |
223 | E_LIMIT | |
224 | }; | |
225 | ||
c3794524 | 226 | extern const char *const errtok[]; |
9da480be | 227 | |
c3794524 MW |
228 | /* The query structure keeps together the parameters to the client's query |
229 | * and our response to it. | |
230 | */ | |
9da480be | 231 | struct query { |
c3794524 MW |
232 | const struct addrops *ao; /* Address family operations */ |
233 | struct socket s[NDIR]; /* The local and remote ends */ | |
234 | unsigned resp; /* Our response type */ | |
235 | union { /* A union of response data */ | |
9da480be | 236 | #define DEFBRANCH(WHAT, branch) branch |
1e00cfaa MW |
237 | #define U_(memb, ty) ty memb; |
238 | #define N_ | |
9da480be | 239 | RESPONSE(DEFBRANCH) |
1e00cfaa MW |
240 | #undef U_ |
241 | #undef N_ | |
9da480be MW |
242 | #undef DEFBRANCH |
243 | } u; | |
244 | } query; | |
245 | ||
c3794524 MW |
246 | /*----- Common utility functions ------------------------------------------*/ |
247 | ||
248 | /* Format and log MSG somewhere sensible, at the syslog(3) priority PRIO. | |
249 | * Prefix it with a description of the query Q, if non-null. | |
250 | */ | |
251 | extern void logmsg(const struct query */*q*/, | |
252 | int /*prio*/, const char */*msg*/, ...); | |
9da480be | 253 | |
c3794524 MW |
254 | /*----- System-specific connection identification code --------------------*/ |
255 | ||
256 | /* Find out who is responsible for the connection described in the query Q. | |
257 | * Write the answer to Q. Errors are logged and reported via the query | |
258 | * structure. | |
259 | */ | |
260 | extern void identify(struct query */*q*/); | |
261 | ||
262 | /* Initialize the system-specific code. */ | |
263 | extern void init_sys(void); | |
264 | ||
265 | /*----- Policy management -------------------------------------------------*/ | |
266 | ||
267 | /* The possible policy actions and their names. */ | |
9da480be MW |
268 | #define ACTIONS(_) \ |
269 | _(USER, "user") \ | |
270 | _(TOKEN, "token") \ | |
271 | _(NAME, "name") \ | |
272 | _(DENY, "deny") \ | |
273 | _(HIDE, "hide") \ | |
274 | _(LIE, "lie") | |
275 | ||
276 | enum { | |
277 | #define DEFENUM(tag, word) A_##tag, | |
278 | ACTIONS(DEFENUM) | |
279 | #undef DEFENUM | |
280 | A_LIMIT | |
281 | }; | |
282 | ||
c3794524 | 283 | /* A policy action. */ |
9da480be MW |
284 | struct action { |
285 | unsigned act; | |
286 | union { | |
c3794524 MW |
287 | unsigned user; /* Bitmask of permitted actions */ |
288 | char *lie; /* The user name to impersonate */ | |
9da480be MW |
289 | } u; |
290 | }; | |
291 | ||
c039c936 MW |
292 | /* A user pattern matches a user if the uid is within the given bounds. */ |
293 | struct userpat { | |
294 | unsigned lo, hi; | |
295 | }; | |
296 | ||
c3794524 MW |
297 | /* A policy rule: if the query matches the pattern, then perform the |
298 | * action. | |
299 | */ | |
9da480be | 300 | struct policy { |
bf4d9761 | 301 | const struct addrops *ao; |
9da480be | 302 | struct sockpat sp[NDIR]; |
c039c936 | 303 | struct userpat up; |
9da480be MW |
304 | struct action act; |
305 | }; | |
c3794524 MW |
306 | #define POLICY_INIT(a) { .act.act = a } |
307 | DA_DECL(policy_v, struct policy); | |
9da480be | 308 | |
c3794524 MW |
309 | /* Initialize a policy structure. In this state, it doesn't actually have |
310 | * any resources allocated (so can be simply discarded) but it's safe to free | |
311 | * (using `free_policy'). | |
312 | */ | |
313 | extern void init_policy(struct policy */*p*/); | |
9da480be | 314 | |
c3794524 MW |
315 | /* Free a policy structure, resetting it to its freshly-initialized state. |
316 | * This function is idempotent. | |
317 | */ | |
318 | extern void free_policy(struct policy */*p*/); | |
319 | ||
320 | /* Print a policy rule to standard output. */ | |
321 | extern void print_policy(const struct policy */*p*/); | |
322 | ||
323 | /* Return true if the query matches the patterns in the policy rule. */ | |
324 | extern int match_policy(const struct policy */*p*/, | |
325 | const struct query */*q*/); | |
326 | ||
327 | /*----- Parsing policy files ----------------------------------------------*/ | |
9da480be | 328 | |
c3794524 MW |
329 | /* Possible results from a parse. */ |
330 | enum { | |
331 | T_OK, /* Successful: results returned */ | |
332 | T_EOL, /* End-of-line found immediately */ | |
b9eb1a36 MW |
333 | T_ERROR, /* Some kind of error occurred */ |
334 | T_EOF /* End-of-file found immediately */ | |
c3794524 | 335 | }; |
9da480be | 336 | |
c3794524 MW |
337 | /* A context for parsing a policy file. */ |
338 | struct policy_file { | |
339 | FILE *fp; /* The file to read from */ | |
340 | const struct query *q; /* A query to use for logging */ | |
341 | const char *name; /* The name of the file */ | |
342 | const char *what; /* A description of the file */ | |
343 | int err; /* Have there been any errors? */ | |
344 | int lno; /* The current line number */ | |
345 | struct policy p; /* Parsed policy rule goes here */ | |
346 | }; | |
bf4d9761 | 347 | |
c3794524 MW |
348 | /* Open a policy file by NAME. The description WHAT and query Q are used for |
349 | * formatting error messages for the log. | |
350 | */ | |
351 | extern int open_policy_file(struct policy_file */*pf*/, const char */*name*/, | |
17272ab8 MW |
352 | const char */*what*/, const struct query */*q*/, |
353 | unsigned /*f*/); | |
354 | #define OPF_NOENTOK 1u /* Don't complain if file missing */ | |
9da480be | 355 | |
c3794524 MW |
356 | /* Read a policy rule from the file, storing it in PF->p. Return one of the |
357 | * T_* codes. | |
358 | */ | |
359 | extern int read_policy_file(struct policy_file */*pf*/); | |
360 | ||
361 | /* Close a policy file. It doesn't matter whether the file was completely | |
362 | * read. | |
363 | */ | |
364 | extern void close_policy_file(struct policy_file */*pf*/); | |
9da480be | 365 | |
c3794524 MW |
366 | /* Load a policy file, writing a vector of records into PV. If the policy |
367 | * file has errors, then leave PV unchanged and return nonzero. | |
368 | */ | |
369 | extern int load_policy_file(const char */*file*/, policy_v */*pv*/); | |
9da480be MW |
370 | |
371 | /*----- That's all, folks -------------------------------------------------*/ | |
372 | ||
373 | #ifdef __cplusplus | |
374 | } | |
375 | #endif | |
376 | ||
377 | #endif |