Browse code

Use hashed MAC addresses as the hostid for Linux.

We determine if we're Linux by the absense of the sysctlbyname()
function. As the code introduced in this commit for getting MAC
addresses is specific to Linux, additional work will need to be
made to handle other operating systems (namely, OpenBSD and Solaris).

Conflicts:
libclamav/Makefile.in

Shawn Webb authored on 2013/10/31 03:28:08
Showing 8 changed files
... ...
@@ -178,6 +178,9 @@
178 178
 /* Define to 1 if the system has the type `error_t'. */
179 179
 #undef HAVE_ERROR_T
180 180
 
181
+/* Define to 1 if you have the <fcntl.h> header file */
182
+#undef HAVE_FCNTL_H
183
+
181 184
 /* have working file descriptor passing support */
182 185
 #undef HAVE_FD_PASSING
183 186
 
... ...
@@ -187,6 +190,9 @@
187 187
 /* have getaddrinfo() */
188 188
 #undef HAVE_GETADDRINFO
189 189
 
190
+/* Define to 1 if you have the `getifaddrs' function. */
191
+#undef HAVE_GETIFADDRS
192
+
190 193
 /* Define to 1 if getpagesize() is available */
191 194
 #undef HAVE_GETPAGESIZE
192 195
 
... ...
@@ -14427,6 +14427,25 @@ _ACEOF
14427 14427
 fi
14428 14428
 done
14429 14429
 
14430
+for ac_func in getifaddrs
14431
+do :
14432
+  ac_fn_c_check_func "$LINENO" "getifaddrs" "ac_cv_func_getifaddrs"
14433
+if test "x$ac_cv_func_getifaddrs" = xyes; then :
14434
+  cat >>confdefs.h <<_ACEOF
14435
+#define HAVE_GETIFADDRS 1
14436
+_ACEOF
14437
+
14438
+fi
14439
+done
14440
+
14441
+ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
14442
+if test "x$ac_cv_header_fcntl_h" = xyes; then :
14443
+
14444
+$as_echo "#define HAVE_FCNTL_H 1" >>confdefs.h
14445
+
14446
+fi
14447
+
14448
+
14430 14449
 
14431 14450
 # Check whether --enable-experimental was given.
14432 14451
 if test "${enable_experimental+set}" = set; then :
... ...
@@ -417,6 +417,8 @@ AC_COMPILE_CHECK_SIZEOF([long long])
417 417
 AC_COMPILE_CHECK_SIZEOF([void *])
418 418
 
419 419
 AC_CHECK_FUNCS([sysctlbyname])
420
+AC_CHECK_FUNCS([getifaddrs])
421
+AC_CHECK_HEADER([fcntl.h], AC_DEFINE([HAVE_FCNTL_H],1,[Define to 1 if you have the <fcntl.h> header file]))
420 422
 
421 423
 AC_ARG_ENABLE([experimental],
422 424
 [  --enable-experimental	enable experimental code],
... ...
@@ -423,7 +423,9 @@ libclamav_la_SOURCES = \
423 423
 	www.c \
424 424
 	www.h \
425 425
 	json.c \
426
-	json.h
426
+	json.h \
427
+	hostid.c \
428
+	hostid.h
427 429
 
428 430
 libclamav_la_SOURCES += bignum.h\
429 431
 	bignum_fast.h\
... ...
@@ -3167,7 +3167,9 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES
3167 3167
 	www.c \
3168 3168
 	www.h \
3169 3169
 	json.c \
3170
-	json.h
3170
+	json.h \
3171
+	hostid.c \
3172
+	hostid.h
3171 3173
 
3172 3174
 .PHONY: version.h.tmp
3173 3175
 version.c: version.h
3174 3176
new file mode 100644
... ...
@@ -0,0 +1,187 @@
0
+#if HAVE_CONFIG_H
1
+#include "clamav-config.h"
2
+#endif
3
+
4
+#include <stdio.h>
5
+#include <stdlib.h>
6
+#include <string.h>
7
+#include <unistd.h>
8
+
9
+#include <sys/types.h>
10
+#include <sys/socket.h>
11
+#include <netdb.h>
12
+#include <sys/ioctl.h>
13
+#include <fcntl.h>
14
+
15
+#if defined(SIOCGIFHWADDR)
16
+#include <net/if.h>
17
+#include <ifaddrs.h>
18
+#include <linux/sockios.h>
19
+#endif
20
+
21
+#include <errno.h>
22
+
23
+#include "hostid.h"
24
+#include "libclamav/md5.h"
25
+
26
+struct device *get_device_entry(struct device *devices, size_t *ndevices, const char *name)
27
+{
28
+    struct device *device;
29
+    void *p;
30
+    size_t i;
31
+
32
+    if ((devices)) {
33
+        int found = 0;
34
+
35
+        for (device = devices; device < devices + *ndevices; device++) {
36
+            if (!strcmp(device->name, name)) {
37
+                found = 1;
38
+                break;
39
+            }
40
+        }
41
+
42
+        if (!found) {
43
+            p = realloc(devices, sizeof(struct device) * (*ndevices + 1));
44
+            if (!(p)) {
45
+                for (i=0; i < *ndevices; i++)
46
+                    free(devices[i].name);
47
+                free(devices);
48
+                return NULL;
49
+            }
50
+
51
+            devices = p;
52
+            device = devices + *ndevices;
53
+            (*ndevices)++;
54
+            memset(device, 0x00, sizeof(struct device));
55
+        }
56
+    } else {
57
+        devices = calloc(1, sizeof(device));
58
+        if (!(devices))
59
+            return NULL;
60
+
61
+        device = devices;
62
+        *ndevices = 1;
63
+    }
64
+
65
+    if (!(device->name))
66
+        device->name = strdup(name);
67
+    return devices;
68
+}
69
+
70
+#if HAVE_GETIFADDRS
71
+struct device *get_devices(void)
72
+{
73
+    struct ifaddrs *addrs, *addr;
74
+    struct device *devices=NULL, *device=NULL;
75
+    size_t ndevices=0, i;
76
+    struct ifreq ifr;
77
+    void *p;
78
+    uint8_t *mac;
79
+    int sock;
80
+
81
+    if (getifaddrs(&addrs))
82
+        return NULL;
83
+
84
+    for (addr = addrs; addr != NULL; addr = addr->ifa_next) {
85
+        if (!(addr->ifa_addr))
86
+            continue;
87
+
88
+        if (addr->ifa_addr->sa_family != AF_PACKET)
89
+            continue;
90
+
91
+        devices = get_device_entry(devices, &ndevices, addr->ifa_name);
92
+        if (!(devices)) {
93
+            freeifaddrs(addrs);
94
+            return NULL;
95
+        }
96
+    }
97
+
98
+    if (addrs) {
99
+        freeifaddrs(addrs);
100
+        addrs = NULL;
101
+    }
102
+
103
+    sock = socket(AF_INET, SOCK_DGRAM, 0);
104
+    if (sock < 0)
105
+        goto err;
106
+
107
+#if defined(SIOCGIFHWADDR)
108
+    for (device = devices; device < devices + (ndevices); device++) {
109
+        memset(&ifr, 0x00, sizeof(struct ifreq));
110
+        strcpy(ifr.ifr_name, device->name);
111
+        if (ioctl(sock, SIOCGIFHWADDR, &ifr)) {
112
+            close(sock);
113
+            goto err;
114
+        }
115
+
116
+        mac = ((uint8_t *)(ifr.ifr_ifru.ifru_hwaddr.sa_data));
117
+        for (i=0; i<6; i++)
118
+            snprintf(device->mac+strlen(device->mac), sizeof(device->mac)-strlen(device->mac)-1, "%02x:", mac[i]);
119
+    }
120
+#endif
121
+
122
+    close(sock);
123
+    
124
+    p = realloc(devices, sizeof(struct device) * (ndevices + 1));
125
+    if (!(p))
126
+        goto err;
127
+
128
+    devices = p;
129
+    devices[ndevices].name =  NULL;
130
+    memset(devices[ndevices].mac, 0x00, sizeof(devices[ndevices].mac));
131
+
132
+    return devices;
133
+
134
+err:
135
+    if (addrs)
136
+        freeifaddrs(addrs);
137
+    if (devices) {
138
+        for (device = devices; device < devices + ndevices; device++)
139
+            if (device->name)
140
+                free(device->name);
141
+
142
+        free(devices);
143
+    }
144
+
145
+    return NULL;
146
+}
147
+#else
148
+struct device *get_devices(void)
149
+{
150
+    return NULL;
151
+}
152
+#endif /* HAVE_GETIFADDRS */
153
+
154
+#if !HAVE_SYSCTLBYNAME && !defined(_WIN32)
155
+char *internal_get_host_id(void)
156
+{
157
+    size_t i;
158
+    unsigned char raw_md5[16];
159
+    char *printable_md5;
160
+    cli_md5_ctx ctx;
161
+    struct device *devices;
162
+
163
+    devices = get_devices();
164
+    if (!(devices))
165
+        return NULL;
166
+
167
+    printable_md5 = calloc(1, 33);
168
+    if (!(printable_md5))
169
+        return NULL;
170
+
171
+    cli_md5_init(&ctx);
172
+    for (i=0; devices[i].name != NULL; i++)
173
+        cli_md5_update(&ctx, devices[i].mac, sizeof(devices[i].mac));
174
+
175
+    cli_md5_final(raw_md5, &ctx);
176
+
177
+    for (i=0; devices[i].name != NULL; i++)
178
+        free(devices[i].name);
179
+    free(devices);
180
+
181
+    for (i=0; i < sizeof(raw_md5); i++)
182
+        sprintf(printable_md5+(i*2), "%02x", raw_md5[i]);
183
+
184
+    return printable_md5;
185
+}
186
+#endif
0 187
new file mode 100644
... ...
@@ -0,0 +1,15 @@
0
+#if !defined(_LIBCLAMAV_HOSTID_H)
1
+#define _LIBCLAMAV_HOSTID_H
2
+
3
+struct device {
4
+    char *name;
5
+    char mac[19];
6
+};
7
+
8
+struct device *get_devices(void);
9
+
10
+#if !HAVE_SYSCTLBYNAME
11
+char *internal_get_host_id(void);
12
+#endif
13
+
14
+#endif
... ...
@@ -23,6 +23,7 @@
23 23
 #include "libclamav/clamav.h"
24 24
 #include "libclamav/json.h"
25 25
 #include "libclamav/stats.h"
26
+#include "libclamav/hostid.h"
26 27
 
27 28
 static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type);
28 29
 void free_sample(cli_flagged_sample_t *sample);
... ...
@@ -400,7 +401,10 @@ char *clamav_stats_get_hostid(void *cbdata)
400 400
         return buf;
401 401
     }
402 402
 #else
403
+    buf = internal_get_host_id();
404
+    if (!(buf))
403 405
         return strdup(STATS_ANON_UUID);
406
+    return buf;
404 407
 #endif
405 408
 
406 409
     return strdup(STATS_ANON_UUID);