1
1
package fi .helsinki .cs .tmc .spyware ;
2
2
3
- import fi .helsinki .cs .tmc .events .TmcEventBus ;
4
3
import fi .helsinki .cs .tmc .utilities .JsonMaker ;
5
4
import java .net .NetworkInterface ;
6
5
import java .nio .charset .Charset ;
6
+ import java .security .MessageDigest ;
7
+ import java .security .NoSuchAlgorithmException ;
7
8
import java .util .ArrayList ;
8
9
import java .util .Enumeration ;
9
10
import java .util .List ;
10
11
import java .util .logging .Level ;
11
12
import java .util .logging .Logger ;
13
+ import javax .crypto .Mac ;
12
14
13
15
/**
14
- * Generates host information used by spyware to identify requests coming from single host.
15
- *
16
- * HostInformation is linked by hopefully unique enough small identifier which is calculated from
17
- * host information.
16
+ * Generates host information used by spyware to identify requests coming from
17
+ * single host.
18
18
*/
19
19
public class HostInformationGenerator {
20
20
21
21
private static final Logger log = Logger .getLogger (HostInformationGenerator .class .getName ());
22
+ private static final Charset UTF8 = Charset .forName ("UTF-8" );
22
23
23
- public int updateHostInformation () {
24
+ public String updateHostInformation (EventReceiver receiver ) {
24
25
JsonMaker data = getStaticHostInformation ();
25
26
// Should be unique enough not to collapse among singe users machines.
26
- int hostId = data .toString ().hashCode ();
27
+
28
+
29
+ String hostId = trySecureHash (data .toString ());
27
30
28
31
data .add ("hostId" , hostId );
29
32
30
- LoggableEvent event =
31
- new LoggableEvent (
33
+ LoggableEvent event
34
+ = new LoggableEvent (
32
35
"host_information_update" ,
33
36
data .toString ().getBytes (Charset .forName ("UTF-8" )));
34
- TmcEventBus . getDefault (). post (event );
37
+ receiver . receiveEvent (event );
35
38
36
39
return hostId ;
37
40
}
@@ -52,13 +55,8 @@ private static JsonMaker getStaticHostInformation() {
52
55
List <String > macs = new ArrayList <String >(2 );
53
56
while (iterator .hasMoreElements ()) {
54
57
NetworkInterface networkInterface = iterator .nextElement ();
55
- if (networkInterface .isUp () && !networkInterface .isLoopback ()) {
56
- byte [] mac = networkInterface .getHardwareAddress ();
57
- StringBuilder sb = new StringBuilder ();
58
- for (int i = 0 ; i < mac .length ; i ++) {
59
- sb .append (String .format ("%02X%s" , mac [i ], (i < mac .length - 1 ) ? ":" : "" ));
60
- }
61
- macs .add (sb .toString ());
58
+ if (!networkInterface .isLoopback ()) {
59
+ macs .add (trySecureHash (networkInterface .getHardwareAddress ()));
62
60
}
63
61
}
64
62
builder .add ("mac_addresses" , macs );
@@ -78,4 +76,31 @@ private static JsonMaker getStaticHostInformation() {
78
76
79
77
return builder ;
80
78
}
79
+
80
+ /**
81
+ * Attempt to provide a reasonably ok hash of mac address. Should the
82
+ * algorithm be missing original string is returned.
83
+ */
84
+ private static String trySecureHash (String mac ) {
85
+ return trySecureHash (mac .getBytes (UTF8 ));
86
+ }
87
+
88
+ private static String trySecureHash (byte [] mac ) {
89
+ try {
90
+ byte [] bytes = MessageDigest .getInstance ("SHA-256" ).digest (mac );
91
+ return byteToHex (bytes );
92
+ } catch (NoSuchAlgorithmException ex ) {
93
+ log .log (Level .WARNING , "Missing sha256 hash: {0}" , ex );
94
+ return byteToHex (mac );
95
+ }
96
+ }
97
+
98
+ private static String byteToHex (byte [] bytes ) {
99
+ StringBuilder sb = new StringBuilder ();
100
+ for (int i = 0 ; i < bytes .length ; i ++) {
101
+ sb .append (String .format ("%02X" , bytes [i ]));
102
+ }
103
+ return sb .toString ();
104
+ }
105
+
81
106
}
0 commit comments