Skip to content

Commit

Permalink
Merge branch '1.x' into 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Skyllarr committed Aug 10, 2023
2 parents ab0080b + 41c43b5 commit bb79353
Show file tree
Hide file tree
Showing 7 changed files with 417 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2023 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.security.auth.callback;


/**
* A {@link javax.security.auth.callback.Callback} to inform a server authentication context of configured mechanism properties.
*
* As an informational {@code Callback} it is optional for the {@code CallbackHandler} to handle this.
*
*/
public class AuthenticationConfigurationCallback implements ExtendedCallback{

/**
* Property of the SASL EXTERNAL mechanism that indicates whether a certificate should be verified against the security realm.
*/
private boolean saslSkipCertificateVerification;

public boolean getSaslSkipCertificateVerification() {
return this.saslSkipCertificateVerification;
}

public void setSaslSkipCertificateVerification(boolean skipCertificateVerification) {
this.saslSkipCertificateVerification = skipCertificateVerification;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.wildfly.security.auth.SupportLevel;
import org.wildfly.security.auth.callback.AnonymousAuthorizationCallback;
import org.wildfly.security.auth.callback.AuthenticationCompleteCallback;
import org.wildfly.security.auth.callback.AuthenticationConfigurationCallback;
import org.wildfly.security.auth.callback.AvailableRealmsCallback;
import org.wildfly.security.auth.callback.CachedIdentityAuthorizeCallback;
import org.wildfly.security.auth.callback.CallbackUtil;
Expand Down Expand Up @@ -862,6 +863,7 @@ CallbackHandler createCallbackHandler() {
return new CallbackHandler() {
private SSLConnection sslConnection;
private X509Certificate[] peerCerts;
private boolean saslSkipCertificateVerification;

@Override
public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException {
Expand Down Expand Up @@ -893,7 +895,16 @@ private void handleOne(final Callback[] callbacks, final int idx) throws IOExcep
if (stateRef.get().canVerifyEvidence()) {
if (peerCerts != null) {
log.tracef("Authentication ID is null but SSL peer certificates are available. Trying to authenticate peer");
verifyEvidence(new X509PeerCertificateChainEvidence(peerCerts));
// if SASL mechanism is used with skip-certificate-verification property then do not verifyEvidence against the security realm
if (saslSkipCertificateVerification) {
// Since evidence verification is being skipped here, ensure evidence decoding still takes place
X509PeerCertificateChainEvidence evidence = new X509PeerCertificateChainEvidence(peerCerts);
setDecodedEvidencePrincipal(evidence);
stateRef.get().setPrincipal(evidence.getDecodedPrincipal(), false);
}
else {
verifyEvidence(new X509PeerCertificateChainEvidence(peerCerts));
}
}
}
}
Expand Down Expand Up @@ -1147,7 +1158,12 @@ private void handleOne(final Callback[] callbacks, final int idx) throws IOExcep
log.tracef("Handling PrincipalAuthorizeCallback: principal = %s authorized = %b", principal, authorized);
authorizeCallback.setAuthorized(authorized);
handleOne(callbacks, idx + 1);
} else {
} else if (callback instanceof AuthenticationConfigurationCallback) {
AuthenticationConfigurationCallback authenticationConfigurationCallback = (AuthenticationConfigurationCallback) callback;
saslSkipCertificateVerification = authenticationConfigurationCallback.getSaslSkipCertificateVerification();
handleOne(callbacks, idx + 1);
}
else {
CallbackUtil.unsupported(callback);
handleOne(callbacks, idx + 1);
}
Expand Down Expand Up @@ -1374,7 +1390,7 @@ public InactiveState(SecurityIdentity capturedIdentity, MechanismConfigurationSe
}

public InactiveState(SecurityIdentity capturedIdentity, MechanismConfigurationSelector mechanismConfigurationSelector,
MechanismInformation mechanismInformation, IdentityCredentials privateCredentials, IdentityCredentials publicCredentials, Attributes runtimeAttributes) {
MechanismInformation mechanismInformation, IdentityCredentials privateCredentials, IdentityCredentials publicCredentials, Attributes runtimeAttributes) {
this.capturedIdentity = capturedIdentity;
this.mechanismConfigurationSelector = mechanismConfigurationSelector;
this.mechanismInformation = checkNotNullParam("mechanismInformation", mechanismInformation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,11 @@ public final class WildFlySasl {
*/
public static final String SKIP_NORMALIZATION = "org.wildfly.sasl.skip-normalization";

/**
* A property used to disable certificate verification against the security realm when using SASL.
*
* Note: This is a server only property and is not used on the client side.
*/
public static final String SASL_SKIP_CERTIFICATE_VERIFICATION = "org.wildfly.security.sasl.skip-certificate-verification";

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
import java.nio.charset.StandardCharsets;
import java.text.Normalizer;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.AuthorizeCallback;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;

import org.wildfly.common.array.Arrays2;
import org.wildfly.security.auth.callback.AuthenticationConfigurationCallback;
import org.wildfly.security.sasl.util.SaslMechanismInformation;

/**
Expand All @@ -41,9 +42,16 @@ final class ExternalSaslServer implements SaslServer {
private final CallbackHandler cbh;
private boolean complete;
private String authorizationID;
private final boolean skipCertificateVerification;

ExternalSaslServer(final CallbackHandler cbh) {
this.cbh = cbh;
this.skipCertificateVerification = false;
}

ExternalSaslServer(final CallbackHandler cbh, boolean skipCertVerification) {
this.cbh = cbh;
this.skipCertificateVerification = skipCertVerification;
}

public String getMechanismName() {
Expand All @@ -65,8 +73,11 @@ public byte[] evaluateResponse(final byte[] response) throws SaslException {
}
}
final AuthorizeCallback authorizeCallback = new AuthorizeCallback(null, authorizationId);
final AuthenticationConfigurationCallback authenticationConfigurationCallback = new AuthenticationConfigurationCallback();
authenticationConfigurationCallback.setSaslSkipCertificateVerification(skipCertificateVerification);
Callback[] callbacks = new Callback[]{authenticationConfigurationCallback, authorizeCallback};
try {
cbh.handle(Arrays2.of(authorizeCallback));
cbh.handle(callbacks);
} catch (SaslException e) {
throw e;
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import org.wildfly.security.sasl.WildFlySasl;
import org.wildfly.security.sasl.util.SaslMechanismInformation;

import static org.wildfly.security.sasl.WildFlySasl.SASL_SKIP_CERTIFICATE_VERIFICATION;

/**
* Implementation of the SASL {@code EXTERNAL} server mechanism. See <a href="https://tools.ietf.org/html/rfc4422#appendix-A">RFC 4422
* appendix A</a> for more information about the {@code EXTERNAL} mechanism.
Expand All @@ -41,7 +43,9 @@
public final class ExternalSaslServerFactory implements SaslServerFactory {

public SaslServer createSaslServer(final String mechanism, final String protocol, final String serverName, final Map<String, ?> props, final CallbackHandler cbh) throws SaslException {
return mechanism.equals(SaslMechanismInformation.Names.EXTERNAL) && getMechanismNames(props, false).length != 0 ? new ExternalSaslServer(cbh) : null;
Object skipCertVerificationProp = props == null ? null : props.get(SASL_SKIP_CERTIFICATE_VERIFICATION);
String skipCertVerification = skipCertVerificationProp instanceof String ? (String) skipCertVerificationProp : null;
return mechanism.equals(SaslMechanismInformation.Names.EXTERNAL) && getMechanismNames(props, false).length != 0 ? new ExternalSaslServer(cbh, Boolean.parseBoolean(skipCertVerification)) : null;
}

private String[] getMechanismNames(final Map<String, ?> props, boolean query) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.wildfly.security.auth.callback.AuthenticationConfigurationCallback;
import org.wildfly.security.sasl.WildFlySasl;
import org.wildfly.security.sasl.util.AbstractSaslParticipant;

Expand All @@ -66,6 +67,8 @@ public class ExternalSaslServerTest {
if (callback instanceof AuthorizeCallback) {
final AuthorizeCallback ac = (AuthorizeCallback) callback;
ac.setAuthorized(ADMIN.equals(ac.getAuthorizationID()));
} else if (callback instanceof AuthenticationConfigurationCallback) {
//ignore
} else {
throw new UnsupportedCallbackException(callback);
}
Expand Down
Loading

0 comments on commit bb79353

Please sign in to comment.