Skip to content

Commit

Permalink
Fix Advapi32Test, IPHlpAPITest, Secur32Test
Browse files Browse the repository at this point in the history
- Advapi32#DecryptFile can be called on read-only file
- FixedInfo.DnsServerList.IpAddress may hold an empty string.
  Observed on system with only IPv6 DNS servers
- Secur32Test is unstable with ImpersonateSecurityContext, splitting it
  into separate test improves stability
  • Loading branch information
matthiasblaesing committed Apr 24, 2024
1 parent 19ce86a commit 2db19b3
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 92 deletions.
13 changes: 8 additions & 5 deletions contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -1950,12 +1950,14 @@ public void testDecryptFile() throws Exception {

// decrypt a read only file
file.setWritable(false);
assertFalse(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError());
boolean successful = Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0));
if(! successful) {
assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError());

// decrypt
file.setWritable(true);
assertTrue(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
// decrypt
file.setWritable(true);
assertTrue(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
}

file.delete();
}
Expand Down Expand Up @@ -2170,4 +2172,5 @@ public void testCreateProcessWithLogonW() {
// should fail with "the user name or password is incorrect" (error 1326)
assertEquals("GetLastError() should have returned ERROR_LOGON_FAILURE because the username was bogus.", W32Errors.ERROR_LOGON_FAILURE, Native.getLastError());
}

}
36 changes: 27 additions & 9 deletions contrib/platform/test/com/sun/jna/platform/win32/IPHlpAPITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ public void testGetNetworkParams() {
if (nullPos != -1) {
addr = addr.substring(0, nullPos);
}
// addr is now a dotted-notation IP string. Test valid
assertTrue(ValidIP.matcher(addr).matches());
// addr is now a dotted-notation IP string. Test valid - address can be empty if DNS is IPv6
assertTrue("Address not valid: " + addr, ValidIP.matcher(addr).matches() || addr.isEmpty());
dns = dns.Next;
}
}
Expand Down Expand Up @@ -166,22 +166,40 @@ public void testGetUdpStatistics() {
MIB_UDPSTATS stats = new MIB_UDPSTATS();
int err = IPHlpAPI.INSTANCE.GetUdpStatistics(stats);
assertEquals(String.format("Error %d calling GetUdpStatistics.", err), WinError.NO_ERROR, err);
assertTrue("Datagrams received with errors or no port should be less than inbound datagrams.",
stats.dwNoPorts + stats.dwInErrors <= stats.dwInDatagrams);
assertTrue(
String.format("Datagrams received with errors (%d) or no port (%d) should be less than inbound datagrams (%d).",
stats.dwNoPorts, stats.dwInErrors, stats.dwInDatagrams
),
stats.dwNoPorts + stats.dwInErrors <= stats.dwInDatagrams
);

// Above should roughly match IPv4 stats with Ex version
MIB_UDPSTATS stats4 = new MIB_UDPSTATS();
err = IPHlpAPI.INSTANCE.GetUdpStatisticsEx(stats4, IPHlpAPI.AF_INET);
assertEquals(String.format("Error %d calling GetUdpStatistics.", err), WinError.NO_ERROR, err);
assertTrue(
"Datagrams received with no port should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx",
stats.dwNoPorts <= stats4.dwNoPorts);
String.format(
"Datagrams received with no port should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)",
stats.dwNoPorts,stats4.dwNoPorts
),
stats.dwNoPorts <= stats4.dwNoPorts
);
assertTrue(
"Datagrams received with errors should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx",
String.format(
"Datagrams received with errors should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)",
stats.dwInErrors, stats4.dwInErrors
),
stats.dwInErrors <= stats4.dwInErrors);
assertTrue("Datagrams received should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx",
assertTrue(
String.format(
"Datagrams received should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)",
stats.dwInDatagrams, stats4.dwInDatagrams
),
stats.dwInDatagrams <= stats4.dwInDatagrams);
assertTrue("Datagrams received with errors or no port should be less than inbound datagrams.",
assertTrue(
String.format("Datagrams received with errors (%d) or no port (%d) should be less than inbound datagrams (%d). (Ex-Version)",
stats4.dwNoPorts, stats4.dwInErrors, stats4.dwInDatagrams
),
stats4.dwNoPorts + stats4.dwInErrors <= stats4.dwInDatagrams);
}

Expand Down
78 changes: 0 additions & 78 deletions contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,84 +190,6 @@ public void testAcceptSecurityContext() {
phClientCredential));
}

public void testImpersonateRevertSecurityContext() {
// client ----------- acquire outbound credential handle
CredHandle phClientCredential = new CredHandle();
TimeStamp ptsClientExpiry = new TimeStamp();
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null,
null, phClientCredential, ptsClientExpiry));
// client ----------- security context
CtxtHandle phClientContext = new CtxtHandle();
IntByReference pfClientContextAttr = new IntByReference();
// server ----------- acquire inbound credential handle
CredHandle phServerCredential = new CredHandle();
TimeStamp ptsServerExpiry = new TimeStamp();
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null,
null, phServerCredential, ptsServerExpiry));
// server ----------- security context
CtxtHandle phServerContext = new CtxtHandle();
ManagedSecBufferDesc pbServerToken = null;
IntByReference pfServerContextAttr = new IntByReference();
int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED;
int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED;
do {
// client ----------- initialize security context, produce a client token
// client token returned is always new
ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
// server token is empty the first time
ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null
? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes());
clientRc = Secur32.INSTANCE.InitializeSecurityContext(
phClientCredential,
phClientContext.isNull() ? null : phClientContext,
Advapi32Util.getUserName(),
Sspi.ISC_REQ_CONNECTION,
0,
Sspi.SECURITY_NATIVE_DREP,
pbServerTokenCopy,
0,
phClientContext,
pbClientToken,
pfClientContextAttr,
null);
assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK);
}
// server ----------- accept security context, produce a server token
if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes());
serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential,
phServerContext.isNull() ? null : phServerContext,
pbClientTokenByValue,
Sspi.ISC_REQ_CONNECTION,
Sspi.SECURITY_NATIVE_DREP,
phServerContext,
pbServerToken,
pfServerContextAttr,
ptsServerExpiry);
assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK);
}
} while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK);
// impersonate
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.ImpersonateSecurityContext(
phServerContext));
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.RevertSecurityContext(
phServerContext));
// release server context
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
phServerContext));
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
phServerCredential));
// release client context
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
phClientContext));
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
phClientCredential));
}

public void testEnumerateSecurityPackages() {
IntByReference pcPackages = new IntByReference();
PSecPkgInfo.ByReference pPackageInfo = new PSecPkgInfo.ByReference();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna.platform.win32;

import com.sun.jna.ptr.IntByReference;
import org.junit.Test;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;


public class Secur32_Impersonate_Test {

@Test
public void testImpersonateRevertSecurityContext() {
// client ----------- acquire outbound credential handle
Sspi.CredHandle phClientCredential = new Sspi.CredHandle();
Sspi.TimeStamp ptsClientExpiry = new Sspi.TimeStamp();
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null,
null, phClientCredential, ptsClientExpiry));
// client ----------- security context
Sspi.CtxtHandle phClientContext = new Sspi.CtxtHandle();
IntByReference pfClientContextAttr = new IntByReference();
// server ----------- acquire inbound credential handle
Sspi.CredHandle phServerCredential = new Sspi.CredHandle();
Sspi.TimeStamp ptsServerExpiry = new Sspi.TimeStamp();
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null,
null, phServerCredential, ptsServerExpiry));
// server ----------- security context
Sspi.CtxtHandle phServerContext = new Sspi.CtxtHandle();
SspiUtil.ManagedSecBufferDesc pbServerToken = null;
IntByReference pfServerContextAttr = new IntByReference();
int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED;
int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED;
do {
// client ----------- initialize security context, produce a client token
// client token returned is always new
SspiUtil.ManagedSecBufferDesc pbClientToken = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
// server token is empty the first time
SspiUtil.ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null
? null : new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes());
clientRc = Secur32.INSTANCE.InitializeSecurityContext(
phClientCredential,
phClientContext.isNull() ? null : phClientContext,
Advapi32Util.getUserName(),
Sspi.ISC_REQ_CONNECTION,
0,
Sspi.SECURITY_NATIVE_DREP,
pbServerTokenCopy,
0,
phClientContext,
pbClientToken,
pfClientContextAttr,
null);
assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK);
}
// server ----------- accept security context, produce a server token
if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
pbServerToken = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
SspiUtil.ManagedSecBufferDesc pbClientTokenByValue = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes());
serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential,
phServerContext.isNull() ? null : phServerContext,
pbClientTokenByValue,
Sspi.ISC_REQ_CONNECTION,
Sspi.SECURITY_NATIVE_DREP,
phServerContext,
pbServerToken,
pfServerContextAttr,
ptsServerExpiry);
assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK);
}
} while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK);
// impersonate
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.ImpersonateSecurityContext(
phServerContext));
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.RevertSecurityContext(
phServerContext));
// release server context
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
phServerContext));
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
phServerCredential));
// release client context
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
phClientContext));
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
phClientCredential));
}
}

0 comments on commit 2db19b3

Please sign in to comment.