Skip to content

Commit dcc58b1

Browse files
committed
Revert "[snmp] SNMP v3 fixes and improvements (openhab#16803)"
This reverts commit 51da65b.
1 parent 98961fe commit dcc58b1

File tree

10 files changed

+84
-182
lines changed

10 files changed

+84
-182
lines changed

bundles/org.openhab.binding.snmp/README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,13 @@ The default is `v1`.
7777

7878
### `target3`
7979

80-
The `target3` thing has an additional mandatory parameter: `user`.
81-
This value of this parameter is named "securityName" or "userName" in most agents.
80+
The `target3` thing has additional mandatory parameters: `engineId` and `user`.
81+
82+
The `engineId` must be given in hexadecimal notation (case-insensitive) without separators (e.g. `80000009035c710dbcd9e6`).
83+
The allowed length is 11 to 32 bytes (22 to 64 hex characters).
84+
If you encounter problems, please check if your agent prefixes the set engine id (e.g. Mikrotik uses `80003a8c04` and appends the set value to that).
85+
86+
The `user` parameter is named "securityName" or "userName" in most agents.
8287

8388
Optional configuration parameters are: `securityModel`, `authProtocol`, `authPassphrase`, `privProtocol` and `privPassphrase`.
8489

@@ -94,7 +99,7 @@ If authentication encryption is required, at least `authPassphrase` needs to be
9499
Other possible values for `authProtocol` are `SHA`, `HMAC128SHA224`, `HMAC192SHA256`, `HMAC256SHA384` and `HMAC384SHA512`.
95100

96101
If encryption of transmitted data (privacy encryption) is required, at least `privPassphrase` needs to be set, while `privProtocol` defaults to `DES`.
97-
Other possible values for `privProtocol` are `DES3`, `AES128`, `AES192` and `AES256`.
102+
Other possible values for `privProtocol` are `AES128`, `AES192` and `AES256`.
98103

99104
## Channels
100105

bundles/org.openhab.binding.snmp/pom.xml

+1-7
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,7 @@
1818
<dependency>
1919
<groupId>org.snmp4j</groupId>
2020
<artifactId>snmp4j</artifactId>
21-
<version>3.8.2</version>
22-
<scope>compile</scope>
23-
</dependency>
24-
<dependency>
25-
<groupId>org.snmp4j</groupId>
26-
<artifactId>snmp4j-unix-transport</artifactId>
27-
<version>1.1.0</version>
21+
<version>2.8.6</version>
2822
<scope>compile</scope>
2923
</dependency>
3024
</dependencies>

bundles/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/internal/SnmpService.java

+5-47
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@
1616

1717
import org.eclipse.jdt.annotation.NonNullByDefault;
1818
import org.eclipse.jdt.annotation.Nullable;
19+
import org.openhab.binding.snmp.internal.types.SnmpAuthProtocol;
20+
import org.openhab.binding.snmp.internal.types.SnmpPrivProtocol;
1921
import org.snmp4j.CommandResponder;
2022
import org.snmp4j.PDU;
2123
import org.snmp4j.Target;
2224
import org.snmp4j.event.ResponseListener;
23-
import org.snmp4j.security.UsmUser;
24-
import org.snmp4j.smi.Address;
25-
import org.snmp4j.smi.OctetString;
2625

2726
/**
2827
* The {@link SnmpService} is responsible for SNMP communication
@@ -34,53 +33,12 @@
3433
@NonNullByDefault
3534
public interface SnmpService {
3635

37-
/**
38-
* Add a listener for received PDUs to the service
39-
*
40-
* @param listener the listener
41-
*/
4236
void addCommandResponder(CommandResponder listener);
4337

44-
/**
45-
* Remove a listener for received PDUs from the service
46-
*
47-
* @param listener the listener
48-
*/
4938
void removeCommandResponder(CommandResponder listener);
5039

51-
/**
52-
* Send a PDU to the given target
53-
*
54-
* @param pdu the PDU
55-
* @param target the target
56-
* @param userHandle an optional user-handle to identify the request
57-
* @param listener the listener for the response (always called, even in case of timeout)
58-
* @throws IOException when an error occurs
59-
*/
60-
void send(PDU pdu, Target<?> target, @Nullable Object userHandle, ResponseListener listener) throws IOException;
40+
void send(PDU pdu, Target target, @Nullable Object userHandle, ResponseListener listener) throws IOException;
6141

62-
/**
63-
* Add a user to the service for a given engine id (v3 only)
64-
*
65-
* @param user the {@link UsmUser} that should be added
66-
* @param engineId the engine id
67-
*/
68-
void addUser(UsmUser user, OctetString engineId);
69-
70-
/**
71-
* Remove a user from the service and clear the context engine id for this address (v3 only)
72-
*
73-
* @param address the remote address
74-
* @param user the user
75-
* @param engineId the engine id
76-
*/
77-
void removeUser(Address address, UsmUser user, OctetString engineId);
78-
79-
/**
80-
* Get the engine id of a remote system for a given address (v3 only)
81-
*
82-
* @param address the address of the remote system
83-
* @return the engine id or {@code null} when engine id could not be determined
84-
*/
85-
byte @Nullable [] getEngineId(Address address);
42+
void addUser(String userName, SnmpAuthProtocol snmpAuthProtocol, @Nullable String authPassphrase,
43+
SnmpPrivProtocol snmpPrivProtocol, @Nullable String privPassphrase, byte[] engineId);
8644
}

bundles/org.openhab.binding.snmp/src/main/java/org/openhab/binding/snmp/internal/SnmpServiceImpl.java

+30-55
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.eclipse.jdt.annotation.NonNullByDefault;
2323
import org.eclipse.jdt.annotation.Nullable;
2424
import org.openhab.binding.snmp.internal.config.SnmpServiceConfiguration;
25+
import org.openhab.binding.snmp.internal.types.SnmpAuthProtocol;
26+
import org.openhab.binding.snmp.internal.types.SnmpPrivProtocol;
2527
import org.openhab.core.config.core.Configuration;
2628
import org.osgi.service.component.annotations.Activate;
2729
import org.osgi.service.component.annotations.Component;
@@ -35,22 +37,11 @@
3537
import org.snmp4j.Target;
3638
import org.snmp4j.event.ResponseListener;
3739
import org.snmp4j.mp.MPv3;
38-
import org.snmp4j.security.AuthHMAC128SHA224;
39-
import org.snmp4j.security.AuthHMAC192SHA256;
40-
import org.snmp4j.security.AuthHMAC256SHA384;
41-
import org.snmp4j.security.AuthHMAC384SHA512;
42-
import org.snmp4j.security.AuthMD5;
43-
import org.snmp4j.security.AuthSHA;
4440
import org.snmp4j.security.Priv3DES;
45-
import org.snmp4j.security.PrivAES128;
46-
import org.snmp4j.security.PrivAES192;
47-
import org.snmp4j.security.PrivAES256;
48-
import org.snmp4j.security.PrivDES;
4941
import org.snmp4j.security.SecurityModels;
5042
import org.snmp4j.security.SecurityProtocols;
5143
import org.snmp4j.security.USM;
5244
import org.snmp4j.security.UsmUser;
53-
import org.snmp4j.smi.Address;
5445
import org.snmp4j.smi.OctetString;
5546
import org.snmp4j.smi.UdpAddress;
5647
import org.snmp4j.transport.DefaultUdpTransportMapping;
@@ -67,6 +58,7 @@
6758
public class SnmpServiceImpl implements SnmpService {
6859
private final Logger logger = LoggerFactory.getLogger(SnmpServiceImpl.class);
6960

61+
private @NonNullByDefault({}) SnmpServiceConfiguration config;
7062
private @Nullable Snmp snmp;
7163
private @Nullable DefaultUdpTransportMapping transport;
7264

@@ -75,7 +67,9 @@ public class SnmpServiceImpl implements SnmpService {
7567

7668
@Activate
7769
public SnmpServiceImpl(Map<String, Object> config) {
78-
addProtocols();
70+
SecurityProtocols.getInstance().addDefaultProtocols();
71+
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
72+
7973
OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
8074
USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
8175
SecurityModels.getInstance().addSecurityModel(usm);
@@ -85,33 +79,34 @@ public SnmpServiceImpl(Map<String, Object> config) {
8579

8680
@Modified
8781
protected void modified(Map<String, Object> config) {
88-
SnmpServiceConfiguration snmpCfg = new Configuration(config).as(SnmpServiceConfiguration.class);
82+
this.config = new Configuration(config).as(SnmpServiceConfiguration.class);
8983
try {
9084
shutdownSnmp();
9185

9286
final DefaultUdpTransportMapping transport;
9387

94-
if (snmpCfg.port > 0) {
95-
transport = new DefaultUdpTransportMapping(new UdpAddress(snmpCfg.port), true);
88+
if (this.config.port > 0) {
89+
transport = new DefaultUdpTransportMapping(new UdpAddress(this.config.port), true);
9690
} else {
9791
transport = new DefaultUdpTransportMapping();
9892
}
9993

100-
addProtocols();
94+
SecurityProtocols.getInstance().addDefaultProtocols();
95+
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
10196

10297
final Snmp snmp = new Snmp(transport);
10398
listeners.forEach(snmp::addCommandResponder);
10499
snmp.listen();
105100

106101
// re-add user entries
107-
userEntries.forEach(u -> snmp.getUSM().addUser(u.user, u.engineId));
102+
userEntries.forEach(u -> addUser(snmp, u));
108103

109104
this.snmp = snmp;
110105
this.transport = transport;
111106

112107
logger.debug("initialized SNMP at {}", transport.getAddress());
113108
} catch (IOException e) {
114-
logger.warn("could not open SNMP instance on port {}: {}", snmpCfg.port, e.getMessage());
109+
logger.warn("could not open SNMP instance on port {}: {}", this.config.port, e.getMessage());
115110
}
116111
}
117112

@@ -125,21 +120,6 @@ public void deactivate() {
125120
}
126121
}
127122

128-
private void addProtocols() {
129-
SecurityProtocols secProtocols = SecurityProtocols.getInstance();
130-
secProtocols.addAuthenticationProtocol(new AuthMD5());
131-
secProtocols.addAuthenticationProtocol(new AuthSHA());
132-
secProtocols.addAuthenticationProtocol(new AuthHMAC128SHA224());
133-
secProtocols.addAuthenticationProtocol(new AuthHMAC192SHA256());
134-
secProtocols.addAuthenticationProtocol(new AuthHMAC256SHA384());
135-
secProtocols.addAuthenticationProtocol(new AuthHMAC384SHA512());
136-
secProtocols.addPrivacyProtocol(new PrivDES());
137-
secProtocols.addPrivacyProtocol(new Priv3DES());
138-
secProtocols.addPrivacyProtocol(new PrivAES128());
139-
secProtocols.addPrivacyProtocol(new PrivAES192());
140-
secProtocols.addPrivacyProtocol(new PrivAES256());
141-
}
142-
143123
private void shutdownSnmp() throws IOException {
144124
DefaultUdpTransportMapping transport = this.transport;
145125
if (transport != null) {
@@ -172,7 +152,7 @@ public void removeCommandResponder(CommandResponder listener) {
172152
}
173153

174154
@Override
175-
public void send(PDU pdu, Target<?> target, @Nullable Object userHandle, ResponseListener listener)
155+
public void send(PDU pdu, Target target, @Nullable Object userHandle, ResponseListener listener)
176156
throws IOException {
177157
Snmp snmp = this.snmp;
178158
if (snmp != null) {
@@ -184,40 +164,35 @@ public void send(PDU pdu, Target<?> target, @Nullable Object userHandle, Respons
184164
}
185165

186166
@Override
187-
public void addUser(UsmUser user, OctetString engineId) {
188-
UserEntry userEntry = new UserEntry(user, engineId);
167+
public void addUser(String userName, SnmpAuthProtocol snmpAuthProtocol, @Nullable String authPassphrase,
168+
SnmpPrivProtocol snmpPrivProtocol, @Nullable String privPassphrase, byte[] engineId) {
169+
UsmUser usmUser = new UsmUser(new OctetString(userName),
170+
authPassphrase != null ? snmpAuthProtocol.getOid() : null,
171+
authPassphrase != null ? new OctetString(authPassphrase) : null,
172+
privPassphrase != null ? snmpPrivProtocol.getOid() : null,
173+
privPassphrase != null ? new OctetString(privPassphrase) : null);
174+
OctetString securityNameOctets = new OctetString(userName);
175+
176+
UserEntry userEntry = new UserEntry(securityNameOctets, new OctetString(engineId), usmUser);
189177
userEntries.add(userEntry);
190178

191179
Snmp snmp = this.snmp;
192180
if (snmp != null) {
193-
snmp.getUSM().addUser(user, engineId);
181+
addUser(snmp, userEntry);
194182
}
195183
}
196184

197-
@Override
198-
public void removeUser(Address address, UsmUser user, OctetString engineId) {
199-
Snmp snmp = this.snmp;
200-
if (snmp != null) {
201-
snmp.getUSM().removeAllUsers(user.getSecurityName(), engineId);
202-
snmp.removeCachedContextEngineId(address);
203-
}
204-
userEntries.removeIf(e -> e.engineId.equals(engineId) && e.user.equals(user));
205-
}
206-
207-
@Override
208-
public byte @Nullable [] getEngineId(Address address) {
209-
Snmp snmp = this.snmp;
210-
if (snmp != null) {
211-
return snmp.discoverAuthoritativeEngineID(address, 15000);
212-
}
213-
return null;
185+
private static void addUser(Snmp snmp, UserEntry userEntry) {
186+
snmp.getUSM().addUser(userEntry.securityName, userEntry.engineId, userEntry.user);
214187
}
215188

216189
private static class UserEntry {
190+
public OctetString securityName;
217191
public OctetString engineId;
218192
public UsmUser user;
219193

220-
public UserEntry(UsmUser user, OctetString engineId) {
194+
public UserEntry(OctetString securityName, OctetString engineId, UsmUser user) {
195+
this.securityName = securityName;
221196
this.engineId = engineId;
222197
this.user = user;
223198
}

0 commit comments

Comments
 (0)