11package fi .helsinki .cs .tmc .spyware ;
22
3- import fi .helsinki .cs .tmc .events .TmcEventBus ;
43import fi .helsinki .cs .tmc .utilities .JsonMaker ;
54import java .net .NetworkInterface ;
65import java .nio .charset .Charset ;
6+ import java .security .MessageDigest ;
7+ import java .security .NoSuchAlgorithmException ;
78import java .util .ArrayList ;
89import java .util .Enumeration ;
910import java .util .List ;
1011import java .util .logging .Level ;
1112import java .util .logging .Logger ;
13+ import javax .crypto .Mac ;
1214
1315/**
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.
1818 */
1919public class HostInformationGenerator {
2020
2121 private static final Logger log = Logger .getLogger (HostInformationGenerator .class .getName ());
22+ private static final Charset UTF8 = Charset .forName ("UTF-8" );
2223
23- public int updateHostInformation () {
24+ public String updateHostInformation (EventReceiver receiver ) {
2425 JsonMaker data = getStaticHostInformation ();
2526 // 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 ());
2730
2831 data .add ("hostId" , hostId );
2932
30- LoggableEvent event =
31- new LoggableEvent (
33+ LoggableEvent event
34+ = new LoggableEvent (
3235 "host_information_update" ,
3336 data .toString ().getBytes (Charset .forName ("UTF-8" )));
34- TmcEventBus . getDefault (). post (event );
37+ receiver . receiveEvent (event );
3538
3639 return hostId ;
3740 }
@@ -52,13 +55,8 @@ private static JsonMaker getStaticHostInformation() {
5255 List <String > macs = new ArrayList <String >(2 );
5356 while (iterator .hasMoreElements ()) {
5457 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 ()));
6260 }
6361 }
6462 builder .add ("mac_addresses" , macs );
@@ -78,4 +76,31 @@ private static JsonMaker getStaticHostInformation() {
7876
7977 return builder ;
8078 }
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+
81106}
0 commit comments