Skip to content

Commit

Permalink
TEMP - needs rebased
Browse files Browse the repository at this point in the history
  • Loading branch information
hazendaz committed Sep 14, 2024
1 parent 0003070 commit 1cd9de2
Show file tree
Hide file tree
Showing 15 changed files with 139 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,7 @@ public boolean login() throws LoginException {
.replace("{}", e.getCallback().getClass().getName()));
}

IWindowsIdentity windowsIdentity;
try {
windowsIdentity = this.auth.logonUser(userName, password);
} catch (final Exception e) {
WindowsLoginModule.LOGGER.trace("", e);
throw new LoginException(e.getMessage());
}

try {
try (IWindowsIdentity windowsIdentity = this.auth.logonUser(userName, password)) {
// disable guest login
if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
WindowsLoginModule.LOGGER.debug("guest login disabled: {}", windowsIdentity.getFqn());
Expand All @@ -172,10 +164,10 @@ public boolean login() throws LoginException {
this.username = windowsIdentity.getFqn();
WindowsLoginModule.LOGGER.debug("successfully logged in {} ({})", this.username,
windowsIdentity.getSidString());
} finally {
windowsIdentity.dispose();
} catch (final Exception e) {
WindowsLoginModule.LOGGER.trace("", e);
throw new LoginException(e.getMessage());
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,21 +173,12 @@ public void doFilter(final ServletRequest sreq, final ServletResponse sres, fina
if (!authorizationHeader.isNull()) {

// log the user in using the token
IWindowsIdentity windowsIdentity;
try {
windowsIdentity = this.providers.doFilter(request, response);
try (IWindowsIdentity windowsIdentity = this.providers.doFilter(request, response)) {
// TODO I don't think null is possible here
if (windowsIdentity == null) {
return;
}
} catch (final IOException e) {
NegotiateSecurityFilter.LOGGER.warn("error logging in user: {}", e.getMessage());
NegotiateSecurityFilter.LOGGER.trace("", e);
this.sendUnauthorized(response, true);
return;
}

IWindowsImpersonationContext ctx = null;
try {
if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
NegotiateSecurityFilter.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
this.sendUnauthorized(response, true);
Expand All @@ -198,6 +189,7 @@ public void doFilter(final ServletRequest sreq, final ServletResponse sres, fina
windowsIdentity.getSidString());

final HttpSession session = request.getSession(true);
// TODO This is not possible as this creates a session so it cannot be null
if (session == null) {
throw new ServletException("Expected HttpSession");
}
Expand Down Expand Up @@ -227,17 +219,17 @@ public void doFilter(final ServletRequest sreq, final ServletResponse sres, fina

if (this.impersonate) {
NegotiateSecurityFilter.LOGGER.debug("impersonating user");
ctx = windowsIdentity.impersonate();
}

chain.doFilter(requestWrapper, response);
} finally {
if (this.impersonate && ctx != null) {
NegotiateSecurityFilter.LOGGER.debug("terminating impersonation");
ctx.revertToSelf();
try (IWindowsImpersonationContext ctx = windowsIdentity.impersonate()) {
chain.doFilter(requestWrapper, response);
}
} else {
windowsIdentity.dispose();
chain.doFilter(requestWrapper, response);
}
} catch (final IOException e) {
NegotiateSecurityFilter.LOGGER.warn("error logging in user: {}", e.getMessage());
NegotiateSecurityFilter.LOGGER.trace("", e);
this.sendUnauthorized(response, true);
return;
}

return;
Expand Down Expand Up @@ -298,18 +290,13 @@ private boolean doFilterPrincipal(final HttpServletRequest request, final HttpSe

final NegotiateRequestWrapper requestWrapper = new NegotiateRequestWrapper(request, windowsPrincipal);

IWindowsImpersonationContext ctx = null;
if (this.impersonate) {
NegotiateSecurityFilter.LOGGER.debug("re-impersonating user");
ctx = windowsPrincipal.getIdentity().impersonate();
}
try {
chain.doFilter(requestWrapper, response);
} finally {
if (this.impersonate && ctx != null) {
NegotiateSecurityFilter.LOGGER.debug("terminating impersonation");
ctx.revertToSelf();
try (IWindowsImpersonationContext ctx = windowsPrincipal.getIdentity().impersonate()) {
chain.doFilter(requestWrapper, response);
}
} else {
chain.doFilter(requestWrapper, response);
}
} else {
NegotiateSecurityFilter.LOGGER.debug("previously authenticated user: {}", principal.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@

import com.sun.jna.platform.win32.Sspi.CredHandle;

import java.io.Closeable;

/**
* Windows credentials handle.
*/
public interface IWindowsCredentialsHandle {
public interface IWindowsCredentialsHandle extends Closeable {
/**
* Initialize.
*/
Expand All @@ -45,4 +47,7 @@ public interface IWindowsCredentialsHandle {
* @return CredHandle.
*/
CredHandle getHandle();

@Override
void close();
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/**
* A Windows Identity.
*/
public interface IWindowsIdentity {
public interface IWindowsIdentity extends AutoCloseable {

/**
* Sid.
Expand Down Expand Up @@ -74,4 +74,7 @@ public interface IWindowsIdentity {
* @return True if the identity represents a Guest account, false otherwise.
*/
boolean isGuest();

@Override
void close();
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@
/**
* A Windows impersonation context.
*/
public interface IWindowsImpersonationContext {
public interface IWindowsImpersonationContext extends AutoCloseable {

/**
* Terminate the impersonation of a client application.
*/
void revertToSelf();

@Override
void close();
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,71 +112,70 @@ public IWindowsSecurityContext acceptSecurityToken(final String connectionId, fi
throw new Win32Exception(WinError.SEC_E_INVALID_TOKEN);
}

CtxtHandle continueHandle = null;
IWindowsCredentialsHandle serverCredential;
ContinueContext continueContext = this.continueContexts.get(connectionId);
if (continueContext != null) {
continueHandle = continueContext.continueHandle;
serverCredential = continueContext.serverCredential;
} else {
serverCredential = new WindowsCredentialsHandleImpl(null, Sspi.SECPKG_CRED_INBOUND, securityPackage);
try (final IWindowsCredentialsHandle serverCredential = new WindowsCredentialsHandleImpl(null,
Sspi.SECPKG_CRED_INBOUND, securityPackage)) {
serverCredential.initialize();
}

WindowsSecurityContextImpl sc;
WindowsSecurityContextImpl sc;

int rc;
int tokenSize = Sspi.MAX_TOKEN_SIZE;
int rc;
int tokenSize = Sspi.MAX_TOKEN_SIZE;

do {
final ManagedSecBufferDesc pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, tokenSize);
final ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, token);
CtxtHandle continueContext;
ManagedSecBufferDesc pbServerToken;
ManagedSecBufferDesc pbClientToken;
final IntByReference pfClientContextAttr = new IntByReference();

final CtxtHandle phNewServerContext = new CtxtHandle();
rc = Secur32.INSTANCE.AcceptSecurityContext(serverCredential.getHandle(), continueHandle, pbClientToken,
Sspi.ISC_REQ_CONNECTION, Sspi.SECURITY_NATIVE_DREP, phNewServerContext, pbServerToken,
pfClientContextAttr, null);

sc = new WindowsSecurityContextImpl();
sc.setCredentialsHandle(serverCredential);
sc.setSecurityPackage(securityPackage);
sc.setSecurityContext(phNewServerContext);

switch (rc) {
case WinError.SEC_E_BUFFER_TOO_SMALL:
tokenSize += Sspi.MAX_TOKEN_SIZE;
sc.dispose();
WindowsSecurityContextImpl.dispose(continueHandle);
break;
case WinError.SEC_E_OK:
// the security context received from the client was accepted
this.resetSecurityToken(connectionId);
// if an output token was generated by the function, it must be sent to the client process
if (pbServerToken.pBuffers != null && pbServerToken.cBuffers == 1
&& pbServerToken.getBuffer(0).cbBuffer > 0) {
sc.setToken(pbServerToken.getBuffer(0).getBytes() == null ? new byte[0]
do {
pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, tokenSize);
pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, token);

continueContext = this.continueContexts.get(connectionId);

rc = Secur32.INSTANCE.AcceptSecurityContext(serverCredential.getHandle(), continueContext,
pbClientToken, Sspi.ISC_REQ_CONNECTION, Sspi.SECURITY_NATIVE_DREP, phNewServerContext,
pbServerToken, pfClientContextAttr, null);

sc = new WindowsSecurityContextImpl();
sc.setCredentialsHandle(serverCredential);
sc.setSecurityPackage(securityPackage);
sc.setSecurityContext(phNewServerContext);

switch (rc) {
case WinError.SEC_E_BUFFER_TOO_SMALL:
tokenSize += Sspi.MAX_TOKEN_SIZE;
sc.dispose();
WindowsSecurityContextImpl.dispose(continueContext);
break;
case WinError.SEC_E_OK:
// the security context received from the client was accepted
this.resetSecurityToken(connectionId);
// if an output token was generated by the function, it must be sent to the client process
if (pbServerToken.pBuffers != null && pbServerToken.cBuffers == 1
&& pbServerToken.pBuffers(0).cbBuffer > 0) {
sc.setToken(pbServerToken.getBuffer(0).getBytes() == null ? new byte[0]
: pbServerToken.getBuffer(0).getBytes().clone());
}
sc.setContinue(false);
break;
case WinError.SEC_I_CONTINUE_NEEDED:
// the server must send the output token to the client and wait for a returned token
continueContext = new ContinueContext(phNewServerContext, serverCredential);
this.continueContexts.put(connectionId, continueContext);
sc.setToken(pbServerToken.getBuffer(0).getBytes() == null ? new byte[0]
}
sc.setContinue(false);
break;
case WinError.SEC_I_CONTINUE_NEEDED:
// the server must send the output token to the client and wait for a returned token
this.continueContexts.put(connectionId, phNewServerContext);
sc.setToken(pbServerToken.getBuffer(0).getBytes() == null ? new byte[0]
: pbServerToken.getBuffer(0).getBytes().clone());
sc.setContinue(true);
break;
default:
sc.dispose();
WindowsSecurityContextImpl.dispose(continueHandle);
this.resetSecurityToken(connectionId);
throw new Win32Exception(rc);
}
} while (rc == WinError.SEC_E_BUFFER_TOO_SMALL);

return sc;
sc.setContinue(true);
break;
default:
sc.dispose();
WindowsSecurityContextImpl.dispose(continueContext);
this.resetSecurityToken(connectionId);
throw new Win32Exception(rc);
}
} while (rc == WinError.SEC_E_BUFFER_TOO_SMALL);

return sc;
}
}

@Override
Expand Down Expand Up @@ -232,7 +231,7 @@ public IWindowsAccount lookupAccount(final String username) {

@Override
public void resetSecurityToken(final String connectionId) {
this.continueContexts.remove(connectionId);
this.resetSecurityToken(connectionId);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,9 @@ public void dispose() {
public CredHandle getHandle() {
return this.handle;
}

@Override
public void close() {
this.dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,10 @@ public WindowsIdentityImpersonationContextImpl(final HANDLE windowsIdentity) {
public void revertToSelf() {
Advapi32.INSTANCE.RevertToSelf();
}

@Override
public void close() {
this.revertToSelf();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,10 @@ public boolean isGuest() {
}
return Advapi32Util.isWellKnownSid(this.getSid(), WELL_KNOWN_SID_TYPE.WinAnonymousSid);
}

@Override
public void close() {
this.dispose();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ public void revertToSelf() {
throw new Win32Exception(rc);
}
}

@Override
public void close() {
this.revertToSelf();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,18 @@ public byte[] getToken() {
*/
public static IWindowsSecurityContext getCurrent(final String securityPackage, final String targetName) {
IWindowsCredentialsHandle credentialsHandle = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
credentialsHandle.initialize();
try {
final WindowsSecurityContextImpl ctx = new WindowsSecurityContextImpl();
ctx.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
ctx.setCredentialsHandle(credentialsHandle);
ctx.setSecurityPackage(securityPackage);
ctx.initialize(null, null, targetName);

// Starting from here ctx 'owns' the credentials handle, so let's null out the
// variable. This will prevent the finally block below from disposing it right away.
credentialsHandle = null;

return ctx;
} finally {
if (credentialsHandle != null) {
credentialsHandle.dispose();
}
}

final WindowsSecurityContextImpl ctx = new WindowsSecurityContextImpl();
ctx.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
ctx.setCredentialsHandle(credentialsHandle);
ctx.setSecurityPackage(securityPackage);
ctx.initialize(null, null, targetName);

// Starting from here ctx 'owns' the credentials handle, so let's null out the
// variable. This will prevent disposing it right away.
credentialsHandle = null;

return ctx;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ class WindowsCredentialsHandleTest {
*/
@Test
void testGetCurrent() {
final IWindowsCredentialsHandle handle = WindowsCredentialsHandleImpl.getCurrent("Negotiate");
Assertions.assertNotNull(handle);
handle.initialize();
handle.dispose();
try (final IWindowsCredentialsHandle handle = WindowsCredentialsHandleImpl.getCurrent("Negotiate")) {
Assertions.assertNotNull(handle);
}
}
}
Loading

0 comments on commit 1cd9de2

Please sign in to comment.