From 67ac2acfdbac0376d2632f27f5b66394f7a1fb24 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Thu, 23 Aug 2012 23:45:34 +0300 Subject: [PATCH 1/3] Adds support for checking ipv6 tempaddr usage. Signed-off-by: Aki Tuomi --- configure.in | 3 +- src/common/compat.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/common/compat.h | 1 + src/or/main.c | 7 ++++ 4 files changed, 117 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 1c342c5..23187b2 100644 --- a/configure.in +++ b/configure.in @@ -687,7 +687,8 @@ AC_CHECK_HEADERS( sys/utime.h \ sys/wait.h \ syslog.h \ - utime.h + utime.h \ + dirent.h ) AC_CHECK_HEADERS(sys/param.h) diff --git a/src/common/compat.c b/src/common/compat.c index ca850a3..7d33de7 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -59,6 +59,14 @@ #include #endif +#ifdef HAVE_DIRENT_H +#include +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#endif + #ifndef HAVE_GETTIMEOFDAY #ifdef HAVE_FTIME #include @@ -3090,3 +3098,102 @@ format_win32_error(DWORD err) } #endif +/** + * Checks for any interface(s) that do not have use_tempaddr set + * enabling possible leak of MAC address. Logging can be enabled + * setting verbose to 1. + * + * Returns -1 on error, 0 on success/non-applicable, or + * number of interfaces that have failed. + */ +#ifdef _WIN32 +int +check_ipv6_tempaddr(int verbose) +{ + return 0; +} +#elif HAVE_DIRENT_H && HAVE_SYS_STAT_H +int +check_ipv6_tempaddr(int verbose) +{ + struct stat buf; + DIR *dir; + struct dirent *ent; + int n_of_interfaces; + + /* check for proc access */ + if (stat("/proc/sys/net/ipv6", &buf) == -1) { + return 0; /* no ipv6 enabled, or no proc fs */ + } + + /* then we check the interfaces */ + dir = opendir("/proc/sys/net/ipv6/conf"); + if (dir == NULL) { + if (verbose != 0) + log_warn(LD_GENERAL, "Could not open /proc/sys/net/ipv6/conf"); + return -1; + } + + n_of_interfaces = 0; + while ((ent = readdir(dir) ) != NULL) { + char fname[1024] = {0}; + + /* skip dot-files */ + if (ent->d_name[0] == '.') continue; + /* not an interface */ + if (!strncmp(ent->d_name, "all", 3) || + /* not an interface */ + !strncmp(ent->d_name, "default", 7) || + /* localhost is not outbound */ + !strncmp(ent->d_name, "lo", 2)) continue; + + snprintf(fname, sizeof fname, "%s/%s", "/proc/sys/net/ipv6/conf", + ent->d_name); + if (stat(fname, &buf) == 0) { + if (!S_ISDIR(buf.st_mode)) continue; /* not a directory */ + } else { + continue; /* not accessible */ + } + + snprintf(fname, sizeof fname, "%s/%s/use_tempaddr", + "/proc/sys/net/ipv6/conf", ent->d_name); + if (stat(fname, &buf) == 0) { + int state; + FILE *f; + /* read the value */ + f = fopen(fname, "r"); + if (f == NULL) { + if (verbose) + log_warn(LD_GENERAL, "Cannot check use_tempaddr for interface %s", + ent->d_name); + continue; + } + state = 0; + if (fscanf(f, "%d", &state) == 1) { + if (state == 0) { + n_of_interfaces++; + if (verbose) + log_warn(LD_GENERAL, "Interface %s might expose your MAC \ +address to world, you can fix this with \ +sysctl -p net.ipv6.conf.%s.use_tempaddr=2", ent->d_name, ent->d_name); + } + } else { + if (verbose) + log_warn(LD_GENERAL, + "Cannot check use_tempaddr for interface %s", + ent->d_name); + } + fclose(f); + } + } + closedir(dir); + return n_of_interfaces; +} +#else +int +check_ipv6_tempaddr(int verbose) +{ + return 0; +} +#endif + diff --git a/src/common/compat.h b/src/common/compat.h index 42648bb..01e3a12 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -692,3 +692,4 @@ char *format_win32_error(DWORD err); #endif +int check_ipv6_tempaddr(int); diff --git a/src/or/main.c b/src/or/main.c index 20a1e08..f9affdb 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -63,6 +63,10 @@ #include #endif +#ifdef HAVE_DIRENT_H +#include +#endif + void evdns_shutdown(int); /********* PROTOTYPES **********/ @@ -1850,6 +1854,9 @@ do_main_loop(void) int loop_result; time_t now; + /* check for IPv6 tempaddr use, in verbose mode */ + check_ipv6_tempaddr(1); + /* initialize dns resolve map, spawn workers if needed */ if (dns_init() < 0) { if (get_options()->ServerDNSAllowBrokenConfig) -- 1.7.9.5