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