Skip to content

Commit 981510e

Browse files
Merge pull request #745 from barney2k7/secur32_query_context_attributes
Added Secur32#QueryContextAttributes
2 parents d377ac5 + 7cf905e commit 981510e

File tree

4 files changed

+227
-1
lines changed

4 files changed

+227
-1
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Features
7070
* [#732](https://github.com/java-native-access/jna/pull/732): Added initialization of FILETIME from LARGE_INTEGER - [@amarcionek](https://github.com/amarcionek).
7171
* [#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).
7272
* [#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).
73+
* [#745](https://github.com/java-native-access/jna/pull/745): Added Secur32#QueryContextAttributes - [@barney2k7](https://github.com/barney2k7).
7374

7475
Bug Fixes
7576
---------

contrib/platform/src/com/sun/jna/platform/win32/Secur32.java

+21
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import com.sun.jna.Native;
2727
import com.sun.jna.Pointer;
28+
import com.sun.jna.Structure;
2829
import com.sun.jna.platform.win32.Sspi.CredHandle;
2930
import com.sun.jna.platform.win32.Sspi.CtxtHandle;
3031
import com.sun.jna.platform.win32.Sspi.PSecPkgInfo;
@@ -319,4 +320,24 @@ int AcceptSecurityContext(CredHandle phCredential, CtxtHandle phContext,
319320
* If the function fails, the return value can be either SEC_E_INVALID_HANDLE or SEC_E_UNSUPPORTED_FUNCTION.
320321
*/
321322
int RevertSecurityContext(CtxtHandle phContext);
323+
324+
/**
325+
* Enables a transport application to query a security package for certain
326+
* attributes of a security context.
327+
*
328+
* @param phContext
329+
* A handle to the security context to be queried.
330+
* @param ulAttribute
331+
* Specifies the attribute of the context to be returned. This
332+
* parameter can be one of the SECPKG_ATTR_* values defined in
333+
* {@link Sspi}.
334+
* @param pBuffer
335+
* A pointer to a structure that receives the attributes. The
336+
* type of structure pointed to depends on the value specified in
337+
* the ulAttribute parameter.
338+
* @return
339+
* If the function succeeds, the return value is SEC_E_OK.
340+
* If the function fails, the return value is a nonzero error code.
341+
*/
342+
int QueryContextAttributes(CtxtHandle phContext, int ulAttribute, Structure pBuffer);
322343
}

contrib/platform/src/com/sun/jna/platform/win32/Sspi.java

+139-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.sun.jna.Memory;
2929
import com.sun.jna.Pointer;
3030
import com.sun.jna.Structure;
31-
import com.sun.jna.TypeMapper;
3231
import com.sun.jna.win32.W32APITypeMapper;
3332

3433
/**
@@ -143,6 +142,116 @@ public interface Sspi {
143142
*/
144143
int SECBUFFER_TOKEN = 2;
145144

145+
// for ulAttribute parameter in QueryContextAttributes function
146+
// (https://msdn.microsoft.com/en-us/library/windows/desktop/aa379326(v=vs.85).aspx)
147+
/**
148+
* The pBuffer parameter contains a pointer to a
149+
* {@link SecPkgContext_PackageInfo} structure.
150+
*
151+
* Returns information on the SSP in use.
152+
*/
153+
int SECPKG_ATTR_PACKAGE_INFO = 0x0000000A;
154+
155+
// flags for SecPkgInfo fCapabilities
156+
// (https://msdn.microsoft.com/en-us/library/windows/desktop/aa380104(v=vs.85).aspx)
157+
/**
158+
* Supports integrity on messages
159+
*/
160+
int SECPKG_FLAG_INTEGRITY = 0x00000001;
161+
/**
162+
* Supports privacy (confidentiality)
163+
*/
164+
int SECPKG_FLAG_PRIVACY = 0x00000002;
165+
/**
166+
* Only security token needed
167+
*/
168+
int SECPKG_FLAG_TOKEN_ONLY = 0x00000004;
169+
/**
170+
* Datagram RPC support
171+
*/
172+
int SECPKG_FLAG_DATAGRAM = 0x00000008;
173+
/**
174+
* Connection oriented RPC support
175+
*/
176+
int SECPKG_FLAG_CONNECTION = 0x00000010;
177+
/**
178+
* Full 3-leg required for re-auth.
179+
*/
180+
int SECPKG_FLAG_MULTI_REQUIRED = 0x00000020;
181+
/**
182+
* Server side functionality not available
183+
*/
184+
int SECPKG_FLAG_CLIENT_ONLY = 0x00000040;
185+
/**
186+
* Supports extended error msgs
187+
*/
188+
int SECPKG_FLAG_EXTENDED_ERROR = 0x00000080;
189+
/**
190+
* Supports impersonation
191+
*/
192+
int SECPKG_FLAG_IMPERSONATION = 0x00000100;
193+
/**
194+
* Accepts Win32 names
195+
*/
196+
int SECPKG_FLAG_ACCEPT_WIN32_NAME = 0x00000200;
197+
/**
198+
* Supports stream semantics
199+
*/
200+
int SECPKG_FLAG_STREAM = 0x00000400;
201+
/**
202+
* Can be used by the negotiate package
203+
*/
204+
int SECPKG_FLAG_NEGOTIABLE = 0x00000800;
205+
/**
206+
* GSS Compatibility Available
207+
*/
208+
int SECPKG_FLAG_GSS_COMPATIBLE = 0x00001000;
209+
/**
210+
* Supports common LsaLogonUser
211+
*/
212+
int SECPKG_FLAG_LOGON = 0x00002000;
213+
/**
214+
* Token Buffers are in ASCII
215+
*/
216+
int SECPKG_FLAG_ASCII_BUFFERS = 0x00004000;
217+
/**
218+
* Package can fragment to fit
219+
*/
220+
int SECPKG_FLAG_FRAGMENT = 0x00008000;
221+
/**
222+
* Package can perform mutual authentication
223+
*/
224+
int SECPKG_FLAG_MUTUAL_AUTH = 0x00010000;
225+
/**
226+
* Package can delegate
227+
*/
228+
int SECPKG_FLAG_DELEGATION = 0x00020000;
229+
/**
230+
* Supports callers with restricted tokens.
231+
*/
232+
int SECPKG_FLAG_RESTRICTED_TOKENS = 0x80000;
233+
/**
234+
* The security package extends the Microsoft Negotiate security package.
235+
*/
236+
int SECPKG_FLAG_NEGO_EXTENDER = 0x00100000;
237+
/**
238+
* This package is negotiated by the package of type SECPKG_FLAG_NEGO_EXTENDER.
239+
*/
240+
int SECPKG_FLAG_NEGOTIABLE2 = 0x00200000;
241+
/**
242+
* This package receives all calls from app container apps.
243+
*/
244+
int SECPKG_FLAG_APPCONTAINER_PASSTHROUGH = 0x00400000;
245+
/**
246+
* This package receives calls from app container apps if one of the following checks succeeds.
247+
* <ul>
248+
* <li>Caller has default credentials capability.</li>
249+
* <li>The target is a proxy server.</li>
250+
* <li>The caller has supplied credentials.</li>
251+
* </ul>
252+
*/
253+
int SECPKG_FLAG_APPCONTAINER_CHECKS = 0x00800000;
254+
146255
/**
147256
* Security handle.
148257
*/
@@ -472,4 +581,33 @@ protected List<String> getFieldOrder() {
472581
return FIELDS;
473582
}
474583
}
584+
585+
/**
586+
* The SecPkgContext_PackageInfo structure.
587+
*/
588+
public static class SecPkgContext_PackageInfo extends Structure {
589+
/**
590+
* A reference pointer to a SecPkgContext_PackageInfo structure.
591+
*/
592+
public static class ByReference extends SecPkgContext_PackageInfo implements Structure.ByReference {
593+
}
594+
595+
public static final List<String> FIELDS = createFieldsOrder("PackageInfo");
596+
597+
/**
598+
* Pointer to a SecPkgInfo structure containing the name of the SSP in
599+
* use.
600+
*/
601+
public SecPkgInfo.ByReference PackageInfo;
602+
603+
public SecPkgContext_PackageInfo() {
604+
super(W32APITypeMapper.DEFAULT);
605+
}
606+
607+
@Override
608+
protected List<String> getFieldOrder() {
609+
return FIELDS;
610+
}
611+
}
612+
475613
}

contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java

+66
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
import com.sun.jna.platform.win32.Sspi.CtxtHandle;
1818
import com.sun.jna.platform.win32.Sspi.PSecPkgInfo;
1919
import com.sun.jna.platform.win32.Sspi.SecBufferDesc;
20+
import com.sun.jna.platform.win32.Sspi.SecPkgContext_PackageInfo;
2021
import com.sun.jna.platform.win32.Sspi.SecPkgInfo;
22+
import com.sun.jna.platform.win32.Sspi.SecPkgInfo.ByReference;
2123
import com.sun.jna.platform.win32.Sspi.TimeStamp;
2224
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
2325
import com.sun.jna.ptr.IntByReference;
@@ -341,4 +343,68 @@ public void testCreateEmptyToken() {
341343
assertEquals(Sspi.MAX_TOKEN_SIZE, token.pBuffers[0].cbBuffer);
342344
assertEquals(token.getBytes().length, token.pBuffers[0].getBytes().length);
343345
}
346+
347+
public void testQueryContextAttributes() {
348+
// client ----------- acquire outbound credential handle
349+
CredHandle phClientCredential = new CredHandle();
350+
TimeStamp ptsClientExpiry = new TimeStamp();
351+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(null, "Negotiate",
352+
Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phClientCredential, ptsClientExpiry));
353+
// client ----------- security context
354+
CtxtHandle phClientContext = new CtxtHandle();
355+
IntByReference pfClientContextAttr = new IntByReference();
356+
// server ----------- acquire inbound credential handle
357+
CredHandle phServerCredential = new CredHandle();
358+
TimeStamp ptsServerExpiry = new TimeStamp();
359+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(null, "Negotiate",
360+
Sspi.SECPKG_CRED_INBOUND, null, null, null, null, phServerCredential, ptsServerExpiry));
361+
// server ----------- security context
362+
CtxtHandle phServerContext = new CtxtHandle();
363+
SecBufferDesc pbServerToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
364+
IntByReference pfServerContextAttr = new IntByReference();
365+
int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED;
366+
int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED;
367+
do {
368+
// client token returned is always new
369+
SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
370+
// client ----------- initialize security context, produce a client
371+
// token
372+
if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
373+
// server token is empty the first time
374+
clientRc = Secur32.INSTANCE.InitializeSecurityContext(phClientCredential,
375+
phClientContext.isNull() ? null : phClientContext, Advapi32Util.getUserName(),
376+
Sspi.ISC_REQ_CONNECTION, 0, Sspi.SECURITY_NATIVE_DREP, pbServerToken, 0, phClientContext,
377+
pbClientToken, pfClientContextAttr, null);
378+
assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK);
379+
}
380+
// server ----------- accept security context, produce a server
381+
// token
382+
if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
383+
serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, phServerContext.isNull() ? null
384+
: phServerContext, pbClientToken, Sspi.ISC_REQ_CONNECTION, Sspi.SECURITY_NATIVE_DREP,
385+
phServerContext, pbServerToken, pfServerContextAttr, ptsServerExpiry);
386+
assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK);
387+
}
388+
} while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK);
389+
// query context attributes
390+
SecPkgContext_PackageInfo packageinfo = new SecPkgContext_PackageInfo();
391+
assertEquals(W32Errors.SEC_E_OK,
392+
Secur32.INSTANCE.QueryContextAttributes(phServerContext, Sspi.SECPKG_ATTR_PACKAGE_INFO, packageinfo));
393+
ByReference info = packageinfo.PackageInfo;
394+
395+
assertNotNull(info.Name);
396+
assertNotNull(info.Comment);
397+
398+
assertTrue(!info.Name.isEmpty());
399+
assertTrue(!info.Comment.isEmpty());
400+
401+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeContextBuffer(info.getPointer()));
402+
403+
// release server context
404+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(phServerContext));
405+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(phServerCredential));
406+
// release client context
407+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(phClientContext));
408+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(phClientCredential));
409+
}
344410
}

0 commit comments

Comments
 (0)