Blame


1 7a554149 2024-02-18 op /*
2 7a554149 2024-02-18 op * This is free and unencumbered software released into the public domain.
3 7a554149 2024-02-18 op *
4 7a554149 2024-02-18 op * Anyone is free to copy, modify, publish, use, compile, sell, or
5 7a554149 2024-02-18 op * distribute this software, either in source code form or as a compiled
6 7a554149 2024-02-18 op * binary, for any purpose, commercial or non-commercial, and by any
7 7a554149 2024-02-18 op * means.
8 7a554149 2024-02-18 op *
9 7a554149 2024-02-18 op * In jurisdictions that recognize copyright laws, the author or authors
10 7a554149 2024-02-18 op * of this software dedicate any and all copyright interest in the
11 7a554149 2024-02-18 op * software to the public domain. We make this dedication for the benefit
12 7a554149 2024-02-18 op * of the public at large and to the detriment of our heirs and
13 7a554149 2024-02-18 op * successors. We intend this dedication to be an overt act of
14 7a554149 2024-02-18 op * relinquishment in perpetuity of all present and future rights to this
15 7a554149 2024-02-18 op * software under copyright law.
16 7a554149 2024-02-18 op *
17 7a554149 2024-02-18 op * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 7a554149 2024-02-18 op * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 7a554149 2024-02-18 op * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 7a554149 2024-02-18 op * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 7a554149 2024-02-18 op * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 7a554149 2024-02-18 op * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 7a554149 2024-02-18 op * OTHER DEALINGS IN THE SOFTWARE.
24 7a554149 2024-02-18 op */
25 7a554149 2024-02-18 op
26 7a554149 2024-02-18 op #include "compat.h"
27 7a554149 2024-02-18 op
28 7a554149 2024-02-18 op #include <assert.h>
29 7a554149 2024-02-18 op #include <errno.h>
30 7a554149 2024-02-18 op #include <stdarg.h>
31 7a554149 2024-02-18 op #include <stdint.h>
32 7a554149 2024-02-18 op #include <stdio.h>
33 7a554149 2024-02-18 op #include <stdlib.h>
34 7a554149 2024-02-18 op #include <string.h>
35 7a554149 2024-02-18 op #include <tls.h>
36 7a554149 2024-02-18 op #include <unistd.h>
37 7a554149 2024-02-18 op
38 7a554149 2024-02-18 op #include "bufio.h"
39 7a554149 2024-02-18 op
40 7a554149 2024-02-18 op int
41 7a554149 2024-02-18 op buf_init(struct buf *buf)
42 7a554149 2024-02-18 op {
43 7a554149 2024-02-18 op const size_t cap = BIO_CHUNK;
44 7a554149 2024-02-18 op
45 7a554149 2024-02-18 op memset(buf, 0, sizeof(*buf));
46 7a554149 2024-02-18 op if ((buf->buf = malloc(cap)) == NULL)
47 7a554149 2024-02-18 op return (-1);
48 7a554149 2024-02-18 op buf->cap = cap;
49 7a554149 2024-02-18 op return (0);
50 7a554149 2024-02-18 op }
51 7a554149 2024-02-18 op
52 7a554149 2024-02-18 op static int
53 7a554149 2024-02-18 op buf_grow(struct buf *buf)
54 7a554149 2024-02-18 op {
55 7a554149 2024-02-18 op size_t newcap;
56 7a554149 2024-02-18 op void *t;
57 7a554149 2024-02-18 op
58 7a554149 2024-02-18 op newcap = buf->cap + BIO_CHUNK;
59 7a554149 2024-02-18 op t = realloc(buf->buf, newcap);
60 7a554149 2024-02-18 op if (t == NULL)
61 7a554149 2024-02-18 op return (-1);
62 7a554149 2024-02-18 op buf->buf = t;
63 7a554149 2024-02-18 op buf->cap = newcap;
64 7a554149 2024-02-18 op return (0);
65 7a554149 2024-02-18 op }
66 7a554149 2024-02-18 op
67 7a554149 2024-02-18 op int
68 7a554149 2024-02-18 op buf_has_line(struct buf *buf, const char *nl)
69 7a554149 2024-02-18 op {
70 7a554149 2024-02-18 op return (memmem(buf->buf, buf->len, nl, strlen(nl)) != NULL);
71 7a554149 2024-02-18 op }
72 7a554149 2024-02-18 op
73 7a554149 2024-02-18 op void
74 7a554149 2024-02-18 op buf_drain(struct buf *buf, size_t l)
75 7a554149 2024-02-18 op {
76 7a554149 2024-02-18 op buf->cur = 0;
77 7a554149 2024-02-18 op
78 7a554149 2024-02-18 op if (l >= buf->len) {
79 7a554149 2024-02-18 op buf->len = 0;
80 7a554149 2024-02-18 op return;
81 7a554149 2024-02-18 op }
82 7a554149 2024-02-18 op
83 7a554149 2024-02-18 op memmove(buf->buf, buf->buf + l, buf->len - l);
84 7a554149 2024-02-18 op buf->len -= l;
85 7a554149 2024-02-18 op }
86 7a554149 2024-02-18 op
87 7a554149 2024-02-18 op void
88 7a554149 2024-02-18 op buf_drain_line(struct buf *buf, const char *nl)
89 7a554149 2024-02-18 op {
90 7a554149 2024-02-18 op uint8_t *endln;
91 7a554149 2024-02-18 op size_t nlen;
92 7a554149 2024-02-18 op
93 7a554149 2024-02-18 op nlen = strlen(nl);
94 7a554149 2024-02-18 op if ((endln = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
95 7a554149 2024-02-18 op return;
96 7a554149 2024-02-18 op buf_drain(buf, endln + nlen - buf->buf);
97 7a554149 2024-02-18 op }
98 7a554149 2024-02-18 op
99 7a554149 2024-02-18 op void
100 7a554149 2024-02-18 op buf_free(struct buf *buf)
101 7a554149 2024-02-18 op {
102 7a554149 2024-02-18 op free(buf->buf);
103 7a554149 2024-02-18 op memset(buf, 0, sizeof(*buf));
104 7a554149 2024-02-18 op }
105 7a554149 2024-02-18 op
106 7a554149 2024-02-18 op int
107 7a554149 2024-02-18 op bufio_init(struct bufio *bio)
108 7a554149 2024-02-18 op {
109 7a554149 2024-02-18 op memset(bio, 0, sizeof(*bio));
110 7a554149 2024-02-18 op bio->fd = -1;
111 7a554149 2024-02-18 op
112 7a554149 2024-02-18 op if (buf_init(&bio->wbuf) == -1)
113 7a554149 2024-02-18 op return (-1);
114 7a554149 2024-02-18 op if (buf_init(&bio->rbuf) == -1) {
115 7a554149 2024-02-18 op buf_free(&bio->wbuf);
116 7a554149 2024-02-18 op return (-1);
117 7a554149 2024-02-18 op }
118 7a554149 2024-02-18 op return (0);
119 7a554149 2024-02-18 op }
120 7a554149 2024-02-18 op
121 0d6af421 2024-02-18 op void
122 0d6af421 2024-02-18 op bufio_free(struct bufio *bio)
123 7a554149 2024-02-18 op {
124 7a554149 2024-02-18 op if (bio->ctx)
125 0d6af421 2024-02-18 op tls_free(bio->ctx);
126 0d6af421 2024-02-18 op bio->ctx = NULL;
127 0d6af421 2024-02-18 op
128 7a554149 2024-02-18 op if (bio->fd != -1)
129 7a554149 2024-02-18 op close(bio->fd);
130 0d6af421 2024-02-18 op bio->fd = -1;
131 7a554149 2024-02-18 op
132 7a554149 2024-02-18 op buf_free(&bio->rbuf);
133 7a554149 2024-02-18 op buf_free(&bio->wbuf);
134 0d6af421 2024-02-18 op }
135 0d6af421 2024-02-18 op
136 0d6af421 2024-02-18 op int
137 8b00d570 2024-02-18 op bufio_close(struct bufio *bio)
138 8b00d570 2024-02-18 op {
139 8b00d570 2024-02-18 op if (bio->ctx == NULL)
140 8b00d570 2024-02-18 op return (0);
141 8b00d570 2024-02-18 op
142 8b00d570 2024-02-18 op switch (tls_close(bio->ctx)) {
143 8b00d570 2024-02-18 op case 0:
144 8b00d570 2024-02-18 op return 0;
145 8b00d570 2024-02-18 op case TLS_WANT_POLLIN:
146 ce023433 2024-02-22 op errno = EAGAIN;
147 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_READ;
148 ce023433 2024-02-22 op return (-1);
149 8b00d570 2024-02-18 op case TLS_WANT_POLLOUT:
150 8b00d570 2024-02-18 op errno = EAGAIN;
151 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_WRITE;
152 ce023433 2024-02-22 op return (-1);
153 8b00d570 2024-02-18 op default:
154 8b00d570 2024-02-18 op return (-1);
155 8b00d570 2024-02-18 op }
156 8b00d570 2024-02-18 op }
157 8b00d570 2024-02-18 op
158 8b00d570 2024-02-18 op int
159 0d6af421 2024-02-18 op bufio_reset(struct bufio *bio)
160 0d6af421 2024-02-18 op {
161 0d6af421 2024-02-18 op bufio_free(bio);
162 7a554149 2024-02-18 op return (bufio_init(bio));
163 7a554149 2024-02-18 op }
164 7a554149 2024-02-18 op
165 7a554149 2024-02-18 op void
166 7a554149 2024-02-18 op bufio_set_fd(struct bufio *bio, int fd)
167 7a554149 2024-02-18 op {
168 7a554149 2024-02-18 op bio->fd = fd;
169 7a554149 2024-02-18 op }
170 7a554149 2024-02-18 op
171 7a554149 2024-02-18 op int
172 9c5586a7 2024-02-18 op bufio_starttls(struct bufio *bio, const char *host, int insecure,
173 9c5586a7 2024-02-18 op const uint8_t *cert, size_t certlen, const uint8_t *key, size_t keylen)
174 7a554149 2024-02-18 op {
175 7a554149 2024-02-18 op struct tls_config *conf;
176 7a554149 2024-02-18 op
177 7a554149 2024-02-18 op if ((conf = tls_config_new()) == NULL)
178 7a554149 2024-02-18 op return (-1);
179 7a554149 2024-02-18 op
180 7a554149 2024-02-18 op if (insecure) {
181 7a554149 2024-02-18 op tls_config_insecure_noverifycert(conf);
182 7a554149 2024-02-18 op tls_config_insecure_noverifyname(conf);
183 7a554149 2024-02-18 op tls_config_insecure_noverifytime(conf);
184 7a554149 2024-02-18 op }
185 7a554149 2024-02-18 op
186 9c5586a7 2024-02-18 op if (cert && tls_config_set_keypair_mem(conf, cert, certlen,
187 9c5586a7 2024-02-18 op key, keylen) == -1) {
188 9c5586a7 2024-02-18 op tls_config_free(conf);
189 9c5586a7 2024-02-18 op return (-1);
190 9c5586a7 2024-02-18 op }
191 9c5586a7 2024-02-18 op
192 7a554149 2024-02-18 op if ((bio->ctx = tls_client()) == NULL) {
193 7a554149 2024-02-18 op tls_config_free(conf);
194 7a554149 2024-02-18 op return (-1);
195 7a554149 2024-02-18 op }
196 7a554149 2024-02-18 op
197 7a554149 2024-02-18 op if (tls_configure(bio->ctx, conf) == -1) {
198 7a554149 2024-02-18 op tls_config_free(conf);
199 7a554149 2024-02-18 op return (-1);
200 7a554149 2024-02-18 op }
201 7a554149 2024-02-18 op
202 7a554149 2024-02-18 op tls_config_free(conf);
203 7a554149 2024-02-18 op
204 7a554149 2024-02-18 op if (tls_connect_socket(bio->ctx, bio->fd, host) == -1)
205 7a554149 2024-02-18 op return (-1);
206 7a554149 2024-02-18 op
207 7a554149 2024-02-18 op return (0);
208 7a554149 2024-02-18 op }
209 7a554149 2024-02-18 op
210 e3693ed9 2024-02-18 op int
211 e3693ed9 2024-02-18 op bufio_ev(struct bufio *bio)
212 7a554149 2024-02-18 op {
213 7a554149 2024-02-18 op short ev;
214 7a554149 2024-02-18 op
215 7a554149 2024-02-18 op if (bio->pflags)
216 7a554149 2024-02-18 op return (bio->pflags);
217 7a554149 2024-02-18 op
218 ce023433 2024-02-22 op ev = BUFIO_WANT_READ;
219 7a554149 2024-02-18 op if (bio->wbuf.len != 0)
220 ce023433 2024-02-22 op ev |= BUFIO_WANT_WRITE;
221 7a554149 2024-02-18 op
222 7a554149 2024-02-18 op return (ev);
223 7a554149 2024-02-18 op }
224 7a554149 2024-02-18 op
225 0e0994b2 2024-02-18 op int
226 0e0994b2 2024-02-18 op bufio_handshake(struct bufio *bio)
227 0e0994b2 2024-02-18 op {
228 0e0994b2 2024-02-18 op if (bio->ctx == NULL) {
229 0e0994b2 2024-02-18 op errno = EINVAL;
230 0e0994b2 2024-02-18 op return (-1);
231 0e0994b2 2024-02-18 op }
232 0e0994b2 2024-02-18 op
233 0e0994b2 2024-02-18 op switch (tls_handshake(bio->ctx)) {
234 0e0994b2 2024-02-18 op case 0:
235 0e0994b2 2024-02-18 op return (0);
236 0e0994b2 2024-02-18 op case TLS_WANT_POLLIN:
237 ce023433 2024-02-22 op errno = EAGAIN;
238 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_READ;
239 ce023433 2024-02-22 op return (-1);
240 0e0994b2 2024-02-18 op case TLS_WANT_POLLOUT:
241 0e0994b2 2024-02-18 op errno = EAGAIN;
242 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_WRITE;
243 ce023433 2024-02-22 op return (-1);
244 0e0994b2 2024-02-18 op default:
245 0e0994b2 2024-02-18 op return (-1);
246 0e0994b2 2024-02-18 op }
247 0e0994b2 2024-02-18 op }
248 0e0994b2 2024-02-18 op
249 7a554149 2024-02-18 op ssize_t
250 7a554149 2024-02-18 op bufio_read(struct bufio *bio)
251 7a554149 2024-02-18 op {
252 7a554149 2024-02-18 op struct buf *rbuf = &bio->rbuf;
253 7a554149 2024-02-18 op ssize_t r;
254 7a554149 2024-02-18 op
255 7a554149 2024-02-18 op assert(rbuf->cap >= rbuf->len);
256 7a554149 2024-02-18 op if (rbuf->cap - rbuf->len < BIO_CHUNK) {
257 7a554149 2024-02-18 op if (buf_grow(rbuf) == -1)
258 7a554149 2024-02-18 op return (-1);
259 7a554149 2024-02-18 op }
260 7a554149 2024-02-18 op
261 7a554149 2024-02-18 op if (bio->ctx) {
262 7a554149 2024-02-18 op r = tls_read(bio->ctx, rbuf->buf + rbuf->len,
263 e634cfa6 2024-02-18 op rbuf->cap - rbuf->len);
264 7a554149 2024-02-18 op switch (r) {
265 7a554149 2024-02-18 op case TLS_WANT_POLLIN:
266 ce023433 2024-02-22 op errno = EAGAIN;
267 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_READ;
268 ce023433 2024-02-22 op return (-1);
269 7a554149 2024-02-18 op case TLS_WANT_POLLOUT:
270 7a554149 2024-02-18 op errno = EAGAIN;
271 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_WRITE;
272 7a554149 2024-02-18 op return (-1);
273 7a554149 2024-02-18 op case -1:
274 7a554149 2024-02-18 op return (-1);
275 7a554149 2024-02-18 op default:
276 7a554149 2024-02-18 op bio->pflags = 0;
277 7a554149 2024-02-18 op rbuf->len += r;
278 7a554149 2024-02-18 op return (r);
279 7a554149 2024-02-18 op }
280 7a554149 2024-02-18 op }
281 7a554149 2024-02-18 op
282 7a554149 2024-02-18 op r = read(bio->fd, rbuf->buf + rbuf->len, rbuf->cap - rbuf->len);
283 7a554149 2024-02-18 op if (r == -1)
284 7a554149 2024-02-18 op return (-1);
285 7a554149 2024-02-18 op rbuf->len += r;
286 7a554149 2024-02-18 op return (r);
287 b19b8dbc 2024-02-18 op }
288 b19b8dbc 2024-02-18 op
289 b19b8dbc 2024-02-18 op size_t
290 b19b8dbc 2024-02-18 op bufio_drain(struct bufio *bio, void *d, size_t len)
291 b19b8dbc 2024-02-18 op {
292 b19b8dbc 2024-02-18 op struct buf *rbuf = &bio->rbuf;
293 b19b8dbc 2024-02-18 op
294 b19b8dbc 2024-02-18 op if (len > rbuf->len)
295 b19b8dbc 2024-02-18 op len = rbuf->len;
296 b19b8dbc 2024-02-18 op memcpy(d, rbuf->buf, len);
297 b19b8dbc 2024-02-18 op buf_drain(rbuf, len);
298 b19b8dbc 2024-02-18 op return (len);
299 7a554149 2024-02-18 op }
300 7a554149 2024-02-18 op
301 7a554149 2024-02-18 op ssize_t
302 7a554149 2024-02-18 op bufio_write(struct bufio *bio)
303 7a554149 2024-02-18 op {
304 7a554149 2024-02-18 op struct buf *wbuf = &bio->wbuf;
305 7a554149 2024-02-18 op ssize_t w;
306 7a554149 2024-02-18 op
307 7a554149 2024-02-18 op if (bio->ctx) {
308 7a554149 2024-02-18 op switch (w = tls_write(bio->ctx, wbuf->buf, wbuf->len)) {
309 7a554149 2024-02-18 op case TLS_WANT_POLLIN:
310 ce023433 2024-02-22 op errno = EAGAIN;
311 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_READ;
312 ce023433 2024-02-22 op return (-1);
313 7a554149 2024-02-18 op case TLS_WANT_POLLOUT:
314 7a554149 2024-02-18 op errno = EAGAIN;
315 ce023433 2024-02-22 op bio->pflags = BUFIO_WANT_WRITE;
316 7a554149 2024-02-18 op return (-1);
317 7a554149 2024-02-18 op case -1:
318 7a554149 2024-02-18 op return (-1);
319 7a554149 2024-02-18 op default:
320 7a554149 2024-02-18 op bio->pflags = 0;
321 7a554149 2024-02-18 op buf_drain(wbuf, w);
322 7a554149 2024-02-18 op return (w);
323 7a554149 2024-02-18 op }
324 7a554149 2024-02-18 op }
325 7a554149 2024-02-18 op
326 7a554149 2024-02-18 op w = write(bio->fd, wbuf->buf, wbuf->len);
327 7a554149 2024-02-18 op if (w == -1)
328 7a554149 2024-02-18 op return (-1);
329 7a554149 2024-02-18 op buf_drain(wbuf, w);
330 7a554149 2024-02-18 op return (w);
331 7a554149 2024-02-18 op }
332 7a554149 2024-02-18 op
333 7a554149 2024-02-18 op int
334 7a554149 2024-02-18 op bufio_compose(struct bufio *bio, const void *d, size_t len)
335 7a554149 2024-02-18 op {
336 7a554149 2024-02-18 op struct buf *wbuf = &bio->wbuf;
337 7a554149 2024-02-18 op
338 7a554149 2024-02-18 op while (wbuf->cap - wbuf->len < len) {
339 7a554149 2024-02-18 op if (buf_grow(wbuf) == -1)
340 7a554149 2024-02-18 op return (-1);
341 7a554149 2024-02-18 op }
342 7a554149 2024-02-18 op
343 7a554149 2024-02-18 op memcpy(wbuf->buf + wbuf->len, d, len);
344 7a554149 2024-02-18 op wbuf->len += len;
345 7a554149 2024-02-18 op return (0);
346 7a554149 2024-02-18 op }
347 7a554149 2024-02-18 op
348 7a554149 2024-02-18 op int
349 7a554149 2024-02-18 op bufio_compose_str(struct bufio *bio, const char *str)
350 7a554149 2024-02-18 op {
351 7a554149 2024-02-18 op return (bufio_compose(bio, str, strlen(str)));
352 7a554149 2024-02-18 op }
353 7a554149 2024-02-18 op
354 7a554149 2024-02-18 op int
355 7a554149 2024-02-18 op bufio_compose_fmt(struct bufio *bio, const char *fmt, ...)
356 7a554149 2024-02-18 op {
357 7a554149 2024-02-18 op va_list ap;
358 7a554149 2024-02-18 op char *str;
359 7a554149 2024-02-18 op int r;
360 7a554149 2024-02-18 op
361 7a554149 2024-02-18 op va_start(ap, fmt);
362 7a554149 2024-02-18 op r = vasprintf(&str, fmt, ap);
363 7a554149 2024-02-18 op va_end(ap);
364 7a554149 2024-02-18 op
365 7a554149 2024-02-18 op if (r == -1)
366 7a554149 2024-02-18 op return (-1);
367 7a554149 2024-02-18 op r = bufio_compose(bio, str, r);
368 7a554149 2024-02-18 op free(str);
369 7a554149 2024-02-18 op return (r);
370 7a554149 2024-02-18 op }
371 7a554149 2024-02-18 op
372 7a554149 2024-02-18 op void
373 7a554149 2024-02-18 op bufio_rewind_cursor(struct bufio *bio)
374 7a554149 2024-02-18 op {
375 7a554149 2024-02-18 op bio->rbuf.cur = 0;
376 7a554149 2024-02-18 op }
377 7a554149 2024-02-18 op
378 7a554149 2024-02-18 op int
379 7a554149 2024-02-18 op bufio_get_cb(void *d)
380 7a554149 2024-02-18 op {
381 7a554149 2024-02-18 op struct bufio *bio = d;
382 7a554149 2024-02-18 op struct buf *rbuf = &bio->rbuf;
383 7a554149 2024-02-18 op
384 7a554149 2024-02-18 op if (rbuf->cur >= rbuf->len)
385 7a554149 2024-02-18 op return (EOF);
386 7a554149 2024-02-18 op return (rbuf->buf[rbuf->cur++]);
387 7a554149 2024-02-18 op }
388 7a554149 2024-02-18 op
389 7a554149 2024-02-18 op int
390 7a554149 2024-02-18 op bufio_peek_cb(void *d)
391 7a554149 2024-02-18 op {
392 7a554149 2024-02-18 op struct bufio *bio = d;
393 7a554149 2024-02-18 op struct buf *rbuf = &bio->rbuf;
394 7a554149 2024-02-18 op
395 7a554149 2024-02-18 op if (rbuf->cur >= rbuf->len)
396 7a554149 2024-02-18 op return (EOF);
397 7a554149 2024-02-18 op return (rbuf->buf[rbuf->cur]);
398 7a554149 2024-02-18 op }