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.
28 if ((buf
= calloc(1, sizeof(struct buf
))) == NULL
)
30 if ((buf
->buf
= malloc(len
)) == NULL
) {
40 buf_add(struct buf
*buf
, void *data
, size_t len
)
42 if (buf
->wpos
+ len
> buf
->size
)
45 memcpy(buf
->buf
+ buf
->wpos
, data
, len
);
51 buf_close(int sock
, struct buf
*buf
)
56 n
= write(sock
, buf
->buf
+ buf
->rpos
, buf
->size
- buf
->rpos
);
59 if (n
== 0) { /* connection closed */
63 } while (n
== -1 && (errno
== EAGAIN
|| errno
== EINTR
));
65 if (buf
->rpos
< buf
->size
)
66 error("short write: wanted %lu got %ld bytes",
67 (unsigned long)buf
->size
, (long)buf
->rpos
);
75 buf_read(int sock
, void *buf
, size_t nbytes
)
81 n
= read(sock
, p
, nbytes
);
83 error("connection closed");
89 } while (n
== -1 && (errno
== EINTR
|| errno
== EAGAIN
));
92 error("buf_read: %m");
95 error("short read: wanted %lu got %ld bytes",
96 (unsigned long)nbytes
, (long)r
);
102 dispatch_imsg(int fd
)
105 char *medium
, *reason
, *filename
,
106 *servername
, *prefix
;
107 size_t medium_len
, reason_len
, filename_len
,
108 servername_len
, prefix_len
, totlen
;
109 struct client_lease lease
;
113 buf_read(fd
, &hdr
, sizeof(hdr
));
116 case IMSG_SCRIPT_INIT
:
117 if (hdr
.len
< sizeof(hdr
) + sizeof(size_t))
118 error("corrupted message received");
119 buf_read(fd
, &medium_len
, sizeof(medium_len
));
120 if (hdr
.len
< medium_len
+ sizeof(size_t) + sizeof(hdr
)
121 + sizeof(size_t) || medium_len
== SIZE_T_MAX
)
122 error("corrupted message received");
123 if (medium_len
> 0) {
124 if ((medium
= calloc(1, medium_len
+ 1)) == NULL
)
126 buf_read(fd
, medium
, medium_len
);
130 buf_read(fd
, &reason_len
, sizeof(reason_len
));
131 if (hdr
.len
< medium_len
+ reason_len
+ sizeof(hdr
) ||
132 reason_len
== SIZE_T_MAX
)
133 error("corrupted message received");
134 if (reason_len
> 0) {
135 if ((reason
= calloc(1, reason_len
+ 1)) == NULL
)
137 buf_read(fd
, reason
, reason_len
);
141 // priv_script_init(reason, medium);
145 case IMSG_SCRIPT_WRITE_PARAMS
:
146 //bzero(&lease, sizeof lease);
147 memset(&lease
, 0, sizeof(lease
));
148 totlen
= sizeof(hdr
) + sizeof(lease
) + sizeof(size_t);
149 if (hdr
.len
< totlen
)
150 error("corrupted message received");
151 buf_read(fd
, &lease
, sizeof(lease
));
153 buf_read(fd
, &filename_len
, sizeof(filename_len
));
154 totlen
+= filename_len
+ sizeof(size_t);
155 if (hdr
.len
< totlen
|| filename_len
== SIZE_T_MAX
)
156 error("corrupted message received");
157 if (filename_len
> 0) {
158 if ((filename
= calloc(1, filename_len
+ 1)) == NULL
)
160 buf_read(fd
, filename
, filename_len
);
164 buf_read(fd
, &servername_len
, sizeof(servername_len
));
165 totlen
+= servername_len
+ sizeof(size_t);
166 if (hdr
.len
< totlen
|| servername_len
== SIZE_T_MAX
)
167 error("corrupted message received");
168 if (servername_len
> 0) {
170 calloc(1, servername_len
+ 1)) == NULL
)
172 buf_read(fd
, servername
, servername_len
);
176 buf_read(fd
, &prefix_len
, sizeof(prefix_len
));
177 totlen
+= prefix_len
;
178 if (hdr
.len
< totlen
|| prefix_len
== SIZE_T_MAX
)
179 error("corrupted message received");
180 if (prefix_len
> 0) {
181 if ((prefix
= calloc(1, prefix_len
+ 1)) == NULL
)
183 buf_read(fd
, prefix
, prefix_len
);
187 for (i
= 0; i
< 256; i
++) {
188 totlen
+= sizeof(optlen
);
189 if (hdr
.len
< totlen
)
190 error("corrupted message received");
191 buf_read(fd
, &optlen
, sizeof(optlen
));
192 lease
.options
[i
].data
= NULL
;
193 lease
.options
[i
].len
= optlen
;
196 if (hdr
.len
< totlen
|| optlen
== SIZE_T_MAX
)
197 error("corrupted message received");
198 lease
.options
[i
].data
=
199 calloc(1, optlen
+ 1);
200 if (lease
.options
[i
].data
== NULL
)
202 buf_read(fd
, lease
.options
[i
].data
, optlen
);
205 lease
.server_name
= servername
;
206 lease
.filename
= filename
;
208 // priv_script_write_params(prefix, &lease);
213 for (i
= 0; i
< 256; i
++)
214 if (lease
.options
[i
].len
> 0)
215 free(lease
.options
[i
].data
);
218 if (hdr
.len
!= sizeof(hdr
))
219 error("corrupted message received");
221 // ret = priv_script_go();
223 hdr
.code
= IMSG_SCRIPT_GO_RET
;
224 hdr
.len
= sizeof(struct imsg_hdr
) + sizeof(int);
225 if ((buf
= buf_open(hdr
.len
)) == NULL
)
226 error("buf_open: %m");
227 if (buf_add(buf
, &hdr
, sizeof(hdr
)))
228 error("buf_add: %m");
229 if (buf_add(buf
, &ret
, sizeof(ret
)))
230 error("buf_add: %m");
231 if (buf_close(fd
, buf
) == -1)
232 error("buf_close: %m");
235 error("received unknown message, code %d", hdr
.code
);