Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.

Commit b8063ec

Browse files
committed
Merge branch 'dev'
2 parents 9a6d9d7 + 465e411 commit b8063ec

18 files changed

+1435
-72
lines changed

TODO.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Sailgauge tries port 8080
3030
Make Waypoint 'here' option
3131

3232
Enable users and passwords and protect server pages
33-
Add restart from web page
33+
3434
config.html wont delete arrays
3535
NMEA ais outputs incorrect position format?
3636
ais requires Cog true? cogM not considered.
@@ -40,10 +40,10 @@ log4j and config may need re-working after upgrade.
4040
REST api needs attention - http://www:8088/signalk/v1/config returns all
4141

4242
Finish adding XMPP support
43-
start xmpp routes
4443
add outgoing filters
4544
use queue to collect buffer
4645
* dont make xmmp.42.co.nz the default!
46+
*firewall needs an MSG_SRC_IP or a filter on XMPP server.
4747

4848
need avahi-utils?
4949

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
<version>0.0.1-SNAPSHOT</version>
77
<name>signalk-server-java</name>
88
<properties>
9+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
10+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
11+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
912
<!-- <bundle.name>nsb-${project.version}</bundle.name> -->
1013
<signalk.core.version>0.0.1-SNAPSHOT</signalk.core.version>
1114
<jetty.version>8.1.16.v20140903</jetty.version>
@@ -174,6 +177,11 @@
174177
<artifactId>camel-core</artifactId>
175178
<version>${camel.core.version}</version>
176179
</dependency>
180+
<dependency>
181+
<groupId>org.apache.camel</groupId>
182+
<artifactId>camel-spring-security</artifactId>
183+
<version>${camel.version}</version>
184+
</dependency>
177185
<dependency>
178186
<groupId>org.apache.camel</groupId>
179187
<artifactId>camel-websocket</artifactId>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
*
3+
* Copyright (C) 2012-2014 R T Huitema. All Rights Reserved.
4+
* Web: www.42.co.nz
5+
6+
* Author: R T Huitema
7+
*
8+
* This file is part of the signalk-server-java project
9+
*
10+
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11+
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12+
*
13+
* Licensed under the Apache License, Version 2.0 (the "License");
14+
* you may not use this file except in compliance with the License.
15+
* You may obtain a copy of the License at
16+
*
17+
* http://www.apache.org/licenses/LICENSE-2.0
18+
*
19+
* Unless required by applicable law or agreed to in writing, software
20+
* distributed under the License is distributed on an "AS IS" BASIS,
21+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
* See the License for the specific language governing permissions and
23+
* limitations under the License.
24+
*
25+
*/
26+
package nz.co.fortytwo.signalk.processor;
27+
28+
import static nz.co.fortytwo.signalk.util.SignalKConstants.LIST;
29+
import static nz.co.fortytwo.signalk.util.SignalKConstants.dot;
30+
import static nz.co.fortytwo.signalk.util.SignalKConstants.vessels;
31+
import static nz.co.fortytwo.signalk.util.SignalKConstants.vessels_dot_self;
32+
33+
import java.util.Iterator;
34+
import java.util.concurrent.ConcurrentHashMap;
35+
import java.util.concurrent.ConcurrentMap;
36+
37+
import org.apache.camel.Exchange;
38+
import org.apache.camel.Processor;
39+
import org.apache.commons.lang3.StringUtils;
40+
import org.apache.logging.log4j.LogManager;
41+
import org.apache.logging.log4j.Logger;
42+
43+
import com.google.common.collect.Multiset.Entry;
44+
import com.google.common.eventbus.Subscribe;
45+
46+
import nz.co.fortytwo.signalk.model.event.PathEvent;
47+
import nz.co.fortytwo.signalk.util.Util;
48+
49+
/**
50+
* Periodically run through the AIS entries and remove expired.
51+
* @author robert
52+
*
53+
*/
54+
public class AisExpiryProcessor extends SignalkProcessor implements Processor {
55+
56+
private static Logger logger = LogManager.getLogger(AisExpiryProcessor.class);
57+
private ConcurrentMap<String, Long> map = new ConcurrentHashMap<>();
58+
59+
60+
public AisExpiryProcessor(){
61+
signalkModel.getEventBus().register(this);
62+
for(String key: signalkModel.getKeys()){
63+
processPath(key);
64+
}
65+
}
66+
67+
@Override
68+
public void process(Exchange exchange) throws Exception {
69+
//event based, just triggers the checking
70+
//30 min ago.
71+
long millis = System.currentTimeMillis()-(30*60*1000);
72+
Iterator<java.util.Map.Entry<String, Long>> itr = map.entrySet().iterator();
73+
while(itr.hasNext()){
74+
java.util.Map.Entry<String, Long> e = itr.next();
75+
if(millis > e.getValue()){
76+
//drop the entry
77+
signalkModel.put(e.getKey(), null, "self.ais.expiry");
78+
itr.remove();
79+
}
80+
}
81+
}
82+
83+
/**
84+
* @param pathEvent the path that was changed
85+
*/
86+
@Subscribe
87+
public void recordEvent(PathEvent pathEvent) {
88+
if (pathEvent == null)
89+
return;
90+
91+
String path = pathEvent.getPath();
92+
processPath(path);
93+
94+
}
95+
96+
private void processPath(String path) {
97+
if(StringUtils.isBlank(path)) return;
98+
if (path.startsWith(vessels + dot)) {
99+
int p1 = path.indexOf(vessels) + vessels.length() + 1;
100+
int pos = path.indexOf(".", p1);
101+
if (pos < 0)return;
102+
path = path.substring(0, pos);
103+
if(vessels_dot_self.equals(path))return;
104+
map.put(path, System.currentTimeMillis());
105+
}
106+
}
107+
108+
}

src/main/java/nz/co/fortytwo/signalk/processor/FullExportProcessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ public void recordEvent(PathEvent pathEvent) {
227227
return;
228228

229229
if(path.endsWith(dot+source)
230-
&& path.endsWith(dot+timestamp)
231-
&& path.contains(dot+source+dot)
232-
&& path.endsWith(dot+sourceRef)){
230+
|| path.endsWith(dot+timestamp)
231+
|| path.contains(dot+source+dot)
232+
|| path.endsWith(dot+sourceRef)){
233233
return;
234234
}
235235
// Send update if necessary.

src/main/java/nz/co/fortytwo/signalk/processor/IncomingSecurityFilter.java renamed to src/main/java/nz/co/fortytwo/signalk/processor/IncomingSecurityFirewall.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,46 +23,46 @@
2323
*/
2424
package nz.co.fortytwo.signalk.processor;
2525

26-
import static nz.co.fortytwo.signalk.util.SignalKConstants.CONFIG;
2726
import static nz.co.fortytwo.signalk.util.SignalKConstants.CONFIG_ACTION;
2827
import static nz.co.fortytwo.signalk.util.SignalKConstants.CONFIG_ACTION_SAVE;
2928
import static nz.co.fortytwo.signalk.util.SignalKConstants.CONTEXT;
29+
import static nz.co.fortytwo.signalk.util.SignalKConstants.DEMO;
3030
import static nz.co.fortytwo.signalk.util.SignalKConstants.INTERNAL_IP;
3131
import static nz.co.fortytwo.signalk.util.SignalKConstants.MSG_SRC_IP;
3232
import static nz.co.fortytwo.signalk.util.SignalKConstants.MSG_TYPE;
3333
import static nz.co.fortytwo.signalk.util.SignalKConstants.PUT;
3434
import static nz.co.fortytwo.signalk.util.SignalKConstants.SERIAL;
3535
import static nz.co.fortytwo.signalk.util.SignalKConstants.UPDATES;
36-
import static nz.co.fortytwo.signalk.util.SignalKConstants.dot;
3736
import static nz.co.fortytwo.signalk.util.SignalKConstants.self;
3837

3938
import java.util.ArrayList;
4039
import java.util.List;
4140

41+
import org.apache.camel.Exchange;
42+
import org.apache.camel.Processor;
43+
import org.apache.logging.log4j.LogManager;
44+
import org.apache.logging.log4j.Logger;
45+
4246
import mjson.Json;
4347
import nz.co.fortytwo.signalk.util.ConfigConstants;
4448
import nz.co.fortytwo.signalk.util.Util;
4549

46-
import org.apache.camel.Exchange;
47-
import org.apache.camel.Processor;
48-
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;
49-
5050
/**
5151
* Parse the signalkModel json and remove anything that violates security
5252
*
5353
* @author robert
5454
*
5555
*/
56-
public class IncomingSecurityFilter extends SignalkProcessor implements
56+
public class IncomingSecurityFirewall extends SignalkProcessor implements
5757
Processor {
5858

5959
private static Logger logger = LogManager
60-
.getLogger(IncomingSecurityFilter.class);
60+
.getLogger(IncomingSecurityFirewall.class);
6161
private List<String> whiteList = new ArrayList<String>();
6262
private List<String> configAcceptList = new ArrayList<String>();
6363
private List<String> denyList = new ArrayList<String>();
6464

65-
public IncomingSecurityFilter() {
65+
public IncomingSecurityFirewall() {
6666
// load lists now
6767
Json deny = Util.getConfigJsonArray(ConfigConstants.SECURITY_DENY);
6868
Json white = Util.getConfigJsonArray(ConfigConstants.SECURITY_WHITE);
@@ -90,16 +90,21 @@ public void process(Exchange exchange) throws Exception {
9090
// we trust local serial
9191
String type = exchange.getIn().getHeader(MSG_TYPE,
9292
String.class);
93-
if (SERIAL.equals(type))
93+
if (SERIAL.equals(type)||DEMO.equals(type)){
94+
if (logger.isDebugEnabled())
95+
logger.debug("Accepting msg:" + type);
9496
return;
95-
97+
}
98+
//TODO: check for valid XMPP/STOMP/MQTT SRC_IP ??
99+
96100
// we filter on ip
97101
String srcIp = exchange.getIn().getHeader(MSG_SRC_IP,
98102
String.class);
99103
if (logger.isDebugEnabled())
100104
logger.debug("Checking src ip:" + srcIp);
101105
if (srcIp == null) {
102-
logger.debug(exchange);
106+
logger.debug("Src ip null:"+exchange.getIn().getHeaders());
107+
//exchange.getIn().setBody(null);
103108
return;
104109
}
105110
// denied - drop now
@@ -131,8 +136,7 @@ public void process(Exchange exchange) throws Exception {
131136
// we trust INTERNAL_IP
132137
if (INTERNAL_IP.equals(type)) {
133138
if (logger.isDebugEnabled())
134-
logger.debug("Message allowed for src ip (internal):"
135-
+ srcIp);
139+
logger.debug("Message allowed for src ip (internal):"+ srcIp+":"+exchange.getIn().getHeaders());
136140
return;
137141
}
138142

src/main/java/nz/co/fortytwo/signalk/processor/LoggerProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import java.io.File;
2929
import java.io.IOException;
30+
import java.nio.charset.StandardCharsets;
3031
import java.util.NavigableMap;
3132

3233
import javax.servlet.http.HttpServletRequest;
@@ -90,7 +91,7 @@ private void processPost(Exchange exchange) throws IOException {
9091
String conf = exchange.getIn().getBody(String.class);
9192
//Json confJson = Json.read(conf);
9293
logger.debug("POST Log4j2 = " + conf);
93-
FileUtils.writeStringToFile(new File(Util.getRootPath()+"./conf/log4j2.json"), conf);
94+
FileUtils.writeStringToFile(new File(Util.getRootPath()+"./conf/log4j2.json"), conf, StandardCharsets.UTF_8);
9495

9596
}
9697

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
*
3+
* Copyright (C) 2012-2014 R T Huitema. All Rights Reserved.
4+
* Web: www.42.co.nz
5+
6+
* Author: R T Huitema
7+
*
8+
* This file is part of the signalk-server-java project
9+
*
10+
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11+
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12+
*
13+
* Licensed under the Apache License, Version 2.0 (the "License");
14+
* you may not use this file except in compliance with the License.
15+
* You may obtain a copy of the License at
16+
*
17+
* http://www.apache.org/licenses/LICENSE-2.0
18+
*
19+
* Unless required by applicable law or agreed to in writing, software
20+
* distributed under the License is distributed on an "AS IS" BASIS,
21+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
* See the License for the specific language governing permissions and
23+
* limitations under the License.
24+
*
25+
*/
26+
package nz.co.fortytwo.signalk.processor;
27+
28+
import java.security.Principal;
29+
30+
import javax.security.auth.Subject;
31+
32+
import org.apache.camel.Exchange;
33+
import org.apache.camel.Processor;
34+
35+
import nz.co.fortytwo.signalk.model.SignalKModel;
36+
37+
/**
38+
* Apply a permissions filter to the map based on meta data for the entries, and provided user.
39+
*
40+
* @author robert
41+
*
42+
*/
43+
public class PermissionsProcessor extends SignalkProcessor implements Processor {
44+
45+
@Override
46+
public void process(Exchange exchange) throws Exception {
47+
if (exchange.getIn().getBody() instanceof SignalKModel) {
48+
Subject subject = exchange.getIn().getHeader(Exchange.AUTHENTICATION, Subject.class);
49+
if(subject==null)return;
50+
for(Principal p:subject.getPrincipals()){
51+
p.getName();
52+
53+
}
54+
}
55+
56+
}
57+
58+
}

src/main/java/nz/co/fortytwo/signalk/processor/SourceToSourceRefProcessor.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,22 @@
2424

2525
package nz.co.fortytwo.signalk.processor;
2626

27+
import static nz.co.fortytwo.signalk.util.SignalKConstants.MSG_TYPE;
2728
import static nz.co.fortytwo.signalk.util.SignalKConstants.dot;
28-
import static nz.co.fortytwo.signalk.util.SignalKConstants.normal;
29+
import static nz.co.fortytwo.signalk.util.SignalKConstants.label;
2930
import static nz.co.fortytwo.signalk.util.SignalKConstants.source;
3031
import static nz.co.fortytwo.signalk.util.SignalKConstants.sourceRef;
3132
import static nz.co.fortytwo.signalk.util.SignalKConstants.sources;
32-
import static nz.co.fortytwo.signalk.util.SignalKConstants.type;
33-
import static nz.co.fortytwo.signalk.util.SignalKConstants.vessels_dot_self_dot;
3433

3534
import java.util.Map.Entry;
3635
import java.util.NavigableMap;
3736

38-
import mjson.Json;
39-
import nz.co.fortytwo.signalk.model.SignalKModel;
40-
import nz.co.fortytwo.signalk.util.JsonSerializer;
41-
4237
import org.apache.camel.Exchange;
4338
import org.apache.camel.Processor;
44-
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;
39+
import org.apache.logging.log4j.LogManager;
40+
import org.apache.logging.log4j.Logger;
41+
42+
import nz.co.fortytwo.signalk.model.SignalKModel;
4543

4644
/**
4745
* Replaces source with the actual $sourceRef object and stores source in sources.*
@@ -66,27 +64,28 @@ public void process(Exchange exchange) throws Exception {
6664
for(String key : model.getKeys()){
6765
//get the source.type key
6866
//if(logger.isDebugEnabled())logger.debug("Key:"+key);
69-
if(key.endsWith(dot+source+dot+type)){
67+
if(key.endsWith(dot+source+dot+label)){
7068
if(logger.isDebugEnabled())logger.debug("Convert key:"+key);
7169
int pos = key.indexOf(dot+source+dot);
72-
String typeVal = (String) model.get(key);
70+
String typeVal = exchange.getIn().getHeader(MSG_TYPE,String.class);
7371

7472
int pos1 = pos+source.length()+2;
7573
String refKey = key.substring(0,pos);
76-
if(logger.isDebugEnabled())logger.debug("refKey:"+refKey+", type:"+typeVal);
74+
if(logger.isDebugEnabled())logger.debug("refKey:"+refKey+", bus:"+typeVal);
7775
//get the label
78-
String label = (String) model.get(refKey+dot+source+dot+"label");
76+
String lbl = (String) model.get(refKey+dot+source+dot+label);
77+
if(logger.isDebugEnabled())logger.debug("refKey:"+refKey+", label:"+lbl);
7978
//set sourceRef
80-
model.getFullData().put(refKey+dot+sourceRef, typeVal+dot+label);
79+
model.getFullData().put(refKey+dot+sourceRef, typeVal+dot+lbl);
8180
//put in sources
8281
NavigableMap<String, Object> node = signalkModel.getSubMap(refKey+dot+source);
8382
if(logger.isDebugEnabled())logger.debug("Found keys:"+node.size());
8483
//node is the source object
8584
if(node!=null){
8685
for(Entry<String, Object> entry:node.entrySet()){
8786
String nodeKey = entry.getKey().substring(pos1);
88-
model.getFullData().put(sources+dot+typeVal+dot+label+dot+nodeKey, entry.getValue());
89-
if(logger.isDebugEnabled())logger.debug("Added key:"+sources+dot+typeVal+dot+label+dot+nodeKey+"="+entry.getValue());
87+
model.getFullData().put(sources+dot+typeVal+dot+lbl+dot+nodeKey, entry.getValue());
88+
if(logger.isDebugEnabled())logger.debug("Added key:"+sources+dot+typeVal+dot+lbl+dot+nodeKey+"="+entry.getValue());
9089
}
9190

9291
//drop the source key and all subkeys

0 commit comments

Comments
 (0)