Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/rofl0r/proxychains-ng.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrofl0r <retnyg@gmx.net>2014-11-14 14:33:58 +0300
committerrofl0r <retnyg@gmx.net>2014-11-14 14:33:58 +0300
commit4fb7eb05328465c97b5c374244a82596da9734cf (patch)
treed627248fcb0da3f5d9bf9cff2ff6c5a350279379
parent567935b1abb93af561600081461a46b89468b9ca (diff)
replace problematic hostentdb with hostsreader
the hostentdb introduced between 4.2 and 4.3 (via af5c6f0c6a7cddd46b801b7b59af7a5e9383c645 ) had several issues: - it caused breakage on FreeBSD and was commented out there - prevented usage of the hostdb when proxy_dns was turned off (issue #42) - required dynamic memory allocation which was accessed from several threads - wouldnt reflect changes to the hosts file made during program run the only sensible solution is to remove the hostentdb and replace it with a home-grown hosts parser (we can't use gethostent() since that would mess up the gethostent()-state from different threads). the new parser used here is deliberately held simple and only meant to provide the user with means to reference hardcoded ipv4 addresses via his hosts file. fixes #42
-rw-r--r--Makefile2
-rw-r--r--src/core.c9
-rw-r--r--src/hostentdb.c63
-rw-r--r--src/hostentdb.h23
-rw-r--r--src/hostsreader.c119
5 files changed, 122 insertions, 94 deletions
diff --git a/Makefile b/Makefile
index 3a179ea..0ebfa17 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ OBJS = $(SRCS:.c=.o)
LOBJS = src/nameinfo.o src/version.o \
src/core.o src/common.o src/libproxychains.o src/shm.o \
src/allocator_thread.o src/ip_type.o src/stringdump.o \
- src/hostentdb.o src/hash.o src/debug.o
+ src/hostsreader.o src/hash.o src/debug.o
GENH = src/version.h
diff --git a/src/core.c b/src/core.c
index 51a5973..49caf64 100644
--- a/src/core.c
+++ b/src/core.c
@@ -719,11 +719,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
return -1;
}
-#include "hostentdb.h"
-struct hostent_list hl;
-
void core_initialize(void) {
- hdb_init(&hl);
}
void core_unload(void) {
@@ -734,6 +730,7 @@ static void gethostbyname_data_setstring(struct gethostbyname_data* data, char*
data->hostent_space.h_name = data->addr_name;
}
+extern ip_type hostsreader_get_numeric_ip_for_name(const char* name);
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
PFUNC();
char buff[256];
@@ -758,10 +755,8 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
goto retname;
}
- memset(buff, 0, sizeof(buff));
-
// this iterates over the "known hosts" db, usually /etc/hosts
- ip_type hdb_res = hdb_get(&hl, (char*) name);
+ ip_type hdb_res = hostsreader_get_numeric_ip_for_name(name);
if(hdb_res.as_int != ip_type_invalid.as_int) {
data->resolved_addr = hdb_res.as_int;
goto retname;
diff --git a/src/hostentdb.c b/src/hostentdb.c
deleted file mode 100644
index 488e983..000000000
--- a/src/hostentdb.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <stdint.h>
-#include <string.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#include "ip_type.h"
-#include "hash.h"
-#include "stringdump.h"
-#include "hostentdb.h"
-#include "common.h"
-#include "debug.h"
-
-#define STEP 16
-static void hdb_add(struct hostent_list* hl, char* host, ip_type ip) {
- if(hl->count +1 > hl->capa) {
- void * nu = realloc(hl->entries, (hl->capa + STEP) * sizeof(struct hostent_entry));
- if(!nu) return;
- hl->entries = nu;
- hl->capa += STEP;
- }
- struct hostent_entry *h = &hl->entries[hl->count];
- h->hash = dalias_hash(host);
- h->ip.as_int = ip.as_int;
- h->str = dumpstring(host, strlen(host) + 1);
- if(h->str) hl->count++;
-}
-
-static void hdb_fill(struct hostent_list *hl) {
-#ifndef IS_BSD
- struct hostent* hp;
- while((hp = gethostent()))
- if(hp->h_addrtype == AF_INET && hp->h_length == sizeof(in_addr_t)) {
- hdb_add(hl, hp->h_name, (ip_type) { .as_int = *((in_addr_t*)(hp->h_addr_list[0])) });
- }
-#else
- /* FreeBSD hangs on gethostent(). since this feature is not crucial, we just do nothing */
- (void) hl;
-#endif
-}
-
-void hdb_init(struct hostent_list *hl) {
- memset(hl, 0, sizeof *hl);
- hdb_fill(hl);
-}
-
-ip_type hdb_get(struct hostent_list *hl, char* host) {
- size_t i;
- PFUNC();
- uint32_t hash = dalias_hash(host);
- for(i = 0; i < hl->count; i++) {
- if(hl->entries[i].hash == hash && !strcmp(hl->entries[i].str, host)) {
- #ifdef DEBUG
- char ipbuf[16];
- pc_stringfromipv4(hl->entries[i].ip.octet, ipbuf);
- PDEBUG("got ip %s for hostent entry %s\n", ipbuf, host);
- #endif
- return hl->entries[i].ip;
- }
- }
- return ip_type_invalid;
-}
diff --git a/src/hostentdb.h b/src/hostentdb.h
deleted file mode 100644
index 4f807d1..000000000
--- a/src/hostentdb.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef HOSTENTDB_H
-#define HOSTENTDB_H
-
-#include "ip_type.h"
-#include <unistd.h>
-
-struct hostent_entry {
- uint32_t hash;
- ip_type ip;
- char* str;
-};
-
-struct hostent_list {
- size_t count;
- size_t capa;
- struct hostent_entry *entries;
-};
-
-void hdb_init(struct hostent_list *hl);
-ip_type hdb_get(struct hostent_list *hl, char* host);
-
-//RcB: DEP "hostendb.c"
-#endif
diff --git a/src/hostsreader.c b/src/hostsreader.c
new file mode 100644
index 000000000..d20a1a5
--- /dev/null
+++ b/src/hostsreader.c
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+/*
+ simple reader for /etc/hosts
+ it only supports comments, blank lines and lines consisting of an ipv4 hostname pair.
+ this is required so we can return entries from the host db without messing up the
+ non-thread-safe state of libc's gethostent().
+
+*/
+
+struct hostsreader {
+ FILE *f;
+ char* ip, *name;
+};
+
+int hostsreader_open(struct hostsreader *ctx) {
+ if(!(ctx->f = fopen("/etc/hosts", "r"))) return 0;
+ return 1;
+}
+
+void hostsreader_close(struct hostsreader *ctx) {
+ fclose(ctx->f);
+}
+
+static int isnumericipv4(const char* ipstring);
+int hostsreader_get(struct hostsreader *ctx, char* buf, size_t bufsize) {
+ while(1) {
+ if(!fgets(buf, bufsize, ctx->f)) return 0;
+ if(*buf == '#') continue;
+ ctx->ip = buf;
+ while(*buf && !isspace(*buf) && bufsize) {
+ buf++;
+ bufsize--;
+ }
+ if(!bufsize || !*buf || buf == ctx->ip) continue;
+ *buf = 0;
+ buf++;
+ while(*buf && isspace(*buf) && bufsize) {
+ buf++;
+ bufsize--;
+ }
+ if(!bufsize || !*buf) continue;
+ ctx->name = buf;
+ while(*buf && !isspace(*buf) && bufsize) {
+ buf++;
+ bufsize--;
+ }
+ if(!bufsize || !*buf) continue;
+ *buf = 0;
+ if(isnumericipv4(ctx->ip)) return 1;
+ }
+}
+
+char* hostsreader_get_ip_for_name(const char* name, char* buf, size_t bufsize) {
+ struct hostsreader ctx;
+ char *res = 0;
+ if(!hostsreader_open(&ctx)) return 0;
+ while(hostsreader_get(&ctx, buf, bufsize)) {
+ if(!strcmp(ctx.name, name)) {
+ res = ctx.ip;
+ break;
+ }
+ }
+ hostsreader_close(&ctx);
+ return res;
+}
+
+#include "ip_type.h"
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+ip_type hostsreader_get_numeric_ip_for_name(const char* name) {
+ char *hres;
+ char buf[320];
+ if((hres = hostsreader_get_ip_for_name(name, buf, sizeof buf))) {
+ struct in_addr c;
+ inet_aton(hres, &c);
+ ip_type res;
+ memcpy(res.octet, &c.s_addr, 4);
+ return res;
+ } else return ip_type_invalid;
+}
+
+#ifdef HOSTSREADER_TEST
+int main() {
+ char buf[256];
+ char * ret = hostsreader_get_ip_for_name("goo", buf, sizeof buf);
+ printf("%s\n", ret ? ret : "null");
+}
+#endif
+
+/* isnumericipv4() taken from libulz */
+static int isnumericipv4(const char* ipstring) {
+ size_t x = 0, n = 0, d = 0;
+ int wasdot = 0;
+ while(1) {
+ switch(ipstring[x]) {
+ case 0: goto done;
+ case '.':
+ if(!n || wasdot) return 0;
+ d++;
+ wasdot = 1;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n++;
+ wasdot = 0;
+ break;
+ default:
+ return 0;
+ }
+ x++;
+ }
+ done:
+ if(d == 3 && n >= 4 && n <= 12) return 1;
+ return 0;
+}