Fri Oct 2 22:05:52 2009 UTC ()
Let the ipkdb subsystem allow operations related to it rather than wrongly
doing so in the suser secmodel.


(elad)
diff -r1.26 -r1.27 src/sys/ipkdb/ipkdb_ipkdb.c
diff -r1.3 -r1.4 src/sys/secmodel/suser/secmodel_suser.c

cvs diff -r1.26 -r1.27 src/sys/ipkdb/Attic/ipkdb_ipkdb.c (switch to unified diff)

--- src/sys/ipkdb/Attic/ipkdb_ipkdb.c 2009/04/12 22:37:50 1.26
+++ src/sys/ipkdb/Attic/ipkdb_ipkdb.c 2009/10/02 22:05:52 1.27
@@ -1,1101 +1,1125 @@ @@ -1,1101 +1,1125 @@
1/* $NetBSD: ipkdb_ipkdb.c,v 1.26 2009/04/12 22:37:50 elad Exp $ */ 1/* $NetBSD: ipkdb_ipkdb.c,v 1.27 2009/10/02 22:05:52 elad Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1993-2000 Wolfgang Solfrank. 4 * Copyright (C) 1993-2000 Wolfgang Solfrank.
5 * Copyright (C) 1993-2000 TooLs GmbH. 5 * Copyright (C) 1993-2000 TooLs GmbH.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH. 18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: ipkdb_ipkdb.c,v 1.26 2009/04/12 22:37:50 elad Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: ipkdb_ipkdb.c,v 1.27 2009/10/02 22:05:52 elad Exp $");
36 36
37#include "opt_ipkdb.h" 37#include "opt_ipkdb.h"
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/socket.h> 40#include <sys/socket.h>
41#include <sys/mbuf.h> 41#include <sys/mbuf.h>
42#include <sys/reboot.h> 42#include <sys/reboot.h>
43#include <sys/systm.h> 43#include <sys/systm.h>
44#include <sys/kauth.h> 44#include <sys/kauth.h>
45#include <sys/cpu.h> 45#include <sys/cpu.h>
46 46
47#include <net/if.h> 47#include <net/if.h>
48#include <net/if_arp.h> 48#include <net/if_arp.h>
49#include <net/if_ether.h> 49#include <net/if_ether.h>
50 50
51#include <netinet/in.h> 51#include <netinet/in.h>
52#include <netinet/in_systm.h> 52#include <netinet/in_systm.h>
53#include <netinet/if_inarp.h> 53#include <netinet/if_inarp.h>
54#include <netinet/ip.h> 54#include <netinet/ip.h>
55#include <netinet/ip_var.h> 55#include <netinet/ip_var.h>
56#include <netinet/udp.h> 56#include <netinet/udp.h>
57 57
58#include <machine/reg.h> 58#include <machine/reg.h>
59 59
60#include <ipkdb/ipkdb.h> 60#include <ipkdb/ipkdb.h>
61#include <machine/ipkdb.h> 61#include <machine/ipkdb.h>
62 62
63int ipkdbpanic = 0; 63int ipkdbpanic = 0;
64 64
65#ifndef IPKDBKEY 65#ifndef IPKDBKEY
66#error You must specify the IPKDBKEY option to use IPKDB. 66#error You must specify the IPKDBKEY option to use IPKDB.
67#else 67#else
68static char ipkdbkey[] = IPKDBKEY; 68static char ipkdbkey[] = IPKDBKEY;
69#endif 69#endif
70 70
71static struct ipkdb_if ipkdb_if; 71static struct ipkdb_if ipkdb_if;
72 72
 73static kauth_listener_t ipkdb_listener;
 74
73static u_char *ipkdbaddr(u_char *, int *, void **); 75static u_char *ipkdbaddr(u_char *, int *, void **);
74static void peekmem(struct ipkdb_if *, u_char *, void *, long); 76static void peekmem(struct ipkdb_if *, u_char *, void *, long);
75static void pokemem(struct ipkdb_if *, u_char *, void *, long); 77static void pokemem(struct ipkdb_if *, u_char *, void *, long);
76static u_int32_t getnl(void *); 78static u_int32_t getnl(void *);
77static u_int getns(void *); 79static u_int getns(void *);
78static void setnl(void *, u_int32_t); 80static void setnl(void *, u_int32_t);
79static void setns(void *, int); 81static void setns(void *, int);
80static u_short cksum(u_short, void *, int); 82static u_short cksum(u_short, void *, int);
81static int assemble(struct ipkdb_if *, void *); 83static int assemble(struct ipkdb_if *, void *);
82static char *inpkt(struct ipkdb_if *, char *, int); 84static char *inpkt(struct ipkdb_if *, char *, int);
83static void outpkt(struct ipkdb_if *, char *, int, int, int); 85static void outpkt(struct ipkdb_if *, char *, int, int, int);
84static void init(struct ipkdb_if *); 86static void init(struct ipkdb_if *);
85static void *chksum(void *, int); 87static void *chksum(void *, int);
86static void getpkt(struct ipkdb_if *, char *, int *); 88static void getpkt(struct ipkdb_if *, char *, int *);
87static void putpkt(struct ipkdb_if *, const char *, int); 89static void putpkt(struct ipkdb_if *, const char *, int);
88static int check_ipkdb(struct ipkdb_if *, struct in_addr *, char *, int); 90static int check_ipkdb(struct ipkdb_if *, struct in_addr *, char *, int);
89static int connectipkdb(struct ipkdb_if *, char *, int); 91static int connectipkdb(struct ipkdb_if *, char *, int);
90static int hmac_init(void); 92static int hmac_init(void);
91 93
 94static int
 95ipkdb_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
 96 void *arg0, void *arg1, void *arg2, void *arg3)
 97{
 98 enum kauth_system_req req;
 99 int result;
 100
 101 req = (enum kauth_system_req)arg0;
 102 result = KAUTH_RESULT_DEFER;
 103
 104 if ((action != KAUTH_SYSTEM_DEBUG) ||
 105 (req != KAUTH_REQ_SYSTEM_DEBUG_IPKDB))
 106 return result;
 107
 108 result = KAUTH_RESULT_ALLOW;
 109
 110 return result;
 111}
 112
92void 113void
93ipkdb_init(void) 114ipkdb_init(void)
94{ 115{
95 ipkdbinit(); 116 ipkdbinit();
96 if ( ipkdbifinit(&ipkdb_if) < 0 117 if ( ipkdbifinit(&ipkdb_if) < 0
97 || !(ipkdb_if.flags&IPKDB_MYHW) 118 || !(ipkdb_if.flags&IPKDB_MYHW)
98 || !hmac_init()) { 119 || !hmac_init()) {
99 /* Interface not found, drop IPKDB */ 120 /* Interface not found, drop IPKDB */
100 printf("IPKDB: No interface found!\n"); 121 printf("IPKDB: No interface found!\n");
101 boothowto &= ~RB_KDB; 122 boothowto &= ~RB_KDB;
102 } 123 }
 124
 125 ipkdb_listener = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
 126 ipkdb_listener_cb, NULL);
103} 127}
104 128
105void 129void
106ipkdb_connect(int when) 130ipkdb_connect(int when)
107{ 131{
108 boothowto |= RB_KDB; 132 boothowto |= RB_KDB;
109 if (when == 0) 133 if (when == 0)
110 printf("waiting for remote debugger\n"); 134 printf("waiting for remote debugger\n");
111 ipkdb_trap(); 135 ipkdb_trap();
112} 136}
113 137
114void 138void
115ipkdb_panic(void) 139ipkdb_panic(void)
116{ 140{
117 ipkdbpanic = 1; 141 ipkdbpanic = 1;
118 ipkdb_trap(); 142 ipkdb_trap();
119} 143}
120 144
121/* 145/*
122 * Doesn't handle overlapping regions! 146 * Doesn't handle overlapping regions!
123 */ 147 */
124void 148void
125ipkdbcopy(const void *s, void *d, int n) 149ipkdbcopy(const void *s, void *d, int n)
126{ 150{
127 const char *sp = s; 151 const char *sp = s;
128 char *dp = d; 152 char *dp = d;
129 153
130 while (--n >= 0) 154 while (--n >= 0)
131 *dp++ = *sp++; 155 *dp++ = *sp++;
132} 156}
133 157
134void 158void
135ipkdbzero(void *d, int n) 159ipkdbzero(void *d, int n)
136{ 160{
137 char *dp = d; 161 char *dp = d;
138 162
139 while (--n >= 0) 163 while (--n >= 0)
140 *dp++ = 0; 164 *dp++ = 0;
141} 165}
142 166
143int 167int
144ipkdbcmp(void *s, void *d, int n) 168ipkdbcmp(void *s, void *d, int n)
145{ 169{
146 char *sp = s, *dp = d; 170 char *sp = s, *dp = d;
147 171
148 while (--n >= 0) 172 while (--n >= 0)
149 if (*sp++ != *dp++) 173 if (*sp++ != *dp++)
150 return *--dp - *--sp; 174 return *--dp - *--sp;
151 return 0; 175 return 0;
152} 176}
153 177
154int 178int
155ipkdbcmds(void) 179ipkdbcmds(void)
156{ 180{
157 static char buf[512]; 181 static char buf[512];
158 char *cp; 182 char *cp;
159 int plen; 183 int plen;
160 184
161 if (!(ipkdb_if.flags&IPKDB_MYHW)) /* no interface */ 185 if (!(ipkdb_if.flags&IPKDB_MYHW)) /* no interface */
162 return IPKDB_CMD_EXIT; 186 return IPKDB_CMD_EXIT;
163 init(&ipkdb_if); 187 init(&ipkdb_if);
164 if (ipkdbpanic > 1) { 188 if (ipkdbpanic > 1) {
165 ipkdb_if.leave(&ipkdb_if); 189 ipkdb_if.leave(&ipkdb_if);
166 return IPKDB_CMD_RUN; 190 return IPKDB_CMD_RUN;
167 } 191 }
168 putpkt(&ipkdb_if, "s", 1); 192 putpkt(&ipkdb_if, "s", 1);
169 while (1) { 193 while (1) {
170 getpkt(&ipkdb_if, buf, &plen); 194 getpkt(&ipkdb_if, buf, &plen);
171 if (!plen) { 195 if (!plen) {
172 if (ipkdbpanic && ipkdb_poll()) { 196 if (ipkdbpanic && ipkdb_poll()) {
173 ipkdb_if.leave(&ipkdb_if); 197 ipkdb_if.leave(&ipkdb_if);
174 return IPKDB_CMD_RUN; 198 return IPKDB_CMD_RUN;
175 } else 199 } else
176 continue; 200 continue;
177 } else 201 } else
178 ipkdbpanic = 0; 202 ipkdbpanic = 0;
179 switch (*buf) { 203 switch (*buf) {
180 default: 204 default:
181 putpkt(&ipkdb_if, "eunknown command", 16); 205 putpkt(&ipkdb_if, "eunknown command", 16);
182 break; 206 break;
183 case 'O': 207 case 'O':
184 /* This is an allowed reconnect, ack it */ 208 /* This is an allowed reconnect, ack it */
185 putpkt(&ipkdb_if, "s", 1); 209 putpkt(&ipkdb_if, "s", 1);
186 break; 210 break;
187 case 'R': 211 case 'R':
188 peekmem(&ipkdb_if, buf, ipkdbregs, sizeof ipkdbregs); 212 peekmem(&ipkdb_if, buf, ipkdbregs, sizeof ipkdbregs);
189 break; 213 break;
190 case 'W': 214 case 'W':
191 if (plen != sizeof ipkdbregs + 1) { 215 if (plen != sizeof ipkdbregs + 1) {
192 putpkt(&ipkdb_if, "einvalid register size", 22); 216 putpkt(&ipkdb_if, "einvalid register size", 22);
193 break; 217 break;
194 } 218 }
195 pokemem(&ipkdb_if, buf + 1, ipkdbregs, sizeof ipkdbregs); 219 pokemem(&ipkdb_if, buf + 1, ipkdbregs, sizeof ipkdbregs);
196 break; 220 break;
197 case 'M': 221 case 'M':
198 { 222 {
199 void *addr, *len; 223 void *addr, *len;
200 224
201 plen--; 225 plen--;
202 if ( !(cp = ipkdbaddr(buf + 1, &plen, &addr)) 226 if ( !(cp = ipkdbaddr(buf + 1, &plen, &addr))
203 || !ipkdbaddr(cp, &plen, &len)) { 227 || !ipkdbaddr(cp, &plen, &len)) {
204 putpkt(&ipkdb_if, "einvalid peek format", 20); 228 putpkt(&ipkdb_if, "einvalid peek format", 20);
205 break; 229 break;
206 } 230 }
207 peekmem(&ipkdb_if, buf, addr, (long)len); 231 peekmem(&ipkdb_if, buf, addr, (long)len);
208 break; 232 break;
209 } 233 }
210 case 'N': 234 case 'N':
211 { 235 {
212 void *addr, *len; 236 void *addr, *len;
213 237
214 plen--; 238 plen--;
215 if ( !(cp = ipkdbaddr(buf + 1, &plen, &addr)) 239 if ( !(cp = ipkdbaddr(buf + 1, &plen, &addr))
216 || !(cp = ipkdbaddr(cp, &plen, &len)) 240 || !(cp = ipkdbaddr(cp, &plen, &len))
217 || plen < (long)len) { 241 || plen < (long)len) {
218 putpkt(&ipkdb_if, "einvalid poke format", 20); 242 putpkt(&ipkdb_if, "einvalid poke format", 20);
219 break; 243 break;
220 } 244 }
221 pokemem(&ipkdb_if, cp, addr, (long)len); 245 pokemem(&ipkdb_if, cp, addr, (long)len);
222 break; 246 break;
223 } 247 }
224 case 'S': 248 case 'S':
225 ipkdb_if.leave(&ipkdb_if); 249 ipkdb_if.leave(&ipkdb_if);
226 return IPKDB_CMD_STEP; 250 return IPKDB_CMD_STEP;
227 case 'X': 251 case 'X':
228 putpkt(&ipkdb_if, "ok",2); 252 putpkt(&ipkdb_if, "ok",2);
229 ipkdb_if.leave(&ipkdb_if); 253 ipkdb_if.leave(&ipkdb_if);
230 return IPKDB_CMD_EXIT; 254 return IPKDB_CMD_EXIT;
231 case 'C': 255 case 'C':
232 ipkdb_if.leave(&ipkdb_if); 256 ipkdb_if.leave(&ipkdb_if);
233 return IPKDB_CMD_RUN; 257 return IPKDB_CMD_RUN;
234 } 258 }
235 } 259 }
236} 260}
237 261
238static u_char * 262static u_char *
239ipkdbaddr(u_char *cp, int *pl, void **dp) 263ipkdbaddr(u_char *cp, int *pl, void **dp)
240{ 264{
241 /* Assume that sizeof(void *) <= sizeof(u_long) */ 265 /* Assume that sizeof(void *) <= sizeof(u_long) */
242 u_long l; 266 u_long l;
243 int i; 267 int i;
244 268
245 if ((*pl -= sizeof *dp) < 0) 269 if ((*pl -= sizeof *dp) < 0)
246 return 0; 270 return 0;
247 for (i = sizeof *dp, l = 0; --i >= 0;) { 271 for (i = sizeof *dp, l = 0; --i >= 0;) {
248 l <<= 8; 272 l <<= 8;
249 l |= *cp++; 273 l |= *cp++;
250 } 274 }
251 *dp = (void *)l; 275 *dp = (void *)l;
252 return cp; 276 return cp;
253} 277}
254 278
255static void 279static void
256peekmem(struct ipkdb_if *ifp, u_char *buf, void *addr, long len) 280peekmem(struct ipkdb_if *ifp, u_char *buf, void *addr, long len)
257{ 281{
258 u_char *cp, *p = addr; 282 u_char *cp, *p = addr;
259 int l; 283 int l;
260 284
261 cp = buf; 285 cp = buf;
262 *cp++ = 'p'; 286 *cp++ = 'p';
263 for (l = len; --l >= 0;) 287 for (l = len; --l >= 0;)
264 *cp++ = ipkdbfbyte(p++); 288 *cp++ = ipkdbfbyte(p++);
265 putpkt(ifp, buf, len + 1); 289 putpkt(ifp, buf, len + 1);
266} 290}
267 291
268static void 292static void
269pokemem(struct ipkdb_if *ifp, u_char *cp, void *addr, long len) 293pokemem(struct ipkdb_if *ifp, u_char *cp, void *addr, long len)
270{ 294{
271 u_char *p = addr; 295 u_char *p = addr;
272 296
273 while (--len >= 0) 297 while (--len >= 0)
274 ipkdbsbyte(p++, *cp++); 298 ipkdbsbyte(p++, *cp++);
275 putpkt(ifp, "ok", 2); 299 putpkt(ifp, "ok", 2);
276} 300}
277 301
278inline static u_int32_t 302inline static u_int32_t
279getnl(void *vs) 303getnl(void *vs)
280{ 304{
281 u_char *s = vs; 305 u_char *s = vs;
282 306
283 return (*s << 24)|(s[1] << 16)|(s[2] << 8)|s[3]; 307 return (*s << 24)|(s[1] << 16)|(s[2] << 8)|s[3];
284} 308}
285 309
286inline static u_int 310inline static u_int
287getns(void *vs) 311getns(void *vs)
288{ 312{
289 u_char *s = vs; 313 u_char *s = vs;
290 314
291 return (*s << 8)|s[1]; 315 return (*s << 8)|s[1];
292} 316}
293 317
294inline static void 318inline static void
295setnl(void *vs, u_int32_t l) 319setnl(void *vs, u_int32_t l)
296{ 320{
297 u_char *s = vs; 321 u_char *s = vs;
298 322
299 *s++ = l >> 24; 323 *s++ = l >> 24;
300 *s++ = l >> 16; 324 *s++ = l >> 16;
301 *s++ = l >> 8; 325 *s++ = l >> 8;
302 *s = l; 326 *s = l;
303} 327}
304 328
305inline static void 329inline static void
306setns(void *vs, int l) 330setns(void *vs, int l)
307{ 331{
308 u_char *s = vs; 332 u_char *s = vs;
309 333
310 *s++ = l >> 8; 334 *s++ = l >> 8;
311 *s = l; 335 *s = l;
312} 336}
313 337
314static u_short 338static u_short
315cksum(u_short st, void *vcp, int l) 339cksum(u_short st, void *vcp, int l)
316{ 340{
317 u_char *cp = vcp; 341 u_char *cp = vcp;
318 u_long s; 342 u_long s;
319 343
320 for (s = st; (l -= 2) >= 0; cp += 2) 344 for (s = st; (l -= 2) >= 0; cp += 2)
321 s += (*cp << 8) + cp[1]; 345 s += (*cp << 8) + cp[1];
322 if (l == -1) 346 if (l == -1)
323 s += *cp << 8; 347 s += *cp << 8;
324 while (s&0xffff0000) 348 while (s&0xffff0000)
325 s = (s&0xffff) + (s >> 16); 349 s = (s&0xffff) + (s >> 16);
326 return s == 0xffff ? 0 : s; 350 return s == 0xffff ? 0 : s;
327} 351}
328 352
329static int 353static int
330assemble(struct ipkdb_if *ifp, void *buf) 354assemble(struct ipkdb_if *ifp, void *buf)
331{ 355{
332 struct ip *ip, iph; 356 struct ip *ip, iph;
333 int off, len, i; 357 int off, len, i;
334 u_char *cp, *ecp; 358 u_char *cp, *ecp;
335 359
336 ip = (struct ip *)buf; 360 ip = (struct ip *)buf;
337 ipkdbcopy(ip, &iph, sizeof iph); 361 ipkdbcopy(ip, &iph, sizeof iph);
338 iph.ip_hl = 5; 362 iph.ip_hl = 5;
339 iph.ip_tos = 0; 363 iph.ip_tos = 0;
340 iph.ip_len = 0; 364 iph.ip_len = 0;
341 iph.ip_off = 0; 365 iph.ip_off = 0;
342 iph.ip_ttl = 0; 366 iph.ip_ttl = 0;
343 iph.ip_sum = 0; 367 iph.ip_sum = 0;
344 if (ifp->asslen) { 368 if (ifp->asslen) {
345 if (ipkdbcmp(&iph, ifp->ass, sizeof iph)) { 369 if (ipkdbcmp(&iph, ifp->ass, sizeof iph)) {
346 /* 370 /*
347 * different packet 371 * different packet
348 * decide whether to keep the old 372 * decide whether to keep the old
349 * or start a new one 373 * or start a new one
350 */ 374 */
351 i = (getns(&ip->ip_id) 375 i = (getns(&ip->ip_id)
352 ^ getns(&((struct ip *)ifp->ass)->ip_id)); 376 ^ getns(&((struct ip *)ifp->ass)->ip_id));
353 i ^= ((i >> 2) ^ (i >> 4) ^ (i >> 8) ^ (i >> 12)); 377 i ^= ((i >> 2) ^ (i >> 4) ^ (i >> 8) ^ (i >> 12));
354 if (i & 1) 378 if (i & 1)
355 /* keep the old */ 379 /* keep the old */
356 return 0; 380 return 0;
357 ifp->asslen = 0; 381 ifp->asslen = 0;
358 } 382 }
359 } 383 }
360 if (!ifp->asslen) { 384 if (!ifp->asslen) {
361 ipkdbzero(ifp->assbit, sizeof ifp->assbit); 385 ipkdbzero(ifp->assbit, sizeof ifp->assbit);
362 ipkdbcopy(&iph, ifp->ass, sizeof iph); 386 ipkdbcopy(&iph, ifp->ass, sizeof iph);
363 } 387 }
364 off = getns(&ip->ip_off); 388 off = getns(&ip->ip_off);
365 len = ((off & IP_OFFMASK) << 3) + getns(&ip->ip_len) - ip->ip_hl * 4; 389 len = ((off & IP_OFFMASK) << 3) + getns(&ip->ip_len) - ip->ip_hl * 4;
366 if (ifp->asslen < len) 390 if (ifp->asslen < len)
367 ifp->asslen = len; 391 ifp->asslen = len;
368 if (ifp->asslen + sizeof *ip > sizeof ifp->ass) { 392 if (ifp->asslen + sizeof *ip > sizeof ifp->ass) {
369 /* packet too long */ 393 /* packet too long */
370 ifp->asslen = 0; 394 ifp->asslen = 0;
371 return 0; 395 return 0;
372 } 396 }
373 if (!(off & IP_MF)) { 397 if (!(off & IP_MF)) {
374 off &= IP_OFFMASK; 398 off &= IP_OFFMASK;
375 cp = ifp->assbit + (off >> 3); 399 cp = ifp->assbit + (off >> 3);
376 for (i = (off & 7); i < 8; *cp |= 1 << i++); 400 for (i = (off & 7); i < 8; *cp |= 1 << i++);
377 for (; cp < ifp->assbit + sizeof ifp->assbit; *cp++ = -1); 401 for (; cp < ifp->assbit + sizeof ifp->assbit; *cp++ = -1);
378 } else { 402 } else {
379 off &= IP_OFFMASK; 403 off &= IP_OFFMASK;
380 cp = ifp->assbit + (off >> 3); 404 cp = ifp->assbit + (off >> 3);
381 ecp = ifp->assbit + (len >> 6); 405 ecp = ifp->assbit + (len >> 6);
382 if (cp == ecp) 406 if (cp == ecp)
383 for (i = (off & 7); i <= ((len >> 3) & 7); 407 for (i = (off & 7); i <= ((len >> 3) & 7);
384 *cp |= 1 << i++); 408 *cp |= 1 << i++);
385 else { 409 else {
386 for (i = (off & 7); i < 8; *cp |= 1 << i++); 410 for (i = (off & 7); i < 8; *cp |= 1 << i++);
387 for (; ++cp < ecp; *cp = -1); 411 for (; ++cp < ecp; *cp = -1);
388 for (i = 0; i < ((len >> 3) & 7); *cp |= 1 << i++); 412 for (i = 0; i < ((len >> 3) & 7); *cp |= 1 << i++);
389 } 413 }
390 } 414 }
391 ipkdbcopy((char *)buf + ip->ip_hl * 4, 415 ipkdbcopy((char *)buf + ip->ip_hl * 4,
392 ifp->ass + sizeof *ip + (off << 3), 416 ifp->ass + sizeof *ip + (off << 3),
393 len - (off << 3)); 417 len - (off << 3));
394 for (cp = ifp->assbit; cp < ifp->assbit + sizeof ifp->assbit;) 418 for (cp = ifp->assbit; cp < ifp->assbit + sizeof ifp->assbit;)
395 if (*cp++ != (u_char)-1) 419 if (*cp++ != (u_char)-1)
396 /* not complete */ 420 /* not complete */
397 return 0; 421 return 0;
398 ip = (struct ip *)ifp->ass; 422 ip = (struct ip *)ifp->ass;
399 setns(&ip->ip_len, sizeof *ip + ifp->asslen); 423 setns(&ip->ip_len, sizeof *ip + ifp->asslen);
400 /* complete */ 424 /* complete */
401 return 1; 425 return 1;
402} 426}
403 427
404static char * 428static char *
405inpkt(struct ipkdb_if *ifp, char *ibuf, int poll) 429inpkt(struct ipkdb_if *ifp, char *ibuf, int poll)
406{ 430{
407 int cnt = 1000000; 431 int cnt = 1000000;
408 int l, ul; 432 int l, ul;
409 struct ether_header *eh; 433 struct ether_header *eh;
410 struct arphdr *ah; 434 struct arphdr *ah;
411 struct ip *ip; 435 struct ip *ip;
412 struct udphdr *udp; 436 struct udphdr *udp;
413 struct ipovly ipo; 437 struct ipovly ipo;
414 438
415 while (1) { 439 while (1) {
416 l = ifp->receive(ifp, ibuf, poll != 0); 440 l = ifp->receive(ifp, ibuf, poll != 0);
417 if (!l) { 441 if (!l) {
418 if (poll == 1 || (poll == 2 && --cnt <= 0)) 442 if (poll == 1 || (poll == 2 && --cnt <= 0))
419 break; 443 break;
420 else 444 else
421 continue; 445 continue;
422 } 446 }
423 eh = (struct ether_header *)ibuf; 447 eh = (struct ether_header *)ibuf;
424 switch (getns(&eh->ether_type)) { 448 switch (getns(&eh->ether_type)) {
425 case ETHERTYPE_ARP: 449 case ETHERTYPE_ARP:
426 ah = (struct arphdr *)(ibuf + 14); 450 ah = (struct arphdr *)(ibuf + 14);
427 if ( getns(&ah->ar_hrd) != ARPHRD_ETHER 451 if ( getns(&ah->ar_hrd) != ARPHRD_ETHER
428 || getns(&ah->ar_pro) != ETHERTYPE_IP 452 || getns(&ah->ar_pro) != ETHERTYPE_IP
429 || ah->ar_hln != 6 453 || ah->ar_hln != 6
430 || ah->ar_pln != 4) 454 || ah->ar_pln != 4)
431 /* unsupported arp packet */ 455 /* unsupported arp packet */
432 break; 456 break;
433 switch (getns(&ah->ar_op)) { 457 switch (getns(&ah->ar_op)) {
434 case ARPOP_REQUEST: 458 case ARPOP_REQUEST:
435 if ( (ifp->flags&IPKDB_MYIP) 459 if ( (ifp->flags&IPKDB_MYIP)
436 && !ipkdbcmp(ar_tpa(ah), 460 && !ipkdbcmp(ar_tpa(ah),
437 ifp->myinetaddr, 461 ifp->myinetaddr,
438 sizeof ifp->myinetaddr)) { 462 sizeof ifp->myinetaddr)) {
439 /* someone requested my address */ 463 /* someone requested my address */
440 ipkdbcopy(eh->ether_shost, 464 ipkdbcopy(eh->ether_shost,
441 eh->ether_dhost, 465 eh->ether_dhost,
442 sizeof eh->ether_dhost); 466 sizeof eh->ether_dhost);
443 ipkdbcopy(ifp->myenetaddr, 467 ipkdbcopy(ifp->myenetaddr,
444 eh->ether_shost, 468 eh->ether_shost,
445 sizeof eh->ether_shost); 469 sizeof eh->ether_shost);
446 setns(&ah->ar_op, ARPOP_REPLY); 470 setns(&ah->ar_op, ARPOP_REPLY);
447 ipkdbcopy(ar_sha(ah), 471 ipkdbcopy(ar_sha(ah),
448 ar_tha(ah), 472 ar_tha(ah),
449 ah->ar_hln); 473 ah->ar_hln);
450 ipkdbcopy(ar_spa(ah), 474 ipkdbcopy(ar_spa(ah),
451 ar_tpa(ah), 475 ar_tpa(ah),
452 ah->ar_pln); 476 ah->ar_pln);
453 ipkdbcopy(ifp->myenetaddr, 477 ipkdbcopy(ifp->myenetaddr,
454 ar_sha(ah), 478 ar_sha(ah),
455 ah->ar_hln); 479 ah->ar_hln);
456 ipkdbcopy(ifp->myinetaddr, 480 ipkdbcopy(ifp->myinetaddr,
457 ar_spa(ah), 481 ar_spa(ah),
458 ah->ar_pln); 482 ah->ar_pln);
459 ifp->send(ifp, ibuf, 74); 483 ifp->send(ifp, ibuf, 74);
460 continue; 484 continue;
461 } 485 }
462 break; 486 break;
463 default: 487 default:
464 break; 488 break;
465 } 489 }
466 break; 490 break;
467 case ETHERTYPE_IP: 491 case ETHERTYPE_IP:
468 ip = (struct ip *)(ibuf + 14); 492 ip = (struct ip *)(ibuf + 14);
469 if ( ip->ip_v != IPVERSION 493 if ( ip->ip_v != IPVERSION
470 || ip->ip_hl < 5 494 || ip->ip_hl < 5
471 || getns(&ip->ip_len) + 14 > l) 495 || getns(&ip->ip_len) + 14 > l)
472 /* invalid packet */ 496 /* invalid packet */
473 break; 497 break;
474 if (cksum(0, ip, ip->ip_hl * 4)) 498 if (cksum(0, ip, ip->ip_hl * 4))
475 /* wrong checksum */ 499 /* wrong checksum */
476 break; 500 break;
477 if (ip->ip_p != IPPROTO_UDP) 501 if (ip->ip_p != IPPROTO_UDP)
478 break; 502 break;
479 if (getns(&ip->ip_off) & ~IP_DF) { 503 if (getns(&ip->ip_off) & ~IP_DF) {
480 if (!assemble(ifp, ip)) 504 if (!assemble(ifp, ip))
481 break; 505 break;
482 ip = (struct ip *)ifp->ass; 506 ip = (struct ip *)ifp->ass;
483 ifp->asslen = 0; 507 ifp->asslen = 0;
484 } 508 }
485 udp = (struct udphdr *)((char *)ip + ip->ip_hl * 4); 509 udp = (struct udphdr *)((char *)ip + ip->ip_hl * 4);
486 ul = getns(&ip->ip_len) - ip->ip_hl * 4; 510 ul = getns(&ip->ip_len) - ip->ip_hl * 4;
487 if (getns(&udp->uh_ulen) != ul) 511 if (getns(&udp->uh_ulen) != ul)
488 /* invalid UDP packet length */ 512 /* invalid UDP packet length */
489 break; 513 break;
490 ipkdbcopy(ip, &ipo, sizeof ipo); 514 ipkdbcopy(ip, &ipo, sizeof ipo);
491 ipkdbzero(ipo.ih_x1, sizeof ipo.ih_x1); 515 ipkdbzero(ipo.ih_x1, sizeof ipo.ih_x1);
492 ipo.ih_len = udp->uh_ulen; 516 ipo.ih_len = udp->uh_ulen;
493 if ( udp->uh_sum 517 if ( udp->uh_sum
494 && cksum(cksum(0, &ipo, sizeof ipo), udp, ul)) 518 && cksum(cksum(0, &ipo, sizeof ipo), udp, ul))
495 /* wrong checksum */ 519 /* wrong checksum */
496 break; 520 break;
497 if (!(ifp->flags & IPKDB_MYIP)) { 521 if (!(ifp->flags & IPKDB_MYIP)) {
498 if ( getns(&udp->uh_sport) == 67 522 if ( getns(&udp->uh_sport) == 67
499 && getns(&udp->uh_dport) == 68 523 && getns(&udp->uh_dport) == 68
500 && *(char *)(udp + 1) == 2) { 524 && *(char *)(udp + 1) == 2) {
501 /* this is a BOOTP reply to our ethernet address */ 525 /* this is a BOOTP reply to our ethernet address */
502 /* should check a bit more? XXX */ 526 /* should check a bit more? XXX */
503 char *bootp = (char *)(udp + 1); 527 char *bootp = (char *)(udp + 1);
504 ipkdbcopy(bootp + 16, 528 ipkdbcopy(bootp + 16,
505 ifp->myinetaddr, 529 ifp->myinetaddr,
506 sizeof ifp->myinetaddr); 530 sizeof ifp->myinetaddr);
507 ifp->flags |= IPKDB_MYIP; 531 ifp->flags |= IPKDB_MYIP;
508 } 532 }
509 /* give caller a chance to resend his request */ 533 /* give caller a chance to resend his request */
510 return 0; 534 return 0;
511 } 535 }
512 if ( ipkdbcmp(&ip->ip_dst, ifp->myinetaddr, sizeof ifp->myinetaddr) 536 if ( ipkdbcmp(&ip->ip_dst, ifp->myinetaddr, sizeof ifp->myinetaddr)
513 || getns(&udp->uh_dport) != IPKDBPORT) 537 || getns(&udp->uh_dport) != IPKDBPORT)
514 break; 538 break;
515 /* so now it's a UDP packet for the debugger */ 539 /* so now it's a UDP packet for the debugger */
516 { 540 {
517 /* Check for reconnect packet */ 541 /* Check for reconnect packet */
518 u_char *p; 542 u_char *p;
519 543
520 p = (u_char *)(udp + 1); 544 p = (u_char *)(udp + 1);
521 if (!getnl(p) && p[6] == 'O') { 545 if (!getnl(p) && p[6] == 'O') {
522 l = getns(p + 4); 546 l = getns(p + 4);
523 if ( l <= ul - sizeof *udp - 6 547 if ( l <= ul - sizeof *udp - 6
524 && check_ipkdb(ifp, &ip->ip_src, 548 && check_ipkdb(ifp, &ip->ip_src,
525 p, l + 6)) { 549 p, l + 6)) {
526 ipkdbcopy(&ip->ip_src, 550 ipkdbcopy(&ip->ip_src,
527 ifp->hisinetaddr, 551 ifp->hisinetaddr,
528 sizeof ifp->hisinetaddr); 552 sizeof ifp->hisinetaddr);
529 ipkdbcopy(eh->ether_shost, 553 ipkdbcopy(eh->ether_shost,
530 ifp->hisenetaddr, 554 ifp->hisenetaddr,
531 sizeof ifp->hisenetaddr); 555 sizeof ifp->hisenetaddr);
532 ifp->hisport = getns(&udp->uh_sport); 556 ifp->hisport = getns(&udp->uh_sport);
533 ifp->flags |= IPKDB_HISHW|IPKDB_HISIP; 557 ifp->flags |= IPKDB_HISHW|IPKDB_HISIP;
534 return p; 558 return p;
535 } 559 }
536 } 560 }
537 } 561 }
538 if ( (ifp->flags&IPKDB_HISIP) 562 if ( (ifp->flags&IPKDB_HISIP)
539 && ipkdbcmp(&ip->ip_src, 563 && ipkdbcmp(&ip->ip_src,
540 ifp->hisinetaddr, sizeof ifp->hisinetaddr)) 564 ifp->hisinetaddr, sizeof ifp->hisinetaddr))
541 /* It's a packet from someone else */ 565 /* It's a packet from someone else */
542 break; 566 break;
543 if (!(ifp->flags&IPKDB_HISIP)) 567 if (!(ifp->flags&IPKDB_HISIP))
544 break; 568 break;
545 return (char *)(udp + 1); 569 return (char *)(udp + 1);
546 default: 570 default:
547 /* unknown type */ 571 /* unknown type */
548 break; 572 break;
549 } 573 }
550 } 574 }
551 return 0; 575 return 0;
552} 576}
553 577
554static short ipkdb_ipid = 0; 578static short ipkdb_ipid = 0;
555 579
556static void 580static void
557outpkt(struct ipkdb_if *ifp, char *in, int l, int srcport, int dstport) 581outpkt(struct ipkdb_if *ifp, char *in, int l, int srcport, int dstport)
558{ 582{
559 struct ether_header *eh; 583 struct ether_header *eh;
560 struct ip *ip; 584 struct ip *ip;
561 struct udphdr *udp; 585 struct udphdr *udp;
562 u_char *cp; 586 u_char *cp;
563 char _obuf[ETHERMTU + 16]; 587 char _obuf[ETHERMTU + 16];
564#define obuf (_obuf + 2) /* align ip data in packet */ 588#define obuf (_obuf + 2) /* align ip data in packet */
565 struct ipovly ipo; 589 struct ipovly ipo;
566 int i, off; 590 int i, off;
567 591
568 ipkdbzero(_obuf, sizeof _obuf); 592 ipkdbzero(_obuf, sizeof _obuf);
569 eh = (struct ether_header *)obuf; 593 eh = (struct ether_header *)obuf;
570 /* 594 /*
571 * If we don't have his ethernet address, or this is a bootp request, 595 * If we don't have his ethernet address, or this is a bootp request,
572 * broadcast the packet. 596 * broadcast the packet.
573 */ 597 */
574 if (!(ifp->flags & IPKDB_HISHW) 598 if (!(ifp->flags & IPKDB_HISHW)
575 || dstport == 67) 599 || dstport == 67)
576 for (cp = eh->ether_dhost; 600 for (cp = eh->ether_dhost;
577 cp < eh->ether_dhost + sizeof eh->ether_dhost; 601 cp < eh->ether_dhost + sizeof eh->ether_dhost;
578 *cp++ = -1); 602 *cp++ = -1);
579 else 603 else
580 ipkdbcopy(ifp->hisenetaddr, eh->ether_dhost, sizeof eh->ether_dhost); 604 ipkdbcopy(ifp->hisenetaddr, eh->ether_dhost, sizeof eh->ether_dhost);
581 ipkdbcopy(ifp->myenetaddr, eh->ether_shost, sizeof eh->ether_shost); 605 ipkdbcopy(ifp->myenetaddr, eh->ether_shost, sizeof eh->ether_shost);
582 setns(&eh->ether_type, ETHERTYPE_IP); 606 setns(&eh->ether_type, ETHERTYPE_IP);
583 ip = (struct ip *)(obuf + 14); 607 ip = (struct ip *)(obuf + 14);
584 ip->ip_v = IPVERSION; 608 ip->ip_v = IPVERSION;
585 ip->ip_hl = 5; 609 ip->ip_hl = 5;
586 setns(&ip->ip_id, ipkdb_ipid++); 610 setns(&ip->ip_id, ipkdb_ipid++);
587 ip->ip_ttl = 255; 611 ip->ip_ttl = 255;
588 ip->ip_p = IPPROTO_UDP; 612 ip->ip_p = IPPROTO_UDP;
589 ipkdbcopy(ifp->myinetaddr, &ip->ip_src, sizeof ip->ip_src); 613 ipkdbcopy(ifp->myinetaddr, &ip->ip_src, sizeof ip->ip_src);
590 /* 614 /*
591 * If this is a bootp request, broadcast it. 615 * If this is a bootp request, broadcast it.
592 */ 616 */
593 if (dstport == 67) 617 if (dstport == 67)
594 for (cp = (u_char *)&ip->ip_dst; 618 for (cp = (u_char *)&ip->ip_dst;
595 cp < (u_char *)&ip->ip_dst + sizeof ip->ip_dst; 619 cp < (u_char *)&ip->ip_dst + sizeof ip->ip_dst;
596 *cp++ = -1); 620 *cp++ = -1);
597 else 621 else
598 ipkdbcopy(ifp->hisinetaddr, &ip->ip_dst, sizeof ip->ip_dst); 622 ipkdbcopy(ifp->hisinetaddr, &ip->ip_dst, sizeof ip->ip_dst);
599 udp = (struct udphdr *)(ip + 1); 623 udp = (struct udphdr *)(ip + 1);
600 setns(&udp->uh_sport, srcport); 624 setns(&udp->uh_sport, srcport);
601 setns(&udp->uh_dport, dstport); 625 setns(&udp->uh_dport, dstport);
602 setns(&udp->uh_ulen, l + sizeof *udp); 626 setns(&udp->uh_ulen, l + sizeof *udp);
603 ipkdbcopy(ip, &ipo, sizeof ipo); 627 ipkdbcopy(ip, &ipo, sizeof ipo);
604 ipkdbzero(ipo.ih_x1, sizeof ipo.ih_x1); 628 ipkdbzero(ipo.ih_x1, sizeof ipo.ih_x1);
605 ipo.ih_len = udp->uh_ulen; 629 ipo.ih_len = udp->uh_ulen;
606 setns(&udp->uh_sum, 630 setns(&udp->uh_sum,
607 ~cksum(cksum(cksum(0, &ipo, sizeof ipo), 631 ~cksum(cksum(cksum(0, &ipo, sizeof ipo),
608 udp, sizeof *udp), 632 udp, sizeof *udp),
609 in, l)); 633 in, l));
610 for (cp = (u_char *)(udp + 1), l += sizeof *udp, off = 0; 634 for (cp = (u_char *)(udp + 1), l += sizeof *udp, off = 0;
611 l > 0; 635 l > 0;
612 l -= i, in += i, off += i, cp = (u_char *)udp) { 636 l -= i, in += i, off += i, cp = (u_char *)udp) {
613 i = l > ifp->mtu - sizeof *ip ? ((ifp->mtu - sizeof *ip) & ~7) : l; 637 i = l > ifp->mtu - sizeof *ip ? ((ifp->mtu - sizeof *ip) & ~7) : l;
614 ipkdbcopy(in, cp, i); 638 ipkdbcopy(in, cp, i);
615 setns(&ip->ip_len, i + sizeof *ip); 639 setns(&ip->ip_len, i + sizeof *ip);
616 setns(&ip->ip_off, (l > i ? IP_MF : 0) | (off >> 3)); 640 setns(&ip->ip_off, (l > i ? IP_MF : 0) | (off >> 3));
617 ip->ip_sum = 0; 641 ip->ip_sum = 0;
618 setns(&ip->ip_sum, ~cksum(0, ip, sizeof *ip)); 642 setns(&ip->ip_sum, ~cksum(0, ip, sizeof *ip));
619 if (i + sizeof *ip < ETHERMIN) 643 if (i + sizeof *ip < ETHERMIN)
620 i = ETHERMIN - sizeof *ip; 644 i = ETHERMIN - sizeof *ip;
621 ifp->send(ifp, obuf, i + sizeof *ip + 14); 645 ifp->send(ifp, obuf, i + sizeof *ip + 14);
622 } 646 }
623#undef obuf 647#undef obuf
624} 648}
625 649
626static void 650static void
627init(struct ipkdb_if *ifp) 651init(struct ipkdb_if *ifp)
628{ 652{
629 u_char *cp; 653 u_char *cp;
630 u_char _ibuf[ETHERMTU + 16]; 654 u_char _ibuf[ETHERMTU + 16];
631#define ibuf (_ibuf + 2) /* align ip data in packet */ 655#define ibuf (_ibuf + 2) /* align ip data in packet */
632 int secs = 0; 656 int secs = 0;
633 657
634 ifp->start(ifp); 658 ifp->start(ifp);
635 if (ifp->flags & IPKDB_MYIP) 659 if (ifp->flags & IPKDB_MYIP)
636 return; 660 return;
637 661
638 while (!(ifp->flags & IPKDB_MYIP)) { 662 while (!(ifp->flags & IPKDB_MYIP)) {
639 ipkdbzero(_ibuf, sizeof _ibuf); 663 ipkdbzero(_ibuf, sizeof _ibuf);
640 cp = _ibuf; 664 cp = _ibuf;
641 *cp++ = 1; /* BOOTP_REQUEST */ 665 *cp++ = 1; /* BOOTP_REQUEST */
642 *cp++ = 1; /* Ethernet hardware */ 666 *cp++ = 1; /* Ethernet hardware */
643 *cp++ = 6; /* length of address */ 667 *cp++ = 6; /* length of address */
644 setnl(++cp, 0x12345678); /* some random number? */ 668 setnl(++cp, 0x12345678); /* some random number? */
645 setns(cp + 4, secs++); 669 setns(cp + 4, secs++);
646 ipkdbcopy(ifp->myenetaddr, cp + 24, sizeof ifp->myenetaddr); 670 ipkdbcopy(ifp->myenetaddr, cp + 24, sizeof ifp->myenetaddr);
647 outpkt(ifp, _ibuf, 300, 68, 67); 671 outpkt(ifp, _ibuf, 300, 68, 67);
648 inpkt(ifp, ibuf, 2); 672 inpkt(ifp, ibuf, 2);
649 if (ipkdbpanic && ipkdb_poll()) { 673 if (ipkdbpanic && ipkdb_poll()) {
650 ipkdbpanic++; 674 ipkdbpanic++;
651 return; 675 return;
652 } 676 }
653 } 677 }
654 cp = ifp->myinetaddr; 678 cp = ifp->myinetaddr;
655 printf("My IP address is %d.%d.%d.%d\n", 679 printf("My IP address is %d.%d.%d.%d\n",
656 cp[0], cp[1], cp[2], cp[3]); 680 cp[0], cp[1], cp[2], cp[3]);
657#undef ibuf 681#undef ibuf
658} 682}
659 683
660/* HMAC Checksumming routines, see draft-ietf-ipsec-hmac-md5-00.txt */ 684/* HMAC Checksumming routines, see draft-ietf-ipsec-hmac-md5-00.txt */
661#define LENCHK 16 /* Length of checksum in bytes */ 685#define LENCHK 16 /* Length of checksum in bytes */
662 686
663/* 687/*
664 * This code is based on the MD5 implementation as found in ssh. 688 * This code is based on the MD5 implementation as found in ssh.
665 * It's quite a bit hacked by myself, but the original has 689 * It's quite a bit hacked by myself, but the original has
666 * the following non-copyright comments on it: 690 * the following non-copyright comments on it:
667 */ 691 */
668/* This code has been heavily hacked by Tatu Ylonen <ylo@cs.hut.fi> to 692/* This code has been heavily hacked by Tatu Ylonen <ylo@cs.hut.fi> to
669 make it compile on machines like Cray that don't have a 32 bit integer 693 make it compile on machines like Cray that don't have a 32 bit integer
670 type. */ 694 type. */
671/* 695/*
672 * This code implements the MD5 message-digest algorithm. 696 * This code implements the MD5 message-digest algorithm.
673 * The algorithm is due to Ron Rivest. This code was 697 * The algorithm is due to Ron Rivest. This code was
674 * written by Colin Plumb in 1993, no copyright is claimed. 698 * written by Colin Plumb in 1993, no copyright is claimed.
675 * This code is in the public domain; do with it what you wish. 699 * This code is in the public domain; do with it what you wish.
676 * 700 *
677 * Equivalent code is available from RSA Data Security, Inc. 701 * Equivalent code is available from RSA Data Security, Inc.
678 * This code has been tested against that, and is equivalent, 702 * This code has been tested against that, and is equivalent,
679 * except that you don't need to include two pages of legalese 703 * except that you don't need to include two pages of legalese
680 * with every copy. 704 * with every copy.
681 */ 705 */
682static struct ipkdb_MD5Context { 706static struct ipkdb_MD5Context {
683 u_int buf[4]; 707 u_int buf[4];
684 u_int bits[2]; 708 u_int bits[2];
685 u_char in[64]; 709 u_char in[64];
686} icontext, ocontext; 710} icontext, ocontext;
687 711
688static u_int32_t getNl(void *); 712static u_int32_t getNl(void *);
689static void setNl(void *, u_int32_t); 713static void setNl(void *, u_int32_t);
690static void ipkdb_MD5Transform(struct ipkdb_MD5Context *); 714static void ipkdb_MD5Transform(struct ipkdb_MD5Context *);
691static void ipkdb_MD5Init(struct ipkdb_MD5Context *); 715static void ipkdb_MD5Init(struct ipkdb_MD5Context *);
692static void ipkdb_MD5Update(struct ipkdb_MD5Context *, u_char *, u_int); 716static void ipkdb_MD5Update(struct ipkdb_MD5Context *, u_char *, u_int);
693static u_char *ipkdb_MD5Final(struct ipkdb_MD5Context *); 717static u_char *ipkdb_MD5Final(struct ipkdb_MD5Context *);
694 718
695inline static u_int32_t 719inline static u_int32_t
696getNl(void *vs) 720getNl(void *vs)
697{ 721{
698 u_char *s = vs; 722 u_char *s = vs;
699 723
700 return *s | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); 724 return *s | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
701} 725}
702 726
703inline static void 727inline static void
704setNl(void *vs, u_int32_t l) 728setNl(void *vs, u_int32_t l)
705{ 729{
706 u_char *s = vs; 730 u_char *s = vs;
707 731
708 *s++ = l; 732 *s++ = l;
709 *s++ = l >> 8; 733 *s++ = l >> 8;
710 *s++ = l >> 16; 734 *s++ = l >> 16;
711 *s = l >> 24; 735 *s = l >> 24;
712} 736}
713 737
714/* The four core functions - F1 is optimized somewhat */ 738/* The four core functions - F1 is optimized somewhat */
715/* #define F1(x, y, z) (((x) & (y)) | (~(x) & (z))) */ 739/* #define F1(x, y, z) (((x) & (y)) | (~(x) & (z))) */
716#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 740#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
717#define F2(x, y, z) F1(z, x, y) 741#define F2(x, y, z) F1(z, x, y)
718#define F3(x, y, z) ((x) ^ (y) ^ (z)) 742#define F3(x, y, z) ((x) ^ (y) ^ (z))
719#define F4(x, y, z) ((y) ^ ((x) | ~(z))) 743#define F4(x, y, z) ((y) ^ ((x) | ~(z)))
720 744
721/* This is the central step in the MD5 algorithm. */ 745/* This is the central step in the MD5 algorithm. */
722#define ipkdb_MD5STEP(f, w, x, y, z, data, s) \ 746#define ipkdb_MD5STEP(f, w, x, y, z, data, s) \
723 ((w) += f(x, y, z) + (data), \ 747 ((w) += f(x, y, z) + (data), \
724 (w) = ((w) << (s)) | (((w) >> (32 - s)) & 0xffffffff), \ 748 (w) = ((w) << (s)) | (((w) >> (32 - s)) & 0xffffffff), \
725 (w) += (x)) 749 (w) += (x))
726 750
727/* 751/*
728 * The core of the MD5 algorithm, this alters an existing MD5 hash to 752 * The core of the MD5 algorithm, this alters an existing MD5 hash to
729 * reflect the addition of 16 longwords of new data. MD5Update blocks 753 * reflect the addition of 16 longwords of new data. MD5Update blocks
730 * the data for this routine. 754 * the data for this routine.
731 */ 755 */
732static void 756static void
733ipkdb_MD5Transform(struct ipkdb_MD5Context *ctx) 757ipkdb_MD5Transform(struct ipkdb_MD5Context *ctx)
734{ 758{
735 u_int a, b, c, d, i; 759 u_int a, b, c, d, i;
736 u_int in[16]; 760 u_int in[16];
737 761
738 for (i = 0; i < 16; i++) 762 for (i = 0; i < 16; i++)
739 in[i] = getNl(ctx->in + 4 * i); 763 in[i] = getNl(ctx->in + 4 * i);
740 764
741 a = ctx->buf[0]; 765 a = ctx->buf[0];
742 b = ctx->buf[1]; 766 b = ctx->buf[1];
743 c = ctx->buf[2]; 767 c = ctx->buf[2];
744 d = ctx->buf[3]; 768 d = ctx->buf[3];
745 769
746 ipkdb_MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 770 ipkdb_MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
747 ipkdb_MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 771 ipkdb_MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
748 ipkdb_MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 772 ipkdb_MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
749 ipkdb_MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 773 ipkdb_MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
750 ipkdb_MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 774 ipkdb_MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
751 ipkdb_MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 775 ipkdb_MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
752 ipkdb_MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 776 ipkdb_MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
753 ipkdb_MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 777 ipkdb_MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
754 ipkdb_MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 778 ipkdb_MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
755 ipkdb_MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 779 ipkdb_MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
756 ipkdb_MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 780 ipkdb_MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
757 ipkdb_MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 781 ipkdb_MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
758 ipkdb_MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 782 ipkdb_MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
759 ipkdb_MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 783 ipkdb_MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
760 ipkdb_MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 784 ipkdb_MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
761 ipkdb_MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 785 ipkdb_MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
762 786
763 ipkdb_MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 787 ipkdb_MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
764 ipkdb_MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 788 ipkdb_MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
765 ipkdb_MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 789 ipkdb_MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
766 ipkdb_MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 790 ipkdb_MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
767 ipkdb_MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 791 ipkdb_MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
768 ipkdb_MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 792 ipkdb_MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
769 ipkdb_MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 793 ipkdb_MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
770 ipkdb_MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 794 ipkdb_MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
771 ipkdb_MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 795 ipkdb_MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
772 ipkdb_MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 796 ipkdb_MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
773 ipkdb_MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 797 ipkdb_MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
774 ipkdb_MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 798 ipkdb_MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
775 ipkdb_MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 799 ipkdb_MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
776 ipkdb_MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 800 ipkdb_MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
777 ipkdb_MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 801 ipkdb_MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
778 ipkdb_MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 802 ipkdb_MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
779 803
780 ipkdb_MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 804 ipkdb_MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
781 ipkdb_MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 805 ipkdb_MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
782 ipkdb_MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 806 ipkdb_MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
783 ipkdb_MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 807 ipkdb_MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
784 ipkdb_MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 808 ipkdb_MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
785 ipkdb_MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 809 ipkdb_MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
786 ipkdb_MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 810 ipkdb_MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
787 ipkdb_MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 811 ipkdb_MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
788 ipkdb_MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 812 ipkdb_MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
789 ipkdb_MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 813 ipkdb_MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
790 ipkdb_MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 814 ipkdb_MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
791 ipkdb_MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 815 ipkdb_MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
792 ipkdb_MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 816 ipkdb_MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
793 ipkdb_MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 817 ipkdb_MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
794 ipkdb_MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 818 ipkdb_MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
795 ipkdb_MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 819 ipkdb_MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
796 820
797 ipkdb_MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 821 ipkdb_MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
798 ipkdb_MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 822 ipkdb_MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
799 ipkdb_MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 823 ipkdb_MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
800 ipkdb_MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 824 ipkdb_MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
801 ipkdb_MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 825 ipkdb_MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
802 ipkdb_MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 826 ipkdb_MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
803 ipkdb_MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 827 ipkdb_MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
804 ipkdb_MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 828 ipkdb_MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
805 ipkdb_MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 829 ipkdb_MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
806 ipkdb_MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 830 ipkdb_MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
807 ipkdb_MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 831 ipkdb_MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
808 ipkdb_MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 832 ipkdb_MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
809 ipkdb_MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 833 ipkdb_MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
810 ipkdb_MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 834 ipkdb_MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
811 ipkdb_MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 835 ipkdb_MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
812 ipkdb_MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 836 ipkdb_MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
813 837
814 ctx->buf[0] += a; 838 ctx->buf[0] += a;
815 ctx->buf[1] += b; 839 ctx->buf[1] += b;
816 ctx->buf[2] += c; 840 ctx->buf[2] += c;
817 ctx->buf[3] += d; 841 ctx->buf[3] += d;
818} 842}
819 843
820/* 844/*
821 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 845 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
822 * initialization constants. 846 * initialization constants.
823 */ 847 */
824static void 848static void
825ipkdb_MD5Init(struct ipkdb_MD5Context *ctx) 849ipkdb_MD5Init(struct ipkdb_MD5Context *ctx)
826{ 850{
827 ctx->buf[0] = 0x67452301; 851 ctx->buf[0] = 0x67452301;
828 ctx->buf[1] = 0xefcdab89; 852 ctx->buf[1] = 0xefcdab89;
829 ctx->buf[2] = 0x98badcfe; 853 ctx->buf[2] = 0x98badcfe;
830 ctx->buf[3] = 0x10325476; 854 ctx->buf[3] = 0x10325476;
831 855
832 ctx->bits[0] = 0; 856 ctx->bits[0] = 0;
833 ctx->bits[1] = 0; 857 ctx->bits[1] = 0;
834} 858}
835 859
836/* 860/*
837 * Update context to reflect the concatenation of another buffer full 861 * Update context to reflect the concatenation of another buffer full
838 * of bytes. 862 * of bytes.
839 */ 863 */
840static void 864static void
841ipkdb_MD5Update(struct ipkdb_MD5Context *ctx, u_char *buf, unsigned len) 865ipkdb_MD5Update(struct ipkdb_MD5Context *ctx, u_char *buf, unsigned len)
842{ 866{
843 u_int t; 867 u_int t;
844 868
845 /* Update bitcount */ 869 /* Update bitcount */
846 t = ctx->bits[0]; 870 t = ctx->bits[0];
847 if ((ctx->bits[0] = (t + (len << 3)) & 0xffffffff) < t) 871 if ((ctx->bits[0] = (t + (len << 3)) & 0xffffffff) < t)
848 ctx->bits[1]++; /* Carry from low to high */ 872 ctx->bits[1]++; /* Carry from low to high */
849 ctx->bits[1] += (len >> 29) & 0xffffffff; 873 ctx->bits[1] += (len >> 29) & 0xffffffff;
850 874
851 t = (t >> 3) & 0x3f; /* Bytes already in ctx->in */ 875 t = (t >> 3) & 0x3f; /* Bytes already in ctx->in */
852 876
853 /* Handle any leading odd-sized chunks */ 877 /* Handle any leading odd-sized chunks */
854 if (t) { 878 if (t) {
855 u_char *p = ctx->in + t; 879 u_char *p = ctx->in + t;
856 880
857 t = 64 - t; 881 t = 64 - t;
858 if (len < t) { 882 if (len < t) {
859 ipkdbcopy(buf, p, len); 883 ipkdbcopy(buf, p, len);
860 return; 884 return;
861 } 885 }
862 ipkdbcopy(buf, p, t); 886 ipkdbcopy(buf, p, t);
863 ipkdb_MD5Transform(ctx); 887 ipkdb_MD5Transform(ctx);
864 buf += t; 888 buf += t;
865 len -= t; 889 len -= t;
866 } 890 }
867 891
868 /* Process data in 64-byte chunks */ 892 /* Process data in 64-byte chunks */
869 while (len >= 64) { 893 while (len >= 64) {
870 ipkdbcopy(buf, ctx->in, 64); 894 ipkdbcopy(buf, ctx->in, 64);
871 ipkdb_MD5Transform(ctx); 895 ipkdb_MD5Transform(ctx);
872 buf += 64; 896 buf += 64;
873 len -= 64; 897 len -= 64;
874 } 898 }
875 899
876 /* Handle any remaining bytes of data. */ 900 /* Handle any remaining bytes of data. */
877 ipkdbcopy(buf, ctx->in, len); 901 ipkdbcopy(buf, ctx->in, len);
878} 902}
879 903
880/* 904/*
881 * Final wrapup - pad to 64-byte boundary with the bit pattern 905 * Final wrapup - pad to 64-byte boundary with the bit pattern
882 * 1 0* (64-bit count of bits processed, LSB-first) 906 * 1 0* (64-bit count of bits processed, LSB-first)
883 */ 907 */
884static u_char * 908static u_char *
885ipkdb_MD5Final(struct ipkdb_MD5Context *ctx) 909ipkdb_MD5Final(struct ipkdb_MD5Context *ctx)
886{ 910{
887 static u_char digest[16]; 911 static u_char digest[16];
888 unsigned count; 912 unsigned count;
889 u_char *p; 913 u_char *p;
890 914
891 /* Compute number of bytes mod 64 */ 915 /* Compute number of bytes mod 64 */
892 count = (ctx->bits[0] >> 3) & 0x3f; 916 count = (ctx->bits[0] >> 3) & 0x3f;
893 917
894 /* Set the first char of padding to 0x80. This is safe since there is 918 /* Set the first char of padding to 0x80. This is safe since there is
895 always at least one byte free */ 919 always at least one byte free */
896 p = ctx->in + count; 920 p = ctx->in + count;
897 *p++ = 0x80; 921 *p++ = 0x80;
898 922
899 /* Bytes of padding needed to make 64 bytes */ 923 /* Bytes of padding needed to make 64 bytes */
900 count = 64 - 1 - count; 924 count = 64 - 1 - count;
901 925
902 /* Pad out to 56 mod 64 */ 926 /* Pad out to 56 mod 64 */
903 if (count < 8) { 927 if (count < 8) {
904 /* Two lots of padding: Pad the first block to 64 bytes */ 928 /* Two lots of padding: Pad the first block to 64 bytes */
905 ipkdbzero(p, count); 929 ipkdbzero(p, count);
906 ipkdb_MD5Transform(ctx); 930 ipkdb_MD5Transform(ctx);
907 931
908 /* Now fill the next block with 56 bytes */ 932 /* Now fill the next block with 56 bytes */
909 ipkdbzero(ctx->in, 56); 933 ipkdbzero(ctx->in, 56);
910 } else 934 } else
911 /* Pad block to 56 bytes */ 935 /* Pad block to 56 bytes */
912 ipkdbzero(p, count - 8); 936 ipkdbzero(p, count - 8);
913 937
914 /* Append length in bits and transform */ 938 /* Append length in bits and transform */
915 setNl(ctx->in + 56, ctx->bits[0]); 939 setNl(ctx->in + 56, ctx->bits[0]);
916 setNl(ctx->in + 60, ctx->bits[1]); 940 setNl(ctx->in + 60, ctx->bits[1]);
917 941
918 ipkdb_MD5Transform(ctx); 942 ipkdb_MD5Transform(ctx);
919 setNl(digest, ctx->buf[0]); 943 setNl(digest, ctx->buf[0]);
920 setNl(digest + 4, ctx->buf[1]); 944 setNl(digest + 4, ctx->buf[1]);
921 setNl(digest + 8, ctx->buf[2]); 945 setNl(digest + 8, ctx->buf[2]);
922 setNl(digest + 12, ctx->buf[3]); 946 setNl(digest + 12, ctx->buf[3]);
923 947
924 return digest; 948 return digest;
925} 949}
926 950
927/* 951/*
928 * The following code is more or less stolen from the hmac_md5 952 * The following code is more or less stolen from the hmac_md5
929 * function in the Appendix of the HMAC IETF draft, but is 953 * function in the Appendix of the HMAC IETF draft, but is
930 * optimized as suggested in this same paper. 954 * optimized as suggested in this same paper.
931 */ 955 */
932static int 956static int
933hmac_init(void) 957hmac_init(void)
934{ 958{
935 char pad[64]; 959 char pad[64];
936 char tk[16]; 960 char tk[16];
937 u_char *key = ipkdbkey; 961 u_char *key = ipkdbkey;
938 int key_len = strlen(key); 962 int key_len = strlen(key);
939 int i; 963 int i;
940 964
941 /* Require key to be at least 16 bytes long */ 965 /* Require key to be at least 16 bytes long */
942 if (key_len < 16) { 966 if (key_len < 16) {
943 printf("IPKDBKEY must be at least 16 bytes long!\n"); 967 printf("IPKDBKEY must be at least 16 bytes long!\n");
944 ipkdbzero(key, key_len); /* XXX */ 968 ipkdbzero(key, key_len); /* XXX */
945 return 0; 969 return 0;
946 } 970 }
947 971
948 /* if key is longer than 64 bytes reset it to key=MD5(key) */ 972 /* if key is longer than 64 bytes reset it to key=MD5(key) */
949 if (key_len > 64) { 973 if (key_len > 64) {
950 ipkdb_MD5Init(&icontext); 974 ipkdb_MD5Init(&icontext);
951 ipkdb_MD5Update(&icontext, key, key_len); 975 ipkdb_MD5Update(&icontext, key, key_len);
952 ipkdbcopy(ipkdb_MD5Final(&icontext), tk, 16); 976 ipkdbcopy(ipkdb_MD5Final(&icontext), tk, 16);
953 ipkdbzero(key, key_len); /* XXX */ 977 ipkdbzero(key, key_len); /* XXX */
954 key = tk; 978 key = tk;
955 key_len = 16; 979 key_len = 16;
956 } 980 }
957 981
958 /* 982 /*
959 * the HMAC_MD5 transform looks like: 983 * the HMAC_MD5 transform looks like:
960 * 984 *
961 * MD5(K XOR opad, MD5(K XOR ipad, text)) 985 * MD5(K XOR opad, MD5(K XOR ipad, text))
962 * 986 *
963 * where K is and n byte key 987 * where K is and n byte key
964 * ipad is the byte 0x36 repeated 64 times 988 * ipad is the byte 0x36 repeated 64 times
965 * opad is the byte 0x5c repeated 64 times 989 * opad is the byte 0x5c repeated 64 times
966 * and text is the data being protected 990 * and text is the data being protected
967 */ 991 */
968 /* 992 /*
969 * We do the initial part of MD5(K XOR ipad) 993 * We do the initial part of MD5(K XOR ipad)
970 * and MD5(K XOR opad) here, in order to 994 * and MD5(K XOR opad) here, in order to
971 * speed up the computation later on. 995 * speed up the computation later on.
972 */ 996 */
973 ipkdbzero(pad, sizeof pad); 997 ipkdbzero(pad, sizeof pad);
974 ipkdbcopy(key, pad, key_len); 998 ipkdbcopy(key, pad, key_len);
975 for (i = 0; i < 64; i++) 999 for (i = 0; i < 64; i++)
976 pad[i] ^= 0x36; 1000 pad[i] ^= 0x36;
977 ipkdb_MD5Init(&icontext); 1001 ipkdb_MD5Init(&icontext);
978 ipkdb_MD5Update(&icontext, pad, 64); 1002 ipkdb_MD5Update(&icontext, pad, 64);
979 1003
980 ipkdbzero(pad, sizeof pad); 1004 ipkdbzero(pad, sizeof pad);
981 ipkdbcopy(key, pad, key_len); 1005 ipkdbcopy(key, pad, key_len);
982 for (i = 0; i < 64; i++) 1006 for (i = 0; i < 64; i++)
983 pad[i] ^= 0x5c; 1007 pad[i] ^= 0x5c;
984 ipkdb_MD5Init(&ocontext); 1008 ipkdb_MD5Init(&ocontext);
985 ipkdb_MD5Update(&ocontext, pad, 64); 1009 ipkdb_MD5Update(&ocontext, pad, 64);
986 1010
987 /* Zero out the key XXX */ 1011 /* Zero out the key XXX */
988 ipkdbzero(key, key_len); 1012 ipkdbzero(key, key_len);
989 1013
990 return 1; 1014 return 1;
991} 1015}
992 1016
993/* 1017/*
994 * This is more or less hmac_md5 from the HMAC IETF draft, Appendix. 1018 * This is more or less hmac_md5 from the HMAC IETF draft, Appendix.
995 */ 1019 */
996static void * 1020static void *
997chksum(void *buf, int len) 1021chksum(void *buf, int len)
998{ 1022{
999 u_char *digest; 1023 u_char *digest;
1000 struct ipkdb_MD5Context context; 1024 struct ipkdb_MD5Context context;
1001 1025
1002 /* 1026 /*
1003 * the HMAC_MD5 transform looks like: 1027 * the HMAC_MD5 transform looks like:
1004 * 1028 *
1005 * MD5(K XOR opad, MD5(K XOR ipad, text)) 1029 * MD5(K XOR opad, MD5(K XOR ipad, text))
1006 * 1030 *
1007 * where K is an n byte key 1031 * where K is an n byte key
1008 * ipad is the byte 0x36 repeated 64 times 1032 * ipad is the byte 0x36 repeated 64 times
1009 * opad is the byte 0x5c repeated 64 times 1033 * opad is the byte 0x5c repeated 64 times
1010 * and text is the data being protected 1034 * and text is the data being protected
1011 */ 1035 */
1012 /* 1036 /*
1013 * Since we've already done the precomputation, 1037 * Since we've already done the precomputation,
1014 * we can now stuff the data into the relevant 1038 * we can now stuff the data into the relevant
1015 * preinitialized contexts to get the result. 1039 * preinitialized contexts to get the result.
1016 */ 1040 */
1017 /* 1041 /*
1018 * perform inner MD5 1042 * perform inner MD5
1019 */ 1043 */
1020 ipkdbcopy(&icontext, &context, sizeof context); 1044 ipkdbcopy(&icontext, &context, sizeof context);
1021 ipkdb_MD5Update(&context, buf, len); 1045 ipkdb_MD5Update(&context, buf, len);
1022 digest = ipkdb_MD5Final(&context); 1046 digest = ipkdb_MD5Final(&context);
1023 /* 1047 /*
1024 * perform outer MD5 1048 * perform outer MD5
1025 */ 1049 */
1026 ipkdbcopy(&ocontext, &context, sizeof context); 1050 ipkdbcopy(&ocontext, &context, sizeof context);
1027 ipkdb_MD5Update(&context, digest, 16); 1051 ipkdb_MD5Update(&context, digest, 16);
1028 return ipkdb_MD5Final(&context); 1052 return ipkdb_MD5Final(&context);
1029} 1053}
1030 1054
1031static void 1055static void
1032getpkt(struct ipkdb_if *ifp, char *buf, int *lp) 1056getpkt(struct ipkdb_if *ifp, char *buf, int *lp)
1033{ 1057{
1034 char *got; 1058 char *got;
1035 int l; 1059 int l;
1036 char _ibuf[ETHERMTU + 16]; 1060 char _ibuf[ETHERMTU + 16];
1037#define ibuf (_ibuf + 2) /* align ip data in packet */ 1061#define ibuf (_ibuf + 2) /* align ip data in packet */
1038 1062
1039 *lp = 0; 1063 *lp = 0;
1040 while (1) { 1064 while (1) {
1041 if (!(got = inpkt(ifp, ibuf, ipkdbpanic != 0))) { 1065 if (!(got = inpkt(ifp, ibuf, ipkdbpanic != 0))) {
1042 *lp = 0; 1066 *lp = 0;
1043 return; 1067 return;
1044 } 1068 }
1045 if ( ifp->seq == getnl(got) 1069 if ( ifp->seq == getnl(got)
1046 && got[6] >= 'A' 1070 && got[6] >= 'A'
1047 && got[6] <= 'Z' 1071 && got[6] <= 'Z'
1048 && (l = getns(got + 4)) 1072 && (l = getns(got + 4))
1049 && !ipkdbcmp(chksum(got, l + 6), got + l + 6, LENCHK)) { 1073 && !ipkdbcmp(chksum(got, l + 6), got + l + 6, LENCHK)) {
1050 ipkdbcopy(got + 6, buf, *lp = l); 1074 ipkdbcopy(got + 6, buf, *lp = l);
1051 return; 1075 return;
1052 } 1076 }
1053 if ( ifp->pktlen 1077 if ( ifp->pktlen
1054 && ((ifp->flags & (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED)) 1078 && ((ifp->flags & (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED))
1055 == (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED))) 1079 == (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED)))
1056 outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, ifp->hisport); 1080 outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, ifp->hisport);
1057 } 1081 }
1058#undef ibuf 1082#undef ibuf
1059} 1083}
1060 1084
1061static void 1085static void
1062putpkt(struct ipkdb_if *ifp, const char *buf, int l) 1086putpkt(struct ipkdb_if *ifp, const char *buf, int l)
1063{ 1087{
1064 setnl(ifp->pkt, ifp->seq++); 1088 setnl(ifp->pkt, ifp->seq++);
1065 setns(ifp->pkt + 4, l); 1089 setns(ifp->pkt + 4, l);
1066 ipkdbcopy(buf, ifp->pkt + 6, l); 1090 ipkdbcopy(buf, ifp->pkt + 6, l);
1067 ipkdbcopy(chksum(ifp->pkt, l + 6), ifp->pkt + 6 + l, LENCHK); 1091 ipkdbcopy(chksum(ifp->pkt, l + 6), ifp->pkt + 6 + l, LENCHK);
1068 ifp->pktlen = l + 6 + LENCHK; 1092 ifp->pktlen = l + 6 + LENCHK;
1069 if ( (ifp->flags & (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED)) 1093 if ( (ifp->flags & (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED))
1070 != (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED)) 1094 != (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED))
1071 return; 1095 return;
1072 outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, ifp->hisport); 1096 outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, ifp->hisport);
1073} 1097}
1074 1098
1075static int 1099static int
1076check_ipkdb(struct ipkdb_if *ifp, struct in_addr *shost, char *p, int l) 1100check_ipkdb(struct ipkdb_if *ifp, struct in_addr *shost, char *p, int l)
1077{ 1101{
1078 u_char hisenet[6]; 1102 u_char hisenet[6];
1079 u_char hisinet[4]; 1103 u_char hisinet[4];
1080 u_int16_t hisport; 1104 u_int16_t hisport;
1081 char save; 1105 char save;
1082 1106
1083#ifndef IPKDBSECURE 1107#ifndef IPKDBSECURE
1084 if (kauth_authorize_system(curlwp->l_cred, KAUTH_SYSTEM_DEBUG, 1108 if (kauth_authorize_system(curlwp->l_cred, KAUTH_SYSTEM_DEBUG,
1085 KAUTH_REQ_SYSTEM_DEBUG_IPKDB, NULL, NULL, NULL)) 1109 KAUTH_REQ_SYSTEM_DEBUG_IPKDB, NULL, NULL, NULL))
1086 return 0; 1110 return 0;
1087#endif 1111#endif
1088 if (ipkdbcmp(chksum(p, l), p + l, LENCHK)) 1112 if (ipkdbcmp(chksum(p, l), p + l, LENCHK))
1089 return 0; 1113 return 0;
1090 ipkdbcopy(ifp->hisenetaddr, hisenet, sizeof hisenet); 1114 ipkdbcopy(ifp->hisenetaddr, hisenet, sizeof hisenet);
1091 ipkdbcopy(ifp->hisinetaddr, hisinet, sizeof hisinet); 1115 ipkdbcopy(ifp->hisinetaddr, hisinet, sizeof hisinet);
1092 hisport = ifp->hisport; 1116 hisport = ifp->hisport;
1093 save = ifp->flags; 1117 save = ifp->flags;
1094 ipkdbcopy(shost, ifp->hisinetaddr, sizeof ifp->hisinetaddr); 1118 ipkdbcopy(shost, ifp->hisinetaddr, sizeof ifp->hisinetaddr);
1095 ifp->flags &= ~IPKDB_HISHW; 1119 ifp->flags &= ~IPKDB_HISHW;
1096 ifp->flags |= IPKDB_HISIP; 1120 ifp->flags |= IPKDB_HISIP;
1097 if (connectipkdb(ifp, p + 6, l - 6) < 0) { 1121 if (connectipkdb(ifp, p + 6, l - 6) < 0) {
1098 ipkdbcopy(hisenet, ifp->hisenetaddr, sizeof ifp->hisenetaddr); 1122 ipkdbcopy(hisenet, ifp->hisenetaddr, sizeof ifp->hisenetaddr);
1099 ipkdbcopy(hisinet, ifp->hisinetaddr, sizeof ifp->hisinetaddr); 1123 ipkdbcopy(hisinet, ifp->hisinetaddr, sizeof ifp->hisinetaddr);
1100 ifp->hisport = hisport; 1124 ifp->hisport = hisport;
1101 ifp->flags = save; 1125 ifp->flags = save;

cvs diff -r1.3 -r1.4 src/sys/secmodel/suser/secmodel_suser.c (switch to unified diff)

--- src/sys/secmodel/suser/secmodel_suser.c 2009/10/02 21:56:28 1.3
+++ src/sys/secmodel/suser/secmodel_suser.c 2009/10/02 22:05:52 1.4
@@ -1,1281 +1,1270 @@ @@ -1,1281 +1,1270 @@
1/* $NetBSD: secmodel_suser.c,v 1.3 2009/10/02 21:56:28 elad Exp $ */ 1/* $NetBSD: secmodel_suser.c,v 1.4 2009/10/02 22:05:52 elad Exp $ */
2/*- 2/*-
3 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org> 3 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products 14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission. 15 * derived from this software without specific prior written permission.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * This file contains kauth(9) listeners needed to implement the traditional 30 * This file contains kauth(9) listeners needed to implement the traditional
31 * NetBSD superuser access restrictions. 31 * NetBSD superuser access restrictions.
32 * 32 *
33 * There are two main resources a request can be issued to: user-owned and 33 * There are two main resources a request can be issued to: user-owned and
34 * system owned. For the first, traditional Unix access checks are done, as 34 * system owned. For the first, traditional Unix access checks are done, as
35 * well as superuser checks. If needed, the request context is examined before 35 * well as superuser checks. If needed, the request context is examined before
36 * a decision is made. For the latter, usually only superuser checks are done 36 * a decision is made. For the latter, usually only superuser checks are done
37 * as normal users are not allowed to access system resources. 37 * as normal users are not allowed to access system resources.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.3 2009/10/02 21:56:28 elad Exp $"); 41__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.4 2009/10/02 22:05:52 elad Exp $");
42 42
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/kauth.h> 45#include <sys/kauth.h>
46 46
47#include <sys/acct.h> 47#include <sys/acct.h>
48#include <sys/mutex.h> 48#include <sys/mutex.h>
49#include <sys/ktrace.h> 49#include <sys/ktrace.h>
50#include <sys/mount.h> 50#include <sys/mount.h>
51#include <sys/pset.h> 51#include <sys/pset.h>
52#include <sys/socketvar.h> 52#include <sys/socketvar.h>
53#include <sys/sysctl.h> 53#include <sys/sysctl.h>
54#include <sys/tty.h> 54#include <sys/tty.h>
55#include <net/route.h> 55#include <net/route.h>
56#include <sys/ptrace.h> 56#include <sys/ptrace.h>
57#include <sys/vnode.h> 57#include <sys/vnode.h>
58#include <sys/proc.h> 58#include <sys/proc.h>
59#include <sys/uidinfo.h> 59#include <sys/uidinfo.h>
60#include <sys/module.h> 60#include <sys/module.h>
61 61
62#include <miscfs/procfs/procfs.h> 62#include <miscfs/procfs/procfs.h>
63 63
64#include <secmodel/suser/suser.h> 64#include <secmodel/suser/suser.h>
65 65
66MODULE(MODULE_CLASS_SECMODEL, suser, NULL); 66MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
67 67
68static int secmodel_bsd44_curtain; 68static int secmodel_bsd44_curtain;
69/* static */ int dovfsusermount; 69/* static */ int dovfsusermount;
70 70
71static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep, 71static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
72 l_device, l_vnode; 72 l_device, l_vnode;
73 73
74static struct sysctllog *suser_sysctl_log; 74static struct sysctllog *suser_sysctl_log;
75 75
76void 76void
77sysctl_security_suser_setup(struct sysctllog **clog) 77sysctl_security_suser_setup(struct sysctllog **clog)
78{ 78{
79 const struct sysctlnode *rnode; 79 const struct sysctlnode *rnode;
80 80
81 sysctl_createv(clog, 0, NULL, &rnode, 81 sysctl_createv(clog, 0, NULL, &rnode,
82 CTLFLAG_PERMANENT, 82 CTLFLAG_PERMANENT,
83 CTLTYPE_NODE, "security", NULL, 83 CTLTYPE_NODE, "security", NULL,
84 NULL, 0, NULL, 0, 84 NULL, 0, NULL, 0,
85 CTL_SECURITY, CTL_EOL); 85 CTL_SECURITY, CTL_EOL);
86 86
87 sysctl_createv(clog, 0, &rnode, &rnode, 87 sysctl_createv(clog, 0, &rnode, &rnode,
88 CTLFLAG_PERMANENT, 88 CTLFLAG_PERMANENT,
89 CTLTYPE_NODE, "models", NULL, 89 CTLTYPE_NODE, "models", NULL,
90 NULL, 0, NULL, 0, 90 NULL, 0, NULL, 0,
91 CTL_CREATE, CTL_EOL); 91 CTL_CREATE, CTL_EOL);
92 92
93 sysctl_createv(clog, 0, &rnode, &rnode, 93 sysctl_createv(clog, 0, &rnode, &rnode,
94 CTLFLAG_PERMANENT, 94 CTLFLAG_PERMANENT,
95 CTLTYPE_NODE, "suser", NULL, 95 CTLTYPE_NODE, "suser", NULL,
96 NULL, 0, NULL, 0, 96 NULL, 0, NULL, 0,
97 CTL_CREATE, CTL_EOL); 97 CTL_CREATE, CTL_EOL);
98 98
99 sysctl_createv(clog, 0, &rnode, NULL, 99 sysctl_createv(clog, 0, &rnode, NULL,
100 CTLFLAG_PERMANENT, 100 CTLFLAG_PERMANENT,
101 CTLTYPE_STRING, "name", NULL, 101 CTLTYPE_STRING, "name", NULL,
102 NULL, 0, __UNCONST("Traditional NetBSD: Superuser"), 0, 102 NULL, 0, __UNCONST("Traditional NetBSD: Superuser"), 0,
103 CTL_CREATE, CTL_EOL); 103 CTL_CREATE, CTL_EOL);
104 104
105 sysctl_createv(clog, 0, &rnode, NULL, 105 sysctl_createv(clog, 0, &rnode, NULL,
106 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 106 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
107 CTLTYPE_INT, "curtain", 107 CTLTYPE_INT, "curtain",
108 SYSCTL_DESCR("Curtain information about objects to "\ 108 SYSCTL_DESCR("Curtain information about objects to "\
109 "users not owning them."), 109 "users not owning them."),
110 NULL, 0, &secmodel_bsd44_curtain, 0, 110 NULL, 0, &secmodel_bsd44_curtain, 0,
111 CTL_CREATE, CTL_EOL); 111 CTL_CREATE, CTL_EOL);
112 112
113 sysctl_createv(clog, 0, &rnode, NULL, 113 sysctl_createv(clog, 0, &rnode, NULL,
114 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 114 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
115 CTLTYPE_INT, "usermount", 115 CTLTYPE_INT, "usermount",
116 SYSCTL_DESCR("Whether unprivileged users may mount " 116 SYSCTL_DESCR("Whether unprivileged users may mount "
117 "filesystems"), 117 "filesystems"),
118 NULL, 0, &dovfsusermount, 0, 118 NULL, 0, &dovfsusermount, 0,
119 CTL_CREATE, CTL_EOL); 119 CTL_CREATE, CTL_EOL);
120 120
121 /* Compatibility: security.curtain */ 121 /* Compatibility: security.curtain */
122 sysctl_createv(clog, 0, NULL, &rnode, 122 sysctl_createv(clog, 0, NULL, &rnode,
123 CTLFLAG_PERMANENT, 123 CTLFLAG_PERMANENT,
124 CTLTYPE_NODE, "security", NULL, 124 CTLTYPE_NODE, "security", NULL,
125 NULL, 0, NULL, 0, 125 NULL, 0, NULL, 0,
126 CTL_SECURITY, CTL_EOL); 126 CTL_SECURITY, CTL_EOL);
127 127
128 sysctl_createv(clog, 0, &rnode, NULL, 128 sysctl_createv(clog, 0, &rnode, NULL,
129 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 129 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
130 CTLTYPE_INT, "curtain", 130 CTLTYPE_INT, "curtain",
131 SYSCTL_DESCR("Curtain information about objects to "\ 131 SYSCTL_DESCR("Curtain information about objects to "\
132 "users not owning them."), 132 "users not owning them."),
133 NULL, 0, &secmodel_bsd44_curtain, 0, 133 NULL, 0, &secmodel_bsd44_curtain, 0,
134 CTL_CREATE, CTL_EOL); 134 CTL_CREATE, CTL_EOL);
135 135
136 /* Compatibility: vfs.generic.usermount */ 136 /* Compatibility: vfs.generic.usermount */
137 sysctl_createv(clog, 0, NULL, NULL, 137 sysctl_createv(clog, 0, NULL, NULL,
138 CTLFLAG_PERMANENT, 138 CTLFLAG_PERMANENT,
139 CTLTYPE_NODE, "vfs", NULL, 139 CTLTYPE_NODE, "vfs", NULL,
140 NULL, 0, NULL, 0, 140 NULL, 0, NULL, 0,
141 CTL_VFS, CTL_EOL); 141 CTL_VFS, CTL_EOL);
142 142
143 sysctl_createv(clog, 0, NULL, NULL, 143 sysctl_createv(clog, 0, NULL, NULL,
144 CTLFLAG_PERMANENT, 144 CTLFLAG_PERMANENT,
145 CTLTYPE_NODE, "generic", 145 CTLTYPE_NODE, "generic",
146 SYSCTL_DESCR("Non-specific vfs related information"), 146 SYSCTL_DESCR("Non-specific vfs related information"),
147 NULL, 0, NULL, 0, 147 NULL, 0, NULL, 0,
148 CTL_VFS, VFS_GENERIC, CTL_EOL); 148 CTL_VFS, VFS_GENERIC, CTL_EOL);
149 149
150 sysctl_createv(clog, 0, NULL, NULL, 150 sysctl_createv(clog, 0, NULL, NULL,
151 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 151 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
152 CTLTYPE_INT, "usermount", 152 CTLTYPE_INT, "usermount",
153 SYSCTL_DESCR("Whether unprivileged users may mount " 153 SYSCTL_DESCR("Whether unprivileged users may mount "
154 "filesystems"), 154 "filesystems"),
155 NULL, 0, &dovfsusermount, 0, 155 NULL, 0, &dovfsusermount, 0,
156 CTL_VFS, VFS_GENERIC, VFS_USERMOUNT, CTL_EOL); 156 CTL_VFS, VFS_GENERIC, VFS_USERMOUNT, CTL_EOL);
157} 157}
158 158
159void 159void
160secmodel_suser_init(void) 160secmodel_suser_init(void)
161{ 161{
162 secmodel_bsd44_curtain = 0; 162 secmodel_bsd44_curtain = 0;
163 dovfsusermount = 0; 163 dovfsusermount = 0;
164} 164}
165 165
166void 166void
167secmodel_suser_start(void) 167secmodel_suser_start(void)
168{ 168{
169 l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC, 169 l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
170 secmodel_suser_generic_cb, NULL); 170 secmodel_suser_generic_cb, NULL);
171 l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM, 171 l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
172 secmodel_suser_system_cb, NULL); 172 secmodel_suser_system_cb, NULL);
173 l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 173 l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
174 secmodel_suser_process_cb, NULL); 174 secmodel_suser_process_cb, NULL);
175 l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK, 175 l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
176 secmodel_suser_network_cb, NULL); 176 secmodel_suser_network_cb, NULL);
177 l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP, 177 l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
178 secmodel_suser_machdep_cb, NULL); 178 secmodel_suser_machdep_cb, NULL);
179 l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE, 179 l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
180 secmodel_suser_device_cb, NULL); 180 secmodel_suser_device_cb, NULL);
181 l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE, 181 l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
182 secmodel_suser_vnode_cb, NULL); 182 secmodel_suser_vnode_cb, NULL);
183} 183}
184 184
185void 185void
186secmodel_suser_stop(void) 186secmodel_suser_stop(void)
187{ 187{
188 kauth_unlisten_scope(l_generic); 188 kauth_unlisten_scope(l_generic);
189 kauth_unlisten_scope(l_system); 189 kauth_unlisten_scope(l_system);
190 kauth_unlisten_scope(l_process); 190 kauth_unlisten_scope(l_process);
191 kauth_unlisten_scope(l_network); 191 kauth_unlisten_scope(l_network);
192 kauth_unlisten_scope(l_machdep); 192 kauth_unlisten_scope(l_machdep);
193 kauth_unlisten_scope(l_device); 193 kauth_unlisten_scope(l_device);
194 kauth_unlisten_scope(l_vnode); 194 kauth_unlisten_scope(l_vnode);
195} 195}
196 196
197static int 197static int
198suser_modcmd(modcmd_t cmd, void *arg) 198suser_modcmd(modcmd_t cmd, void *arg)
199{ 199{
200 int error = 0; 200 int error = 0;
201 201
202 switch (cmd) { 202 switch (cmd) {
203 case MODULE_CMD_INIT: 203 case MODULE_CMD_INIT:
204 secmodel_suser_init(); 204 secmodel_suser_init();
205 secmodel_suser_start(); 205 secmodel_suser_start();
206 sysctl_security_suser_setup(&suser_sysctl_log); 206 sysctl_security_suser_setup(&suser_sysctl_log);
207 break; 207 break;
208 208
209 case MODULE_CMD_FINI: 209 case MODULE_CMD_FINI:
210 sysctl_teardown(&suser_sysctl_log); 210 sysctl_teardown(&suser_sysctl_log);
211 secmodel_suser_stop(); 211 secmodel_suser_stop();
212 break; 212 break;
213 213
214 case MODULE_CMD_AUTOUNLOAD: 214 case MODULE_CMD_AUTOUNLOAD:
215 error = EPERM; 215 error = EPERM;
216 break; 216 break;
217 217
218 default: 218 default:
219 error = ENOTTY; 219 error = ENOTTY;
220 break; 220 break;
221 } 221 }
222 222
223 return (error); 223 return (error);
224} 224}
225 225
226/* 226/*
227 * kauth(9) listener 227 * kauth(9) listener
228 * 228 *
229 * Security model: Traditional NetBSD 229 * Security model: Traditional NetBSD
230 * Scope: Generic 230 * Scope: Generic
231 * Responsibility: Superuser access 231 * Responsibility: Superuser access
232 */ 232 */
233int 233int
234secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action, 234secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
235 void *cookie, void *arg0, void *arg1, 235 void *cookie, void *arg0, void *arg1,
236 void *arg2, void *arg3) 236 void *arg2, void *arg3)
237{ 237{
238 bool isroot; 238 bool isroot;
239 int result; 239 int result;
240 240
241 isroot = (kauth_cred_geteuid(cred) == 0); 241 isroot = (kauth_cred_geteuid(cred) == 0);
242 result = KAUTH_RESULT_DEFER; 242 result = KAUTH_RESULT_DEFER;
243 243
244 switch (action) { 244 switch (action) {
245 case KAUTH_GENERIC_ISSUSER: 245 case KAUTH_GENERIC_ISSUSER:
246 if (isroot) 246 if (isroot)
247 result = KAUTH_RESULT_ALLOW; 247 result = KAUTH_RESULT_ALLOW;
248 break; 248 break;
249 249
250 case KAUTH_GENERIC_CANSEE:  250 case KAUTH_GENERIC_CANSEE:
251 if (!secmodel_bsd44_curtain) 251 if (!secmodel_bsd44_curtain)
252 result = KAUTH_RESULT_ALLOW; 252 result = KAUTH_RESULT_ALLOW;
253 else if (isroot || kauth_cred_uidmatch(cred, arg0)) 253 else if (isroot || kauth_cred_uidmatch(cred, arg0))
254 result = KAUTH_RESULT_ALLOW; 254 result = KAUTH_RESULT_ALLOW;
255 255
256 break; 256 break;
257 257
258 default: 258 default:
259 result = KAUTH_RESULT_DEFER; 259 result = KAUTH_RESULT_DEFER;
260 break; 260 break;
261 } 261 }
262 262
263 return (result); 263 return (result);
264} 264}
265 265
266/* 266/*
267 * kauth(9) listener 267 * kauth(9) listener
268 * 268 *
269 * Security model: Traditional NetBSD 269 * Security model: Traditional NetBSD
270 * Scope: System 270 * Scope: System
271 * Responsibility: Superuser access 271 * Responsibility: Superuser access
272 */ 272 */
273int 273int
274secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action, 274secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
275 void *cookie, void *arg0, void *arg1, 275 void *cookie, void *arg0, void *arg1,
276 void *arg2, void *arg3) 276 void *arg2, void *arg3)
277{ 277{
278 bool isroot; 278 bool isroot;
279 int result; 279 int result;
280 enum kauth_system_req req; 280 enum kauth_system_req req;
281 281
282 isroot = (kauth_cred_geteuid(cred) == 0); 282 isroot = (kauth_cred_geteuid(cred) == 0);
283 result = KAUTH_RESULT_DEFER; 283 result = KAUTH_RESULT_DEFER;
284 req = (enum kauth_system_req)arg0; 284 req = (enum kauth_system_req)arg0;
285 285
286 switch (action) { 286 switch (action) {
287 case KAUTH_SYSTEM_CPU: 287 case KAUTH_SYSTEM_CPU:
288 switch (req) { 288 switch (req) {
289 case KAUTH_REQ_SYSTEM_CPU_SETSTATE: 289 case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
290 if (isroot) 290 if (isroot)
291 result = KAUTH_RESULT_ALLOW; 291 result = KAUTH_RESULT_ALLOW;
292 292
293 break; 293 break;
294 294
295 default: 295 default:
296 break; 296 break;
297 } 297 }
298 298
299 break; 299 break;
300 300
301 case KAUTH_SYSTEM_FS_QUOTA: 301 case KAUTH_SYSTEM_FS_QUOTA:
302 switch (req) { 302 switch (req) {
303 case KAUTH_REQ_SYSTEM_FS_QUOTA_GET: 303 case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
304 case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF: 304 case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
305 case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE: 305 case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
306 case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT: 306 case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
307 if (isroot) 307 if (isroot)
308 result = KAUTH_RESULT_ALLOW; 308 result = KAUTH_RESULT_ALLOW;
309 break; 309 break;
310 310
311 default: 311 default:
312 break; 312 break;
313 } 313 }
314 314
315 break; 315 break;
316 316
317 case KAUTH_SYSTEM_FS_RESERVEDSPACE: 317 case KAUTH_SYSTEM_FS_RESERVEDSPACE:
318 if (isroot) 318 if (isroot)
319 result = KAUTH_RESULT_ALLOW; 319 result = KAUTH_RESULT_ALLOW;
320 break; 320 break;
321 321
322 case KAUTH_SYSTEM_MOUNT: 322 case KAUTH_SYSTEM_MOUNT:
323 switch (req) { 323 switch (req) {
324 case KAUTH_REQ_SYSTEM_MOUNT_GET: 324 case KAUTH_REQ_SYSTEM_MOUNT_GET:
325 result = KAUTH_RESULT_ALLOW; 325 result = KAUTH_RESULT_ALLOW;
326 break; 326 break;
327 327
328 case KAUTH_REQ_SYSTEM_MOUNT_NEW: 328 case KAUTH_REQ_SYSTEM_MOUNT_NEW:
329 if (isroot) 329 if (isroot)
330 result = KAUTH_RESULT_ALLOW; 330 result = KAUTH_RESULT_ALLOW;
331 else if (dovfsusermount) { 331 else if (dovfsusermount) {
332 struct vnode *vp = arg1; 332 struct vnode *vp = arg1;
333 u_long flags = (u_long)arg2; 333 u_long flags = (u_long)arg2;
334 334
335 if (!(flags & MNT_NODEV) || 335 if (!(flags & MNT_NODEV) ||
336 !(flags & MNT_NOSUID)) 336 !(flags & MNT_NOSUID))
337 break; 337 break;
338 338
339 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) && 339 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) &&
340 !(flags & MNT_NOEXEC)) 340 !(flags & MNT_NOEXEC))
341 break; 341 break;
342 342
343 result = KAUTH_RESULT_ALLOW; 343 result = KAUTH_RESULT_ALLOW;
344 } 344 }
345 345
346 break; 346 break;
347 347
348 case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT: 348 case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
349 if (isroot) 349 if (isroot)
350 result = KAUTH_RESULT_ALLOW; 350 result = KAUTH_RESULT_ALLOW;
351 else { 351 else {
352 struct mount *mp = arg1; 352 struct mount *mp = arg1;
353 353
354 if (mp->mnt_stat.f_owner == 354 if (mp->mnt_stat.f_owner ==
355 kauth_cred_geteuid(cred)) 355 kauth_cred_geteuid(cred))
356 result = KAUTH_RESULT_ALLOW; 356 result = KAUTH_RESULT_ALLOW;
357 } 357 }
358 358
359 break; 359 break;
360 360
361 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE: 361 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
362 if (isroot) 362 if (isroot)
363 result = KAUTH_RESULT_ALLOW; 363 result = KAUTH_RESULT_ALLOW;
364 else if (dovfsusermount) { 364 else if (dovfsusermount) {
365 struct mount *mp = arg1; 365 struct mount *mp = arg1;
366 u_long flags = (u_long)arg2; 366 u_long flags = (u_long)arg2;
367 367
368 /* No exporting for non-root. */ 368 /* No exporting for non-root. */
369 if (flags & MNT_EXPORTED) 369 if (flags & MNT_EXPORTED)
370 break; 370 break;
371 371
372 if (!(flags & MNT_NODEV) || 372 if (!(flags & MNT_NODEV) ||
373 !(flags & MNT_NOSUID)) 373 !(flags & MNT_NOSUID))
374 break; 374 break;
375 375
376 /* 376 /*
377 * Only super-user, or user that did the mount, 377 * Only super-user, or user that did the mount,
378 * can update. 378 * can update.
379 */ 379 */
380 if (mp->mnt_stat.f_owner != 380 if (mp->mnt_stat.f_owner !=
381 kauth_cred_geteuid(cred)) 381 kauth_cred_geteuid(cred))
382 break; 382 break;
383 383
384 /* Retain 'noexec'. */ 384 /* Retain 'noexec'. */
385 if ((mp->mnt_flag & MNT_NOEXEC) && 385 if ((mp->mnt_flag & MNT_NOEXEC) &&
386 !(flags & MNT_NOEXEC)) 386 !(flags & MNT_NOEXEC))
387 break; 387 break;
388 388
389 result = KAUTH_RESULT_ALLOW; 389 result = KAUTH_RESULT_ALLOW;
390 } 390 }
391 391
392 break; 392 break;
393 393
394 default: 394 default:
395 result = KAUTH_RESULT_DEFER; 395 result = KAUTH_RESULT_DEFER;
396 break; 396 break;
397 } 397 }
398 398
399 break; 399 break;
400 400
401 case KAUTH_SYSTEM_PSET: 401 case KAUTH_SYSTEM_PSET:
402 switch (req) { 402 switch (req) {
403 case KAUTH_REQ_SYSTEM_PSET_ASSIGN: 403 case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
404 case KAUTH_REQ_SYSTEM_PSET_BIND: 404 case KAUTH_REQ_SYSTEM_PSET_BIND:
405 case KAUTH_REQ_SYSTEM_PSET_CREATE: 405 case KAUTH_REQ_SYSTEM_PSET_CREATE:
406 case KAUTH_REQ_SYSTEM_PSET_DESTROY: 406 case KAUTH_REQ_SYSTEM_PSET_DESTROY:
407 if (isroot) 407 if (isroot)
408 result = KAUTH_RESULT_ALLOW; 408 result = KAUTH_RESULT_ALLOW;
409 409
410 break; 410 break;
411 411
412 default: 412 default:
413 break; 413 break;
414 } 414 }
415 415
416 break; 416 break;
417 417
418 case KAUTH_SYSTEM_TIME: 418 case KAUTH_SYSTEM_TIME:
419 switch (req) { 419 switch (req) {
420 case KAUTH_REQ_SYSTEM_TIME_ADJTIME: 420 case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
421 case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME: 421 case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
422 case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS: 422 case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
423 if (isroot) 423 if (isroot)
424 result = KAUTH_RESULT_ALLOW; 424 result = KAUTH_RESULT_ALLOW;
425 break; 425 break;
426 426
427 case KAUTH_REQ_SYSTEM_TIME_SYSTEM: { 427 case KAUTH_REQ_SYSTEM_TIME_SYSTEM: {
428 bool device_context = (bool)arg3; 428 bool device_context = (bool)arg3;
429 429
430 if (device_context || isroot) 430 if (device_context || isroot)
431 result = KAUTH_RESULT_ALLOW; 431 result = KAUTH_RESULT_ALLOW;
432 432
433 break; 433 break;
434 } 434 }
435 435
436 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET: 436 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
437 if (isroot) 437 if (isroot)
438 result = KAUTH_RESULT_ALLOW; 438 result = KAUTH_RESULT_ALLOW;
439 break; 439 break;
440 440
441 default: 441 default:
442 result = KAUTH_RESULT_DEFER; 442 result = KAUTH_RESULT_DEFER;
443 break; 443 break;
444 } 444 }
445 break; 445 break;
446 446
447 case KAUTH_SYSTEM_SYSCTL: 447 case KAUTH_SYSTEM_SYSCTL:
448 switch (req) { 448 switch (req) {
449 case KAUTH_REQ_SYSTEM_SYSCTL_ADD: 449 case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
450 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE: 450 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
451 case KAUTH_REQ_SYSTEM_SYSCTL_DESC: 451 case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
452 case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY: 452 case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
453 case KAUTH_REQ_SYSTEM_SYSCTL_PRVT: 453 case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
454 if (isroot) 454 if (isroot)
455 result = KAUTH_RESULT_ALLOW; 455 result = KAUTH_RESULT_ALLOW;
456 break; 456 break;
457 457
458 default: 458 default:
459 break; 459 break;
460 } 460 }
461 461
462 break; 462 break;
463 463
464 case KAUTH_SYSTEM_SWAPCTL: 464 case KAUTH_SYSTEM_SWAPCTL:
465 case KAUTH_SYSTEM_ACCOUNTING: 465 case KAUTH_SYSTEM_ACCOUNTING:
466 case KAUTH_SYSTEM_REBOOT: 466 case KAUTH_SYSTEM_REBOOT:
467 case KAUTH_SYSTEM_CHROOT: 467 case KAUTH_SYSTEM_CHROOT:
468 case KAUTH_SYSTEM_FILEHANDLE: 468 case KAUTH_SYSTEM_FILEHANDLE:
469 case KAUTH_SYSTEM_MKNOD: 469 case KAUTH_SYSTEM_MKNOD:
470 if (isroot) 470 if (isroot)
471 result = KAUTH_RESULT_ALLOW; 471 result = KAUTH_RESULT_ALLOW;
472 break; 472 break;
473 473
474 case KAUTH_SYSTEM_DEBUG: 
475 switch (req) { 
476 case KAUTH_REQ_SYSTEM_DEBUG_IPKDB: 
477 default: 
478 /* Decisions are root-agnostic. */ 
479 result = KAUTH_RESULT_ALLOW; 
480 break; 
481 } 
482 
483 break; 
484 
485 case KAUTH_SYSTEM_CHSYSFLAGS: 474 case KAUTH_SYSTEM_CHSYSFLAGS:
486 /* 475 /*
487 * Needs to be checked in conjunction with the immutable and 476 * Needs to be checked in conjunction with the immutable and
488 * append-only flags (usually). Should be handled differently. 477 * append-only flags (usually). Should be handled differently.
489 * Infects ufs, ext2fs, tmpfs, and rump. 478 * Infects ufs, ext2fs, tmpfs, and rump.
490 */ 479 */
491 if (isroot) 480 if (isroot)
492 result = KAUTH_RESULT_ALLOW; 481 result = KAUTH_RESULT_ALLOW;
493 482
494 break; 483 break;
495 484
496 case KAUTH_SYSTEM_SETIDCORE: 485 case KAUTH_SYSTEM_SETIDCORE:
497 if (isroot) 486 if (isroot)
498 result = KAUTH_RESULT_ALLOW; 487 result = KAUTH_RESULT_ALLOW;
499 488
500 break; 489 break;
501 490
502 case KAUTH_SYSTEM_MODULE: 491 case KAUTH_SYSTEM_MODULE:
503 if (isroot) 492 if (isroot)
504 result = KAUTH_RESULT_ALLOW; 493 result = KAUTH_RESULT_ALLOW;
505 if ((uintptr_t)arg2 != 0) /* autoload */ 494 if ((uintptr_t)arg2 != 0) /* autoload */
506 result = KAUTH_RESULT_ALLOW; 495 result = KAUTH_RESULT_ALLOW;
507 break; 496 break;
508 497
509 default: 498 default:
510 result = KAUTH_RESULT_DEFER; 499 result = KAUTH_RESULT_DEFER;
511 break; 500 break;
512 } 501 }
513 502
514 return (result); 503 return (result);
515} 504}
516 505
517/* 506/*
518 * common code for corename, rlimit, and stopflag. 507 * common code for corename, rlimit, and stopflag.
519 */ 508 */
520static int 509static int
521proc_uidmatch(kauth_cred_t cred, kauth_cred_t target) 510proc_uidmatch(kauth_cred_t cred, kauth_cred_t target)
522{ 511{
523 int r = 0; 512 int r = 0;
524 513
525 if (kauth_cred_getuid(cred) != kauth_cred_getuid(target) || 514 if (kauth_cred_getuid(cred) != kauth_cred_getuid(target) ||
526 kauth_cred_getuid(cred) != kauth_cred_getsvuid(target)) { 515 kauth_cred_getuid(cred) != kauth_cred_getsvuid(target)) {
527 /* 516 /*
528 * suid proc of ours or proc not ours 517 * suid proc of ours or proc not ours
529 */ 518 */
530 r = EPERM; 519 r = EPERM;
531 } else if (kauth_cred_getgid(target) != kauth_cred_getsvgid(target)) { 520 } else if (kauth_cred_getgid(target) != kauth_cred_getsvgid(target)) {
532 /* 521 /*
533 * sgid proc has sgid back to us temporarily 522 * sgid proc has sgid back to us temporarily
534 */ 523 */
535 r = EPERM; 524 r = EPERM;
536 } else { 525 } else {
537 /* 526 /*
538 * our rgid must be in target's group list (ie, 527 * our rgid must be in target's group list (ie,
539 * sub-processes started by a sgid process) 528 * sub-processes started by a sgid process)
540 */ 529 */
541 int ismember = 0; 530 int ismember = 0;
542 531
543 if (kauth_cred_ismember_gid(cred, 532 if (kauth_cred_ismember_gid(cred,
544 kauth_cred_getgid(target), &ismember) != 0 || 533 kauth_cred_getgid(target), &ismember) != 0 ||
545 !ismember) 534 !ismember)
546 r = EPERM; 535 r = EPERM;
547 } 536 }
548 537
549 return (r); 538 return (r);
550} 539}
551 540
552/* 541/*
553 * kauth(9) listener 542 * kauth(9) listener
554 * 543 *
555 * Security model: Traditional NetBSD 544 * Security model: Traditional NetBSD
556 * Scope: Process 545 * Scope: Process
557 * Responsibility: Superuser access 546 * Responsibility: Superuser access
558 */ 547 */
559int 548int
560secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action, 549secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
561 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 550 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
562{ 551{
563 struct proc *p; 552 struct proc *p;
564 bool isroot; 553 bool isroot;
565 int result; 554 int result;
566 555
567 isroot = (kauth_cred_geteuid(cred) == 0); 556 isroot = (kauth_cred_geteuid(cred) == 0);
568 result = KAUTH_RESULT_DEFER; 557 result = KAUTH_RESULT_DEFER;
569 p = arg0; 558 p = arg0;
570 559
571 switch (action) { 560 switch (action) {
572 case KAUTH_PROCESS_SIGNAL: { 561 case KAUTH_PROCESS_SIGNAL: {
573 int signum; 562 int signum;
574 563
575 signum = (int)(unsigned long)arg1; 564 signum = (int)(unsigned long)arg1;
576 565
577 if (isroot || kauth_cred_uidmatch(cred, p->p_cred) || 566 if (isroot || kauth_cred_uidmatch(cred, p->p_cred) ||
578 (signum == SIGCONT && (curproc->p_session == p->p_session))) 567 (signum == SIGCONT && (curproc->p_session == p->p_session)))
579 result = KAUTH_RESULT_ALLOW; 568 result = KAUTH_RESULT_ALLOW;
580 break; 569 break;
581 } 570 }
582 571
583 case KAUTH_PROCESS_CANSEE: { 572 case KAUTH_PROCESS_CANSEE: {
584 unsigned long req; 573 unsigned long req;
585 574
586 req = (unsigned long)arg1; 575 req = (unsigned long)arg1;
587 576
588 switch (req) { 577 switch (req) {
589 case KAUTH_REQ_PROCESS_CANSEE_ARGS: 578 case KAUTH_REQ_PROCESS_CANSEE_ARGS:
590 case KAUTH_REQ_PROCESS_CANSEE_ENTRY: 579 case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
591 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES: 580 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
592 if (!secmodel_bsd44_curtain) 581 if (!secmodel_bsd44_curtain)
593 result = KAUTH_RESULT_ALLOW; 582 result = KAUTH_RESULT_ALLOW;
594 else if (isroot || kauth_cred_uidmatch(cred, p->p_cred)) 583 else if (isroot || kauth_cred_uidmatch(cred, p->p_cred))
595 result = KAUTH_RESULT_ALLOW; 584 result = KAUTH_RESULT_ALLOW;
596 break; 585 break;
597 586
598 case KAUTH_REQ_PROCESS_CANSEE_ENV: 587 case KAUTH_REQ_PROCESS_CANSEE_ENV:
599 if (!isroot && 588 if (!isroot &&
600 (kauth_cred_getuid(cred) != 589 (kauth_cred_getuid(cred) !=
601 kauth_cred_getuid(p->p_cred) || 590 kauth_cred_getuid(p->p_cred) ||
602 kauth_cred_getuid(cred) != 591 kauth_cred_getuid(cred) !=
603 kauth_cred_getsvuid(p->p_cred))) 592 kauth_cred_getsvuid(p->p_cred)))
604 break; 593 break;
605 else 594 else
606 result = KAUTH_RESULT_ALLOW; 595 result = KAUTH_RESULT_ALLOW;
607 596
608 break; 597 break;
609 598
610 default: 599 default:
611 break; 600 break;
612 } 601 }
613 602
614 break; 603 break;
615 } 604 }
616 605
617 case KAUTH_PROCESS_KTRACE: 606 case KAUTH_PROCESS_KTRACE:
618 if (isroot) 607 if (isroot)
619 result = KAUTH_RESULT_ALLOW; 608 result = KAUTH_RESULT_ALLOW;
620 609
621 break; 610 break;
622 611
623 case KAUTH_PROCESS_PROCFS: { 612 case KAUTH_PROCESS_PROCFS: {
624 enum kauth_process_req req = (enum kauth_process_req)arg2; 613 enum kauth_process_req req = (enum kauth_process_req)arg2;
625 struct pfsnode *pfs = arg1; 614 struct pfsnode *pfs = arg1;
626 615
627 if (isroot) { 616 if (isroot) {
628 result = KAUTH_RESULT_ALLOW; 617 result = KAUTH_RESULT_ALLOW;
629 break; 618 break;
630 } 619 }
631 620
632 if (req == KAUTH_REQ_PROCESS_PROCFS_CTL) { 621 if (req == KAUTH_REQ_PROCESS_PROCFS_CTL) {
633 break; 622 break;
634 } 623 }
635 624
636 switch (pfs->pfs_type) { 625 switch (pfs->pfs_type) {
637 case PFSregs: 626 case PFSregs:
638 case PFSfpregs: 627 case PFSfpregs:
639 case PFSmem: 628 case PFSmem:
640 if (kauth_cred_getuid(cred) != 629 if (kauth_cred_getuid(cred) !=
641 kauth_cred_getuid(p->p_cred) || 630 kauth_cred_getuid(p->p_cred) ||
642 ISSET(p->p_flag, PK_SUGID)) { 631 ISSET(p->p_flag, PK_SUGID)) {
643 break; 632 break;
644 } 633 }
645 /*FALLTHROUGH*/ 634 /*FALLTHROUGH*/
646 default: 635 default:
647 result = KAUTH_RESULT_ALLOW; 636 result = KAUTH_RESULT_ALLOW;
648 break; 637 break;
649 } 638 }
650 639
651 break; 640 break;
652 } 641 }
653 642
654 case KAUTH_PROCESS_PTRACE: { 643 case KAUTH_PROCESS_PTRACE: {
655 switch ((u_long)arg1) { 644 switch ((u_long)arg1) {
656 case PT_TRACE_ME: 645 case PT_TRACE_ME:
657 case PT_ATTACH: 646 case PT_ATTACH:
658 case PT_WRITE_I: 647 case PT_WRITE_I:
659 case PT_WRITE_D: 648 case PT_WRITE_D:
660 case PT_READ_I: 649 case PT_READ_I:
661 case PT_READ_D: 650 case PT_READ_D:
662 case PT_IO: 651 case PT_IO:
663#ifdef PT_GETREGS 652#ifdef PT_GETREGS
664 case PT_GETREGS: 653 case PT_GETREGS:
665#endif 654#endif
666#ifdef PT_SETREGS 655#ifdef PT_SETREGS
667 case PT_SETREGS: 656 case PT_SETREGS:
668#endif 657#endif
669#ifdef PT_GETFPREGS 658#ifdef PT_GETFPREGS
670 case PT_GETFPREGS: 659 case PT_GETFPREGS:
671#endif 660#endif
672#ifdef PT_SETFPREGS 661#ifdef PT_SETFPREGS
673 case PT_SETFPREGS: 662 case PT_SETFPREGS:
674#endif 663#endif
675#ifdef __HAVE_PTRACE_MACHDEP 664#ifdef __HAVE_PTRACE_MACHDEP
676 PTRACE_MACHDEP_REQUEST_CASES 665 PTRACE_MACHDEP_REQUEST_CASES
677#endif 666#endif
678 if (isroot) { 667 if (isroot) {
679 result = KAUTH_RESULT_ALLOW; 668 result = KAUTH_RESULT_ALLOW;
680 break; 669 break;
681 } 670 }
682 671
683 if (kauth_cred_getuid(cred) != 672 if (kauth_cred_getuid(cred) !=
684 kauth_cred_getuid(p->p_cred) || 673 kauth_cred_getuid(p->p_cred) ||
685 ISSET(p->p_flag, PK_SUGID)) { 674 ISSET(p->p_flag, PK_SUGID)) {
686 break; 675 break;
687 } 676 }
688 677
689 result = KAUTH_RESULT_ALLOW; 678 result = KAUTH_RESULT_ALLOW;
690 break; 679 break;
691 680
692#ifdef PT_STEP 681#ifdef PT_STEP
693 case PT_STEP: 682 case PT_STEP:
694#endif 683#endif
695 case PT_CONTINUE: 684 case PT_CONTINUE:
696 case PT_KILL: 685 case PT_KILL:
697 case PT_DETACH: 686 case PT_DETACH:
698 case PT_LWPINFO: 687 case PT_LWPINFO:
699 case PT_SYSCALL: 688 case PT_SYSCALL:
700 case PT_DUMPCORE: 689 case PT_DUMPCORE:
701 result = KAUTH_RESULT_ALLOW; 690 result = KAUTH_RESULT_ALLOW;
702 break; 691 break;
703 692
704 default: 693 default:
705 result = KAUTH_RESULT_DEFER; 694 result = KAUTH_RESULT_DEFER;
706 break; 695 break;
707 } 696 }
708 697
709 break; 698 break;
710 } 699 }
711 700
712 case KAUTH_PROCESS_CORENAME: 701 case KAUTH_PROCESS_CORENAME:
713 if (isroot || proc_uidmatch(cred, p->p_cred) == 0) 702 if (isroot || proc_uidmatch(cred, p->p_cred) == 0)
714 result = KAUTH_RESULT_ALLOW; 703 result = KAUTH_RESULT_ALLOW;
715 704
716 break; 705 break;
717 706
718 case KAUTH_PROCESS_FORK: { 707 case KAUTH_PROCESS_FORK: {
719 int lnprocs = (int)(unsigned long)arg2; 708 int lnprocs = (int)(unsigned long)arg2;
720 709
721 /* 710 /*
722 * Don't allow a nonprivileged user to use the last few 711 * Don't allow a nonprivileged user to use the last few
723 * processes. The variable lnprocs is the current number of 712 * processes. The variable lnprocs is the current number of
724 * processes, maxproc is the limit. 713 * processes, maxproc is the limit.
725 */ 714 */
726 if (__predict_false((lnprocs >= maxproc - 5) && !isroot)) 715 if (__predict_false((lnprocs >= maxproc - 5) && !isroot))
727 break; 716 break;
728 else 717 else
729 result = KAUTH_RESULT_ALLOW; 718 result = KAUTH_RESULT_ALLOW;
730 719
731 break; 720 break;
732 } 721 }
733 722
734 case KAUTH_PROCESS_KEVENT_FILTER: 723 case KAUTH_PROCESS_KEVENT_FILTER:
735 if ((kauth_cred_getuid(p->p_cred) != 724 if ((kauth_cred_getuid(p->p_cred) !=
736 kauth_cred_getuid(cred) || 725 kauth_cred_getuid(cred) ||
737 ISSET(p->p_flag, PK_SUGID)) && 726 ISSET(p->p_flag, PK_SUGID)) &&
738 !isroot) 727 !isroot)
739 break; 728 break;
740 else 729 else
741 result = KAUTH_RESULT_ALLOW; 730 result = KAUTH_RESULT_ALLOW;
742 731
743 break; 732 break;
744 733
745 case KAUTH_PROCESS_NICE: 734 case KAUTH_PROCESS_NICE:
746 if (isroot) { 735 if (isroot) {
747 result = KAUTH_RESULT_ALLOW; 736 result = KAUTH_RESULT_ALLOW;
748 break; 737 break;
749 } 738 }
750 739
751 if (kauth_cred_geteuid(cred) != 740 if (kauth_cred_geteuid(cred) !=
752 kauth_cred_geteuid(p->p_cred) && 741 kauth_cred_geteuid(p->p_cred) &&
753 kauth_cred_getuid(cred) != 742 kauth_cred_getuid(cred) !=
754 kauth_cred_geteuid(p->p_cred)) { 743 kauth_cred_geteuid(p->p_cred)) {
755 break; 744 break;
756 } 745 }
757 746
758 if ((u_long)arg1 >= p->p_nice) 747 if ((u_long)arg1 >= p->p_nice)
759 result = KAUTH_RESULT_ALLOW; 748 result = KAUTH_RESULT_ALLOW;
760 749
761 break; 750 break;
762 751
763 case KAUTH_PROCESS_RLIMIT: { 752 case KAUTH_PROCESS_RLIMIT: {
764 unsigned long req; 753 unsigned long req;
765 754
766 req = (unsigned long)arg1; 755 req = (unsigned long)arg1;
767 756
768 switch (req) { 757 switch (req) {
769 case KAUTH_REQ_PROCESS_RLIMIT_SET: { 758 case KAUTH_REQ_PROCESS_RLIMIT_SET: {
770 struct rlimit *new_rlimit; 759 struct rlimit *new_rlimit;
771 u_long which; 760 u_long which;
772 761
773 if (isroot) { 762 if (isroot) {
774 result = KAUTH_RESULT_ALLOW; 763 result = KAUTH_RESULT_ALLOW;
775 break; 764 break;
776 } 765 }
777 766
778 if ((p != curlwp->l_proc) && 767 if ((p != curlwp->l_proc) &&
779 (proc_uidmatch(cred, p->p_cred) != 0)) { 768 (proc_uidmatch(cred, p->p_cred) != 0)) {
780 break; 769 break;
781 } 770 }
782 771
783 new_rlimit = arg2; 772 new_rlimit = arg2;
784 which = (u_long)arg3; 773 which = (u_long)arg3;
785 774
786 if (new_rlimit->rlim_max <= 775 if (new_rlimit->rlim_max <=
787 p->p_rlimit[which].rlim_max) 776 p->p_rlimit[which].rlim_max)
788 result = KAUTH_RESULT_ALLOW; 777 result = KAUTH_RESULT_ALLOW;
789 778
790 break; 779 break;
791 } 780 }
792 781
793 case KAUTH_REQ_PROCESS_RLIMIT_GET: 782 case KAUTH_REQ_PROCESS_RLIMIT_GET:
794 result = KAUTH_RESULT_ALLOW; 783 result = KAUTH_RESULT_ALLOW;
795 break; 784 break;
796 785
797 default: 786 default:
798 break; 787 break;
799 } 788 }
800 789
801 break; 790 break;
802 } 791 }
803 792
804 case KAUTH_PROCESS_SCHEDULER_GETPARAM: 793 case KAUTH_PROCESS_SCHEDULER_GETPARAM:
805 if (isroot || kauth_cred_uidmatch(cred, p->p_cred)) 794 if (isroot || kauth_cred_uidmatch(cred, p->p_cred))
806 result = KAUTH_RESULT_ALLOW; 795 result = KAUTH_RESULT_ALLOW;
807 796
808 break; 797 break;
809 798
810 case KAUTH_PROCESS_SCHEDULER_SETPARAM: 799 case KAUTH_PROCESS_SCHEDULER_SETPARAM:
811 if (isroot) 800 if (isroot)
812 result = KAUTH_RESULT_ALLOW; 801 result = KAUTH_RESULT_ALLOW;
813 else if (kauth_cred_uidmatch(cred, p->p_cred)) { 802 else if (kauth_cred_uidmatch(cred, p->p_cred)) {
814 struct lwp *l; 803 struct lwp *l;
815 int policy; 804 int policy;
816 pri_t priority; 805 pri_t priority;
817 806
818 l = arg1; 807 l = arg1;
819 policy = (int)(unsigned long)arg2; 808 policy = (int)(unsigned long)arg2;
820 priority = (pri_t)(unsigned long)arg3; 809 priority = (pri_t)(unsigned long)arg3;
821 810
822 if ((policy == l->l_class || 811 if ((policy == l->l_class ||
823 (policy != SCHED_FIFO && policy != SCHED_RR)) && 812 (policy != SCHED_FIFO && policy != SCHED_RR)) &&
824 priority <= l->l_priority) 813 priority <= l->l_priority)
825 result = KAUTH_RESULT_ALLOW; 814 result = KAUTH_RESULT_ALLOW;
826 } 815 }
827 816
828 break; 817 break;
829 818
830 case KAUTH_PROCESS_SCHEDULER_GETAFFINITY: 819 case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
831 result = KAUTH_RESULT_ALLOW; 820 result = KAUTH_RESULT_ALLOW;
832 821
833 break; 822 break;
834 823
835 case KAUTH_PROCESS_SCHEDULER_SETAFFINITY: 824 case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
836 if (isroot) 825 if (isroot)
837 result = KAUTH_RESULT_ALLOW; 826 result = KAUTH_RESULT_ALLOW;
838 827
839 break; 828 break;
840 829
841 case KAUTH_PROCESS_SETID: 830 case KAUTH_PROCESS_SETID:
842 if (isroot) 831 if (isroot)
843 result = KAUTH_RESULT_ALLOW; 832 result = KAUTH_RESULT_ALLOW;
844 break; 833 break;
845 834
846 case KAUTH_PROCESS_STOPFLAG: 835 case KAUTH_PROCESS_STOPFLAG:
847 if (isroot || proc_uidmatch(cred, p->p_cred) == 0) { 836 if (isroot || proc_uidmatch(cred, p->p_cred) == 0) {
848 result = KAUTH_RESULT_ALLOW; 837 result = KAUTH_RESULT_ALLOW;
849 break; 838 break;
850 } 839 }
851 break; 840 break;
852 841
853 default: 842 default:
854 result = KAUTH_RESULT_DEFER; 843 result = KAUTH_RESULT_DEFER;
855 break; 844 break;
856 } 845 }
857 846
858 return (result); 847 return (result);
859} 848}
860 849
861/* 850/*
862 * kauth(9) listener 851 * kauth(9) listener
863 * 852 *
864 * Security model: Traditional NetBSD 853 * Security model: Traditional NetBSD
865 * Scope: Network 854 * Scope: Network
866 * Responsibility: Superuser access 855 * Responsibility: Superuser access
867 */ 856 */
868int 857int
869secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action, 858secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
870 void *cookie, void *arg0, void *arg1, void *arg2, 859 void *cookie, void *arg0, void *arg1, void *arg2,
871 void *arg3) 860 void *arg3)
872{ 861{
873 bool isroot; 862 bool isroot;
874 int result; 863 int result;
875 enum kauth_network_req req; 864 enum kauth_network_req req;
876 865
877 isroot = (kauth_cred_geteuid(cred) == 0); 866 isroot = (kauth_cred_geteuid(cred) == 0);
878 result = KAUTH_RESULT_DEFER; 867 result = KAUTH_RESULT_DEFER;
879 req = (enum kauth_network_req)arg0; 868 req = (enum kauth_network_req)arg0;
880 869
881 switch (action) { 870 switch (action) {
882 case KAUTH_NETWORK_ALTQ: 871 case KAUTH_NETWORK_ALTQ:
883 switch (req) { 872 switch (req) {
884 case KAUTH_REQ_NETWORK_ALTQ_AFMAP: 873 case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
885 case KAUTH_REQ_NETWORK_ALTQ_BLUE: 874 case KAUTH_REQ_NETWORK_ALTQ_BLUE:
886 case KAUTH_REQ_NETWORK_ALTQ_CBQ: 875 case KAUTH_REQ_NETWORK_ALTQ_CBQ:
887 case KAUTH_REQ_NETWORK_ALTQ_CDNR: 876 case KAUTH_REQ_NETWORK_ALTQ_CDNR:
888 case KAUTH_REQ_NETWORK_ALTQ_CONF: 877 case KAUTH_REQ_NETWORK_ALTQ_CONF:
889 case KAUTH_REQ_NETWORK_ALTQ_FIFOQ: 878 case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
890 case KAUTH_REQ_NETWORK_ALTQ_HFSC: 879 case KAUTH_REQ_NETWORK_ALTQ_HFSC:
891 case KAUTH_REQ_NETWORK_ALTQ_JOBS: 880 case KAUTH_REQ_NETWORK_ALTQ_JOBS:
892 case KAUTH_REQ_NETWORK_ALTQ_PRIQ: 881 case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
893 case KAUTH_REQ_NETWORK_ALTQ_RED: 882 case KAUTH_REQ_NETWORK_ALTQ_RED:
894 case KAUTH_REQ_NETWORK_ALTQ_RIO: 883 case KAUTH_REQ_NETWORK_ALTQ_RIO:
895 case KAUTH_REQ_NETWORK_ALTQ_WFQ: 884 case KAUTH_REQ_NETWORK_ALTQ_WFQ:
896 if (isroot) 885 if (isroot)
897 result = KAUTH_RESULT_ALLOW; 886 result = KAUTH_RESULT_ALLOW;
898 break; 887 break;
899 888
900 default: 889 default:
901 result = KAUTH_RESULT_DEFER; 890 result = KAUTH_RESULT_DEFER;
902 break; 891 break;
903 } 892 }
904 893
905 break; 894 break;
906 895
907 case KAUTH_NETWORK_BIND: 896 case KAUTH_NETWORK_BIND:
908 switch (req) { 897 switch (req) {
909 case KAUTH_REQ_NETWORK_BIND_PORT: 898 case KAUTH_REQ_NETWORK_BIND_PORT:
910 result = KAUTH_RESULT_ALLOW; 899 result = KAUTH_RESULT_ALLOW;
911 break; 900 break;
912 901
913 case KAUTH_REQ_NETWORK_BIND_PRIVPORT: 902 case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
914 if (isroot) 903 if (isroot)
915 result = KAUTH_RESULT_ALLOW; 904 result = KAUTH_RESULT_ALLOW;
916 break; 905 break;
917 906
918 default: 907 default:
919 break; 908 break;
920 } 909 }
921 break; 910 break;
922 911
923 case KAUTH_NETWORK_FIREWALL: 912 case KAUTH_NETWORK_FIREWALL:
924 switch (req) { 913 switch (req) {
925 case KAUTH_REQ_NETWORK_FIREWALL_FW: 914 case KAUTH_REQ_NETWORK_FIREWALL_FW:
926 case KAUTH_REQ_NETWORK_FIREWALL_NAT: 915 case KAUTH_REQ_NETWORK_FIREWALL_NAT:
927 /* 916 /*
928 * Decisions are root-agnostic. 917 * Decisions are root-agnostic.
929 * 918 *
930 * Both requests are issued from the context of a 919 * Both requests are issued from the context of a
931 * device with permission bits acting as access 920 * device with permission bits acting as access
932 * control. 921 * control.
933 */ 922 */
934 result = KAUTH_RESULT_ALLOW; 923 result = KAUTH_RESULT_ALLOW;
935 break; 924 break;
936 925
937 default: 926 default:
938 break; 927 break;
939 } 928 }
940 break; 929 break;
941 930
942 case KAUTH_NETWORK_FORWSRCRT: 931 case KAUTH_NETWORK_FORWSRCRT:
943 if (isroot) 932 if (isroot)
944 result = KAUTH_RESULT_ALLOW; 933 result = KAUTH_RESULT_ALLOW;
945 934
946 break; 935 break;
947 936
948 case KAUTH_NETWORK_INTERFACE: 937 case KAUTH_NETWORK_INTERFACE:
949 switch (req) { 938 switch (req) {
950 case KAUTH_REQ_NETWORK_INTERFACE_GET: 939 case KAUTH_REQ_NETWORK_INTERFACE_GET:
951 case KAUTH_REQ_NETWORK_INTERFACE_SET: 940 case KAUTH_REQ_NETWORK_INTERFACE_SET:
952 result = KAUTH_RESULT_ALLOW; 941 result = KAUTH_RESULT_ALLOW;
953 break; 942 break;
954 943
955 case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV: 944 case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
956 case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV: 945 case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
957 if (isroot) 946 if (isroot)
958 result = KAUTH_RESULT_ALLOW; 947 result = KAUTH_RESULT_ALLOW;
959 break; 948 break;
960 949
961 default: 950 default:
962 result = KAUTH_RESULT_DEFER; 951 result = KAUTH_RESULT_DEFER;
963 break; 952 break;
964 } 953 }
965 break; 954 break;
966 955
967 case KAUTH_NETWORK_INTERFACE_PPP: 956 case KAUTH_NETWORK_INTERFACE_PPP:
968 switch (req) { 957 switch (req) {
969 case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD: 958 case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
970 if (isroot) 959 if (isroot)
971 result = KAUTH_RESULT_ALLOW; 960 result = KAUTH_RESULT_ALLOW;
972 break; 961 break;
973 962
974 default: 963 default:
975 break; 964 break;
976 } 965 }
977 966
978 break; 967 break;
979 968
980 case KAUTH_NETWORK_INTERFACE_SLIP: 969 case KAUTH_NETWORK_INTERFACE_SLIP:
981 switch (req) { 970 switch (req) {
982 case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD: 971 case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
983 if (isroot) 972 if (isroot)
984 result = KAUTH_RESULT_ALLOW; 973 result = KAUTH_RESULT_ALLOW;
985 break; 974 break;
986 975
987 default: 976 default:
988 break; 977 break;
989 } 978 }
990 979
991 break; 980 break;
992 981
993 case KAUTH_NETWORK_INTERFACE_STRIP: 982 case KAUTH_NETWORK_INTERFACE_STRIP:
994 switch (req) { 983 switch (req) {
995 case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD: 984 case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
996 if (isroot) 985 if (isroot)
997 result = KAUTH_RESULT_ALLOW; 986 result = KAUTH_RESULT_ALLOW;
998 break; 987 break;
999 988
1000 default: 989 default:
1001 break; 990 break;
1002 } 991 }
1003 992
1004 break; 993 break;
1005 994
1006 case KAUTH_NETWORK_INTERFACE_TUN: 995 case KAUTH_NETWORK_INTERFACE_TUN:
1007 switch (req) { 996 switch (req) {
1008 case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD: 997 case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
1009 if (isroot) 998 if (isroot)
1010 result = KAUTH_RESULT_ALLOW; 999 result = KAUTH_RESULT_ALLOW;
1011 break; 1000 break;
1012 1001
1013 default: 1002 default:
1014 break; 1003 break;
1015 } 1004 }
1016 1005
1017 break; 1006 break;
1018 1007
1019 case KAUTH_NETWORK_NFS: 1008 case KAUTH_NETWORK_NFS:
1020 switch (req) { 1009 switch (req) {
1021 case KAUTH_REQ_NETWORK_NFS_EXPORT: 1010 case KAUTH_REQ_NETWORK_NFS_EXPORT:
1022 case KAUTH_REQ_NETWORK_NFS_SVC: 1011 case KAUTH_REQ_NETWORK_NFS_SVC:
1023 if (isroot) 1012 if (isroot)
1024 result = KAUTH_RESULT_ALLOW; 1013 result = KAUTH_RESULT_ALLOW;
1025 1014
1026 break; 1015 break;
1027 1016
1028 default: 1017 default:
1029 result = KAUTH_RESULT_DEFER; 1018 result = KAUTH_RESULT_DEFER;
1030 break; 1019 break;
1031 } 1020 }
1032 break; 1021 break;
1033 1022
1034 case KAUTH_NETWORK_ROUTE: 1023 case KAUTH_NETWORK_ROUTE:
1035 switch (((struct rt_msghdr *)arg1)->rtm_type) { 1024 switch (((struct rt_msghdr *)arg1)->rtm_type) {
1036 case RTM_GET: 1025 case RTM_GET:
1037 result = KAUTH_RESULT_ALLOW; 1026 result = KAUTH_RESULT_ALLOW;
1038 break; 1027 break;
1039 1028
1040 default: 1029 default:
1041 if (isroot) 1030 if (isroot)
1042 result = KAUTH_RESULT_ALLOW; 1031 result = KAUTH_RESULT_ALLOW;
1043 break; 1032 break;
1044 } 1033 }
1045 break; 1034 break;
1046 1035
1047 case KAUTH_NETWORK_SOCKET: 1036 case KAUTH_NETWORK_SOCKET:
1048 switch (req) { 1037 switch (req) {
1049 case KAUTH_REQ_NETWORK_SOCKET_DROP: 1038 case KAUTH_REQ_NETWORK_SOCKET_DROP:
1050 /* 1039 /*
1051 * The superuser can drop any connection. Normal users 1040 * The superuser can drop any connection. Normal users
1052 * can only drop their own connections. 1041 * can only drop their own connections.
1053 */ 1042 */
1054 if (isroot) 1043 if (isroot)
1055 result = KAUTH_RESULT_ALLOW; 1044 result = KAUTH_RESULT_ALLOW;
1056 else { 1045 else {
1057 struct socket *so = (struct socket *)arg1; 1046 struct socket *so = (struct socket *)arg1;
1058 uid_t sockuid = so->so_uidinfo->ui_uid; 1047 uid_t sockuid = so->so_uidinfo->ui_uid;
1059 1048
1060 if (sockuid == kauth_cred_getuid(cred) || 1049 if (sockuid == kauth_cred_getuid(cred) ||
1061 sockuid == kauth_cred_geteuid(cred)) 1050 sockuid == kauth_cred_geteuid(cred))
1062 result = KAUTH_RESULT_ALLOW; 1051 result = KAUTH_RESULT_ALLOW;
1063 } 1052 }
1064 1053
1065  1054
1066 break; 1055 break;
1067 1056
1068 case KAUTH_REQ_NETWORK_SOCKET_OPEN: 1057 case KAUTH_REQ_NETWORK_SOCKET_OPEN:
1069 if ((u_long)arg1 == PF_ROUTE || (u_long)arg1 == PF_BLUETOOTH) 1058 if ((u_long)arg1 == PF_ROUTE || (u_long)arg1 == PF_BLUETOOTH)
1070 result = KAUTH_RESULT_ALLOW; 1059 result = KAUTH_RESULT_ALLOW;
1071 else if ((u_long)arg2 == SOCK_RAW) { 1060 else if ((u_long)arg2 == SOCK_RAW) {
1072 if (isroot) 1061 if (isroot)
1073 result = KAUTH_RESULT_ALLOW; 1062 result = KAUTH_RESULT_ALLOW;
1074 } else 1063 } else
1075 result = KAUTH_RESULT_ALLOW; 1064 result = KAUTH_RESULT_ALLOW;
1076 break; 1065 break;
1077 1066
1078 case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK: 1067 case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
1079 if (isroot) 1068 if (isroot)
1080 result = KAUTH_RESULT_ALLOW; 1069 result = KAUTH_RESULT_ALLOW;
1081 break; 1070 break;
1082 1071
1083 case KAUTH_REQ_NETWORK_SOCKET_CANSEE: 1072 case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
1084 if (secmodel_bsd44_curtain) { 1073 if (secmodel_bsd44_curtain) {
1085 uid_t so_uid; 1074 uid_t so_uid;
1086 1075
1087 so_uid = 1076 so_uid =
1088 ((struct socket *)arg1)->so_uidinfo->ui_uid; 1077 ((struct socket *)arg1)->so_uidinfo->ui_uid;
1089 if (isroot || 1078 if (isroot ||
1090 kauth_cred_geteuid(cred) == so_uid) 1079 kauth_cred_geteuid(cred) == so_uid)
1091 result = KAUTH_RESULT_ALLOW; 1080 result = KAUTH_RESULT_ALLOW;
1092 } else 1081 } else
1093 result = KAUTH_RESULT_ALLOW; 1082 result = KAUTH_RESULT_ALLOW;
1094 break; 1083 break;
1095 1084
1096 case KAUTH_REQ_NETWORK_SOCKET_SETPRIV: 1085 case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
1097 if (isroot) 1086 if (isroot)
1098 result = KAUTH_RESULT_ALLOW; 1087 result = KAUTH_RESULT_ALLOW;
1099 break; 1088 break;
1100 1089
1101 default: 1090 default:
1102 break; 1091 break;
1103 } 1092 }
1104 1093
1105 break; 1094 break;
1106 1095
1107 1096
1108 default: 1097 default:
1109 result = KAUTH_RESULT_DEFER; 1098 result = KAUTH_RESULT_DEFER;
1110 break; 1099 break;
1111 } 1100 }
1112 1101
1113 return (result); 1102 return (result);
1114} 1103}
1115 1104
1116/* 1105/*
1117 * kauth(9) listener 1106 * kauth(9) listener
1118 * 1107 *
1119 * Security model: Traditional NetBSD 1108 * Security model: Traditional NetBSD
1120 * Scope: Machdep 1109 * Scope: Machdep
1121 * Responsibility: Superuser access 1110 * Responsibility: Superuser access
1122 */ 1111 */
1123int 1112int
1124secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action, 1113secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
1125 void *cookie, void *arg0, void *arg1, void *arg2, 1114 void *cookie, void *arg0, void *arg1, void *arg2,
1126 void *arg3) 1115 void *arg3)
1127{ 1116{
1128 bool isroot; 1117 bool isroot;
1129 int result; 1118 int result;
1130 1119
1131 isroot = (kauth_cred_geteuid(cred) == 0); 1120 isroot = (kauth_cred_geteuid(cred) == 0);
1132 result = KAUTH_RESULT_DEFER; 1121 result = KAUTH_RESULT_DEFER;
1133 1122
1134 switch (action) { 1123 switch (action) {
1135 case KAUTH_MACHDEP_IOPERM_GET: 1124 case KAUTH_MACHDEP_IOPERM_GET:
1136 case KAUTH_MACHDEP_LDT_GET: 1125 case KAUTH_MACHDEP_LDT_GET:
1137 case KAUTH_MACHDEP_LDT_SET: 1126 case KAUTH_MACHDEP_LDT_SET:
1138 case KAUTH_MACHDEP_MTRR_GET: 1127 case KAUTH_MACHDEP_MTRR_GET:
1139 result = KAUTH_RESULT_ALLOW; 1128 result = KAUTH_RESULT_ALLOW;
1140 break; 1129 break;
1141 1130
1142 case KAUTH_MACHDEP_CACHEFLUSH: 1131 case KAUTH_MACHDEP_CACHEFLUSH:
1143 case KAUTH_MACHDEP_IOPERM_SET: 1132 case KAUTH_MACHDEP_IOPERM_SET:
1144 case KAUTH_MACHDEP_IOPL: 1133 case KAUTH_MACHDEP_IOPL:
1145 case KAUTH_MACHDEP_MTRR_SET: 1134 case KAUTH_MACHDEP_MTRR_SET:
1146 case KAUTH_MACHDEP_NVRAM: 1135 case KAUTH_MACHDEP_NVRAM:
1147 case KAUTH_MACHDEP_UNMANAGEDMEM: 1136 case KAUTH_MACHDEP_UNMANAGEDMEM:
1148 if (isroot) 1137 if (isroot)
1149 result = KAUTH_RESULT_ALLOW; 1138 result = KAUTH_RESULT_ALLOW;
1150 break; 1139 break;
1151 1140
1152 default: 1141 default:
1153 result = KAUTH_RESULT_DEFER; 1142 result = KAUTH_RESULT_DEFER;
1154 break; 1143 break;
1155 } 1144 }
1156 1145
1157 return (result); 1146 return (result);
1158} 1147}
1159 1148
1160/* 1149/*
1161 * kauth(9) listener 1150 * kauth(9) listener
1162 * 1151 *
1163 * Security model: Traditional NetBSD 1152 * Security model: Traditional NetBSD
1164 * Scope: Device 1153 * Scope: Device
1165 * Responsibility: Superuser access 1154 * Responsibility: Superuser access
1166 */ 1155 */
1167int 1156int
1168secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action, 1157secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
1169 void *cookie, void *arg0, void *arg1, void *arg2, 1158 void *cookie, void *arg0, void *arg1, void *arg2,
1170 void *arg3) 1159 void *arg3)
1171{ 1160{
1172 struct tty *tty; 1161 struct tty *tty;
1173 bool isroot; 1162 bool isroot;
1174 int result; 1163 int result;
1175 1164
1176 isroot = (kauth_cred_geteuid(cred) == 0); 1165 isroot = (kauth_cred_geteuid(cred) == 0);
1177 result = KAUTH_RESULT_DEFER; 1166 result = KAUTH_RESULT_DEFER;
1178 1167
1179 switch (action) { 1168 switch (action) {
1180 case KAUTH_DEVICE_BLUETOOTH_SETPRIV: 1169 case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
1181 case KAUTH_DEVICE_BLUETOOTH_SEND: 1170 case KAUTH_DEVICE_BLUETOOTH_SEND:
1182 case KAUTH_DEVICE_BLUETOOTH_RECV: 1171 case KAUTH_DEVICE_BLUETOOTH_RECV:
1183 if (isroot) 1172 if (isroot)
1184 result = KAUTH_RESULT_ALLOW; 1173 result = KAUTH_RESULT_ALLOW;
1185 break; 1174 break;
1186 1175
1187 case KAUTH_DEVICE_BLUETOOTH_BCSP: 1176 case KAUTH_DEVICE_BLUETOOTH_BCSP:
1188 case KAUTH_DEVICE_BLUETOOTH_BTUART: { 1177 case KAUTH_DEVICE_BLUETOOTH_BTUART: {
1189 enum kauth_device_req req; 1178 enum kauth_device_req req;
1190 1179
1191 req = (enum kauth_device_req)arg0; 1180 req = (enum kauth_device_req)arg0;
1192 switch (req) { 1181 switch (req) {
1193 case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD: 1182 case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
1194 case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD: 1183 case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
1195 if (isroot) 1184 if (isroot)
1196 result = KAUTH_RESULT_ALLOW; 1185 result = KAUTH_RESULT_ALLOW;
1197 break; 1186 break;
1198 1187
1199 default: 1188 default:
1200 break; 1189 break;
1201 } 1190 }
1202 1191
1203 break; 1192 break;
1204 } 1193 }
1205 1194
1206 case KAUTH_DEVICE_RAWIO_SPEC: 1195 case KAUTH_DEVICE_RAWIO_SPEC:
1207 case KAUTH_DEVICE_RAWIO_PASSTHRU: 1196 case KAUTH_DEVICE_RAWIO_PASSTHRU:
1208 /* 1197 /*
1209 * Decision is root-agnostic. 1198 * Decision is root-agnostic.
1210 * 1199 *
1211 * Both requests can be issued on devices subject to their 1200 * Both requests can be issued on devices subject to their
1212 * permission bits. 1201 * permission bits.
1213 */ 1202 */
1214 result = KAUTH_RESULT_ALLOW; 1203 result = KAUTH_RESULT_ALLOW;
1215 break; 1204 break;
1216 1205
1217 case KAUTH_DEVICE_TTY_OPEN: 1206 case KAUTH_DEVICE_TTY_OPEN:
1218 tty = arg0; 1207 tty = arg0;
1219 1208
1220 if (!(tty->t_state & TS_ISOPEN)) 1209 if (!(tty->t_state & TS_ISOPEN))
1221 result = KAUTH_RESULT_ALLOW; 1210 result = KAUTH_RESULT_ALLOW;
1222 else if (tty->t_state & TS_XCLUDE) { 1211 else if (tty->t_state & TS_XCLUDE) {
1223 if (isroot) 1212 if (isroot)
1224 result = KAUTH_RESULT_ALLOW; 1213 result = KAUTH_RESULT_ALLOW;
1225 } else 1214 } else
1226 result = KAUTH_RESULT_ALLOW; 1215 result = KAUTH_RESULT_ALLOW;
1227 1216
1228 break; 1217 break;
1229 1218
1230 case KAUTH_DEVICE_TTY_PRIVSET: 1219 case KAUTH_DEVICE_TTY_PRIVSET:
1231 if (isroot) 1220 if (isroot)
1232 result = KAUTH_RESULT_ALLOW; 1221 result = KAUTH_RESULT_ALLOW;
1233 1222
1234 break; 1223 break;
1235 1224
1236 case KAUTH_DEVICE_TTY_STI: 1225 case KAUTH_DEVICE_TTY_STI:
1237 if (isroot) 1226 if (isroot)
1238 result = KAUTH_RESULT_ALLOW; 1227 result = KAUTH_RESULT_ALLOW;
1239 1228
1240 break; 1229 break;
1241 1230
1242 case KAUTH_DEVICE_RND_ADDDATA: 1231 case KAUTH_DEVICE_RND_ADDDATA:
1243 case KAUTH_DEVICE_RND_GETPRIV: 1232 case KAUTH_DEVICE_RND_GETPRIV:
1244 case KAUTH_DEVICE_RND_SETPRIV: 1233 case KAUTH_DEVICE_RND_SETPRIV:
1245 if (isroot) 1234 if (isroot)
1246 result = KAUTH_RESULT_ALLOW; 1235 result = KAUTH_RESULT_ALLOW;
1247 break; 1236 break;
1248 1237
1249 case KAUTH_DEVICE_GPIO_PINSET: 1238 case KAUTH_DEVICE_GPIO_PINSET:
1250 /* 1239 /*
1251 * root can access gpio pins, secmodel_securlevel can veto 1240 * root can access gpio pins, secmodel_securlevel can veto
1252 * this decision. 1241 * this decision.
1253 */ 1242 */
1254 if (isroot) 1243 if (isroot)
1255 result = KAUTH_RESULT_ALLOW; 1244 result = KAUTH_RESULT_ALLOW;
1256 break; 1245 break;
1257 1246
1258 default: 1247 default:
1259 result = KAUTH_RESULT_DEFER; 1248 result = KAUTH_RESULT_DEFER;
1260 break; 1249 break;
1261 } 1250 }
1262 1251
1263 return (result); 1252 return (result);
1264} 1253}
1265 1254
1266int 1255int
1267secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action, 1256secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
1268 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 1257 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
1269{ 1258{
1270 bool isroot; 1259 bool isroot;
1271 int result; 1260 int result;
1272 1261
1273 isroot = (kauth_cred_geteuid(cred) == 0); 1262 isroot = (kauth_cred_geteuid(cred) == 0);
1274 result = KAUTH_RESULT_DEFER; 1263 result = KAUTH_RESULT_DEFER;
1275 1264
1276 if (isroot) 1265 if (isroot)
1277 result = KAUTH_RESULT_ALLOW; 1266 result = KAUTH_RESULT_ALLOW;
1278 1267
1279 return (result); 1268 return (result);
1280} 1269}
1281 1270