1 /* $OpenBSD: privsep.c,v 1.7 2004/05/10 18:34:42 deraadt Exp $ */
4 * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
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.
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.
19 #include <sys/cdefs.h>
20 __FBSDID("$FreeBSD$");
30 if ((buf
= calloc(1, sizeof(struct buf
))) == NULL
)
32 if ((buf
->buf
= malloc(len
)) == NULL
) {
42 buf_add(struct buf
*buf
, void *data
, size_t len
)
44 if (buf
->wpos
+ len
> buf
->size
)
47 memcpy(buf
->buf
+ buf
->wpos
, data
, len
);
53 buf_close(int sock
, struct buf
*buf
)
58 n
= write(sock
, buf
->buf
+ buf
->rpos
, buf
->size
- buf
->rpos
);
61 if (n
== 0) { /* connection closed */
65 } while (n
== -1 && (errno
== EAGAIN
|| errno
== EINTR
));
67 if (buf
->rpos
< buf
->size
)
68 error("short write: wanted %lu got %ld bytes",
69 (unsigned long)buf
->size
, (long)buf
->rpos
);
77 buf_read(int sock
, void *buf
, size_t nbytes
)
83 n
= read(sock
, p
, nbytes
);
85 error("connection closed");
91 } while (n
== -1 && (errno
== EINTR
|| errno
== EAGAIN
));
94 error("buf_read: %m");
97 error("short read: wanted %lu got %ld bytes",
98 (unsigned long)nbytes
, (long)r
);
104 dispatch_imsg(struct interface_info
*ifi
, int fd
)
107 char *medium
, *reason
, *filename
,
108 *servername
, *prefix
;
109 size_t medium_len
, reason_len
, filename_len
,
110 servername_len
, prefix_len
, totlen
;
111 struct client_lease lease
;
115 buf_read(fd
, &hdr
, sizeof(hdr
));
118 case IMSG_SCRIPT_INIT
:
119 if (hdr
.len
< sizeof(hdr
) + sizeof(size_t))
120 error("corrupted message received");
121 buf_read(fd
, &medium_len
, sizeof(medium_len
));
122 if (hdr
.len
< medium_len
+ sizeof(size_t) + sizeof(hdr
)
123 + sizeof(size_t) || medium_len
== SIZE_T_MAX
)
124 error("corrupted message received");
125 if (medium_len
> 0) {
126 if ((medium
= calloc(1, medium_len
+ 1)) == NULL
)
128 buf_read(fd
, medium
, medium_len
);
132 buf_read(fd
, &reason_len
, sizeof(reason_len
));
133 if (hdr
.len
< medium_len
+ reason_len
+ sizeof(hdr
) ||
134 reason_len
== SIZE_T_MAX
)
135 error("corrupted message received");
136 if (reason_len
> 0) {
137 if ((reason
= calloc(1, reason_len
+ 1)) == NULL
)
139 buf_read(fd
, reason
, reason_len
);
143 priv_script_init(reason
, medium
);
147 case IMSG_SCRIPT_WRITE_PARAMS
:
148 bzero(&lease
, sizeof lease
);
149 totlen
= sizeof(hdr
) + sizeof(lease
) + sizeof(size_t);
150 if (hdr
.len
< totlen
)
151 error("corrupted message received");
152 buf_read(fd
, &lease
, sizeof(lease
));
154 buf_read(fd
, &filename_len
, sizeof(filename_len
));
155 totlen
+= filename_len
+ sizeof(size_t);
156 if (hdr
.len
< totlen
|| filename_len
== SIZE_T_MAX
)
157 error("corrupted message received");
158 if (filename_len
> 0) {
159 if ((filename
= calloc(1, filename_len
+ 1)) == NULL
)
161 buf_read(fd
, filename
, filename_len
);
165 buf_read(fd
, &servername_len
, sizeof(servername_len
));
166 totlen
+= servername_len
+ sizeof(size_t);
167 if (hdr
.len
< totlen
|| servername_len
== SIZE_T_MAX
)
168 error("corrupted message received");
169 if (servername_len
> 0) {
171 calloc(1, servername_len
+ 1)) == NULL
)
173 buf_read(fd
, servername
, servername_len
);
177 buf_read(fd
, &prefix_len
, sizeof(prefix_len
));
178 totlen
+= prefix_len
;
179 if (hdr
.len
< totlen
|| prefix_len
== SIZE_T_MAX
)
180 error("corrupted message received");
181 if (prefix_len
> 0) {
182 if ((prefix
= calloc(1, prefix_len
+ 1)) == NULL
)
184 buf_read(fd
, prefix
, prefix_len
);
188 for (i
= 0; i
< 256; i
++) {
189 totlen
+= sizeof(optlen
);
190 if (hdr
.len
< totlen
)
191 error("corrupted message received");
192 buf_read(fd
, &optlen
, sizeof(optlen
));
193 lease
.options
[i
].data
= NULL
;
194 lease
.options
[i
].len
= optlen
;
197 if (hdr
.len
< totlen
|| optlen
== SIZE_T_MAX
)
198 error("corrupted message received");
199 lease
.options
[i
].data
=
200 calloc(1, optlen
+ 1);
201 if (lease
.options
[i
].data
== NULL
)
203 buf_read(fd
, lease
.options
[i
].data
, optlen
);
206 lease
.server_name
= servername
;
207 lease
.filename
= filename
;
209 priv_script_write_params(prefix
, &lease
);
214 for (i
= 0; i
< 256; i
++)
215 if (lease
.options
[i
].len
> 0)
216 free(lease
.options
[i
].data
);
219 if (hdr
.len
!= sizeof(hdr
))
220 error("corrupted message received");
222 ret
= priv_script_go();
224 hdr
.code
= IMSG_SCRIPT_GO_RET
;
225 hdr
.len
= sizeof(struct imsg_hdr
) + sizeof(int);
226 if ((buf
= buf_open(hdr
.len
)) == NULL
)
227 error("buf_open: %m");
228 if (buf_add(buf
, &hdr
, sizeof(hdr
)))
229 error("buf_add: %m");
230 if (buf_add(buf
, &ret
, sizeof(ret
)))
231 error("buf_add: %m");
232 if (buf_close(fd
, buf
) == -1)
233 error("buf_close: %m");
235 case IMSG_SEND_PACKET
:
236 send_packet_priv(ifi
, &hdr
, fd
);
239 error("received unknown message, code %d", hdr
.code
);