1 /*
2 * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "bio_local.h"
13
14 #ifndef OPENSSL_NO_SOCK
15 # define SOCKET_PROTOCOL IPPROTO_TCP
16 # ifdef SO_MAXCONN
17 # define MAX_LISTEN SO_MAXCONN
18 # elif defined(SOMAXCONN)
19 # define MAX_LISTEN SOMAXCONN
20 # else
21 # define MAX_LISTEN 32
22 # endif
23 # if defined(OPENSSL_SYS_WINDOWS)
24 static int wsa_init_done = 0;
25 # endif
26
27 # if defined __TANDEM
28 # include <unistd.h>
29 # include <sys/time.h> /* select */
30 # elif defined _WIN32
31 # include <winsock.h> /* for type fd_set */
32 # else
33 # include <unistd.h>
34 # if defined __VMS
35 # include <sys/socket.h>
36 # elif defined _HPUX_SOURCE
37 # include <sys/time.h>
38 # else
39 # include <sys/select.h>
40 # endif
41 # endif
42 # include "internal/sockets.h" /* for openssl_fdset() */
43
44 # ifndef OPENSSL_NO_DEPRECATED_1_1_0
BIO_get_host_ip(const char * str,unsigned char * ip)45 int BIO_get_host_ip(const char *str, unsigned char *ip)
46 {
47 BIO_ADDRINFO *res = NULL;
48 int ret = 0;
49
50 if (BIO_sock_init() != 1)
51 return 0; /* don't generate another error code here */
52
53 if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
54 size_t l;
55
56 if (BIO_ADDRINFO_family(res) != AF_INET) {
57 ERR_raise(ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
58 } else if (BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l)) {
59 /*
60 * Because only AF_INET addresses will reach this far, we can assert
61 * that l should be 4
62 */
63 if (ossl_assert(l == 4))
64 ret = BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l);
65 }
66 BIO_ADDRINFO_free(res);
67 } else {
68 ERR_add_error_data(2, "host=", str);
69 }
70
71 return ret;
72 }
73
BIO_get_port(const char * str,unsigned short * port_ptr)74 int BIO_get_port(const char *str, unsigned short *port_ptr)
75 {
76 BIO_ADDRINFO *res = NULL;
77 int ret = 0;
78
79 if (str == NULL) {
80 ERR_raise(ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED);
81 return 0;
82 }
83
84 if (BIO_sock_init() != 1)
85 return 0; /* don't generate another error code here */
86
87 if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
88 if (BIO_ADDRINFO_family(res) != AF_INET) {
89 ERR_raise(ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
90 } else {
91 *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
92 ret = 1;
93 }
94 BIO_ADDRINFO_free(res);
95 } else {
96 ERR_add_error_data(2, "host=", str);
97 }
98
99 return ret;
100 }
101 # endif
102
BIO_sock_error(int sock)103 int BIO_sock_error(int sock)
104 {
105 int j = 0, i;
106 socklen_t size = sizeof(j);
107
108 /*
109 * Note: under Windows the third parameter is of type (char *) whereas
110 * under other systems it is (void *) if you don't have a cast it will
111 * choke the compiler: if you do have a cast then you can either go for
112 * (char *) or (void *).
113 */
114 i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size);
115 if (i < 0)
116 return get_last_socket_error();
117 else
118 return j;
119 }
120
121 # ifndef OPENSSL_NO_DEPRECATED_1_1_0
BIO_gethostbyname(const char * name)122 struct hostent *BIO_gethostbyname(const char *name)
123 {
124 /*
125 * Caching gethostbyname() results forever is wrong, so we have to let
126 * the true gethostbyname() worry about this
127 */
128 return gethostbyname(name);
129 }
130 # endif
131
132 # ifdef BIO_HAVE_WSAMSG
133 LPFN_WSARECVMSG bio_WSARecvMsg;
134 LPFN_WSASENDMSG bio_WSASendMsg;
135 # endif
136
BIO_sock_init(void)137 int BIO_sock_init(void)
138 {
139 # ifdef OPENSSL_SYS_WINDOWS
140 static struct WSAData wsa_state;
141
142 if (!wsa_init_done) {
143 wsa_init_done = 1;
144 memset(&wsa_state, 0, sizeof(wsa_state));
145 /*
146 * Not making wsa_state available to the rest of the code is formally
147 * wrong. But the structures we use are [believed to be] invariable
148 * among Winsock DLLs, while API availability is [expected to be]
149 * probed at run-time with DSO_global_lookup.
150 */
151 if (WSAStartup(0x0202, &wsa_state) != 0) {
152 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
153 "calling wsastartup()");
154 ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP);
155 return -1;
156 }
157
158 /*
159 * On Windows, some socket functions are not exposed as a prototype.
160 * Instead, their function pointers must be loaded via this elaborate
161 * process...
162 */
163 # ifdef BIO_HAVE_WSAMSG
164 {
165 GUID id_WSARecvMsg = WSAID_WSARECVMSG;
166 GUID id_WSASendMsg = WSAID_WSASENDMSG;
167 DWORD len_out = 0;
168 SOCKET s;
169
170 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
171 if (s != INVALID_SOCKET) {
172 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
173 &id_WSARecvMsg, sizeof(id_WSARecvMsg),
174 &bio_WSARecvMsg, sizeof(bio_WSARecvMsg),
175 &len_out, NULL, NULL) != 0
176 || len_out != sizeof(bio_WSARecvMsg))
177 bio_WSARecvMsg = NULL;
178
179 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
180 &id_WSASendMsg, sizeof(id_WSASendMsg),
181 &bio_WSASendMsg, sizeof(bio_WSASendMsg),
182 &len_out, NULL, NULL) != 0
183 || len_out != sizeof(bio_WSASendMsg))
184 bio_WSASendMsg = NULL;
185
186 closesocket(s);
187 }
188 }
189 # endif
190 }
191 # endif /* OPENSSL_SYS_WINDOWS */
192 # ifdef WATT32
193 extern int _watt_do_exit;
194 _watt_do_exit = 0; /* don't make sock_init() call exit() */
195 if (sock_init())
196 return -1;
197 # endif
198
199 return 1;
200 }
201
bio_sock_cleanup_int(void)202 void bio_sock_cleanup_int(void)
203 {
204 # ifdef OPENSSL_SYS_WINDOWS
205 if (wsa_init_done) {
206 wsa_init_done = 0;
207 WSACleanup();
208 }
209 # endif
210 }
211
BIO_socket_ioctl(int fd,long type,void * arg)212 int BIO_socket_ioctl(int fd, long type, void *arg)
213 {
214 int i;
215
216 # ifdef __DJGPP__
217 i = ioctlsocket(fd, type, (char *)arg);
218 # else
219 # if defined(OPENSSL_SYS_VMS)
220 /*-
221 * 2011-02-18 SMS.
222 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
223 * observe that all the consumers pass in an "unsigned long *",
224 * so we arrange a local copy with a short pointer, and use
225 * that, instead.
226 */
227 # if __INITIAL_POINTER_SIZE == 64
228 # define ARG arg_32p
229 # pragma pointer_size save
230 # pragma pointer_size 32
231 unsigned long arg_32;
232 unsigned long *arg_32p;
233 # pragma pointer_size restore
234 arg_32p = &arg_32;
235 arg_32 = *((unsigned long *)arg);
236 # else /* __INITIAL_POINTER_SIZE == 64 */
237 # define ARG arg
238 # endif /* __INITIAL_POINTER_SIZE == 64 [else] */
239 # else /* defined(OPENSSL_SYS_VMS) */
240 # define ARG arg
241 # endif /* defined(OPENSSL_SYS_VMS) [else] */
242
243 i = ioctlsocket(fd, type, ARG);
244 # endif /* __DJGPP__ */
245 if (i < 0)
246 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
247 "calling ioctlsocket()");
248 return i;
249 }
250
251 # ifndef OPENSSL_NO_DEPRECATED_1_1_0
BIO_get_accept_socket(char * host,int bind_mode)252 int BIO_get_accept_socket(char *host, int bind_mode)
253 {
254 int s = INVALID_SOCKET;
255 char *h = NULL, *p = NULL;
256 BIO_ADDRINFO *res = NULL;
257
258 if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV))
259 return INVALID_SOCKET;
260
261 if (BIO_sock_init() != 1)
262 return INVALID_SOCKET;
263
264 if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0)
265 goto err;
266
267 if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
268 BIO_ADDRINFO_protocol(res), 0)) == INVALID_SOCKET) {
269 s = INVALID_SOCKET;
270 goto err;
271 }
272
273 if (!BIO_listen(s, BIO_ADDRINFO_address(res),
274 bind_mode ? BIO_SOCK_REUSEADDR : 0)) {
275 BIO_closesocket(s);
276 s = INVALID_SOCKET;
277 }
278
279 err:
280 BIO_ADDRINFO_free(res);
281 OPENSSL_free(h);
282 OPENSSL_free(p);
283
284 return s;
285 }
286
BIO_accept(int sock,char ** ip_port)287 int BIO_accept(int sock, char **ip_port)
288 {
289 BIO_ADDR res;
290 int ret = -1;
291
292 ret = BIO_accept_ex(sock, &res, 0);
293 if (ret == (int)INVALID_SOCKET) {
294 if (BIO_sock_should_retry(ret)) {
295 ret = -2;
296 goto end;
297 }
298 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
299 "calling accept()");
300 ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR);
301 goto end;
302 }
303
304 if (ip_port != NULL) {
305 char *host = BIO_ADDR_hostname_string(&res, 1);
306 char *port = BIO_ADDR_service_string(&res, 1);
307 if (host != NULL && port != NULL) {
308 *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
309 } else {
310 *ip_port = NULL;
311 ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
312 }
313
314 if (*ip_port == NULL) {
315 BIO_closesocket(ret);
316 ret = (int)INVALID_SOCKET;
317 } else {
318 strcpy(*ip_port, host);
319 strcat(*ip_port, ":");
320 strcat(*ip_port, port);
321 }
322 OPENSSL_free(host);
323 OPENSSL_free(port);
324 }
325
326 end:
327 return ret;
328 }
329 # endif
330
BIO_set_tcp_ndelay(int s,int on)331 int BIO_set_tcp_ndelay(int s, int on)
332 {
333 int ret = 0;
334 # if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
335 int opt;
336
337 # ifdef SOL_TCP
338 opt = SOL_TCP;
339 # else
340 # ifdef IPPROTO_TCP
341 opt = IPPROTO_TCP;
342 # endif
343 # endif
344
345 ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
346 # endif
347 return (ret == 0);
348 }
349
BIO_socket_nbio(int s,int mode)350 int BIO_socket_nbio(int s, int mode)
351 {
352 int ret = -1;
353 int l;
354
355 l = mode;
356 # ifdef FIONBIO
357 l = mode;
358
359 ret = BIO_socket_ioctl(s, FIONBIO, &l);
360 # elif defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(FNDELAY))
361 /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
362
363 l = fcntl(s, F_GETFL, 0);
364 if (l == -1) {
365 ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
366 "calling fcntl()");
367 ret = -1;
368 } else {
369 # if defined(O_NONBLOCK)
370 l &= ~O_NONBLOCK;
371 # else
372 l &= ~FNDELAY; /* BSD4.x */
373 # endif
374 if (mode) {
375 # if defined(O_NONBLOCK)
376 l |= O_NONBLOCK;
377 # else
378 l |= FNDELAY; /* BSD4.x */
379 # endif
380 }
381 ret = fcntl(s, F_SETFL, l);
382
383 if (ret < 0) {
384 ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
385 "calling fcntl()");
386 }
387 }
388 # else
389 /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
390 ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_INVALID_ARGUMENT);
391 # endif
392
393 return (ret == 0);
394 }
395
BIO_sock_info(int sock,enum BIO_sock_info_type type,union BIO_sock_info_u * info)396 int BIO_sock_info(int sock,
397 enum BIO_sock_info_type type, union BIO_sock_info_u *info)
398 {
399 switch (type) {
400 case BIO_SOCK_INFO_ADDRESS:
401 {
402 socklen_t addr_len;
403 int ret = 0;
404 addr_len = sizeof(*info->addr);
405 ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
406 &addr_len);
407 if (ret == -1) {
408 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
409 "calling getsockname()");
410 ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR);
411 return 0;
412 }
413 if ((size_t)addr_len > sizeof(*info->addr)) {
414 ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
415 return 0;
416 }
417 }
418 break;
419 default:
420 ERR_raise(ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE);
421 return 0;
422 }
423 return 1;
424 }
425
426 /*
427 * Wait on fd at most until max_time; succeed immediately if max_time == 0.
428 * If for_read == 0 then assume to wait for writing, else wait for reading.
429 * Returns -1 on error, 0 on timeout, and 1 on success.
430 */
BIO_socket_wait(int fd,int for_read,time_t max_time)431 int BIO_socket_wait(int fd, int for_read, time_t max_time)
432 {
433 # if defined(OPENSSL_SYS_WINDOWS) || !defined(POLLIN)
434 fd_set confds;
435 struct timeval tv;
436 time_t now;
437
438 # ifdef _WIN32
439 if ((SOCKET)fd == INVALID_SOCKET)
440 # else
441 if (fd < 0 || fd >= FD_SETSIZE)
442 # endif
443 return -1;
444 if (max_time == 0)
445 return 1;
446
447 now = time(NULL);
448 if (max_time < now)
449 return 0;
450
451 FD_ZERO(&confds);
452 openssl_fdset(fd, &confds);
453 tv.tv_usec = 0;
454 tv.tv_sec = (long)(max_time - now); /* might overflow */
455 return select(fd + 1, for_read ? &confds : NULL,
456 for_read ? NULL : &confds, NULL, &tv);
457 # else
458 struct pollfd confds;
459 time_t now;
460
461 if (fd < 0)
462 return -1;
463 if (max_time == 0)
464 return 1;
465
466 now = time(NULL);
467 if (max_time < now)
468 return 0;
469
470 confds.fd = fd;
471 confds.events = for_read ? POLLIN : POLLOUT;
472 return poll(&confds, 1, (int)(max_time - now) * 1000);
473 # endif
474 }
475 #endif /* !defined(OPENSSL_NO_SOCK) */
476