[DHCP]
[reactos.git] / reactos / base / services / dhcp / privsep.c
1 /* $OpenBSD: privsep.c,v 1.7 2004/05/10 18:34:42 deraadt Exp $ */
2
3 /*
4 * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
15 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include "rosdhcp.h"
20 #include "dhcpd.h"
21 #include "privsep.h"
22
23 struct buf *
24 buf_open(size_t len)
25 {
26 struct buf *buf;
27
28 if ((buf = calloc(1, sizeof(struct buf))) == NULL)
29 return (NULL);
30 if ((buf->buf = malloc(len)) == NULL) {
31 free(buf);
32 return (NULL);
33 }
34 buf->size = len;
35
36 return (buf);
37 }
38
39 int
40 buf_add(struct buf *buf, void *data, size_t len)
41 {
42 if (buf->wpos + len > buf->size)
43 return (-1);
44
45 memcpy(buf->buf + buf->wpos, data, len);
46 buf->wpos += len;
47 return (0);
48 }
49
50 int
51 buf_close(int sock, struct buf *buf)
52 {
53 ssize_t n;
54
55 n = write(sock, buf->buf + buf->rpos, buf->size - buf->rpos);
56 if (n != -1)
57 buf->rpos += n;
58 if (n == 0) { /* connection closed */
59 return (-1);
60 }
61
62 if (buf->rpos < buf->size)
63 error("short write: wanted %lu got %ld bytes",
64 (unsigned long)buf->size, (long)buf->rpos);
65
66 free(buf->buf);
67 free(buf);
68 return (n);
69 }
70
71 ssize_t
72 buf_read(int sock, void *buf, size_t nbytes)
73 {
74 ssize_t n, r = 0;
75 char *p = buf;
76
77 n = read(sock, p, nbytes);
78 if (n == 0)
79 error("connection closed");
80 if (n != -1) {
81 r += n;
82 p += n;
83 nbytes -= n;
84 }
85
86 if (n == -1)
87 error("buf_read: %d", WSAGetLastError());
88
89 if (r < nbytes)
90 error("short read: wanted %lu got %ld bytes",
91 (unsigned long)nbytes, (long)r);
92
93 return (r);
94 }
95
96 void
97 dispatch_imsg(int fd)
98 {
99 struct imsg_hdr hdr;
100 char *medium, *reason, *filename,
101 *servername, *prefix;
102 size_t medium_len, reason_len, filename_len,
103 servername_len, prefix_len, totlen;
104 struct client_lease lease;
105 int ret, i, optlen;
106 struct buf *buf;
107
108 buf_read(fd, &hdr, sizeof(hdr));
109
110 switch (hdr.code) {
111 case IMSG_SCRIPT_INIT:
112 if (hdr.len < sizeof(hdr) + sizeof(size_t))
113 error("corrupted message received");
114 buf_read(fd, &medium_len, sizeof(medium_len));
115 if (hdr.len < medium_len + sizeof(size_t) + sizeof(hdr)
116 + sizeof(size_t) || medium_len == SIZE_T_MAX)
117 error("corrupted message received");
118 if (medium_len > 0) {
119 if ((medium = calloc(1, medium_len + 1)) != NULL)
120 buf_read(fd, medium, medium_len);
121 } else
122 medium = NULL;
123
124 buf_read(fd, &reason_len, sizeof(reason_len));
125 if (hdr.len < medium_len + reason_len + sizeof(hdr) ||
126 reason_len == SIZE_T_MAX)
127 error("corrupted message received");
128 if (reason_len > 0) {
129 if ((reason = calloc(1, reason_len + 1)) != NULL)
130 buf_read(fd, reason, reason_len);
131 } else
132 reason = NULL;
133
134 // priv_script_init(reason, medium);
135 free(reason);
136 free(medium);
137 break;
138 case IMSG_SCRIPT_WRITE_PARAMS:
139 //bzero(&lease, sizeof lease);
140 memset(&lease, 0, sizeof(lease));
141 totlen = sizeof(hdr) + sizeof(lease) + sizeof(size_t);
142 if (hdr.len < totlen)
143 error("corrupted message received");
144 buf_read(fd, &lease, sizeof(lease));
145
146 buf_read(fd, &filename_len, sizeof(filename_len));
147 totlen += filename_len + sizeof(size_t);
148 if (hdr.len < totlen || filename_len == SIZE_T_MAX)
149 error("corrupted message received");
150 if (filename_len > 0) {
151 if ((filename = calloc(1, filename_len + 1)) != NULL)
152 buf_read(fd, filename, filename_len);
153 } else
154 filename = NULL;
155
156 buf_read(fd, &servername_len, sizeof(servername_len));
157 totlen += servername_len + sizeof(size_t);
158 if (hdr.len < totlen || servername_len == SIZE_T_MAX)
159 error("corrupted message received");
160 if (servername_len > 0) {
161 if ((servername =
162 calloc(1, servername_len + 1)) != NULL)
163 buf_read(fd, servername, servername_len);
164 } else
165 servername = NULL;
166
167 buf_read(fd, &prefix_len, sizeof(prefix_len));
168 totlen += prefix_len;
169 if (hdr.len < totlen || prefix_len == SIZE_T_MAX)
170 error("corrupted message received");
171 if (prefix_len > 0) {
172 if ((prefix = calloc(1, prefix_len + 1)) != NULL)
173 buf_read(fd, prefix, prefix_len);
174 } else
175 prefix = NULL;
176
177 for (i = 0; i < 256; i++) {
178 totlen += sizeof(optlen);
179 if (hdr.len < totlen)
180 error("corrupted message received");
181 buf_read(fd, &optlen, sizeof(optlen));
182 lease.options[i].data = NULL;
183 lease.options[i].len = optlen;
184 if (optlen > 0) {
185 totlen += optlen;
186 if (hdr.len < totlen || optlen == SIZE_T_MAX)
187 error("corrupted message received");
188 lease.options[i].data =
189 calloc(1, optlen + 1);
190 if (lease.options[i].data != NULL)
191 buf_read(fd, lease.options[i].data, optlen);
192 }
193 }
194 lease.server_name = servername;
195 lease.filename = filename;
196
197 // priv_script_write_params(prefix, &lease);
198
199 free(servername);
200 free(filename);
201 free(prefix);
202 for (i = 0; i < 256; i++)
203 if (lease.options[i].len > 0)
204 free(lease.options[i].data);
205 break;
206 case IMSG_SCRIPT_GO:
207 if (hdr.len != sizeof(hdr))
208 error("corrupted message received");
209
210 // ret = priv_script_go();
211
212 hdr.code = IMSG_SCRIPT_GO_RET;
213 hdr.len = sizeof(struct imsg_hdr) + sizeof(int);
214 buf = buf_open(hdr.len);
215
216 if (buf != NULL) {
217 buf_add(buf, &hdr, sizeof(hdr));
218 buf_add(buf, &ret, sizeof(ret));
219 buf_close(fd, buf);
220 }
221 break;
222 default:
223 error("received unknown message, code %d", hdr.code);
224 }
225 }