comparison dbutil.c @ 579:8c737cd7c1af

merge of '48fdaa8706d1acda35e9d564adc9a1fbc96c18c8' and '658fd03abd21e0da7c4c89b9fff9dc693c72daae'
author Matt Johnston <matt@ucc.asn.au>
date Sat, 27 Feb 2010 11:53:18 +0000
parents 005530560594
children a98a2138364a
comparison
equal deleted inserted replaced
577:69e98c45db7c 579:8c737cd7c1af
293 293
294 TRACE(("leave dropbear_listen: success, %d socks bound", nsock)) 294 TRACE(("leave dropbear_listen: success, %d socks bound", nsock))
295 return nsock; 295 return nsock;
296 } 296 }
297 297
298 /* Connect to a given unix socket. The socket is blocking */
299 #ifdef ENABLE_CONNECT_UNIX
300 int connect_unix(const char* path) {
301 struct sockaddr_un addr;
302 int fd = -1;
303
304 memset((void*)&addr, 0x0, sizeof(addr));
305 addr.sun_family = AF_UNIX;
306 strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
307 fd = socket(PF_UNIX, SOCK_STREAM, 0);
308 if (fd < 0) {
309 TRACE(("Failed to open unix socket"))
310 return -1;
311 }
312 if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
313 TRACE(("Failed to connect to '%s' socket", path))
314 return -1;
315 }
316 return fd;
317 }
318 #endif
319
298 /* Connect via TCP to a host. Connection will try ipv4 or ipv6, will 320 /* Connect via TCP to a host. Connection will try ipv4 or ipv6, will
299 * return immediately if nonblocking is set. On failure, if errstring 321 * return immediately if nonblocking is set. On failure, if errstring
300 * wasn't null, it will be a newly malloced error message */ 322 * wasn't null, it will be a newly malloced error message */
301 323
302 /* TODO: maxfd */ 324 /* TODO: maxfd */
339 err = errno; 361 err = errno;
340 continue; 362 continue;
341 } 363 }
342 364
343 if (nonblocking) { 365 if (nonblocking) {
344 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { 366 setnonblocking(sock);
345 close(sock);
346 sock = -1;
347 if (errstring != NULL && *errstring == NULL) {
348 *errstring = m_strdup("Failed non-blocking");
349 }
350 TRACE(("Failed non-blocking: %s", strerror(errno)))
351 continue;
352 }
353 } 367 }
354 368
355 if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { 369 if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
356 if (errno == EINPROGRESS && nonblocking) { 370 if (errno == EINPROGRESS && nonblocking) {
357 TRACE(("Connect in progress")) 371 TRACE(("Connect in progress"))
523 } 537 }
524 538
525 execv(usershell, argv); 539 execv(usershell, argv);
526 } 540 }
527 541
542 void get_socket_address(int fd, char **local_host, char **local_port,
543 char **remote_host, char **remote_port, int host_lookup)
544 {
545 struct sockaddr_storage addr;
546 socklen_t addrlen;
547
548 if (local_host || local_port) {
549 addrlen = sizeof(addr);
550 if (getsockname(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
551 dropbear_exit("Failed socket address: %s", strerror(errno));
552 }
553 getaddrstring(&addr, local_host, local_port, host_lookup);
554 }
555 if (remote_host || remote_port) {
556 addrlen = sizeof(addr);
557 if (getpeername(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
558 dropbear_exit("Failed socket address: %s", strerror(errno));
559 }
560 getaddrstring(&addr, remote_host, remote_port, host_lookup);
561 }
562 }
563
528 /* Return a string representation of the socket address passed. The return 564 /* Return a string representation of the socket address passed. The return
529 * value is allocated with malloc() */ 565 * value is allocated with malloc() */
530 unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) { 566 void getaddrstring(struct sockaddr_storage* addr,
531 567 char **ret_host, char **ret_port,
532 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; 568 int host_lookup) {
533 char *retstring = NULL; 569
570 char host[NI_MAXHOST+1], serv[NI_MAXSERV+1];
571 unsigned int len;
534 int ret; 572 int ret;
535 unsigned int len; 573
574 int flags = NI_NUMERICSERV | NI_NUMERICHOST;
575
576 #ifndef DO_HOST_LOOKUP
577 host_lookup = 0;
578 #endif
579
580 if (host_lookup) {
581 flags = NI_NUMERICSERV;
582 }
536 583
537 len = sizeof(struct sockaddr_storage); 584 len = sizeof(struct sockaddr_storage);
538 /* Some platforms such as Solaris 8 require that len is the length 585 /* Some platforms such as Solaris 8 require that len is the length
539 * of the specific structure. Some older linux systems (glibc 2.1.3 586 * of the specific structure. Some older linux systems (glibc 2.1.3
540 * such as debian potato) have sockaddr_storage.__ss_family instead 587 * such as debian potato) have sockaddr_storage.__ss_family instead
548 len = sizeof(struct sockaddr_in6); 595 len = sizeof(struct sockaddr_in6);
549 } 596 }
550 #endif 597 #endif
551 #endif 598 #endif
552 599
553 ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf), 600 ret = getnameinfo((struct sockaddr*)addr, len, host, sizeof(host)-1,
554 sbuf, sizeof(sbuf), NI_NUMERICSERV | NI_NUMERICHOST); 601 serv, sizeof(serv)-1, flags);
555 602
556 if (ret != 0) { 603 if (ret != 0) {
557 /* This is a fairly bad failure - it'll fallback to IP if it 604 if (host_lookup) {
558 * just can't resolve */ 605 /* On some systems (Darwin does it) we get EINTR from getnameinfo
559 dropbear_exit("failed lookup (%d, %d)", ret, errno); 606 * somehow. Eew. So we'll just return the IP, since that doesn't seem
560 } 607 * to exhibit that behaviour. */
561 608 getaddrstring(addr, ret_host, ret_port, 0);
562 if (withport) { 609 return;
563 len = strlen(hbuf) + 2 + strlen(sbuf); 610 } else {
564 retstring = (char*)m_malloc(len); 611 /* if we can't do a numeric lookup, something's gone terribly wrong */
565 snprintf(retstring, len, "%s:%s", hbuf, sbuf); 612 dropbear_exit("Failed lookup: %s", gai_strerror(ret));
566 } else { 613 }
567 retstring = m_strdup(hbuf); 614 }
568 } 615
569 616 if (ret_host) {
570 return retstring; 617 *ret_host = m_strdup(host);
571 618 }
572 } 619 if (ret_port) {
573 620 *ret_port = m_strdup(serv);
574 /* Get the hostname corresponding to the address addr. On failure, the IP 621 }
575 * address is returned. The return value is allocated with strdup() */
576 char* getaddrhostname(struct sockaddr_storage * addr) {
577
578 char hbuf[NI_MAXHOST];
579 char sbuf[NI_MAXSERV];
580 int ret;
581 unsigned int len;
582 #ifdef DO_HOST_LOOKUP
583 const int flags = NI_NUMERICSERV;
584 #else
585 const int flags = NI_NUMERICHOST | NI_NUMERICSERV;
586 #endif
587
588 len = sizeof(struct sockaddr_storage);
589 /* Some platforms such as Solaris 8 require that len is the length
590 * of the specific structure. */
591 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
592 if (addr->ss_family == AF_INET) {
593 len = sizeof(struct sockaddr_in);
594 }
595 #ifdef AF_INET6
596 if (addr->ss_family == AF_INET6) {
597 len = sizeof(struct sockaddr_in6);
598 }
599 #endif
600 #endif
601
602
603 ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
604 sbuf, sizeof(sbuf), flags);
605
606 if (ret != 0) {
607 /* On some systems (Darwin does it) we get EINTR from getnameinfo
608 * somehow. Eew. So we'll just return the IP, since that doesn't seem
609 * to exhibit that behaviour. */
610 return getaddrstring(addr, 0);
611 }
612
613 return m_strdup(hbuf);
614 } 622 }
615 623
616 #ifdef DEBUG_TRACE 624 #ifdef DEBUG_TRACE
617 void printhex(const char * label, const unsigned char * buf, int len) { 625 void printhex(const char * label, const unsigned char * buf, int len) {
618 626