Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ Consequences:
WSMan namespace variants. WSMan fault exceptions additionally carry the detailed `WSManFault`
message (including the provider-level detail, e.g. WMI `WBEM_E_*` mnemonics) alongside the SOAP
reason text.
- Code quality: the PMD report is clean and `pmd:check` now runs in `mvn verify`, so a new violation
of `pmd.xml` fails the build (issue #122). The cleanup is behavior-preserving — redundant
parentheses and modifiers removed, empty catch blocks named and commented, and two loops
restructured. The only signature change is the removal of the unused `target` parameter from the
`CipherGen` constructor (an internal NTLM helper).
25 changes: 25 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,31 @@
</executions>
</plugin>

<!--
pmd: fail the build on any violation of pmd.xml, so the PMD report stays clean.
Version pinned to the one the parent manages for the site report, so the gate and
the report always run the same PMD.
-->
<plugin>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.26.0</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<targetJdk>${maven.compiler.release}</targetJdk>
<rulesets>
<ruleset>pmd.xml</ruleset>
</rulesets>
<printFailingErrors>true</printFailingErrors>
</configuration>
</plugin>

<!-- site: pin a recent maven-site-plugin (the version inherited from oss-parent is too old
for the Doxia 2.0 report plugins and raises a project-info-reports LinkageError) and add
the Sentry skin's companion maven-skin-tools -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ public interface ShareRemoteDirectoryConsumer<W extends WindowsRemoteExecutor, R
* @param shareName The Share Name.
* @param timeout Timeout in milliseconds.
*/
public void apply(final W windowsRemoteExecutor, final R remotePath, final S shareName, final T timeout);
void apply(final W windowsRemoteExecutor, final R remotePath, final S shareName, final T timeout);
}
6 changes: 4 additions & 2 deletions src/main/java/org/metricshub/winrm/ShellFileCopy.java
Original file line number Diff line number Diff line change
Expand Up @@ -637,11 +637,11 @@ private static WindowsRemoteCommandResult run(
static boolean isRetryableQuotaRejection(final Exception exception) {
final String message = exception.getMessage();

return (message != null
return message != null
&&
message.contains(FAULT_OPERATION_QUOTA)
&&
(message.contains("Command failed") || message.contains("Create shell failed")));
(message.contains("Command failed") || message.contains("Create shell failed"));
}

/**
Expand Down Expand Up @@ -810,6 +810,8 @@ private RemoteDigest(final String algorithm, final String digest) {
}

/** Whether this remote digest matches the digest of the given local content. */
// PMD does not resolve the call through Optional<RemoteDigest>#get() and reports this as unused.
@SuppressWarnings("PMD.UnusedPrivateMethod")
private boolean matches(final byte[] content) {
return digestHex("SHA256".equals(algorithm) ? "SHA-256" : "SHA-1", content).equals(digest);
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/metricshub/winrm/WindowsRemoteExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public interface WindowsRemoteExecutor extends AutoCloseable {
* @throws WqlQuerySyntaxException if WQL query syntax is invalid
* @throws WindowsRemoteException For any problem encountered
*/
public List<Map<String, Object>> executeWql(final String wqlQuery, final long timeout)
List<Map<String, Object>> executeWql(final String wqlQuery, final long timeout)
throws TimeoutException, WqlQuerySyntaxException, WindowsRemoteException;

/**
Expand All @@ -55,7 +55,7 @@ public List<Map<String, Object>> executeWql(final String wqlQuery, final long ti
* @throws WindowsRemoteException For any problem encountered
* @throws TimeoutException To notify userName of timeout.
*/
public WindowsRemoteCommandResult executeCommand(
WindowsRemoteCommandResult executeCommand(
final String command,
final String workingDirectory,
final Charset charset,
Expand All @@ -67,27 +67,27 @@ public WindowsRemoteCommandResult executeCommand(
*
* @return
*/
public String getHostname();
String getHostname();

/**
* Get the username.
*
* @return
*/
public String getUsername();
String getUsername();

/**
* Get the password.
*
* @return
*/
public char[] getPassword();
char[] getPassword();

/**
* Close the executor and release its resources. Narrows {@link AutoCloseable#close()} so it does
* not declare a checked exception, letting callers use try-with-resources without catching
* {@link Exception}.
*/
@Override
public void close();
void close();
}
4 changes: 2 additions & 2 deletions src/main/java/org/metricshub/winrm/WmiHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static String createNetworkResource(final String hostname, final String n
*/
public static boolean isLocalNetworkResource(final String networkResource) {
Utils.checkNonNull(networkResource, "networkResource");
return (!networkResource.startsWith("\\\\")
return !networkResource.startsWith("\\\\")
||
networkResource.startsWith("\\\\localhost\\")
||
Expand All @@ -86,7 +86,7 @@ public static boolean isLocalNetworkResource(final String networkResource) {
||
networkResource.startsWith("\\\\0000:0000:0000:0000:0000:0000:0000:0001\\")
||
networkResource.toLowerCase().startsWith("\\\\" + Utils.getComputerName().toLowerCase() + "\\"));
networkResource.toLowerCase().startsWith("\\\\" + Utils.getComputerName().toLowerCase() + "\\");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public static WindowsRemoteCommandResult execute(
: localFileToCopyList.stream().filter(Utils::isNotBlank).collect(Collectors.toList());

try (
final WindowsRemoteExecutor winRMService = WinRMExecutorFactory.createInstance(
WindowsRemoteExecutor winRMService = WinRMExecutorFactory.createInstance(
winRMEndpoint,
timeout,
ticketCache,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static long readLittleEndianUnsignedInt(final byte[] input, final int off
}

public static byte[] concat(final byte[]... sequences) {
try (final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
for (byte[] s : sequences) {
out.write(s);
}
Expand Down
1 change: 0 additions & 1 deletion src/main/java/org/metricshub/winrm/light/CipherGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ public CipherGen(
final String user,
final String password,
final byte[] challenge,
final String target,
final byte[] targetInformation
) {
this.random = random;
Expand Down
40 changes: 20 additions & 20 deletions src/main/java/org/metricshub/winrm/light/Envelopes.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,26 +59,26 @@ private Envelopes() {}
// --- WQL ---------------------------------------------------------------

static String enumerateWql(final String url, final String namespace, final String wql, final long timeoutMs) {
return (envelopeOpen(false) +
return envelopeOpen(false) +
header(url, wmiResourceUri(namespace), ACTION_ENUMERATE, timeoutMs, null, null) +
"<s:Body><wsen:Enumerate>" +
"<wsman:OptimizeEnumeration/>" +
"<wsman:MaxElements>32000</wsman:MaxElements>" +
"<wsman:Filter Dialect=\"http://schemas.microsoft.com/wbem/wsman/1/WQL\">" +
escape(wql) +
"</wsman:Filter>" +
"</wsen:Enumerate></s:Body></s:Envelope>");
"</wsen:Enumerate></s:Body></s:Envelope>";
}

static String pull(final String url, final String namespace, final String context, final long timeoutMs) {
return (envelopeOpen(false) +
return envelopeOpen(false) +
header(url, wmiResourceUri(namespace), ACTION_PULL, timeoutMs, null, null) +
"<s:Body><wsen:Pull>" +
"<wsen:EnumerationContext>" +
escape(context) +
"</wsen:EnumerationContext>" +
"<wsen:MaxElements>32000</wsen:MaxElements>" +
"</wsen:Pull></s:Body></s:Envelope>");
"</wsen:Pull></s:Body></s:Envelope>";
}

// --- Command shell -----------------------------------------------------
Expand All @@ -91,49 +91,49 @@ static String createShell(final String url, final String workingDirectory, final
final String workingDir = (workingDirectory == null || workingDirectory.trim().isEmpty())
? ""
: "<rsp:WorkingDirectory>" + escape(workingDirectory) + "</rsp:WorkingDirectory>";
return (envelopeOpen(true) +
return envelopeOpen(true) +
header(url, SHELL_RESOURCE_URI, ACTION_CREATE, timeoutMs, null, optionSet) +
"<s:Body><rsp:Shell>" +
"<rsp:InputStreams>stdin</rsp:InputStreams>" +
"<rsp:OutputStreams>stdout stderr</rsp:OutputStreams>" +
workingDir +
"</rsp:Shell></s:Body></s:Envelope>");
"</rsp:Shell></s:Body></s:Envelope>";
}

static String command(final String url, final String shellId, final String commandLine, final long timeoutMs) {
final String optionSet = "<wsman:OptionSet>" +
"<wsman:Option Name=\"WINRS_CONSOLEMODE_STDIN\">TRUE</wsman:Option>" +
"<wsman:Option Name=\"WINRS_SKIP_CMD_SHELL\">FALSE</wsman:Option>" +
"</wsman:OptionSet>";
return (envelopeOpen(true) +
return envelopeOpen(true) +
header(url, SHELL_RESOURCE_URI, ACTION_COMMAND, timeoutMs, shellSelector(shellId), optionSet) +
"<s:Body><rsp:CommandLine><rsp:Command>" +
escape(commandLine) +
"</rsp:Command></rsp:CommandLine></s:Body></s:Envelope>");
"</rsp:Command></rsp:CommandLine></s:Body></s:Envelope>";
}

static String receive(final String url, final String shellId, final String commandId, final long timeoutMs) {
return (envelopeOpen(true) +
return envelopeOpen(true) +
header(url, SHELL_RESOURCE_URI, ACTION_RECEIVE, timeoutMs, shellSelector(shellId), null) +
"<s:Body><rsp:Receive><rsp:DesiredStream CommandId=\"" +
escape(commandId) +
"\">stdout stderr</rsp:DesiredStream></rsp:Receive></s:Body></s:Envelope>");
"\">stdout stderr</rsp:DesiredStream></rsp:Receive></s:Body></s:Envelope>";
}

static String signal(final String url, final String shellId, final String commandId, final long timeoutMs) {
return (envelopeOpen(true) +
return envelopeOpen(true) +
header(url, SHELL_RESOURCE_URI, ACTION_SIGNAL, timeoutMs, shellSelector(shellId), null) +
"<s:Body><rsp:Signal CommandId=\"" +
escape(commandId) +
"\"><rsp:Code>" +
TERMINATE_CODE +
"</rsp:Code></rsp:Signal></s:Body></s:Envelope>");
"</rsp:Code></rsp:Signal></s:Body></s:Envelope>";
}

static String deleteShell(final String url, final String shellId, final long timeoutMs) {
return (envelopeOpen(true) +
return envelopeOpen(true) +
header(url, SHELL_RESOURCE_URI, ACTION_DELETE, timeoutMs, shellSelector(shellId), null) +
"<s:Body/></s:Envelope>");
"<s:Body/></s:Envelope>";
}

// --- helpers -----------------------------------------------------------
Expand All @@ -143,8 +143,8 @@ private static String wmiResourceUri(final String namespace) {
}

private static String shellSelector(final String shellId) {
return ("<wsman:SelectorSet><wsman:Selector Name=\"ShellId\">" + escape(shellId)
+ "</wsman:Selector></wsman:SelectorSet>");
return "<wsman:SelectorSet><wsman:Selector Name=\"ShellId\">" + escape(shellId)
+ "</wsman:Selector></wsman:SelectorSet>";
}

/**
Expand All @@ -165,7 +165,7 @@ private static String header(
final String selectorSet,
final String optionSet
) {
return ("<s:Header>" +
return "<s:Header>" +
"<wsa:To>" +
url +
"</wsa:To>" +
Expand All @@ -190,11 +190,11 @@ private static String header(
"<wsman:OperationTimeout>" +
operationTimeout(timeoutMs) +
"</wsman:OperationTimeout>" +
"</s:Header>");
"</s:Header>";
}

private static String envelopeOpen(final boolean shell) {
return ("<s:Envelope xmlns:s=\"" +
return "<s:Envelope xmlns:s=\"" +
SOAP +
"\" xmlns:wsa=\"" +
WSA +
Expand All @@ -204,7 +204,7 @@ private static String envelopeOpen(final boolean shell) {
WSEN +
"\"" +
(shell ? " xmlns:rsp=\"" + RSP + "\"" : "") +
">");
">";
}

private static String escape(final String s) {
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/org/metricshub/winrm/light/HttpTransport.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ private boolean isStalePeerClosed() {
} finally {
try {
socket.setSoTimeout(previousTimeout);
} catch (final IOException ignore) {
} catch (final IOException ignored) {
// socket is being discarded on the stale path anyway
}
}
Expand Down Expand Up @@ -218,7 +218,7 @@ private void ensureConnected() throws IOException {
// cannot leak the freshly created SSLSocket.
try {
newSocket.close();
} catch (final IOException ignore) {
} catch (final IOException ignored) {
// best effort
}
socket = null;
Expand Down Expand Up @@ -355,9 +355,10 @@ private byte[] readChunked() throws IOException {
if (size == 0) {
// After the terminating chunk come zero or more optional trailer fields, then a final
// empty line. Consume them all, or leftover bytes desync the kept-alive NTLM socket.
String trailer;
while ((trailer = readLine()) != null && !trailer.isEmpty()) {
// discard trailer field
String trailer = readLine();
while (trailer != null && !trailer.isEmpty()) {
// discard the trailer field and look at the next line
trailer = readLine();
}
break;
}
Expand All @@ -379,7 +380,7 @@ public void close() {
if (doomed != null) {
try {
doomed.close();
} catch (final IOException ignore) {
} catch (final IOException ignored) {
// best effort
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public void reset() {
if (context != null) {
try {
context.dispose();
} catch (final GSSException ignore) {
} catch (final GSSException ignored) {
// disposing a dead context is best-effort
}
context = null;
Expand Down
Loading
Loading