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