Skip to content

Commit 9effdcc

Browse files
committed
Merge pull request #127 from testmycode/snapshots
Include more details about the system on NetBeans start and link all event to the system
2 parents dc85657 + 098e831 commit 9effdcc

File tree

7 files changed

+237
-47
lines changed

7 files changed

+237
-47
lines changed

tmc-plugin/src/fi/helsinki/cs/tmc/events/TmcEventBus.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class TmcEventBus {
1616
public static TmcEventBus getDefault() {
1717
return instance;
1818
}
19-
19+
2020
// Factory method to avoid accidental creation when getDefault was meant.
2121
public static TmcEventBus createNewInstance() {
2222
return new TmcEventBus();
@@ -28,22 +28,22 @@ public static TmcEventBus createNewInstance() {
2828
private static interface Wrapper {
2929
public boolean wraps(TmcEventListener that);
3030
}
31-
31+
3232
private static class WeakListener extends TmcEventListener implements Wrapper {
3333
private WeakReference<TmcEventListener> weakRef;
34-
34+
3535
public WeakListener(TmcEventListener listener) {
3636
this.weakRef = new WeakReference<TmcEventListener>(listener);
3737
}
38-
38+
3939
@Override
4040
public void receive(TmcEvent event) throws Throwable {
4141
TmcEventListener listener = weakRef.get();
4242
if (listener != null) {
4343
listener.receive(event);
4444
}
4545
}
46-
46+
4747
@Override
4848
public boolean mayBeUnsubscribed() {
4949
return weakRef.get() == null;
@@ -54,16 +54,16 @@ public boolean wraps(TmcEventListener that) {
5454
return that == weakRef.get();
5555
}
5656
}
57-
57+
5858
private static class DependentListener extends TmcEventListener implements Wrapper {
5959
private TmcEventListener listener;
6060
private WeakReference<Object> weakRef;
61-
61+
6262
public DependentListener(TmcEventListener listener, Object dependency) {
6363
this.listener = listener;
6464
this.weakRef = new WeakReference<Object>(dependency);
6565
}
66-
66+
6767
@Override
6868
public void receive(TmcEvent event) throws Throwable {
6969
listener.receive(event);
@@ -91,15 +91,15 @@ private TmcEventBus() {
9191
public synchronized void subscribeStrongly(TmcEventListener listener) {
9292
this.listeners.add(listener);
9393
}
94-
94+
9595
/**
9696
* Subscribes a weak reference to a listener.
9797
* After all normal references to the listener disappear, it will eventually be unsubscribed.
9898
*/
9999
public synchronized void subscribeWeakly(TmcEventListener listener) {
100100
this.listeners.add(new WeakListener(listener));
101101
}
102-
102+
103103
/**
104104
* Subscribes a listener that is eventually removed after a given dependency is garbage-collected.
105105
*/
@@ -125,7 +125,7 @@ public synchronized void post(TmcEvent event) {
125125
eventQueue.add(event);
126126
processEventQueue();
127127
}
128-
128+
129129
private void processEventQueue() {
130130
// This handles post() during post()
131131
// but not yet subscribe*() during post().

tmc-plugin/src/fi/helsinki/cs/tmc/model/ConfigFile.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
import org.openide.filesystems.FileUtil;
1212

1313
public class ConfigFile {
14-
14+
1515
private final String name;
1616
private FileObject fileObject;
17-
17+
1818
public ConfigFile(String name) {
1919
this.name = name;
2020
}
21-
21+
2222
public FileObject getFileObject() throws IOException {
2323
if (fileObject == null) {
2424
FileObject root = FileUtil.getConfigRoot();
@@ -33,19 +33,19 @@ public FileObject getFileObject() throws IOException {
3333
}
3434
return fileObject;
3535
}
36-
36+
3737
public boolean exists() throws IOException {
3838
return getFileObject().getSize() > 0;
3939
}
4040

4141
public Writer getWriter() throws IOException {
4242
return new OutputStreamWriter(new BufferedOutputStream(getFileObject().getOutputStream()), "UTF-8");
4343
}
44-
44+
4545
public Reader getReader() throws IOException {
4646
return new InputStreamReader(new BufferedInputStream(getFileObject().getInputStream()), "UTF-8");
4747
}
48-
48+
4949
public void writeContents(String s) throws IOException {
5050
Writer w = getWriter();
5151
try {
@@ -54,7 +54,7 @@ public void writeContents(String s) throws IOException {
5454
w.close();
5555
}
5656
}
57-
57+
5858
public String readContents() throws IOException {
5959
return getFileObject().asText("UTF-8");
6060
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package fi.helsinki.cs.tmc.spyware;
2+
3+
import fi.helsinki.cs.tmc.utilities.JsonMaker;
4+
import java.net.InetAddress;
5+
import java.net.NetworkInterface;
6+
import java.nio.charset.Charset;
7+
import java.security.MessageDigest;
8+
import java.security.NoSuchAlgorithmException;
9+
import java.util.ArrayList;
10+
import java.util.Enumeration;
11+
import java.util.List;
12+
import java.util.logging.Level;
13+
import java.util.logging.Logger;
14+
import javax.crypto.Mac;
15+
16+
/**
17+
* Generates host information used by spyware to identify requests coming from
18+
* single host.
19+
*/
20+
public class HostInformationGenerator {
21+
22+
private static final Logger log = Logger.getLogger(HostInformationGenerator.class.getName());
23+
private static final Charset UTF8 = Charset.forName("UTF-8");
24+
25+
public String updateHostInformation(EventReceiver receiver) {
26+
JsonMaker data = getStaticHostInformation();
27+
28+
String hostId = trySecureHash(data.toString());
29+
30+
data.add("hostId", hostId);
31+
32+
LoggableEvent event
33+
= new LoggableEvent(
34+
"host_information_update",
35+
data.toString().getBytes(Charset.forName("UTF-8")));
36+
receiver.receiveEvent(event);
37+
38+
return hostId;
39+
}
40+
41+
private static JsonMaker getStaticHostInformation() {
42+
JsonMaker builder = JsonMaker.create();
43+
44+
try {
45+
InetAddress localMachine = java.net.InetAddress.getLocalHost();
46+
builder.add("hostAddress", localMachine.getHostAddress());
47+
builder.add("hostName", localMachine.getHostName());
48+
} catch (Exception ex) {
49+
log.log(Level.WARNING, "Exception while getting host name information: {0}", ex);
50+
}
51+
52+
try {
53+
Enumeration<NetworkInterface> iterator = NetworkInterface.getNetworkInterfaces();
54+
List<String> macs = new ArrayList<String>(2);
55+
while (iterator.hasMoreElements()) {
56+
NetworkInterface networkInterface = iterator.nextElement();
57+
if (!networkInterface.isLoopback()) {
58+
macs.add(trySecureHash(networkInterface.getHardwareAddress()));
59+
}
60+
}
61+
builder.add("mac_addresses", macs);
62+
63+
} catch (Exception ex) {
64+
log.log(Level.WARNING, "Exception while getting host mac information: {0}", ex);
65+
}
66+
67+
try {
68+
builder.add("user.name", System.getProperty("user.name"));
69+
builder.add("java.runtime.version", System.getProperty("java.runtime.version"));
70+
builder.add("os.name", System.getProperty("os.name"));
71+
builder.add("os.version", System.getProperty("os.version"));
72+
} catch (Exception e) {
73+
log.log(Level.WARNING, "Exception while getting basic host information: {0}", e);
74+
}
75+
76+
return builder;
77+
}
78+
79+
/**
80+
* Attempt to provide a reasonably ok hash of mac address. Should the
81+
* algorithm be missing original string is returned.
82+
*/
83+
private static String trySecureHash(String mac) {
84+
return trySecureHash(mac.getBytes(UTF8));
85+
}
86+
87+
private static String trySecureHash(byte[] mac) {
88+
try {
89+
byte[] bytes = MessageDigest.getInstance("SHA-256").digest(mac);
90+
return byteToHex(bytes);
91+
} catch (NoSuchAlgorithmException ex) {
92+
log.log(Level.WARNING, "Missing sha256 hash: {0}", ex);
93+
return byteToHex(mac);
94+
}
95+
}
96+
97+
private static String byteToHex(byte[] bytes) {
98+
StringBuilder sb = new StringBuilder();
99+
for (int i = 0; i < bytes.length; i++) {
100+
sb.append(String.format("%02X", bytes[i]));
101+
}
102+
return sb.toString();
103+
}
104+
105+
}

tmc-plugin/src/fi/helsinki/cs/tmc/spyware/LoggableEvent.java

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,22 @@
33
import fi.helsinki.cs.tmc.data.Course;
44
import fi.helsinki.cs.tmc.data.Exercise;
55
import fi.helsinki.cs.tmc.events.TmcEvent;
6-
import org.netbeans.api.annotations.common.NullAllowed;
6+
import fi.helsinki.cs.tmc.utilities.JsonMaker;
7+
import java.util.List;
8+
import java.util.logging.Logger;
79

810
public class LoggableEvent implements TmcEvent {
911

12+
private static final Logger log = Logger.getLogger(LoggableEvent.class.getName());
13+
1014
private String courseName;
1115
private String exerciseName;
1216
private String eventType;
17+
1318
private byte[] data;
14-
@NullAllowed private String metadata;
19+
20+
private JsonMaker metadata;
21+
1522
private long happenedAt; // millis from epoch
1623
private long systemNanotime;
1724
private transient String key;
@@ -28,20 +35,20 @@ public LoggableEvent(Course course, String eventType, byte[] data) {
2835
this(course.getName(), "", eventType, data, null);
2936
}
3037

31-
public LoggableEvent(Exercise exercise, String eventType, byte[] data, String metadata) {
38+
public LoggableEvent(Exercise exercise, String eventType, byte[] data, JsonMaker metadata) {
3239
this(exercise.getCourseName(), exercise.getName(), eventType, data, metadata);
3340
}
3441

3542
public LoggableEvent(String courseName, String exerciseName, String eventType, byte[] data) {
3643
this(courseName, exerciseName, eventType, data, null);
3744
}
3845

39-
public LoggableEvent(String courseName, String exerciseName, String eventType, byte[] data, String metadata) {
46+
public LoggableEvent(String courseName, String exerciseName, String eventType, byte[] data, JsonMaker metadata) {
4047
this.courseName = courseName;
4148
this.exerciseName = exerciseName;
4249
this.eventType = eventType;
4350
this.data = data;
44-
this.metadata = metadata;
51+
this.metadata = JsonMaker.create().merge(metadata);
4552
this.happenedAt = System.currentTimeMillis();
4653
this.systemNanotime = System.nanoTime();
4754

@@ -68,7 +75,32 @@ public byte[] getData() {
6875
* Optional JSON metadata.
6976
*/
7077
public String getMetadata() {
71-
return metadata;
78+
return metadata.toString();
79+
}
80+
81+
public LoggableEvent addMetadata(String name, String value) {
82+
metadata.add(name, value);
83+
return this;
84+
}
85+
86+
public LoggableEvent addMetadata(String name, long value) {
87+
metadata.add(name, value);
88+
return this;
89+
}
90+
91+
public LoggableEvent addMetadata(String name, boolean value) {
92+
metadata.add(name, value);
93+
return this;
94+
}
95+
96+
public LoggableEvent addMetadata(String name, List<String> values) {
97+
metadata.add(name, values);
98+
return this;
99+
}
100+
101+
public LoggableEvent addMetadata(JsonMaker metadata) {
102+
this.metadata.merge(metadata);
103+
return this;
72104
}
73105

74106
/**

0 commit comments

Comments
 (0)