1 /*
2 socket handling routines
3 Copyright (C) 1998-2004, Joe Orton <joe@manyfish.co.uk>,
4 Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA
20 */
21
22 /*
23 portions were originally under GPL in Mutt, http://www.mutt.org/
24 Relicensed under LGPL for neon, http://www.webdav.org/neon/
25 */
26
27 #include "config.h"
28
29 #ifdef __hpux
30 /* pick up hstrerror */
31 #define _XOPEN_SOURCE_EXTENDED 1
32 /* don't use the broken getaddrinfo shipped in HP-UX 11.11 */
33 #ifdef USE_GETADDRINFO
34 #undef USE_GETADDRINFO
35 #endif
36 #endif
37
38 #include <sys/types.h>
39 #ifdef HAVE_SYS_TIME_H
40 #include <sys/time.h>
41 #endif
42 #include <sys/stat.h>
43 #ifdef HAVE_SYS_SELECT_H
44 #include <sys/select.h>
45 #endif
46 #ifdef HAVE_SYS_SOCKET_H
47 #include <sys/socket.h>
48 #endif
49
50 #ifdef HAVE_NETINET_IN_H
51 #include <netinet/in.h>
52 #endif
53 #ifdef HAVE_NETINET_TCP_H
54 #include <netinet/tcp.h>
55 #endif
56 #ifdef HAVE_ARPA_INET_H
57 #include <arpa/inet.h>
58 #endif
59 #ifdef HAVE_NETDB_H
60 #include <netdb.h>
61 #endif
62
63 #ifdef WIN32
64 #include <winsock2.h>
65 #include <stddef.h>
66 #endif
67
68 #if defined(NEON_SSL) && defined(HAVE_LIMITS_H)
69 #include <limits.h> /* for INT_MAX */
70 #endif
71 #ifdef HAVE_STRING_H
72 #include <string.h>
73 #endif
74 #ifdef HAVE_STRINGS_H
75 #include <strings.h>
76 #endif
77 #ifdef HAVE_UNISTD_H
78 #include <unistd.h>
79 #endif
80 #ifdef HAVE_SIGNAL_H
81 #include <signal.h>
82 #endif
83 #ifdef HAVE_ERRNO_H
84 #include <errno.h>
85 #endif
86 #ifdef HAVE_STDLIB_H
87 #include <stdlib.h>
88 #endif
89
90 #ifdef HAVE_SOCKS_H
91 #include <socks.h>
92 #endif
93
94 #ifdef NEON_SSL
95 #include <openssl/ssl.h>
96 #include <openssl/err.h>
97 #include <openssl/pkcs12.h> /* for PKCS12_PBE_add */
98 #include <openssl/rand.h>
99
100 #include "ne_privssl.h"
101 #endif
102
103 #include "ne_i18n.h"
104 #include "ne_utils.h"
105 #include "ne_string.h"
106
107 #define NE_INET_ADDR_DEFINED
108 /* A slightly ugly hack: change the ne_inet_addr definition to be the
109 * real address type used. The API only exposes ne_inet_addr as a
110 * pointer to an opaque object, so this should be well-defined
111 * behaviour. It avoids the hassle of a real wrapper ne_inet_addr
112 * structure, or losing type-safety by using void *. */
113 #ifdef USE_GETADDRINFO
114 typedef struct addrinfo ne_inet_addr;
115
116 /* To avoid doing AAAA queries unless absolutely necessary, either use
117 * AI_ADDRCONFIG where available, or a run-time check for working IPv6
118 * support; the latter is only known to work on Linux. */
119 #if !defined(USE_GAI_ADDRCONFIG) && defined(__linux__)
120 #define USE_CHECK_IPV6
121 #endif
122
123 #else
124 typedef struct in_addr ne_inet_addr;
125 #endif
126
127 #include "ne_socket.h"
128 #include "ne_alloc.h"
129
130 #if defined(__BEOS__) && !defined(BONE_VERSION)
131 /* pre-BONE */
132 #define ne_write(a,b,c) send(a,b,c,0)
133 #define ne_read(a,b,c) recv(a,b,c,0)
134 #define ne_close(s) closesocket(s)
135 #define ne_errno errno
136 #elif defined(WIN32)
137 #define ne_write(a,b,c) send(a,b,c,0)
138 #define ne_read(a,b,c) recv(a,b,c,0)
139 #define ne_close(s) closesocket(s)
140 #define ne_errno WSAGetLastError()
141 #else /* really Unix! */
142 #define ne_write(a,b,c) write(a,b,c)
143 #define ne_read(a,b,c) read(a,b,c)
144 #define ne_close(s) close(s)
145 #define ne_errno errno
146 #endif
147
148 #ifdef WIN32
149 #define NE_ISRESET(e) ((e) == WSAECONNABORTED || (e) == WSAETIMEDOUT || \
150 (e) == WSAECONNRESET || (e) == WSAENETRESET)
151 #define NE_ISCLOSED(e) ((e) == WSAESHUTDOWN || (e) == WSAENOTCONN)
152 #define NE_ISINTR(e) (0)
153 #else /* Unix */
154 #define NE_ISRESET(e) ((e) == ECONNRESET)
155 #define NE_ISCLOSED(e) ((e) == EPIPE)
156 #define NE_ISINTR(e) ((e) == EINTR)
157 #endif
158
159 /* Socket read timeout */
160 #define SOCKET_READ_TIMEOUT 120
161
162 /* Critical I/O functions on a socket: useful abstraction for easily
163 * handling SSL I/O alongside raw socket I/O. */
164 struct iofns {
165 /* Read up to 'len' bytes into 'buf' from socket. Return <0 on
166 * error or EOF, or >0; number of bytes read. */
167 ssize_t (*read)(ne_socket *s, char *buf, size_t len);
168 /* Write exactly 'len' bytes from 'buf' to socket. Return zero on
169 * success, <0 on error. */
170 ssize_t (*write)(ne_socket *s, const char *buf, size_t len);
171 /* Wait up to 'n' seconds for socket to become readable. Returns
172 * 0 when readable, otherwise NE_SOCK_TIMEOUT or NE_SOCK_ERROR. */
173 int (*readable)(ne_socket *s, int n);
174 };
175
176 struct ne_socket_s {
177 int fd;
178 char error[200];
179 void *progress_ud;
180 int rdtimeout; /* read timeout. */
181 const struct iofns *ops;
182 #ifdef NEON_SSL
183 ne_ssl_socket ssl;
184 #endif
185 /* The read buffer: ->buffer stores byte which have been read; as
186 * these are consumed and passed back to the caller, bufpos
187 * advances through ->buffer. ->bufavail gives the number of
188 * bytes which remain to be consumed in ->buffer (from ->bufpos),
189 * and is hence always <= RDBUFSIZ. */
190 #define RDBUFSIZ 4096
191 char buffer[RDBUFSIZ];
192 char *bufpos;
193 size_t bufavail;
194 };
195
196 /* ne_sock_addr represents an Internet address. */
197 struct ne_sock_addr_s {
198 #ifdef USE_GETADDRINFO
199 struct addrinfo *result, *cursor;
200 #else
201 struct in_addr *addrs;
202 size_t cursor, count;
203 #endif
204 int errnum;
205 };
206
207 /* set_error: set socket error string to 'str'. */
208 #define set_error(s, str) ne_strnzcpy((s)->error, (str), sizeof (s)->error)
209
210 /* set_strerror: set socket error to system error string for 'errnum' */
211 #ifdef WIN32
212 /* Print system error message to given buffer. */
print_error(int errnum,char * buffer,size_t buflen)213 static void print_error(int errnum, char *buffer, size_t buflen)
214 {
215 if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
216 | FORMAT_MESSAGE_IGNORE_INSERTS,
217 NULL, (DWORD) errnum, 0,
218 buffer, buflen, NULL) == 0)
219 ne_snprintf(buffer, buflen, "Socket error %d", errnum);
220 }
221 #define set_strerror(s, e) print_error((e), (s)->error, sizeof (s)->error)
222 #else /* not WIN32 */
223 #define set_strerror(s, e) ne_strerror((e), (s)->error, sizeof (s)->error)
224 #endif
225
226 #ifdef NEON_SSL
227
228 /* Initialize SSL library. */
init_ssl(void)229 static void init_ssl(void)
230 {
231 SSL_load_error_strings();
232 SSL_library_init();
233 PKCS12_PBE_add(); /* ### not sure why this is needed. */
234 }
235
236 /* Seed the SSL PRNG, if necessary; returns non-zero on failure. */
seed_ssl_prng(void)237 static int seed_ssl_prng(void)
238 {
239 /* Check whether the PRNG has already been seeded. */
240 if (RAND_status() == 1)
241 return 0;
242
243 #ifdef EGD_PATH
244 NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from " EGD_PATH "...\n");
245 if (RAND_egd(EGD_PATH) != -1)
246 return 0;
247 #elif defined(ENABLE_EGD)
248 {
249 static const char *paths[] = { "/var/run/egd-pool", "/dev/egd-pool",
250 "/etc/egd-pool", "/etc/entropy" };
251 size_t n;
252 for (n = 0; n < sizeof(paths) / sizeof(char *); n++) {
253 NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from %s...\n", paths[n]);
254 if (RAND_egd(paths[n]) != -1)
255 return 0;
256 }
257 }
258 #endif /* EGD_PATH */
259
260 NE_DEBUG(NE_DBG_SOCKET, "No entropy source found; could not seed PRNG.\n");
261 return -1;
262 }
263 #endif /* NEON_SSL */
264
265 #ifdef USE_CHECK_IPV6
266 static int ipv6_disabled = 0;
267
268 /* On Linux kernels, IPv6 is typically built as a loadable module, and
269 * socket(AF_INET6, ...) will fail if this module is not loaded, so
270 * the slow AAAA lookups can be avoided for this common case. */
init_ipv6(void)271 static void init_ipv6(void)
272 {
273 int fd = socket(AF_INET6, SOCK_STREAM, 0);
274
275 if (fd < 0)
276 ipv6_disabled = 1;
277 else
278 close(fd);
279 }
280 #else
281 #define ipv6_disabled (0)
282 #endif
283
284 static int init_result = 0;
285
ne_sock_init(void)286 int ne_sock_init(void)
287 {
288 #ifdef WIN32
289 WORD wVersionRequested;
290 WSADATA wsaData;
291 int err;
292 #endif
293
294 if (init_result > 0)
295 return 0;
296 else if (init_result < 0)
297 return -1;
298
299 #ifdef WIN32
300 wVersionRequested = MAKEWORD(2, 2);
301
302 err = WSAStartup(wVersionRequested, &wsaData);
303 if (err != 0) {
304 init_result = -1;
305 return -1;
306 }
307
308 #endif
309
310 #ifdef NEON_SOCKS
311 SOCKSinit("neon");
312 #endif
313
314 #if defined(HAVE_SIGNAL) && defined(SIGPIPE)
315 (void) signal(SIGPIPE, SIG_IGN);
316 #endif
317
318 #ifdef USE_CHECK_IPV6
319 init_ipv6();
320 #endif
321
322 #ifdef NEON_SSL
323 init_ssl();
324 #endif
325
326 init_result = 1;
327 return 0;
328 }
329
ne_sock_exit(void)330 void ne_sock_exit(void)
331 {
332 #ifdef WIN32
333 WSACleanup();
334 #endif
335 init_result = 0;
336 }
337
ne_sock_block(ne_socket * sock,int n)338 int ne_sock_block(ne_socket *sock, int n)
339 {
340 if (sock->bufavail)
341 return 0;
342 return sock->ops->readable(sock, n);
343 }
344
345 /* Cast address object AD to type 'sockaddr_TY' */
346 #define SACAST(ty, ad) ((struct sockaddr_##ty *)(ad))
347
348 #define SOCK_ERR(x) do { ssize_t _sock_err = (x); \
349 if (_sock_err < 0) return _sock_err; } while(0)
350
ne_sock_read(ne_socket * sock,char * buffer,size_t buflen)351 ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t buflen)
352 {
353 ssize_t bytes;
354
355 #if 0
356 NE_DEBUG(NE_DBG_SOCKET, "buf: at %d, %d avail [%s]\n",
357 sock->bufpos - sock->buffer, sock->bufavail, sock->bufpos);
358 #endif
359
360 if (sock->bufavail > 0) {
361 /* Deliver buffered data. */
362 if (buflen > sock->bufavail)
363 buflen = sock->bufavail;
364 memcpy(buffer, sock->bufpos, buflen);
365 sock->bufpos += buflen;
366 sock->bufavail -= buflen;
367 return buflen;
368 } else if (buflen >= sizeof sock->buffer) {
369 /* No need for read buffer. */
370 return sock->ops->read(sock, buffer, buflen);
371 } else {
372 /* Fill read buffer. */
373 bytes = sock->ops->read(sock, sock->buffer, sizeof sock->buffer);
374 if (bytes <= 0)
375 return bytes;
376
377 if (buflen > (size_t)bytes)
378 buflen = bytes;
379 memcpy(buffer, sock->buffer, buflen);
380 sock->bufpos = sock->buffer + buflen;
381 sock->bufavail = bytes - buflen;
382 return buflen;
383 }
384 }
385
ne_sock_peek(ne_socket * sock,char * buffer,size_t buflen)386 ssize_t ne_sock_peek(ne_socket *sock, char *buffer, size_t buflen)
387 {
388 ssize_t bytes;
389
390 if (sock->bufavail) {
391 /* just return buffered data. */
392 bytes = sock->bufavail;
393 } else {
394 /* fill the buffer. */
395 bytes = sock->ops->read(sock, sock->buffer, sizeof sock->buffer);
396 if (bytes <= 0)
397 return bytes;
398
399 sock->bufpos = sock->buffer;
400 sock->bufavail = bytes;
401 }
402
403 if (buflen > (size_t)bytes)
404 buflen = bytes;
405
406 memcpy(buffer, sock->bufpos, buflen);
407
408 return buflen;
409 }
410
411 /* Await data on raw fd in socket. */
readable_raw(ne_socket * sock,int secs)412 static int readable_raw(ne_socket *sock, int secs)
413 {
414 int fdno = sock->fd, ret;
415 fd_set rdfds;
416 struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL);
417
418 /* Init the fd set */
419 FD_ZERO(&rdfds);
420 do {
421 FD_SET(fdno, &rdfds);
422 if (tvp) {
423 tvp->tv_sec = secs;
424 tvp->tv_usec = 0;
425 }
426 ret = select(fdno + 1, &rdfds, NULL, NULL, tvp);
427 } while (ret < 0 && NE_ISINTR(ne_errno));
428 if (ret < 0) {
429 set_strerror(sock, ne_errno);
430 return NE_SOCK_ERROR;
431 }
432 return (ret == 0) ? NE_SOCK_TIMEOUT : 0;
433 }
434
read_raw(ne_socket * sock,char * buffer,size_t len)435 static ssize_t read_raw(ne_socket *sock, char *buffer, size_t len)
436 {
437 ssize_t ret;
438
439 ret = readable_raw(sock, sock->rdtimeout);
440 if (ret) return ret;
441
442 do {
443 ret = ne_read(sock->fd, buffer, len);
444 } while (ret == -1 && NE_ISINTR(ne_errno));
445
446 if (ret == 0) {
447 set_error(sock, _("Connection closed"));
448 ret = NE_SOCK_CLOSED;
449 } else if (ret < 0) {
450 int errnum = ne_errno;
451 ret = NE_ISRESET(errnum) ? NE_SOCK_RESET : NE_SOCK_ERROR;
452 set_strerror(sock, errnum);
453 }
454
455 return ret;
456 }
457
458 #define MAP_ERR(e) (NE_ISCLOSED(e) ? NE_SOCK_CLOSED : \
459 (NE_ISRESET(e) ? NE_SOCK_RESET : NE_SOCK_ERROR))
460
write_raw(ne_socket * sock,const char * data,size_t length)461 static ssize_t write_raw(ne_socket *sock, const char *data, size_t length)
462 {
463 ssize_t wrote;
464
465 do {
466 wrote = ne_write(sock->fd, data, length);
467 if (wrote > 0) {
468 data += wrote;
469 length -= wrote;
470 }
471 } while ((wrote > 0 || NE_ISINTR(ne_errno)) && length > 0);
472
473 if (wrote < 0) {
474 int errnum = ne_errno;
475 set_strerror(sock, errnum);
476 return MAP_ERR(errnum);
477 }
478
479 return 0;
480 }
481
482 static const struct iofns iofns_raw = { read_raw, write_raw, readable_raw };
483
484 #ifdef NEON_SSL
485 /* OpenSSL I/O function implementations. */
readable_ossl(ne_socket * sock,int secs)486 static int readable_ossl(ne_socket *sock, int secs)
487 {
488 /* If there is buffered SSL data, then don't block on the socket.
489 * FIXME: make sure that SSL_read *really* won't block if
490 * SSL_pending returns non-zero. Possibly need to do
491 * SSL_read(ssl, buf, SSL_pending(ssl)) */
492
493 if (SSL_pending(sock->ssl.ssl))
494 return 0;
495
496 return readable_raw(sock, secs);
497 }
498
499 /* SSL error handling, according to SSL_get_error(3). */
error_ossl(ne_socket * sock,int sret)500 static int error_ossl(ne_socket *sock, int sret)
501 {
502 int err = SSL_get_error(sock->ssl.ssl, sret), ret = NE_SOCK_ERROR;
503
504 switch (err) {
505 case SSL_ERROR_ZERO_RETURN:
506 ret = NE_SOCK_CLOSED;
507 set_error(sock, _("Connection closed"));
508 break;
509 case SSL_ERROR_SYSCALL:
510 err = ERR_get_error();
511 if (err == 0) {
512 if (sret == 0) {
513 /* EOF without close_notify, possible truncation */
514 set_error(sock, _("Secure connection truncated"));
515 ret = NE_SOCK_TRUNC;
516 } else {
517 /* Other socket error. */
518 err = ne_errno;
519 set_strerror(sock, err);
520 ret = MAP_ERR(err);
521 }
522 } else {
523 ne_snprintf(sock->error, sizeof sock->error,
524 _("SSL error: %s"), ERR_reason_error_string(err));
525 }
526 break;
527 default:
528 ne_snprintf(sock->error, sizeof sock->error, _("SSL error: %s"),
529 ERR_reason_error_string(ERR_get_error()));
530 break;
531 }
532 return ret;
533 }
534
535 /* Work around OpenSSL's use of 'int' rather than 'size_t', to prevent
536 * accidentally passing a negative number, etc. */
537 #define CAST2INT(n) (((n) > INT_MAX) ? INT_MAX : (n))
538
read_ossl(ne_socket * sock,char * buffer,size_t len)539 static ssize_t read_ossl(ne_socket *sock, char *buffer, size_t len)
540 {
541 int ret;
542
543 ret = readable_ossl(sock, sock->rdtimeout);
544 if (ret) return ret;
545
546 ret = SSL_read(sock->ssl.ssl, buffer, CAST2INT(len));
547 if (ret <= 0)
548 ret = error_ossl(sock, ret);
549
550 return ret;
551 }
552
write_ossl(ne_socket * sock,const char * data,size_t len)553 static ssize_t write_ossl(ne_socket *sock, const char *data, size_t len)
554 {
555 int ret, ilen = CAST2INT(len);
556 ret = SSL_write(sock->ssl.ssl, data, ilen);
557 /* ssl.h says SSL_MODE_ENABLE_PARTIAL_WRITE must be enabled to
558 * have SSL_write return < length... so, SSL_write should never
559 * return < length. */
560 if (ret != ilen)
561 return error_ossl(sock, ret);
562 return 0;
563 }
564
565 static const struct iofns iofns_ossl = {
566 read_ossl,
567 write_ossl,
568 readable_ossl
569 };
570
571 #endif /* NEON_SSL */
572
ne_sock_fullwrite(ne_socket * sock,const char * data,size_t len)573 int ne_sock_fullwrite(ne_socket *sock, const char *data, size_t len)
574 {
575 return sock->ops->write(sock, data, len);
576 }
577
ne_sock_readline(ne_socket * sock,char * buf,size_t buflen)578 ssize_t ne_sock_readline(ne_socket *sock, char *buf, size_t buflen)
579 {
580 char *lf;
581 size_t len;
582
583 if ((lf = memchr(sock->bufpos, '\n', sock->bufavail)) == NULL
584 && sock->bufavail < RDBUFSIZ) {
585 /* The buffered data does not contain a complete line: move it
586 * to the beginning of the buffer. */
587 if (sock->bufavail)
588 memmove(sock->buffer, sock->bufpos, sock->bufavail);
589 sock->bufpos = sock->buffer;
590
591 /* Loop filling the buffer whilst no newline is found in the data
592 * buffered so far, and there is still buffer space available */
593 do {
594 /* Read more data onto end of buffer. */
595 ssize_t ret = sock->ops->read(sock, sock->buffer + sock->bufavail,
596 RDBUFSIZ - sock->bufavail);
597 if (ret < 0) return ret;
598 sock->bufavail += ret;
599 } while ((lf = memchr(sock->buffer, '\n', sock->bufavail)) == NULL
600 && sock->bufavail < RDBUFSIZ);
601 }
602
603 if (lf)
604 len = lf - sock->bufpos + 1;
605 else
606 len = buflen; /* fall into "line too long" error... */
607
608 if ((len + 1) > buflen) {
609 set_error(sock, _("Line too long"));
610 return NE_SOCK_ERROR;
611 }
612
613 memcpy(buf, sock->bufpos, len);
614 buf[len] = '\0';
615 /* consume the line from buffer: */
616 sock->bufavail -= len;
617 sock->bufpos += len;
618 return len;
619 }
620
ne_sock_fullread(ne_socket * sock,char * buffer,size_t buflen)621 ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t buflen)
622 {
623 ssize_t len;
624
625 while (buflen > 0) {
626 len = ne_sock_read(sock, buffer, buflen);
627 if (len < 0) return len;
628 buflen -= len;
629 buffer += len;
630 }
631
632 return 0;
633 }
634
635 #ifndef INADDR_NONE
636 #define INADDR_NONE ((unsigned long) -1)
637 #endif
638
639 #if !defined(USE_GETADDRINFO) && !defined(HAVE_DECL_H_ERRNO) && !defined(WIN32)
640 /* Ancient versions of netdb.h don't export h_errno. */
641 extern int h_errno;
642 #endif
643
644 /* This implemementation does not attempt to support IPv6 using
645 * gethostbyname2 et al. */
ne_addr_resolve(const char * hostname,int flags)646 ne_sock_addr *ne_addr_resolve(const char *hostname, int flags)
647 {
648 ne_sock_addr *addr = ne_calloc(sizeof *addr);
649 #ifdef USE_GETADDRINFO
650 struct addrinfo hints = {0};
651 char *pnt;
652 hints.ai_socktype = SOCK_STREAM;
653 if (hostname[0] == '[' && ((pnt = strchr(hostname, ']')) != NULL)) {
654 char *hn = ne_strdup(hostname + 1);
655 hn[pnt - hostname - 1] = '\0';
656 #ifdef AI_NUMERICHOST /* added in the RFC2553 API */
657 hints.ai_flags = AI_NUMERICHOST;
658 #endif
659 hints.ai_family = AF_INET6;
660 addr->errnum = getaddrinfo(hn, NULL, &hints, &addr->result);
661 ne_free(hn);
662 } else {
663 #ifdef USE_GAI_ADDRCONFIG /* added in the RFC3493 API */
664 hints.ai_flags = AI_ADDRCONFIG;
665 hints.ai_family = AF_UNSPEC;
666 addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result);
667 #else
668 hints.ai_family = ipv6_disabled ? AF_INET : AF_UNSPEC;
669 addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result);
670 #endif
671 }
672 #else /* Use gethostbyname() */
673 unsigned long laddr;
674 struct hostent *hp;
675
676 laddr = inet_addr(hostname);
677 if (laddr == INADDR_NONE) {
678 hp = gethostbyname(hostname);
679 if (hp == NULL) {
680 #ifdef WIN32
681 addr->errnum = WSAGetLastError();
682 #else
683 addr->errnum = h_errno;
684 #endif
685 } else if (hp->h_length != sizeof(struct in_addr)) {
686 /* fail gracefully if somebody set RES_USE_INET6 */
687 addr->errnum = NO_RECOVERY;
688 } else {
689 size_t n;
690 /* count addresses */
691 for (n = 0; hp->h_addr_list[n] != NULL; n++)
692 /* noop */;
693
694 addr->count = n;
695 addr->addrs = ne_malloc(n * sizeof *addr->addrs);
696
697 for (n = 0; n < addr->count; n++)
698 memcpy(&addr->addrs[n], hp->h_addr_list[n], hp->h_length);
699 }
700 } else {
701 addr->addrs = ne_malloc(sizeof *addr->addrs);
702 addr->count = 1;
703 memcpy(addr->addrs, &laddr, sizeof *addr->addrs);
704 }
705 #endif
706 return addr;
707 }
708
ne_addr_result(const ne_sock_addr * addr)709 int ne_addr_result(const ne_sock_addr *addr)
710 {
711 return addr->errnum;
712 }
713
ne_addr_first(ne_sock_addr * addr)714 const ne_inet_addr *ne_addr_first(ne_sock_addr *addr)
715 {
716 #ifdef USE_GETADDRINFO
717 addr->cursor = addr->result->ai_next;
718 return addr->result;
719 #else
720 addr->cursor = 0;
721 return &addr->addrs[0];
722 #endif
723 }
724
ne_addr_next(ne_sock_addr * addr)725 const ne_inet_addr *ne_addr_next(ne_sock_addr *addr)
726 {
727 #ifdef USE_GETADDRINFO
728 struct addrinfo *ret = addr->cursor;
729 if (addr->cursor) addr->cursor = addr->cursor->ai_next;
730 #else
731 struct in_addr *ret;
732 if (++addr->cursor < addr->count)
733 ret = &addr->addrs[addr->cursor];
734 else
735 ret = NULL;
736 #endif
737 return ret;
738 }
739
ne_addr_error(const ne_sock_addr * addr,char * buf,size_t bufsiz)740 char *ne_addr_error(const ne_sock_addr *addr, char *buf, size_t bufsiz)
741 {
742 #ifdef WIN32
743 print_error(addr->errnum, buf, bufsiz);
744 #else
745 const char *err;
746 #ifdef USE_GETADDRINFO
747 /* override horrible generic "Name or service not known" error. */
748 if (addr->errnum == EAI_NONAME)
749 err = _("Host not found");
750 else
751 err = gai_strerror(addr->errnum);
752 #elif defined(HAVE_HSTRERROR)
753 err = hstrerror(addr->errnum);
754 #else
755 err = _("Host not found");
756 #endif
757 ne_strnzcpy(buf, err, bufsiz);
758 #endif /* WIN32 */
759 return buf;
760 }
761
ne_iaddr_print(const ne_inet_addr * ia,char * buf,size_t bufsiz)762 char *ne_iaddr_print(const ne_inet_addr *ia, char *buf, size_t bufsiz)
763 {
764 #ifdef USE_GETADDRINFO /* implies inet_ntop */
765 const char *ret;
766 #ifdef AF_INET6
767 if (ia->ai_family == AF_INET6) {
768 struct sockaddr_in6 *in6 = SACAST(in6, ia->ai_addr);
769 ret = inet_ntop(AF_INET6, &in6->sin6_addr, buf, bufsiz);
770 } else
771 #endif
772 if (ia->ai_family == AF_INET) {
773 struct sockaddr_in *in = SACAST(in, ia->ai_addr);
774 ret = inet_ntop(AF_INET, &in->sin_addr, buf, bufsiz);
775 } else
776 ret = NULL;
777 if (ret == NULL)
778 ne_strnzcpy(buf, "[IP address]", bufsiz);
779 #else
780 ne_strnzcpy(buf, inet_ntoa(*ia), bufsiz);
781 #endif
782 return buf;
783 }
784
ne_addr_destroy(ne_sock_addr * addr)785 void ne_addr_destroy(ne_sock_addr *addr)
786 {
787 #ifdef USE_GETADDRINFO
788 if (addr->result)
789 freeaddrinfo(addr->result);
790 #else
791 if (addr->addrs)
792 ne_free(addr->addrs);
793 #endif
794 ne_free(addr);
795 }
796
797 /* Connect socket 'fd' to address 'addr' on given 'port': */
raw_connect(int fd,const ne_inet_addr * addr,unsigned int port)798 static int raw_connect(int fd, const ne_inet_addr *addr, unsigned int port)
799 {
800 #ifdef USE_GETADDRINFO
801 #ifdef AF_INET6
802 /* fill in the _family field for AIX 4.3, which forgets to do so. */
803 if (addr->ai_family == AF_INET6) {
804 struct sockaddr_in6 in6;
805 memcpy(&in6, addr->ai_addr, sizeof in6);
806 in6.sin6_port = port;
807 in6.sin6_family = AF_INET6;
808 return connect(fd, (struct sockaddr *)&in6, sizeof in6);
809 } else
810 #endif
811 if (addr->ai_family == AF_INET) {
812 struct sockaddr_in in;
813 memcpy(&in, addr->ai_addr, sizeof in);
814 in.sin_port = port;
815 in.sin_family = AF_INET;
816 return connect(fd, (struct sockaddr *)&in, sizeof in);
817 } else {
818 errno = EINVAL;
819 return -1;
820 }
821 #else
822 struct sockaddr_in sa = {0};
823 sa.sin_family = AF_INET;
824 sa.sin_port = port;
825 sa.sin_addr = *addr;
826 return connect(fd, (struct sockaddr *)&sa, sizeof sa);
827 #endif
828 }
829
ne_sock_create(void)830 ne_socket *ne_sock_create(void)
831 {
832 ne_socket *sock = ne_calloc(sizeof *sock);
833 sock->rdtimeout = SOCKET_READ_TIMEOUT;
834 sock->bufpos = sock->buffer;
835 sock->ops = &iofns_raw;
836 sock->fd = -1;
837 return sock;
838 }
839
ne_sock_connect(ne_socket * sock,const ne_inet_addr * addr,unsigned int port)840 int ne_sock_connect(ne_socket *sock,
841 const ne_inet_addr *addr, unsigned int port)
842 {
843 int fd;
844
845 #ifdef USE_GETADDRINFO
846 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
847 * implementations do not set ai_socktype, e.g. RHL6.2. */
848 fd = socket(addr->ai_family, SOCK_STREAM, addr->ai_protocol);
849 #else
850 fd = socket(AF_INET, SOCK_STREAM, 0);
851 #endif
852 if (fd < 0) {
853 set_strerror(sock, ne_errno);
854 return -1;
855 }
856
857 #if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT) && defined(IPPROTO_TCP)
858 { /* Disable the Nagle algorithm; better to add write buffering
859 * instead of doing this. */
860 int flag = 1;
861 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);
862 }
863 #endif
864
865 if (raw_connect(fd, addr, ntohs(port))) {
866 set_strerror(sock, ne_errno);
867 ne_close(fd);
868 return -1;
869 }
870
871 sock->fd = fd;
872 return 0;
873 }
874
ne_iaddr_make(ne_iaddr_type type,const unsigned char * raw)875 ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw)
876 {
877 ne_inet_addr *ia;
878 #if !defined(AF_INET6) || !defined(USE_GETADDRINFO)
879 /* fail if IPv6 address is given if IPv6 is not supported. */
880 if (type == ne_iaddr_ipv6)
881 return NULL;
882 #endif
883 ia = ne_calloc(sizeof *ia);
884 #ifdef USE_GETADDRINFO
885 /* ai_protocol and ai_socktype aren't used by raw_connect so
886 * ignore them here. (for now) */
887 if (type == ne_iaddr_ipv4) {
888 struct sockaddr_in *in4 = ne_calloc(sizeof *in4);
889 ia->ai_family = AF_INET;
890 ia->ai_addr = (struct sockaddr *)in4;
891 ia->ai_addrlen = sizeof *in4;
892 in4->sin_family = AF_INET;
893 memcpy(&in4->sin_addr.s_addr, raw, sizeof in4->sin_addr.s_addr);
894 }
895 #ifdef AF_INET6
896 else {
897 struct sockaddr_in6 *in6 = ne_calloc(sizeof *in6);
898 ia->ai_family = AF_INET6;
899 ia->ai_addr = (struct sockaddr *)in6;
900 ia->ai_addrlen = sizeof *in6;
901 in6->sin6_family = AF_INET6;
902 memcpy(&in6->sin6_addr, raw, sizeof in6->sin6_addr.s6_addr);
903 }
904 #endif
905 #else /* !USE_GETADDRINFO */
906 memcpy(&ia->s_addr, raw, sizeof ia->s_addr);
907 #endif
908 return ia;
909 }
910
ne_iaddr_cmp(const ne_inet_addr * i1,const ne_inet_addr * i2)911 int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2)
912 {
913 #ifdef USE_GETADDRINFO
914 if (i1->ai_family != i2->ai_family)
915 return i2->ai_family - i1->ai_family;
916 if (i1->ai_family == AF_INET) {
917 struct sockaddr_in *in1 = SACAST(in, i1->ai_addr),
918 *in2 = SACAST(in, i2->ai_addr);
919 return memcmp(&in1->sin_addr.s_addr, &in2->sin_addr.s_addr,
920 sizeof in1->sin_addr.s_addr);
921 } else if (i1->ai_family == AF_INET6) {
922 struct sockaddr_in6 *in1 = SACAST(in6, i1->ai_addr),
923 *in2 = SACAST(in6, i2->ai_addr);
924 return memcmp(in1->sin6_addr.s6_addr, in2->sin6_addr.s6_addr,
925 sizeof in1->sin6_addr.s6_addr);
926 } else
927 return -1;
928 #else
929 return memcmp(&i1->s_addr, &i2->s_addr, sizeof i1->s_addr);
930 #endif
931 }
932
ne_iaddr_free(ne_inet_addr * addr)933 void ne_iaddr_free(ne_inet_addr *addr)
934 {
935 #ifdef USE_GETADDRINFO
936 ne_free(addr->ai_addr);
937 #endif
938 ne_free(addr);
939 }
940
ne_sock_accept(ne_socket * sock,int listener)941 int ne_sock_accept(ne_socket *sock, int listener)
942 {
943 int fd = accept(listener, NULL, NULL);
944
945 if (fd < 0)
946 return -1;
947
948 sock->fd = fd;
949 return 0;
950 }
951
ne_sock_fd(const ne_socket * sock)952 int ne_sock_fd(const ne_socket *sock)
953 {
954 return sock->fd;
955 }
956
ne_sock_read_timeout(ne_socket * sock,int timeout)957 void ne_sock_read_timeout(ne_socket *sock, int timeout)
958 {
959 sock->rdtimeout = timeout;
960 }
961
962 #ifdef NEON_SSL
963
ne_sock_switch_ssl(ne_socket * sock,void * ssl)964 void ne_sock_switch_ssl(ne_socket *sock, void *ssl)
965 {
966 sock->ssl.ssl = ssl;
967 sock->ops = &iofns_ossl;
968 }
969
ne_sock_connect_ssl(ne_socket * sock,ne_ssl_context * ctx)970 int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx)
971 {
972 SSL *ssl;
973 int ret;
974
975 if (seed_ssl_prng()) {
976 set_error(sock, _("SSL disabled due to lack of entropy"));
977 return NE_SOCK_ERROR;
978 }
979
980 sock->ssl.ssl = ssl = SSL_new(ctx->ctx);
981 if (!ssl) {
982 set_error(sock, _("Could not create SSL structure"));
983 return NE_SOCK_ERROR;
984 }
985
986 SSL_set_app_data(ssl, ctx);
987 SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
988 SSL_set_fd(ssl, sock->fd);
989 sock->ops = &iofns_ossl;
990
991 if (ctx->sess)
992 SSL_set_session(ssl, ctx->sess);
993
994 ret = SSL_connect(ssl);
995 if (ret != 1) {
996 error_ossl(sock, ret);
997 SSL_free(ssl);
998 sock->ssl.ssl = NULL;
999 return NE_SOCK_ERROR;
1000 }
1001
1002 return 0;
1003 }
1004
ne_sock_sslsock(ne_socket * sock)1005 ne_ssl_socket *ne_sock_sslsock(ne_socket *sock)
1006 {
1007 return &sock->ssl;
1008 }
1009
1010 #endif
1011
ne_sock_error(const ne_socket * sock)1012 const char *ne_sock_error(const ne_socket *sock)
1013 {
1014 return sock->error;
1015 }
1016
1017 /* Closes given ne_socket */
ne_sock_close(ne_socket * sock)1018 int ne_sock_close(ne_socket *sock)
1019 {
1020 int ret;
1021 #ifdef NEON_SSL
1022 if (sock->ssl.ssl) {
1023 SSL_shutdown(sock->ssl.ssl);
1024 SSL_free(sock->ssl.ssl);
1025 }
1026 #endif
1027 if (sock->fd < 0)
1028 ret = 0;
1029 else
1030 ret = ne_close(sock->fd);
1031 ne_free(sock);
1032 return ret;
1033 }
1034
1035 /* Returns HOST byte order port of given name */
ne_service_lookup(const char * name)1036 int ne_service_lookup(const char *name)
1037 {
1038 struct servent *ent;
1039 ent = getservbyname(name, "tcp");
1040 if (ent)
1041 return ntohs(ent->s_port);
1042 return 0;
1043 }
1044