You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by gtully <gi...@git.apache.org> on 2017/07/20 17:22:32 UTC

[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

GitHub user gtully opened a pull request:

    https://github.com/apache/qpid-jms/pull/10

    [QPIDJMS-303] implement sasl gssapi (kerberos) mechanism

    Using the current username or configured url prams the current kerberos credential
    is propagated via sasl gssapi mechanism. the default server principal is amqp/<hostName>@<REALM>

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/gtully/qpid-jms-1 QPIDJMS-303

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/qpid-jms/pull/10.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #10
    
----
commit 4ba8b7d954171b357c5552203ee2960434403fad
Author: gtully <ga...@gmail.com>
Date:   2017-07-20T16:55:07Z

    [QPIDJMS-303] implement sasl gssapi (kerberos) mechanism
    
    Using the current username or configured url prams the current kerberos credential
    is propagated via sasl gssapi mechanism. the default server principal is amqp/<hostName>@<REALM>

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128801781
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/TestAmqpPeer.java ---
    @@ -495,6 +512,169 @@ public void run()
             }
         }
     
    +    public void expectGSSAPIFail(Symbol mech) throws Exception {
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        addHandler(new SaslInitMatcher().withMechanism(equalTo(mech)));
    +
    +    }
    +
    +    public void expectGSSAPI(Symbol mech, String serviceName) throws Exception {
    +
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        // setup server gss context
    +        LoginContext loginContext = new LoginContext("", null, null,
    +                kerb5InlineConfig(serviceName, false));
    +        loginContext.login();
    +        final Subject serverSubject =loginContext.getSubject();
    +
    +        LOGGER.info("saslServer subject:" + serverSubject.getPrivateCredentials());
    +
    +        Map<String, ?> config = new HashMap();
    +        final CallbackHandler handler = new CallbackHandler() {
    +            @Override
    +            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    +                LOGGER.info("Here with: " + Arrays.asList(callbacks));
    +                for (Callback callback :callbacks) {
    +                    if (callback instanceof AuthorizeCallback) {
    +                        AuthorizeCallback authorizeCallback = (AuthorizeCallback) callback;
    +                        authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals(authorizeCallback.getAuthorizationID()));
    +                    }
    +                }
    +            }
    +        };
    +        final SaslServer saslServer = Subject.doAs(serverSubject, new PrivilegedExceptionAction<SaslServer>() {
    +            @Override
    +            public SaslServer run() throws Exception {
    +                return Sasl.createSaslServer(mech.toString(), null, null, config, handler);
    +            }
    +        });
    +
    +        final SaslChallengeFrame challengeFrame = new SaslChallengeFrame();
    +
    +        SaslInitMatcher saslInitMatcher = new SaslInitMatcher()
    +                .withMechanism(equalTo(mech))
    +                .withInitialResponse(new BaseMatcher<Binary>() {
    +
    +                    @Override
    +                    public void describeTo(Description description) {}
    +
    +                    @Override
    +                    public boolean matches(Object o) {
    +                        if (o == null) {
    +                            LOGGER.error("Got null initial response!");
    +                            return false;
    +                        }
    +                        final Binary binary = (Binary) o;
    +                        // validate via sasl
    +                        byte[] token = null;
    +                        try {
    +                            token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                                @Override
    +                                public byte[] run() throws Exception {
    +                                    LOGGER.info("Evaluate Response.. size:" + binary.getLength());
    +                                    return saslServer.evaluateResponse(binary.getArray());
    +                                }
    +                            });
    +                        } catch (PrivilegedActionException e) {
    +                            e.printStackTrace();
    +                        }
    +                        LOGGER.info("Complete:" + saslServer.isComplete());
    +
    +                        if (token != null) {
    +                            // fling it back in on complete
    +                            challengeFrame.setChallenge(new Binary(token));
    +                        }
    +                        return true;
    +                    }
    +                }).onCompletion(new AmqpPeerRunnable() {
    +                    @Override
    +                    public void run() {
    +                        TestAmqpPeer.this.sendFrame(
    +                                FrameType.SASL, 0,
    +                                challengeFrame,
    +                                null,
    +                                false, 0);
    +                    }
    +                });
    +
    +        AtomicBoolean response = new AtomicBoolean(false);
    +        SaslResponseMatcher challengeMatcher = new SaslResponseMatcher().withResponse(new BaseMatcher<Binary>() {
    +
    +            @Override
    +            public void describeTo(Description description) {}
    +
    +            @Override
    +            public boolean matches(Object o) {
    +                final Binary binary = (Binary) o;
    +                if (!saslServer.isComplete()) {
    +                    // validate via sasl
    +                    byte[] token = null;
    +                    try {
    +                        token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                            @Override
    +                            public byte[] run() throws Exception {
    +                                LOGGER.info("Evaluate challenge response.. size:" + binary.getLength());
    +                                return saslServer.evaluateResponse(binary.getArray());
    +                            }
    +                        });
    +                    } catch (PrivilegedActionException e) {
    +                        e.printStackTrace();
    +                    }
    +                    LOGGER.info("Complete:" + saslServer.isComplete());
    +                    if (token != null) {
    +                        // fling it back
    +                        challengeFrame.setChallenge(new Binary(token));
    +                        response.set(true);
    +                    }
    +                    return true;
    +                }
    +
    +                return false;
    +            }
    +        }).onCompletion(new AmqpPeerRunnable() {
    +            @Override
    +            public void run() {
    +                if (response.get()) {
    +                    TestAmqpPeer.this.sendFrame(
    +                            FrameType.SASL, 0,
    +                            challengeFrame,
    +                            null,
    +                            false, 0);
    +                }
    +
    +                if (saslServer.isComplete()) {
    --- End diff --
    
    this is interesting. I need to check, good catch :-)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128754720
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslGssApiIntegrationTest.java ---
    @@ -0,0 +1,185 @@
    +/*
    + *
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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.apache.qpid.jms.integration;
    +
    +import org.apache.directory.server.kerberos.shared.keytab.Keytab;
    +import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
    +import org.apache.hadoop.minikdc.MiniKdc;
    +import org.apache.qpid.jms.JmsConnectionFactory;
    +import org.apache.qpid.jms.test.QpidJmsTestCase;
    +import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
    +import org.apache.qpid.proton.amqp.Symbol;
    +import org.junit.After;
    +import org.junit.Before;
    +import org.junit.Test;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +import javax.jms.Connection;
    +import javax.jms.ConnectionFactory;
    +import javax.jms.JMSSecurityException;
    +import java.io.File;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +
    +import static junit.framework.TestCase.assertTrue;
    +import static org.junit.Assert.assertNull;
    +import static org.junit.Assert.fail;
    +
    +public class SaslGssApiIntegrationTest extends QpidJmsTestCase {
    +
    +    private static final Logger LOG = LoggerFactory.getLogger(SaslGssApiIntegrationTest.class);
    +
    +    private static final Symbol GSSAPI = Symbol.valueOf("GSSAPI");
    +    private static final String serviceName = "amqp/localhost";
    +
    +    private MiniKdc kdc;
    +
    +    @Before
    +    public void setUpKerberso() throws Exception {
    +        Path tempDirectory = Files.createTempDirectory("junit.test.");
    +        File root = tempDirectory.toFile();
    +        root.deleteOnExit();
    +        kdc = new MiniKdc(MiniKdc.createConf(), new File(root, "kdc"));
    +        kdc.start();
    +
    +        // hard coded match, default_keytab_name in minikdc-krb5.conf template
    +        File userKeyTab = new File("target/test.krb5.keytab");
    +        kdc.createPrincipal(userKeyTab, "client", serviceName);
    +
    +        Keytab kt = Keytab.read(userKeyTab);
    +        for (KeytabEntry entry : kt.getEntries()) {
    +            LOG.info("KeyTab Kerb PrincipalNames:" + entry.getPrincipalName());
    +        }
    +
    +        java.util.logging.Logger logger = java.util.logging.Logger.getLogger("javax.security.sasl");
    --- End diff --
    
    Is this just for debug? Might be good to make it optional, rather than leave it changing the config for all subsequent tests.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128752547
  
    --- Diff: qpid-jms-client/src/test/resources/minikdc-krb5.conf ---
    @@ -0,0 +1,26 @@
    +#
    +# Licensed to the Apache Software Foundation (ASF) under one
    +# or more contributor license agreements.  See the NOTICE file
    +# distributed with this work for additional information
    +# regarding copyright ownership.  The ASF licenses this file
    +# to you 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.
    +#
    +[libdefaults]
    +    default_realm = {0}
    +    udp_preference_limit = 1
    +    default_keytab_name = FILE:target/test.krb5.keytab
    +
    +[realms]
    +    {0} = '{'
    +        kdc = {1}:{2}
    +    '}'
    --- End diff --
    
    As with the login config, naming it more specifically for the test its used in would be good.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128749340
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/TestAmqpPeer.java ---
    @@ -495,6 +512,169 @@ public void run()
             }
         }
     
    +    public void expectGSSAPIFail(Symbol mech) throws Exception {
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        addHandler(new SaslInitMatcher().withMechanism(equalTo(mech)));
    +
    +    }
    +
    +    public void expectGSSAPI(Symbol mech, String serviceName) throws Exception {
    +
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        // setup server gss context
    +        LoginContext loginContext = new LoginContext("", null, null,
    +                kerb5InlineConfig(serviceName, false));
    --- End diff --
    
    Using this presumably means this test will fail on the IBM JDK since it references the Sun login class? That probably needs addressed in some way.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128810019
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpSaslAuthenticator.java ---
    @@ -137,7 +142,9 @@ private void handleSaslStep() throws JMSSecurityException {
                     byte[] challenge = new byte[sasl.pending()];
                     sasl.recv(challenge, 0, challenge.length);
                     byte[] response = mechanism.getChallengeResponse(challenge);
    -                sasl.send(response, 0, response.length);
    +                if (response != null) {
    --- End diff --
    
    Good point. Interesting, I guess it is allowing for the 'additional-data' style information at the end of the exchange where there isn't a response.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128809457
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/TestAmqpPeer.java ---
    @@ -495,6 +512,169 @@ public void run()
             }
         }
     
    +    public void expectGSSAPIFail(Symbol mech) throws Exception {
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        addHandler(new SaslInitMatcher().withMechanism(equalTo(mech)));
    +
    +    }
    +
    +    public void expectGSSAPI(Symbol mech, String serviceName) throws Exception {
    +
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        // setup server gss context
    +        LoginContext loginContext = new LoginContext("", null, null,
    +                kerb5InlineConfig(serviceName, false));
    +        loginContext.login();
    +        final Subject serverSubject =loginContext.getSubject();
    +
    +        LOGGER.info("saslServer subject:" + serverSubject.getPrivateCredentials());
    +
    +        Map<String, ?> config = new HashMap();
    +        final CallbackHandler handler = new CallbackHandler() {
    +            @Override
    +            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    +                LOGGER.info("Here with: " + Arrays.asList(callbacks));
    +                for (Callback callback :callbacks) {
    +                    if (callback instanceof AuthorizeCallback) {
    +                        AuthorizeCallback authorizeCallback = (AuthorizeCallback) callback;
    +                        authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals(authorizeCallback.getAuthorizationID()));
    +                    }
    +                }
    +            }
    +        };
    +        final SaslServer saslServer = Subject.doAs(serverSubject, new PrivilegedExceptionAction<SaslServer>() {
    +            @Override
    +            public SaslServer run() throws Exception {
    +                return Sasl.createSaslServer(mech.toString(), null, null, config, handler);
    +            }
    +        });
    +
    +        final SaslChallengeFrame challengeFrame = new SaslChallengeFrame();
    +
    +        SaslInitMatcher saslInitMatcher = new SaslInitMatcher()
    +                .withMechanism(equalTo(mech))
    +                .withInitialResponse(new BaseMatcher<Binary>() {
    +
    +                    @Override
    +                    public void describeTo(Description description) {}
    +
    +                    @Override
    +                    public boolean matches(Object o) {
    +                        if (o == null) {
    +                            LOGGER.error("Got null initial response!");
    +                            return false;
    +                        }
    +                        final Binary binary = (Binary) o;
    +                        // validate via sasl
    +                        byte[] token = null;
    +                        try {
    +                            token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                                @Override
    +                                public byte[] run() throws Exception {
    +                                    LOGGER.info("Evaluate Response.. size:" + binary.getLength());
    +                                    return saslServer.evaluateResponse(binary.getArray());
    +                                }
    +                            });
    +                        } catch (PrivilegedActionException e) {
    +                            e.printStackTrace();
    +                        }
    +                        LOGGER.info("Complete:" + saslServer.isComplete());
    +
    +                        if (token != null) {
    +                            // fling it back in on complete
    +                            challengeFrame.setChallenge(new Binary(token));
    +                        }
    +                        return true;
    +                    }
    +                }).onCompletion(new AmqpPeerRunnable() {
    +                    @Override
    +                    public void run() {
    +                        TestAmqpPeer.this.sendFrame(
    +                                FrameType.SASL, 0,
    +                                challengeFrame,
    +                                null,
    +                                false, 0);
    +                    }
    +                });
    +
    +        AtomicBoolean response = new AtomicBoolean(false);
    +        SaslResponseMatcher challengeMatcher = new SaslResponseMatcher().withResponse(new BaseMatcher<Binary>() {
    +
    +            @Override
    +            public void describeTo(Description description) {}
    +
    +            @Override
    +            public boolean matches(Object o) {
    +                final Binary binary = (Binary) o;
    +                if (!saslServer.isComplete()) {
    +                    // validate via sasl
    +                    byte[] token = null;
    +                    try {
    +                        token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                            @Override
    +                            public byte[] run() throws Exception {
    +                                LOGGER.info("Evaluate challenge response.. size:" + binary.getLength());
    +                                return saslServer.evaluateResponse(binary.getArray());
    +                            }
    +                        });
    +                    } catch (PrivilegedActionException e) {
    +                        e.printStackTrace();
    +                    }
    +                    LOGGER.info("Complete:" + saslServer.isComplete());
    +                    if (token != null) {
    +                        // fling it back
    +                        challengeFrame.setChallenge(new Binary(token));
    +                        response.set(true);
    +                    }
    +                    return true;
    +                }
    +
    +                return false;
    +            }
    +        }).onCompletion(new AmqpPeerRunnable() {
    +            @Override
    +            public void run() {
    +                if (response.get()) {
    +                    TestAmqpPeer.this.sendFrame(
    +                            FrameType.SASL, 0,
    +                            challengeFrame,
    +                            null,
    +                            false, 0);
    +                }
    +
    +                if (saslServer.isComplete()) {
    --- End diff --
    
    if it goes on its own it suggests the other bit can be removed or theres an 'else' missing, which doesnt make sense either as there should likely always be an outcome. I also missed earlier that it is sending a successfull auth outcome..the server being complete doesnt necessarily mean it succeeded, and the previous bit allows for it to fail, so it still seems something is off here to me.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128788434
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslGssApiIntegrationTest.java ---
    @@ -0,0 +1,185 @@
    +/*
    + *
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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.apache.qpid.jms.integration;
    +
    +import org.apache.directory.server.kerberos.shared.keytab.Keytab;
    +import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
    +import org.apache.hadoop.minikdc.MiniKdc;
    +import org.apache.qpid.jms.JmsConnectionFactory;
    +import org.apache.qpid.jms.test.QpidJmsTestCase;
    +import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
    +import org.apache.qpid.proton.amqp.Symbol;
    +import org.junit.After;
    +import org.junit.Before;
    +import org.junit.Test;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +import javax.jms.Connection;
    +import javax.jms.ConnectionFactory;
    +import javax.jms.JMSSecurityException;
    +import java.io.File;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +
    +import static junit.framework.TestCase.assertTrue;
    +import static org.junit.Assert.assertNull;
    +import static org.junit.Assert.fail;
    +
    +public class SaslGssApiIntegrationTest extends QpidJmsTestCase {
    +
    +    private static final Logger LOG = LoggerFactory.getLogger(SaslGssApiIntegrationTest.class);
    +
    +    private static final Symbol GSSAPI = Symbol.valueOf("GSSAPI");
    +    private static final String serviceName = "amqp/localhost";
    +
    +    private MiniKdc kdc;
    +
    +    @Before
    +    public void setUpKerberso() throws Exception {
    +        Path tempDirectory = Files.createTempDirectory("junit.test.");
    --- End diff --
    
    agree


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128748789
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/sasl/GssapiMechanism.java ---
    @@ -0,0 +1,163 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.apache.qpid.jms.sasl;
    +
    +import javax.security.auth.Subject;
    +import javax.security.auth.login.AppConfigurationEntry;
    +import javax.security.auth.login.Configuration;
    +import javax.security.auth.login.LoginContext;
    +import javax.security.sasl.Sasl;
    +import javax.security.sasl.SaslClient;
    +import javax.security.sasl.SaslException;
    +import java.security.Principal;
    +import java.security.PrivilegedActionException;
    +import java.security.PrivilegedExceptionAction;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Implements the GSSAPI sasl authentication Mechanism.
    + */
    +public class GssapiMechanism extends AbstractMechanism {
    +
    +    public static final String NAME = "GSSAPI";
    +    private Subject subject;
    +    private SaslClient saslClient;
    +    private String protocol = "amqp";
    +    private String server = null;
    +    private String configScope = null;
    +
    +    // a gss/sasl service name, x@y, morphs to a krbPrincipal a/y@REALM
    +
    +    @Override
    +    public int getPriority() {
    +        return PRIORITY.LOW.getValue();
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public byte[] getInitialResponse() throws SaslException {
    +        try {
    +            LoginContext loginContext = null;
    +            if (configScope != null) {
    +                loginContext = new LoginContext(configScope);
    +            } else {
    +                // inline keytab config using user as principal
    +                loginContext = new LoginContext("", null, null,
    +                        kerb5InlineConfig(getUsername(), true));
    +            }
    +            loginContext.login();
    +            subject = loginContext.getSubject();
    +
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +
    +                @Override
    +                public byte[] run() throws Exception {
    +                    saslClient = Sasl.createSaslClient(new String[]{getName()}, null, protocol, server, null, null);
    +                    if (saslClient.hasInitialResponse()) {
    +                        return saslClient.evaluateChallenge(new byte[0]);
    +                    }
    +                    return null;
    +                }
    +            });
    +        } catch (Exception e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public byte[] getChallengeResponse(final byte[] challenge) throws SaslException {
    +        try {
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +                @Override
    +                public byte[] run() throws Exception {
    +                    return saslClient.evaluateChallenge(challenge);
    +                }
    +            });
    +        } catch (PrivilegedActionException e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public void verifyCompletion() throws SaslException {
    +        boolean result = saslClient.isComplete();
    +        saslClient.dispose();
    +        if (!result) {
    +            throw new SaslException("not complete");
    +        }
    +    }
    +
    +
    +    @Override
    +    public boolean isApplicable(String username, String password, Principal localPrincipal) {
    +        return true;
    +    }
    +
    +    public static Configuration kerb5InlineConfig(String principal, boolean initiator) {
    +        final Map<String, String> krb5LoginModuleOptions = new HashMap<>();
    +        krb5LoginModuleOptions.put("isInitiator", String.valueOf(initiator));
    +        krb5LoginModuleOptions.put("principal", principal);
    +        krb5LoginModuleOptions.put("useKeyTab", "true");
    +        krb5LoginModuleOptions.put("storeKey", "true");
    +        krb5LoginModuleOptions.put("doNotPrompt", "true");
    +        krb5LoginModuleOptions.put("renewTGT", "true");
    +        krb5LoginModuleOptions.put("refreshKrb5Config", "true");
    +        krb5LoginModuleOptions.put("useTicketCache", "true");
    +        String ticketCache = System.getenv("KRB5CCNAME");
    +        if (ticketCache != null) {
    +            krb5LoginModuleOptions.put("ticketCache", ticketCache);
    +        }
    +        return new Configuration() {
    +            @Override
    +            public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
    +                return new AppConfigurationEntry[]{
    +                        new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
    +                                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
    +                                krb5LoginModuleOptions)};
    +            }
    +        };
    +    }
    +
    +    public String getProtocol() {
    +        return protocol;
    +    }
    +
    +    public void setProtocol(String protocol) {
    +        this.protocol = protocol;
    +    }
    +
    +    public String getServer() {
    +        return server;
    +    }
    +
    +    public void setServer(String server) {
    --- End diff --
    
    Name this serverName perhaps? Thats how its referenced by the bits that use it.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128750540
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/TestAmqpPeer.java ---
    @@ -495,6 +512,169 @@ public void run()
             }
         }
     
    +    public void expectGSSAPIFail(Symbol mech) throws Exception {
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        addHandler(new SaslInitMatcher().withMechanism(equalTo(mech)));
    +
    +    }
    +
    +    public void expectGSSAPI(Symbol mech, String serviceName) throws Exception {
    --- End diff --
    
    Rename to expectSaslGSSAPI for consistency with the other sasl verification methods. Passing the mechanism name is perhaps also a bit redundant and could be removed. Similarly for the expectGSSAPIFail.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128800956
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/TestAmqpPeer.java ---
    @@ -495,6 +512,169 @@ public void run()
             }
         }
     
    +    public void expectGSSAPIFail(Symbol mech) throws Exception {
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        addHandler(new SaslInitMatcher().withMechanism(equalTo(mech)));
    +
    +    }
    +
    +    public void expectGSSAPI(Symbol mech, String serviceName) throws Exception {
    +
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        // setup server gss context
    +        LoginContext loginContext = new LoginContext("", null, null,
    +                kerb5InlineConfig(serviceName, false));
    --- End diff --
    
    I have added some unverified support for ibm jdk - I guess it is an argument for only having external jaas config via login.config. But I think in this case ease of use trumps the overhead of maintaining the inline config


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128754495
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/TestAmqpPeer.java ---
    @@ -495,6 +512,169 @@ public void run()
             }
         }
     
    +    public void expectGSSAPIFail(Symbol mech) throws Exception {
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        addHandler(new SaslInitMatcher().withMechanism(equalTo(mech)));
    +
    +    }
    +
    +    public void expectGSSAPI(Symbol mech, String serviceName) throws Exception {
    +
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        // setup server gss context
    +        LoginContext loginContext = new LoginContext("", null, null,
    +                kerb5InlineConfig(serviceName, false));
    +        loginContext.login();
    +        final Subject serverSubject =loginContext.getSubject();
    +
    +        LOGGER.info("saslServer subject:" + serverSubject.getPrivateCredentials());
    +
    +        Map<String, ?> config = new HashMap();
    +        final CallbackHandler handler = new CallbackHandler() {
    +            @Override
    +            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    +                LOGGER.info("Here with: " + Arrays.asList(callbacks));
    +                for (Callback callback :callbacks) {
    +                    if (callback instanceof AuthorizeCallback) {
    +                        AuthorizeCallback authorizeCallback = (AuthorizeCallback) callback;
    +                        authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals(authorizeCallback.getAuthorizationID()));
    +                    }
    +                }
    +            }
    +        };
    +        final SaslServer saslServer = Subject.doAs(serverSubject, new PrivilegedExceptionAction<SaslServer>() {
    +            @Override
    +            public SaslServer run() throws Exception {
    +                return Sasl.createSaslServer(mech.toString(), null, null, config, handler);
    +            }
    +        });
    +
    +        final SaslChallengeFrame challengeFrame = new SaslChallengeFrame();
    +
    +        SaslInitMatcher saslInitMatcher = new SaslInitMatcher()
    +                .withMechanism(equalTo(mech))
    +                .withInitialResponse(new BaseMatcher<Binary>() {
    +
    +                    @Override
    +                    public void describeTo(Description description) {}
    +
    +                    @Override
    +                    public boolean matches(Object o) {
    +                        if (o == null) {
    +                            LOGGER.error("Got null initial response!");
    +                            return false;
    +                        }
    +                        final Binary binary = (Binary) o;
    +                        // validate via sasl
    +                        byte[] token = null;
    +                        try {
    +                            token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                                @Override
    +                                public byte[] run() throws Exception {
    +                                    LOGGER.info("Evaluate Response.. size:" + binary.getLength());
    +                                    return saslServer.evaluateResponse(binary.getArray());
    +                                }
    +                            });
    +                        } catch (PrivilegedActionException e) {
    +                            e.printStackTrace();
    +                        }
    +                        LOGGER.info("Complete:" + saslServer.isComplete());
    +
    +                        if (token != null) {
    +                            // fling it back in on complete
    +                            challengeFrame.setChallenge(new Binary(token));
    +                        }
    +                        return true;
    +                    }
    +                }).onCompletion(new AmqpPeerRunnable() {
    +                    @Override
    +                    public void run() {
    +                        TestAmqpPeer.this.sendFrame(
    +                                FrameType.SASL, 0,
    +                                challengeFrame,
    +                                null,
    +                                false, 0);
    +                    }
    +                });
    +
    +        AtomicBoolean response = new AtomicBoolean(false);
    +        SaslResponseMatcher challengeMatcher = new SaslResponseMatcher().withResponse(new BaseMatcher<Binary>() {
    +
    +            @Override
    +            public void describeTo(Description description) {}
    +
    +            @Override
    +            public boolean matches(Object o) {
    +                final Binary binary = (Binary) o;
    +                if (!saslServer.isComplete()) {
    +                    // validate via sasl
    +                    byte[] token = null;
    +                    try {
    +                        token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                            @Override
    +                            public byte[] run() throws Exception {
    +                                LOGGER.info("Evaluate challenge response.. size:" + binary.getLength());
    +                                return saslServer.evaluateResponse(binary.getArray());
    +                            }
    +                        });
    +                    } catch (PrivilegedActionException e) {
    +                        e.printStackTrace();
    +                    }
    +                    LOGGER.info("Complete:" + saslServer.isComplete());
    +                    if (token != null) {
    +                        // fling it back
    +                        challengeFrame.setChallenge(new Binary(token));
    +                        response.set(true);
    +                    }
    +                    return true;
    +                }
    +
    +                return false;
    +            }
    +        }).onCompletion(new AmqpPeerRunnable() {
    +            @Override
    +            public void run() {
    +                if (response.get()) {
    +                    TestAmqpPeer.this.sendFrame(
    +                            FrameType.SASL, 0,
    +                            challengeFrame,
    +                            null,
    +                            false, 0);
    +                }
    +
    +                if (saslServer.isComplete()) {
    --- End diff --
    
    This bit seems off, we shouldn't really be sending a challenge and an outcome frames at the same time, and in particular changes coming in proton-j 0.20.0 to allow accessing the 'additional-data' in the outcome may mean only one might be seen by the recipient.
    
    Either its really challenge, in which case we expect a response (which can just be empty), or we class it as 'additional-data' and send it as part of the outcome frame (when it is a successful outcome, only).


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128775727
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/sasl/GssapiMechanism.java ---
    @@ -0,0 +1,163 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.apache.qpid.jms.sasl;
    +
    +import javax.security.auth.Subject;
    +import javax.security.auth.login.AppConfigurationEntry;
    +import javax.security.auth.login.Configuration;
    +import javax.security.auth.login.LoginContext;
    +import javax.security.sasl.Sasl;
    +import javax.security.sasl.SaslClient;
    +import javax.security.sasl.SaslException;
    +import java.security.Principal;
    +import java.security.PrivilegedActionException;
    +import java.security.PrivilegedExceptionAction;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Implements the GSSAPI sasl authentication Mechanism.
    + */
    +public class GssapiMechanism extends AbstractMechanism {
    +
    +    public static final String NAME = "GSSAPI";
    +    private Subject subject;
    +    private SaslClient saslClient;
    +    private String protocol = "amqp";
    +    private String server = null;
    +    private String configScope = null;
    +
    +    // a gss/sasl service name, x@y, morphs to a krbPrincipal a/y@REALM
    +
    +    @Override
    +    public int getPriority() {
    +        return PRIORITY.LOW.getValue();
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public byte[] getInitialResponse() throws SaslException {
    +        try {
    +            LoginContext loginContext = null;
    +            if (configScope != null) {
    +                loginContext = new LoginContext(configScope);
    +            } else {
    +                // inline keytab config using user as principal
    +                loginContext = new LoginContext("", null, null,
    +                        kerb5InlineConfig(getUsername(), true));
    +            }
    +            loginContext.login();
    +            subject = loginContext.getSubject();
    +
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +
    +                @Override
    +                public byte[] run() throws Exception {
    +                    saslClient = Sasl.createSaslClient(new String[]{getName()}, null, protocol, server, null, null);
    +                    if (saslClient.hasInitialResponse()) {
    +                        return saslClient.evaluateChallenge(new byte[0]);
    +                    }
    +                    return null;
    +                }
    +            });
    +        } catch (Exception e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public byte[] getChallengeResponse(final byte[] challenge) throws SaslException {
    +        try {
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +                @Override
    +                public byte[] run() throws Exception {
    +                    return saslClient.evaluateChallenge(challenge);
    +                }
    +            });
    +        } catch (PrivilegedActionException e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public void verifyCompletion() throws SaslException {
    +        boolean result = saslClient.isComplete();
    +        saslClient.dispose();
    +        if (!result) {
    +            throw new SaslException("not complete");
    +        }
    +    }
    +
    +
    +    @Override
    +    public boolean isApplicable(String username, String password, Principal localPrincipal) {
    +        return true;
    +    }
    +
    +    public static Configuration kerb5InlineConfig(String principal, boolean initiator) {
    +        final Map<String, String> krb5LoginModuleOptions = new HashMap<>();
    +        krb5LoginModuleOptions.put("isInitiator", String.valueOf(initiator));
    +        krb5LoginModuleOptions.put("principal", principal);
    +        krb5LoginModuleOptions.put("useKeyTab", "true");
    +        krb5LoginModuleOptions.put("storeKey", "true");
    +        krb5LoginModuleOptions.put("doNotPrompt", "true");
    +        krb5LoginModuleOptions.put("renewTGT", "true");
    +        krb5LoginModuleOptions.put("refreshKrb5Config", "true");
    +        krb5LoginModuleOptions.put("useTicketCache", "true");
    +        String ticketCache = System.getenv("KRB5CCNAME");
    +        if (ticketCache != null) {
    +            krb5LoginModuleOptions.put("ticketCache", ticketCache);
    +        }
    +        return new Configuration() {
    +            @Override
    +            public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
    +                return new AppConfigurationEntry[]{
    +                        new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
    +                                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
    +                                krb5LoginModuleOptions)};
    +            }
    +        };
    +    }
    +
    +    public String getProtocol() {
    +        return protocol;
    +    }
    +
    +    public void setProtocol(String protocol) {
    +        this.protocol = protocol;
    +    }
    +
    +    public String getServer() {
    +        return server;
    +    }
    +
    +    public void setServer(String server) {
    --- End diff --
    
    fair enough , url param sasl.serverName


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128774185
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpSaslAuthenticator.java ---
    @@ -137,7 +142,9 @@ private void handleSaslStep() throws JMSSecurityException {
                     byte[] challenge = new byte[sasl.pending()];
                     sasl.recv(challenge, 0, challenge.length);
                     byte[] response = mechanism.getChallengeResponse(challenge);
    -                sasl.send(response, 0, response.length);
    +                if (response != null) {
    --- End diff --
    
    Thanks for the detailed feedback.
    will need to check if that can go, but I think not b/c it delegates to the saslclient which can return null. 
    javax.security.sasl.SaslClient#evaluateChallenge


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128807526
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/sasl/GssapiMechanism.java ---
    @@ -0,0 +1,190 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.apache.qpid.jms.sasl;
    +
    +import javax.security.auth.Subject;
    +import javax.security.auth.login.AppConfigurationEntry;
    +import javax.security.auth.login.Configuration;
    +import javax.security.auth.login.LoginContext;
    +import javax.security.sasl.Sasl;
    +import javax.security.sasl.SaslClient;
    +import javax.security.sasl.SaslException;
    +import java.security.Principal;
    +import java.security.PrivilegedActionException;
    +import java.security.PrivilegedExceptionAction;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Implements the GSSAPI sasl authentication Mechanism.
    + */
    +public class GssapiMechanism extends AbstractMechanism {
    +
    +    public static final String NAME = "GSSAPI";
    +    private Subject subject;
    +    private SaslClient saslClient;
    +    private String protocol = "amqp";
    +    private String serverName = null;
    +    private String configScope = null;
    +
    +    // a gss/sasl service name, x@y, morphs to a krbPrincipal a/y@REALM
    +
    +    @Override
    +    public int getPriority() {
    +        return PRIORITY.LOW.getValue();
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public byte[] getInitialResponse() throws SaslException {
    +        try {
    +            LoginContext loginContext = null;
    +            if (configScope != null) {
    +                loginContext = new LoginContext(configScope);
    +            } else {
    +                // inline keytab config using user as principal
    +                loginContext = new LoginContext("", null, null,
    +                        kerb5InlineConfig(getUsername(), true));
    +            }
    +            loginContext.login();
    +            subject = loginContext.getSubject();
    +
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +
    +                @Override
    +                public byte[] run() throws Exception {
    +                    saslClient = Sasl.createSaslClient(new String[]{NAME}, null, protocol, serverName, null, null);
    +                    if (saslClient.hasInitialResponse()) {
    +                        return saslClient.evaluateChallenge(new byte[0]);
    +                    }
    +                    return null;
    +                }
    +            });
    +        } catch (Exception e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public byte[] getChallengeResponse(final byte[] challenge) throws SaslException {
    +        try {
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +                @Override
    +                public byte[] run() throws Exception {
    +                    return saslClient.evaluateChallenge(challenge);
    +                }
    +            });
    +        } catch (PrivilegedActionException e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public void verifyCompletion() throws SaslException {
    +        boolean result = saslClient.isComplete();
    +        saslClient.dispose();
    +        if (!result) {
    +            throw new SaslException("not complete");
    +        }
    +    }
    +
    +
    +    @Override
    +    public boolean isApplicable(String username, String password, Principal localPrincipal) {
    +        return true;
    +    }
    +
    +    private static final boolean IBM_JAVA =  System.getProperty("java.vendor").contains("IBM");
    +    public static Configuration kerb5InlineConfig(String principal, boolean initiator) {
    +        final Map<String, String> options = new HashMap<>();
    +        if (IBM_JAVA) {
    +            options.put("principal", principal);
    +            options.put("renewable", "true");
    +            options.put("credsType", initiator ? "initiator" : "acceptor");
    +        } else {
    +            options.put("isInitiator", String.valueOf(initiator));
    +            options.put("principal", principal);
    +            options.put("useKeyTab", "true");
    +            options.put("storeKey", "true");
    +            options.put("doNotPrompt", "true");
    +            options.put("renewTGT", "true");
    +            options.put("refreshKrb5Config", "true");
    +            options.put("useTicketCache", "true");
    +            String ticketCache = System.getenv("KRB5CCNAME");
    +
    +            if (IBM_JAVA) {
    +                // If cache is specified via env variable, it takes priority
    --- End diff --
    
    This block is unreachable since its already within a !(IBM_JAVA) branch.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/qpid-jms/pull/10


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128808271
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/sasl/GssapiMechanism.java ---
    @@ -0,0 +1,190 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.apache.qpid.jms.sasl;
    +
    +import javax.security.auth.Subject;
    +import javax.security.auth.login.AppConfigurationEntry;
    +import javax.security.auth.login.Configuration;
    +import javax.security.auth.login.LoginContext;
    +import javax.security.sasl.Sasl;
    +import javax.security.sasl.SaslClient;
    +import javax.security.sasl.SaslException;
    +import java.security.Principal;
    +import java.security.PrivilegedActionException;
    +import java.security.PrivilegedExceptionAction;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Implements the GSSAPI sasl authentication Mechanism.
    + */
    +public class GssapiMechanism extends AbstractMechanism {
    +
    +    public static final String NAME = "GSSAPI";
    +    private Subject subject;
    +    private SaslClient saslClient;
    +    private String protocol = "amqp";
    +    private String serverName = null;
    +    private String configScope = null;
    +
    +    // a gss/sasl service name, x@y, morphs to a krbPrincipal a/y@REALM
    +
    +    @Override
    +    public int getPriority() {
    +        return PRIORITY.LOW.getValue();
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public byte[] getInitialResponse() throws SaslException {
    +        try {
    +            LoginContext loginContext = null;
    +            if (configScope != null) {
    +                loginContext = new LoginContext(configScope);
    +            } else {
    +                // inline keytab config using user as principal
    +                loginContext = new LoginContext("", null, null,
    +                        kerb5InlineConfig(getUsername(), true));
    +            }
    +            loginContext.login();
    +            subject = loginContext.getSubject();
    +
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +
    +                @Override
    +                public byte[] run() throws Exception {
    +                    saslClient = Sasl.createSaslClient(new String[]{NAME}, null, protocol, serverName, null, null);
    +                    if (saslClient.hasInitialResponse()) {
    +                        return saslClient.evaluateChallenge(new byte[0]);
    +                    }
    +                    return null;
    +                }
    +            });
    +        } catch (Exception e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public byte[] getChallengeResponse(final byte[] challenge) throws SaslException {
    +        try {
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +                @Override
    +                public byte[] run() throws Exception {
    +                    return saslClient.evaluateChallenge(challenge);
    +                }
    +            });
    +        } catch (PrivilegedActionException e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public void verifyCompletion() throws SaslException {
    +        boolean result = saslClient.isComplete();
    +        saslClient.dispose();
    +        if (!result) {
    +            throw new SaslException("not complete");
    +        }
    +    }
    +
    +
    +    @Override
    +    public boolean isApplicable(String username, String password, Principal localPrincipal) {
    +        return true;
    +    }
    +
    +    private static final boolean IBM_JAVA =  System.getProperty("java.vendor").contains("IBM");
    +    public static Configuration kerb5InlineConfig(String principal, boolean initiator) {
    +        final Map<String, String> options = new HashMap<>();
    +        if (IBM_JAVA) {
    +            options.put("principal", principal);
    +            options.put("renewable", "true");
    +            options.put("credsType", initiator ? "initiator" : "acceptor");
    +        } else {
    +            options.put("isInitiator", String.valueOf(initiator));
    +            options.put("principal", principal);
    +            options.put("useKeyTab", "true");
    +            options.put("storeKey", "true");
    +            options.put("doNotPrompt", "true");
    +            options.put("renewTGT", "true");
    +            options.put("refreshKrb5Config", "true");
    +            options.put("useTicketCache", "true");
    +            String ticketCache = System.getenv("KRB5CCNAME");
    +
    +            if (IBM_JAVA) {
    +                // If cache is specified via env variable, it takes priority
    +                if (ticketCache != null) {
    +                    // IBM JAVA only respects system property so copy ticket cache to system property
    +                    // The first value searched when "useDefaultCcache" is true.
    +                    System.setProperty("KRB5CCNAME", ticketCache);
    --- End diff --
    
    This doesn't seem good in general, we shouldn't be setting system properties, but in particular its set without checking if it may already be set to something else? If anything these additional mechanics are increasing my feeling that requiring a login.config might be better all round.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128803960
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/test/testpeer/TestAmqpPeer.java ---
    @@ -495,6 +512,169 @@ public void run()
             }
         }
     
    +    public void expectGSSAPIFail(Symbol mech) throws Exception {
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        addHandler(new SaslInitMatcher().withMechanism(equalTo(mech)));
    +
    +    }
    +
    +    public void expectGSSAPI(Symbol mech, String serviceName) throws Exception {
    +
    +        SaslMechanismsFrame saslMechanismsFrame = new SaslMechanismsFrame().setSaslServerMechanisms(mech);
    +
    +        addHandler(new HeaderHandlerImpl(AmqpHeader.SASL_HEADER, AmqpHeader.SASL_HEADER,
    +                new FrameSender(
    +                        this, FrameType.SASL, 0,
    +                        saslMechanismsFrame, null)));
    +
    +        // setup server gss context
    +        LoginContext loginContext = new LoginContext("", null, null,
    +                kerb5InlineConfig(serviceName, false));
    +        loginContext.login();
    +        final Subject serverSubject =loginContext.getSubject();
    +
    +        LOGGER.info("saslServer subject:" + serverSubject.getPrivateCredentials());
    +
    +        Map<String, ?> config = new HashMap();
    +        final CallbackHandler handler = new CallbackHandler() {
    +            @Override
    +            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    +                LOGGER.info("Here with: " + Arrays.asList(callbacks));
    +                for (Callback callback :callbacks) {
    +                    if (callback instanceof AuthorizeCallback) {
    +                        AuthorizeCallback authorizeCallback = (AuthorizeCallback) callback;
    +                        authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals(authorizeCallback.getAuthorizationID()));
    +                    }
    +                }
    +            }
    +        };
    +        final SaslServer saslServer = Subject.doAs(serverSubject, new PrivilegedExceptionAction<SaslServer>() {
    +            @Override
    +            public SaslServer run() throws Exception {
    +                return Sasl.createSaslServer(mech.toString(), null, null, config, handler);
    +            }
    +        });
    +
    +        final SaslChallengeFrame challengeFrame = new SaslChallengeFrame();
    +
    +        SaslInitMatcher saslInitMatcher = new SaslInitMatcher()
    +                .withMechanism(equalTo(mech))
    +                .withInitialResponse(new BaseMatcher<Binary>() {
    +
    +                    @Override
    +                    public void describeTo(Description description) {}
    +
    +                    @Override
    +                    public boolean matches(Object o) {
    +                        if (o == null) {
    +                            LOGGER.error("Got null initial response!");
    +                            return false;
    +                        }
    +                        final Binary binary = (Binary) o;
    +                        // validate via sasl
    +                        byte[] token = null;
    +                        try {
    +                            token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                                @Override
    +                                public byte[] run() throws Exception {
    +                                    LOGGER.info("Evaluate Response.. size:" + binary.getLength());
    +                                    return saslServer.evaluateResponse(binary.getArray());
    +                                }
    +                            });
    +                        } catch (PrivilegedActionException e) {
    +                            e.printStackTrace();
    +                        }
    +                        LOGGER.info("Complete:" + saslServer.isComplete());
    +
    +                        if (token != null) {
    +                            // fling it back in on complete
    +                            challengeFrame.setChallenge(new Binary(token));
    +                        }
    +                        return true;
    +                    }
    +                }).onCompletion(new AmqpPeerRunnable() {
    +                    @Override
    +                    public void run() {
    +                        TestAmqpPeer.this.sendFrame(
    +                                FrameType.SASL, 0,
    +                                challengeFrame,
    +                                null,
    +                                false, 0);
    +                    }
    +                });
    +
    +        AtomicBoolean response = new AtomicBoolean(false);
    +        SaslResponseMatcher challengeMatcher = new SaslResponseMatcher().withResponse(new BaseMatcher<Binary>() {
    +
    +            @Override
    +            public void describeTo(Description description) {}
    +
    +            @Override
    +            public boolean matches(Object o) {
    +                final Binary binary = (Binary) o;
    +                if (!saslServer.isComplete()) {
    +                    // validate via sasl
    +                    byte[] token = null;
    +                    try {
    +                        token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<byte[]>() {
    +                            @Override
    +                            public byte[] run() throws Exception {
    +                                LOGGER.info("Evaluate challenge response.. size:" + binary.getLength());
    +                                return saslServer.evaluateResponse(binary.getArray());
    +                            }
    +                        });
    +                    } catch (PrivilegedActionException e) {
    +                        e.printStackTrace();
    +                    }
    +                    LOGGER.info("Complete:" + saslServer.isComplete());
    +                    if (token != null) {
    +                        // fling it back
    +                        challengeFrame.setChallenge(new Binary(token));
    +                        response.set(true);
    +                    }
    +                    return true;
    +                }
    +
    +                return false;
    +            }
    +        }).onCompletion(new AmqpPeerRunnable() {
    +            @Override
    +            public void run() {
    +                if (response.get()) {
    +                    TestAmqpPeer.this.sendFrame(
    +                            FrameType.SASL, 0,
    +                            challengeFrame,
    +                            null,
    +                            false, 0);
    +                }
    +
    +                if (saslServer.isComplete()) {
    --- End diff --
    
    the response is gated on a boolean, I think it is ok, the outcome goes on its own.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms issue #10: [QPIDJMS-303] implement sasl gssapi (kerberos) mechanism

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on the issue:

    https://github.com/apache/qpid-jms/pull/10
  
    rebased and added negative test to validate client side sasl exceptions percolate up 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128775211
  
    --- Diff: qpid-jms-client/pom.xml ---
    @@ -93,6 +93,19 @@
           <artifactId>hamcrest-all</artifactId>
           <scope>test</scope>
         </dependency>
    +    <dependency>
    +      <groupId>org.apache.hadoop</groupId>
    +      <artifactId>hadoop-minikdc</artifactId>
    +      <version>${hadoop-minikdc-version}</version>
    --- End diff --
    
    sure


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r129354263
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/sasl/GssapiMechanism.java ---
    @@ -0,0 +1,190 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.apache.qpid.jms.sasl;
    +
    +import javax.security.auth.Subject;
    +import javax.security.auth.login.AppConfigurationEntry;
    +import javax.security.auth.login.Configuration;
    +import javax.security.auth.login.LoginContext;
    +import javax.security.sasl.Sasl;
    +import javax.security.sasl.SaslClient;
    +import javax.security.sasl.SaslException;
    +import java.security.Principal;
    +import java.security.PrivilegedActionException;
    +import java.security.PrivilegedExceptionAction;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Implements the GSSAPI sasl authentication Mechanism.
    + */
    +public class GssapiMechanism extends AbstractMechanism {
    +
    +    public static final String NAME = "GSSAPI";
    +    private Subject subject;
    +    private SaslClient saslClient;
    +    private String protocol = "amqp";
    +    private String serverName = null;
    +    private String configScope = null;
    +
    +    // a gss/sasl service name, x@y, morphs to a krbPrincipal a/y@REALM
    +
    +    @Override
    +    public int getPriority() {
    +        return PRIORITY.LOW.getValue();
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public byte[] getInitialResponse() throws SaslException {
    +        try {
    +            LoginContext loginContext = null;
    +            if (configScope != null) {
    +                loginContext = new LoginContext(configScope);
    +            } else {
    +                // inline keytab config using user as principal
    +                loginContext = new LoginContext("", null, null,
    +                        kerb5InlineConfig(getUsername(), true));
    +            }
    +            loginContext.login();
    +            subject = loginContext.getSubject();
    +
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +
    +                @Override
    +                public byte[] run() throws Exception {
    +                    saslClient = Sasl.createSaslClient(new String[]{NAME}, null, protocol, serverName, null, null);
    +                    if (saslClient.hasInitialResponse()) {
    +                        return saslClient.evaluateChallenge(new byte[0]);
    +                    }
    +                    return null;
    +                }
    +            });
    +        } catch (Exception e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public byte[] getChallengeResponse(final byte[] challenge) throws SaslException {
    +        try {
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +                @Override
    +                public byte[] run() throws Exception {
    +                    return saslClient.evaluateChallenge(challenge);
    +                }
    +            });
    +        } catch (PrivilegedActionException e) {
    +            throw new SaslException(e.toString(), e);
    +        }
    +    }
    +
    +    @Override
    +    public void verifyCompletion() throws SaslException {
    +        boolean result = saslClient.isComplete();
    +        saslClient.dispose();
    +        if (!result) {
    +            throw new SaslException("not complete");
    +        }
    +    }
    +
    +
    +    @Override
    +    public boolean isApplicable(String username, String password, Principal localPrincipal) {
    +        return true;
    +    }
    +
    +    private static final boolean IBM_JAVA =  System.getProperty("java.vendor").contains("IBM");
    +    public static Configuration kerb5InlineConfig(String principal, boolean initiator) {
    +        final Map<String, String> options = new HashMap<>();
    +        if (IBM_JAVA) {
    +            options.put("principal", principal);
    +            options.put("renewable", "true");
    +            options.put("credsType", initiator ? "initiator" : "acceptor");
    +        } else {
    +            options.put("isInitiator", String.valueOf(initiator));
    +            options.put("principal", principal);
    +            options.put("useKeyTab", "true");
    +            options.put("storeKey", "true");
    +            options.put("doNotPrompt", "true");
    +            options.put("renewTGT", "true");
    +            options.put("refreshKrb5Config", "true");
    +            options.put("useTicketCache", "true");
    +            String ticketCache = System.getenv("KRB5CCNAME");
    +
    +            if (IBM_JAVA) {
    +                // If cache is specified via env variable, it takes priority
    +                if (ticketCache != null) {
    +                    // IBM JAVA only respects system property so copy ticket cache to system property
    +                    // The first value searched when "useDefaultCcache" is true.
    +                    System.setProperty("KRB5CCNAME", ticketCache);
    --- End diff --
    
    Those conditional have been replaced with the option to provide sasl.krb5.x overrides or additions as url parameters and if you wish fully configure the krb5 login module. 
    The default options work for a client on the sun jdk, the ibm jdk needs url params.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128775254
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/sasl/GssapiMechanism.java ---
    @@ -0,0 +1,163 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.apache.qpid.jms.sasl;
    +
    +import javax.security.auth.Subject;
    +import javax.security.auth.login.AppConfigurationEntry;
    +import javax.security.auth.login.Configuration;
    +import javax.security.auth.login.LoginContext;
    +import javax.security.sasl.Sasl;
    +import javax.security.sasl.SaslClient;
    +import javax.security.sasl.SaslException;
    +import java.security.Principal;
    +import java.security.PrivilegedActionException;
    +import java.security.PrivilegedExceptionAction;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Implements the GSSAPI sasl authentication Mechanism.
    + */
    +public class GssapiMechanism extends AbstractMechanism {
    +
    +    public static final String NAME = "GSSAPI";
    +    private Subject subject;
    +    private SaslClient saslClient;
    +    private String protocol = "amqp";
    +    private String server = null;
    +    private String configScope = null;
    +
    +    // a gss/sasl service name, x@y, morphs to a krbPrincipal a/y@REALM
    +
    +    @Override
    +    public int getPriority() {
    +        return PRIORITY.LOW.getValue();
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public byte[] getInitialResponse() throws SaslException {
    +        try {
    +            LoginContext loginContext = null;
    +            if (configScope != null) {
    +                loginContext = new LoginContext(configScope);
    +            } else {
    +                // inline keytab config using user as principal
    +                loginContext = new LoginContext("", null, null,
    +                        kerb5InlineConfig(getUsername(), true));
    +            }
    +            loginContext.login();
    +            subject = loginContext.getSubject();
    +
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +
    +                @Override
    +                public byte[] run() throws Exception {
    +                    saslClient = Sasl.createSaslClient(new String[]{getName()}, null, protocol, server, null, null);
    --- End diff --
    
    agree


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128754756
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslGssApiIntegrationTest.java ---
    @@ -0,0 +1,185 @@
    +/*
    + *
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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.apache.qpid.jms.integration;
    +
    +import org.apache.directory.server.kerberos.shared.keytab.Keytab;
    +import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
    +import org.apache.hadoop.minikdc.MiniKdc;
    +import org.apache.qpid.jms.JmsConnectionFactory;
    +import org.apache.qpid.jms.test.QpidJmsTestCase;
    +import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
    +import org.apache.qpid.proton.amqp.Symbol;
    +import org.junit.After;
    +import org.junit.Before;
    +import org.junit.Test;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +import javax.jms.Connection;
    +import javax.jms.ConnectionFactory;
    +import javax.jms.JMSSecurityException;
    +import java.io.File;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +
    +import static junit.framework.TestCase.assertTrue;
    +import static org.junit.Assert.assertNull;
    +import static org.junit.Assert.fail;
    +
    +public class SaslGssApiIntegrationTest extends QpidJmsTestCase {
    +
    +    private static final Logger LOG = LoggerFactory.getLogger(SaslGssApiIntegrationTest.class);
    +
    +    private static final Symbol GSSAPI = Symbol.valueOf("GSSAPI");
    +    private static final String serviceName = "amqp/localhost";
    +
    +    private MiniKdc kdc;
    +
    +    @Before
    +    public void setUpKerberso() throws Exception {
    --- End diff --
    
    Typo in name.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128785321
  
    --- Diff: qpid-jms-client/src/main/resources/login.config ---
    @@ -0,0 +1,23 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.
    + */
    +
    +KRB5-CLIENT {
    +    com.sun.security.auth.module.Krb5LoginModule required
    +    useKeyTab=true
    +    principal="client"
    +    keytab="target/test.krb5.keytab";
    +};
    --- End diff --
    
    good point.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128788568
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslGssApiIntegrationTest.java ---
    @@ -0,0 +1,185 @@
    +/*
    + *
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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.apache.qpid.jms.integration;
    +
    +import org.apache.directory.server.kerberos.shared.keytab.Keytab;
    +import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
    +import org.apache.hadoop.minikdc.MiniKdc;
    +import org.apache.qpid.jms.JmsConnectionFactory;
    +import org.apache.qpid.jms.test.QpidJmsTestCase;
    +import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
    +import org.apache.qpid.proton.amqp.Symbol;
    +import org.junit.After;
    +import org.junit.Before;
    +import org.junit.Test;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +import javax.jms.Connection;
    +import javax.jms.ConnectionFactory;
    +import javax.jms.JMSSecurityException;
    +import java.io.File;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +
    +import static junit.framework.TestCase.assertTrue;
    +import static org.junit.Assert.assertNull;
    +import static org.junit.Assert.fail;
    +
    +public class SaslGssApiIntegrationTest extends QpidJmsTestCase {
    +
    +    private static final Logger LOG = LoggerFactory.getLogger(SaslGssApiIntegrationTest.class);
    +
    +    private static final Symbol GSSAPI = Symbol.valueOf("GSSAPI");
    +    private static final String serviceName = "amqp/localhost";
    +
    +    private MiniKdc kdc;
    +
    +    @Before
    +    public void setUpKerberso() throws Exception {
    +        Path tempDirectory = Files.createTempDirectory("junit.test.");
    +        File root = tempDirectory.toFile();
    +        root.deleteOnExit();
    +        kdc = new MiniKdc(MiniKdc.createConf(), new File(root, "kdc"));
    +        kdc.start();
    +
    +        // hard coded match, default_keytab_name in minikdc-krb5.conf template
    +        File userKeyTab = new File("target/test.krb5.keytab");
    +        kdc.createPrincipal(userKeyTab, "client", serviceName);
    +
    +        Keytab kt = Keytab.read(userKeyTab);
    +        for (KeytabEntry entry : kt.getEntries()) {
    +            LOG.info("KeyTab Kerb PrincipalNames:" + entry.getPrincipalName());
    +        }
    +
    +        java.util.logging.Logger logger = java.util.logging.Logger.getLogger("javax.security.sasl");
    --- End diff --
    
    yep.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128747741
  
    --- Diff: qpid-jms-client/src/main/resources/login.config ---
    @@ -0,0 +1,23 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.
    + */
    +
    +KRB5-CLIENT {
    +    com.sun.security.auth.module.Krb5LoginModule required
    +    useKeyTab=true
    +    principal="client"
    +    keytab="target/test.krb5.keytab";
    +};
    --- End diff --
    
    Should this file be in the src/test tree rather than in src/main?
    
    Naming the file more specifically for the test it is used in, e.g <testname>-login.config, would be good for later. Perhaps similarly for the keytab.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128727012
  
    --- Diff: qpid-jms-client/pom.xml ---
    @@ -93,6 +93,19 @@
           <artifactId>hamcrest-all</artifactId>
           <scope>test</scope>
         </dependency>
    +    <dependency>
    +      <groupId>org.apache.hadoop</groupId>
    +      <artifactId>hadoop-minikdc</artifactId>
    +      <version>${hadoop-minikdc-version}</version>
    --- End diff --
    
    The versions should be controlled in the parent dependencyManagement section along with the others.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128747005
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/sasl/GssapiMechanism.java ---
    @@ -0,0 +1,163 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You 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.apache.qpid.jms.sasl;
    +
    +import javax.security.auth.Subject;
    +import javax.security.auth.login.AppConfigurationEntry;
    +import javax.security.auth.login.Configuration;
    +import javax.security.auth.login.LoginContext;
    +import javax.security.sasl.Sasl;
    +import javax.security.sasl.SaslClient;
    +import javax.security.sasl.SaslException;
    +import java.security.Principal;
    +import java.security.PrivilegedActionException;
    +import java.security.PrivilegedExceptionAction;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +/**
    + * Implements the GSSAPI sasl authentication Mechanism.
    + */
    +public class GssapiMechanism extends AbstractMechanism {
    +
    +    public static final String NAME = "GSSAPI";
    +    private Subject subject;
    +    private SaslClient saslClient;
    +    private String protocol = "amqp";
    +    private String server = null;
    +    private String configScope = null;
    +
    +    // a gss/sasl service name, x@y, morphs to a krbPrincipal a/y@REALM
    +
    +    @Override
    +    public int getPriority() {
    +        return PRIORITY.LOW.getValue();
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public byte[] getInitialResponse() throws SaslException {
    +        try {
    +            LoginContext loginContext = null;
    +            if (configScope != null) {
    +                loginContext = new LoginContext(configScope);
    +            } else {
    +                // inline keytab config using user as principal
    +                loginContext = new LoginContext("", null, null,
    +                        kerb5InlineConfig(getUsername(), true));
    +            }
    +            loginContext.login();
    +            subject = loginContext.getSubject();
    +
    +            return Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
    +
    +                @Override
    +                public byte[] run() throws Exception {
    +                    saslClient = Sasl.createSaslClient(new String[]{getName()}, null, protocol, server, null, null);
    --- End diff --
    
    Referencing the constant rather than using getName() might be clearer.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128726699
  
    --- Diff: qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpSaslAuthenticator.java ---
    @@ -137,7 +142,9 @@ private void handleSaslStep() throws JMSSecurityException {
                     byte[] challenge = new byte[sasl.pending()];
                     sasl.recv(challenge, 0, challenge.length);
                     byte[] response = mechanism.getChallengeResponse(challenge);
    -                sasl.send(response, 0, response.length);
    +                if (response != null) {
    --- End diff --
    
    Did you need this null check? The SASL process is likely to hang if there is no response to a challenge. I think its reasonable to require one be given, or fail if there isn't and an exception isn't thrown.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128755403
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslGssApiIntegrationTest.java ---
    @@ -0,0 +1,185 @@
    +/*
    + *
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you 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.apache.qpid.jms.integration;
    +
    +import org.apache.directory.server.kerberos.shared.keytab.Keytab;
    +import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
    +import org.apache.hadoop.minikdc.MiniKdc;
    +import org.apache.qpid.jms.JmsConnectionFactory;
    +import org.apache.qpid.jms.test.QpidJmsTestCase;
    +import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
    +import org.apache.qpid.proton.amqp.Symbol;
    +import org.junit.After;
    +import org.junit.Before;
    +import org.junit.Test;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +import javax.jms.Connection;
    +import javax.jms.ConnectionFactory;
    +import javax.jms.JMSSecurityException;
    +import java.io.File;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +
    +import static junit.framework.TestCase.assertTrue;
    +import static org.junit.Assert.assertNull;
    +import static org.junit.Assert.fail;
    +
    +public class SaslGssApiIntegrationTest extends QpidJmsTestCase {
    +
    +    private static final Logger LOG = LoggerFactory.getLogger(SaslGssApiIntegrationTest.class);
    +
    +    private static final Symbol GSSAPI = Symbol.valueOf("GSSAPI");
    +    private static final String serviceName = "amqp/localhost";
    +
    +    private MiniKdc kdc;
    +
    +    @Before
    +    public void setUpKerberso() throws Exception {
    +        Path tempDirectory = Files.createTempDirectory("junit.test.");
    --- End diff --
    
    Including the test name would also be good to help trace any issues back here.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms issue #10: [QPIDJMS-303] implement sasl gssapi (kerberos) mechanism

Posted by gtully <gi...@git.apache.org>.
Github user gtully commented on the issue:

    https://github.com/apache/qpid-jms/pull/10
  
    I see mechanism verifyComplete from: https://github.com/apache/qpid-jms/pull/9/commits/e0d87347bf283df7a1a295e8666689641fac65c5
    
    I could use that to destroy the saslclient which would be good.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


[GitHub] qpid-jms pull request #10: [QPIDJMS-303] implement sasl gssapi (kerberos) me...

Posted by gemmellr <gi...@git.apache.org>.
Github user gemmellr commented on a diff in the pull request:

    https://github.com/apache/qpid-jms/pull/10#discussion_r128749066
  
    --- Diff: qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslIntegrationTest.java ---
    @@ -54,6 +54,7 @@
         private static final Symbol SCRAM_SHA_1 = Symbol.valueOf("SCRAM-SHA-1");
         private static final Symbol SCRAM_SHA_256 = Symbol.valueOf("SCRAM-SHA-256");
         private static final Symbol EXTERNAL = Symbol.valueOf("EXTERNAL");
    +    private static final Symbol GSSAPI = Symbol.valueOf("GSSAPI");
    --- End diff --
    
    This isn't used and can be removed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org