Skip to content

Commit 07140d6

Browse files
author
Peter Hill
committed
Document compatibility and upgrade AssertJ
Add a maintainer-facing compatibility matrix covering NETCONF RFC support, capability caveats, NMDA coverage, notifications gaps, and Junos-specific helpers. Also align Maven and Gradle on assertj-core 3.27.7 to address CVE-2026-24400 in AssertJ's XML pretty-printing path while keeping the existing XMLUnit-based test style. Bump version to 2.2.1.0
1 parent 9ca7ad5 commit 07140d6

4 files changed

Lines changed: 108 additions & 5 deletions

File tree

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,17 @@ User may download the source code and compile it with desired JDK version.
5252

5353
=======
5454

55+
v2.2.1
56+
------
57+
* Hardened NETCONF XML parsing against XXE and DTD-based attacks
58+
* Fixed NETCONF RPC framing and `message-id` reply correlation for sequential session reuse
59+
* Improved SSH/NETCONF session cleanup on failed connection or session initialization
60+
* Fixed shell exec helpers so commands are set, channels are connected, and timeout/cleanup behavior is more predictable
61+
* Fixed nested XML path construction in the XML helper
62+
* Documented `NetconfSession` as a sequential request/response channel rather than a concurrent in-flight RPC transport
63+
* Added [`docs/compatibility.md`](docs/compatibility.md) with current RFC, capability, NMDA, and extension support details
64+
* Upgraded `assertj-core` to `3.27.7` to address `CVE-2026-24400`
65+
5566
v2.2.0
5667
------
5768
* Java 17 baseline; compiled with `--release 17`

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group = 'net.juniper.netconf'
9-
version = '2.2.0.0'
9+
version = '2.2.1.0'
1010
description = 'An API For NetConf client'
1111

1212
java {
@@ -26,7 +26,7 @@ dependencies {
2626
implementation 'com.google.guava:guava:32.0.1-jre'
2727

2828
testImplementation 'org.hamcrest:hamcrest-all:1.3'
29-
testImplementation 'org.assertj:assertj-core:3.23.1'
29+
testImplementation 'org.assertj:assertj-core:3.27.7'
3030
testImplementation 'org.mockito:mockito-core:4.8.1'
3131
testImplementation 'commons-io:commons-io:2.14.0'
3232
testImplementation 'org.xmlunit:xmlunit-assertj:2.9.0'
@@ -104,4 +104,4 @@ publishing {
104104
}
105105
}
106106
}
107-
}
107+
}

docs/compatibility.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Compatibility Matrix
2+
3+
This document describes what `netconf-java` currently implements. It is an implementation matrix, not a blanket compliance claim. Interoperability still depends on the server's advertised capabilities and on whether the application stays within the library's supported session model.
4+
5+
Mental model: today the library is a synchronous, JSch-backed NETCONF-over-SSH client. Its strongest path is one sequential RPC conversation per `NetconfSession`, with explicit timeouts and explicit cleanup. Core NETCONF 1.0 and 1.1 framing is supported, several Junos workflows are wrapped ergonomically, and the main standards gap is that optional features are not yet enforced uniformly through capability negotiation.
6+
7+
## Status legend
8+
9+
| Status | Meaning |
10+
| --- | --- |
11+
| `Supported` | Implemented and intended for normal use. |
12+
| `Supported with caveats` | Implemented, but there are negotiation, API-surface, or interoperability caveats. |
13+
| `Partial` | Some pieces exist, but coverage is incomplete or not first-class. |
14+
| `Not implemented` | No dedicated support today. |
15+
16+
## Core NETCONF and transport
17+
18+
| Standard / feature | Status | Notes |
19+
| --- | --- | --- |
20+
| RFC 6242 SSH subsystem transport | `Supported` | `Device` opens an SSH subsystem channel with `subsystem=netconf` over JSch. |
21+
| RFC 6241 `<hello>` parsing and generation | `Supported with caveats` | `Hello` parsing/building works, and `Hello.builder()` auto-adds `urn:ietf:params:netconf:base:1.1`. The library does not currently fail the session if the peers do not share a common base capability. |
22+
| NETCONF 1.0 end-of-message framing (`]]>]]>`) | `Supported` | Legacy framing is still supported for both outbound and inbound messages. |
23+
| NETCONF 1.1 chunked framing | `Supported` | Chunked framing is enabled when the server `<hello>` advertises `urn:ietf:params:netconf:base:1.1`. |
24+
| NETCONF 1.0 server interoperability | `Supported with caveats` | A 1.0-only server can interoperate because the client still advertises `base:1.0` and can read/write legacy framing. |
25+
| NETCONF 1.0-only client advertisement | `Not implemented` | The client cannot intentionally advertise only `base:1.0`; `Hello.builder()` always injects `base:1.1`. |
26+
| RPC `message-id` generation and reply correlation | `Supported with caveats` | Missing `message-id` attributes are injected, replies are validated, and sequential same-session alignment is covered by tests. One `NetconfSession` is still a sequential conversation, not a safe multiplexed channel for concurrent in-flight RPCs. |
27+
| `<rpc-error>` parsing | `Supported` | `RpcReply` parses `error-type`, `error-tag`, `error-severity`, `error-path`, `error-message`, and common `error-info` fields into structured objects. |
28+
| `<close-session>` | `Supported` | `NetconfSession.close()` sends `<close-session/>` and disconnects the channel. |
29+
| `<kill-session>` | `Supported` | `NetconfSession.killSession(String)` is implemented. |
30+
| Secure XML parsing | `Supported` | DTDs and XXE resolution are disabled for `Device`, `Hello`, and `RpcReply` parsing paths. |
31+
32+
## Standard capabilities and common operations
33+
34+
| Capability / operation | Status | Notes |
35+
| --- | --- | --- |
36+
| `<get>` | `Supported` | `getRunningConfigAndState(...)` issues `<get>`. |
37+
| `<get-config>` | `Supported` | Candidate and running helpers exist. |
38+
| `<edit-config>` to candidate | `Supported with caveats` | `loadXMLConfiguration(...)` and `loadTextConfiguration(...)` target `candidate`. The API does not expose `test-option`, `error-option`, or capability-gated behavior checks before use. |
39+
| `:candidate:1.0` | `Supported with caveats` | Candidate-oriented helpers are a primary workflow, but the default client capability still uses the legacy `urn:ietf:params:netconf:base:1.0#candidate` form rather than the RFC 6241 `urn:ietf:params:netconf:capability:candidate:1.0` URN. |
40+
| `<commit>` | `Supported` | Standard commit is implemented. |
41+
| `:confirmed-commit:1.1` | `Supported with caveats` | `commitConfirm(seconds, persistToken)` and `cancelCommit(persistId)` exist, but the default client capability still uses the legacy `base:1.0#confirmed-commit` form instead of the RFC 6241 capability URN. |
42+
| `:validate:1.0` | `Supported with caveats` | `validate()` is implemented against candidate, but default advertisement still uses the legacy `base:1.0#validate` URI and the call is not capability-gated at runtime. |
43+
| `<lock>` / `<unlock>` | `Partial` | Candidate lock/unlock helpers exist. There is no first-class running datastore lock helper. |
44+
| `:writable-running:1.0` | `Partial` | Running config retrieval exists, but there is no `edit-config` helper that targets `running` and the capability is not advertised by default. |
45+
| `:startup:1.0` | `Not implemented` | No first-class startup datastore copy/delete flows are present. |
46+
| `:url:1.0` | `Partial` | The default client capability list advertises the legacy `base:1.0#url?protocol=http,ftp,file` form, but there is no dedicated URL-based copy/load API surface. |
47+
| `:xpath:1.0` | `Partial` | The library can pass caller-supplied filter XML through to `<get>` and `<get-data>`, but there is no typed XPath filter API and no runtime capability check. |
48+
| `:rollback-on-error:1.0` | `Not implemented` | No API surface for `error-option rollback-on-error`. |
49+
| `<discard-changes>` | `Not implemented` | No dedicated helper today. |
50+
| `<copy-config>` | `Not implemented` | No dedicated helper today. |
51+
| `<delete-config>` | `Not implemented` | No dedicated helper today. |
52+
| RFC 6243 `with-defaults` | `Not implemented` | No explicit support or helper surface. |
53+
54+
## NMDA and additional datastore support
55+
56+
| Standard / feature | Status | Notes |
57+
| --- | --- | --- |
58+
| RFC 8526 `<get-data>` / `ietf-netconf-nmda` | `Supported with caveats` | `getData(xpathFilter, datastore)` emits NMDA namespace-qualified requests and can target `running`, `candidate`, `startup`, `intended`, or `operational`. The call is not capability-gated; the application must know the server supports NMDA. |
59+
| RFC 8342 datastore naming | `Partial` | `Datastore` includes `RUNNING`, `CANDIDATE`, `STARTUP`, `INTENDED`, and `OPERATIONAL`, but only `getData(...)` uses that model directly. |
60+
61+
## Notifications and subscriptions
62+
63+
| Standard / feature | Status | Notes |
64+
| --- | --- | --- |
65+
| RFC 5277 event notifications | `Not implemented` | No `create-subscription`, no notification stream reader, and no event callback surface. |
66+
| RFC 5277 `:interleave:1.0` | `Not implemented` | No interleaving of notifications with active RPC traffic. |
67+
68+
## Junos-specific and non-standard helpers
69+
70+
| Feature | Status | Notes |
71+
| --- | --- | --- |
72+
| Junos `<load-configuration>` helpers | `Supported` | XML, text, and set-style configuration loading helpers are present. These are vendor-specific, not portable NETCONF. |
73+
| Junos `<commit-configuration><full/>` | `Supported` | `commitFull()` exists and is Junos-specific. |
74+
| Junos CLI command helper | `Supported with caveats` | `runCliCommand(...)` and `runCliCommandRunning(...)` are implemented, but they are not portable to non-Junos servers. |
75+
| Junos configuration mode helpers | `Supported` | `openConfiguration(...)` and `closeConfiguration()` are implemented. |
76+
| SSH exec shell helpers | `Supported with caveats` | `runShellCommand(...)` and `runShellCommandRunning(...)` now connect and clean up channels correctly, and reads are bounded by `commandTimeout`. They still do not provide a richer per-command cancellation model beyond timeout and channel close. |
77+
| Device reboot helper | `Supported with caveats` | `reboot()` exists as a convenience helper, but it is server-specific rather than a portable standards abstraction. |
78+
79+
## Interoperability caveats worth knowing
80+
81+
- Default optional capability advertisement still uses legacy `urn:ietf:params:netconf:base:1.0#...` forms in `Device.DEFAULT_CLIENT_CAPABILITIES`. Many servers accept these, but strict RFC 6241 capability matching may not.
82+
- Capability negotiation is parsed but not enforced consistently before invoking optional operations. The caller can request candidate, validate, confirmed-commit, or NMDA operations even if the server never advertised them.
83+
- `NetconfSession` should be treated as a single sequential request/response channel. Use separate sessions for concurrent workflows.
84+
- The SSH transport is still tightly coupled to JSch. That preserves the current JSch-based deployment model, including existing FIPS-oriented environments, but transport abstraction is future work rather than current behavior.
85+
86+
## Primary implementation points
87+
88+
- [`Device`](../src/main/java/net/juniper/netconf/Device.java) - SSH transport setup, client capability advertisement, device-level helpers
89+
- [`NetconfSession`](../src/main/java/net/juniper/netconf/NetconfSession.java) - NETCONF framing, message-id handling, core RPC helpers, session lifecycle
90+
- [`Hello`](../src/main/java/net/juniper/netconf/element/Hello.java) - `<hello>` parsing and generation
91+
- [`RpcReply`](../src/main/java/net/juniper/netconf/element/RpcReply.java) - `<rpc-reply>` and `<rpc-error>` parsing
92+
- [`Datastore`](../src/main/java/net/juniper/netconf/element/Datastore.java) - datastore enum used by NMDA-style `<get-data>`

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<groupId>net.juniper.netconf</groupId>
99
<artifactId>netconf-java</artifactId>
10-
<version>2.2.0.0</version>
10+
<version>2.2.1.0</version>
1111
<packaging>jar</packaging>
1212

1313
<properties>
@@ -190,7 +190,7 @@
190190
<dependency>
191191
<groupId>org.assertj</groupId>
192192
<artifactId>assertj-core</artifactId>
193-
<version>3.23.1</version>
193+
<version>3.27.7</version>
194194
<scope>test</scope>
195195
</dependency>
196196

0 commit comments

Comments
 (0)