Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Secur32#QueryContextAttributes #745

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
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Features
* [#732](https://github.com/java-native-access/jna/pull/732): Added initialization of FILETIME from LARGE_INTEGER - [@amarcionek](https://github.com/amarcionek).
* [#732](https://github.com/java-native-access/jna/pull/732): Added `GetFileInformationByHandleEx` and `SetFileInformationByHandle` to `com.sun.jna.platform.win32.Kernel32` - [@amarcionek](https://github.com/amarcionek).
* [#740](https://github.com/java-native-access/jna/pull/740): Modified `com.sun.jna.platform.win32.WinioctlUtil` for simplicity dealing with FSCTL_* codes - [@amarcionek](https://github.com/amarcionek).
* [#745](https://github.com/java-native-access/jna/pull/745): Added Secur32#QueryContextAttributes - [@barney2k7](https://github.com/barney2k7).

Bug Fixes
---------
Expand Down
21 changes: 21 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Secur32.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.Sspi.CredHandle;
import com.sun.jna.platform.win32.Sspi.CtxtHandle;
import com.sun.jna.platform.win32.Sspi.PSecPkgInfo;
Expand Down Expand Up @@ -319,4 +320,24 @@ int AcceptSecurityContext(CredHandle phCredential, CtxtHandle phContext,
* If the function fails, the return value can be either SEC_E_INVALID_HANDLE or SEC_E_UNSUPPORTED_FUNCTION.
*/
int RevertSecurityContext(CtxtHandle phContext);

/**
* Enables a transport application to query a security package for certain
* attributes of a security context.
*
* @param phContext
* A handle to the security context to be queried.
* @param ulAttribute
* Specifies the attribute of the context to be returned. This
* parameter can be one of the SECPKG_ATTR_* values defined in
* {@link Sspi}.
* @param pBuffer
* A pointer to a structure that receives the attributes. The
* type of structure pointed to depends on the value specified in
* the ulAttribute parameter.
* @return
* If the function succeeds, the return value is SEC_E_OK.
* If the function fails, the return value is a nonzero error code.
*/
int QueryContextAttributes(CtxtHandle phContext, int ulAttribute, Structure pBuffer);
}
140 changes: 139 additions & 1 deletion contrib/platform/src/com/sun/jna/platform/win32/Sspi.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.TypeMapper;
import com.sun.jna.win32.W32APITypeMapper;

/**
Expand Down Expand Up @@ -143,6 +142,116 @@ public interface Sspi {
*/
int SECBUFFER_TOKEN = 2;

// for ulAttribute parameter in QueryContextAttributes function
// (https://msdn.microsoft.com/en-us/library/windows/desktop/aa379326(v=vs.85).aspx)
/**
* The pBuffer parameter contains a pointer to a
* {@link SecPkgContext_PackageInfo} structure.
*
* Returns information on the SSP in use.
*/
int SECPKG_ATTR_PACKAGE_INFO = 0x0000000A;

// flags for SecPkgInfo fCapabilities
// (https://msdn.microsoft.com/en-us/library/windows/desktop/aa380104(v=vs.85).aspx)
/**
* Supports integrity on messages
*/
int SECPKG_FLAG_INTEGRITY = 0x00000001;
/**
* Supports privacy (confidentiality)
*/
int SECPKG_FLAG_PRIVACY = 0x00000002;
/**
* Only security token needed
*/
int SECPKG_FLAG_TOKEN_ONLY = 0x00000004;
/**
* Datagram RPC support
*/
int SECPKG_FLAG_DATAGRAM = 0x00000008;
/**
* Connection oriented RPC support
*/
int SECPKG_FLAG_CONNECTION = 0x00000010;
/**
* Full 3-leg required for re-auth.
*/
int SECPKG_FLAG_MULTI_REQUIRED = 0x00000020;
/**
* Server side functionality not available
*/
int SECPKG_FLAG_CLIENT_ONLY = 0x00000040;
/**
* Supports extended error msgs
*/
int SECPKG_FLAG_EXTENDED_ERROR = 0x00000080;
/**
* Supports impersonation
*/
int SECPKG_FLAG_IMPERSONATION = 0x00000100;
/**
* Accepts Win32 names
*/
int SECPKG_FLAG_ACCEPT_WIN32_NAME = 0x00000200;
/**
* Supports stream semantics
*/
int SECPKG_FLAG_STREAM = 0x00000400;
/**
* Can be used by the negotiate package
*/
int SECPKG_FLAG_NEGOTIABLE = 0x00000800;
/**
* GSS Compatibility Available
*/
int SECPKG_FLAG_GSS_COMPATIBLE = 0x00001000;
/**
* Supports common LsaLogonUser
*/
int SECPKG_FLAG_LOGON = 0x00002000;
/**
* Token Buffers are in ASCII
*/
int SECPKG_FLAG_ASCII_BUFFERS = 0x00004000;
/**
* Package can fragment to fit
*/
int SECPKG_FLAG_FRAGMENT = 0x00008000;
/**
* Package can perform mutual authentication
*/
int SECPKG_FLAG_MUTUAL_AUTH = 0x00010000;
/**
* Package can delegate
*/
int SECPKG_FLAG_DELEGATION = 0x00020000;
/**
* Supports callers with restricted tokens.
*/
int SECPKG_FLAG_RESTRICTED_TOKENS = 0x80000;
/**
* The security package extends the Microsoft Negotiate security package.
*/
int SECPKG_FLAG_NEGO_EXTENDER = 0x00100000;
/**
* This package is negotiated by the package of type SECPKG_FLAG_NEGO_EXTENDER.
*/
int SECPKG_FLAG_NEGOTIABLE2 = 0x00200000;
/**
* This package receives all calls from app container apps.
*/
int SECPKG_FLAG_APPCONTAINER_PASSTHROUGH = 0x00400000;
/**
* This package receives calls from app container apps if one of the following checks succeeds.
* <ul>
* <li>Caller has default credentials capability.</li>
* <li>The target is a proxy server.</li>
* <li>The caller has supplied credentials.</li>
* </ul>
*/
int SECPKG_FLAG_APPCONTAINER_CHECKS = 0x00800000;

/**
* Security handle.
*/
Expand Down Expand Up @@ -472,4 +581,33 @@ protected List<String> getFieldOrder() {
return FIELDS;
}
}

/**
* The SecPkgContext_PackageInfo structure.
*/
public static class SecPkgContext_PackageInfo extends Structure {
/**
* A reference pointer to a SecPkgContext_PackageInfo structure.
*/
public static class ByReference extends SecPkgContext_PackageInfo implements Structure.ByReference {
}

public static final List<String> FIELDS = createFieldsOrder("PackageInfo");

/**
* Pointer to a SecPkgInfo structure containing the name of the SSP in
* use.
*/
public SecPkgInfo.ByReference PackageInfo;

public SecPkgContext_PackageInfo() {
super(W32APITypeMapper.DEFAULT);
}

@Override
protected List<String> getFieldOrder() {
return FIELDS;
}
}

}
66 changes: 66 additions & 0 deletions contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import com.sun.jna.platform.win32.Sspi.CtxtHandle;
import com.sun.jna.platform.win32.Sspi.PSecPkgInfo;
import com.sun.jna.platform.win32.Sspi.SecBufferDesc;
import com.sun.jna.platform.win32.Sspi.SecPkgContext_PackageInfo;
import com.sun.jna.platform.win32.Sspi.SecPkgInfo;
import com.sun.jna.platform.win32.Sspi.SecPkgInfo.ByReference;
import com.sun.jna.platform.win32.Sspi.TimeStamp;
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
import com.sun.jna.ptr.IntByReference;
Expand Down Expand Up @@ -341,4 +343,68 @@ public void testCreateEmptyToken() {
assertEquals(Sspi.MAX_TOKEN_SIZE, token.pBuffers[0].cbBuffer);
assertEquals(token.getBytes().length, token.pBuffers[0].getBytes().length);
}

public void testQueryContextAttributes() {
// 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();
SecBufferDesc pbServerToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
IntByReference pfServerContextAttr = new IntByReference();
int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED;
int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED;
do {
// client token returned is always new
SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
// client ----------- initialize security context, produce a client
// token
if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
// server token is empty the first time
clientRc = Secur32.INSTANCE.InitializeSecurityContext(phClientCredential,
phClientContext.isNull() ? null : phClientContext, Advapi32Util.getUserName(),
Sspi.ISC_REQ_CONNECTION, 0, Sspi.SECURITY_NATIVE_DREP, pbServerToken, 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) {
serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, phServerContext.isNull() ? null
: phServerContext, pbClientToken, 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);
// query context attributes
SecPkgContext_PackageInfo packageinfo = new SecPkgContext_PackageInfo();
assertEquals(W32Errors.SEC_E_OK,
Secur32.INSTANCE.QueryContextAttributes(phServerContext, Sspi.SECPKG_ATTR_PACKAGE_INFO, packageinfo));
ByReference info = packageinfo.PackageInfo;

assertNotNull(info.Name);
assertNotNull(info.Comment);

assertTrue(!info.Name.isEmpty());
assertTrue(!info.Comment.isEmpty());

assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeContextBuffer(info.getPointer()));

// 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));
}
}