| /* |
| * 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.avro.ipc; |
| |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.net.InetSocketAddress; |
| |
| import javax.security.auth.callback.Callback; |
| import javax.security.auth.callback.CallbackHandler; |
| import javax.security.auth.callback.NameCallback; |
| import javax.security.auth.callback.PasswordCallback; |
| import javax.security.auth.callback.UnsupportedCallbackException; |
| import javax.security.sasl.AuthorizeCallback; |
| import javax.security.sasl.RealmCallback; |
| import javax.security.sasl.Sasl; |
| import javax.security.sasl.SaslClient; |
| import javax.security.sasl.SaslException; |
| |
| import org.apache.avro.generic.GenericData; |
| import org.apache.avro.generic.GenericRecord; |
| import org.apache.avro.ipc.generic.GenericRequestor; |
| import org.apache.avro.TestProtocolGeneric; |
| import org.apache.avro.util.Utf8; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.junit.Before; |
| import org.junit.Test; |
| import static org.junit.Assert.assertEquals; |
| |
| public class TestSaslDigestMd5 extends TestProtocolGeneric { |
| |
| private static final Logger LOG = |
| LoggerFactory.getLogger(TestSaslDigestMd5.class); |
| |
| private static final String HOST = "localhost"; |
| private static final String SERVICE = "avro-test"; |
| private static final String PRINCIPAL = "avro-test-principal"; |
| private static final String PASSWORD = "super secret password"; |
| private static final String REALM = "avro-test-realm"; |
| |
| private static final String DIGEST_MD5_MECHANISM = "DIGEST-MD5"; |
| private static final Map<String, String> DIGEST_MD5_PROPS = |
| new HashMap<String, String>(); |
| |
| static { |
| DIGEST_MD5_PROPS.put(Sasl.QOP, "auth-int"); |
| DIGEST_MD5_PROPS.put("com.sun.security.sasl.digest.realm", REALM); |
| } |
| |
| private static class TestSaslCallbackHandler implements CallbackHandler { |
| @Override |
| public void handle(Callback[] callbacks) |
| throws IOException, UnsupportedCallbackException { |
| for (Callback c : callbacks) { |
| if (c instanceof NameCallback) { |
| ((NameCallback) c).setName(PRINCIPAL); |
| } else if (c instanceof PasswordCallback) { |
| ((PasswordCallback) c).setPassword(PASSWORD.toCharArray()); |
| } else if (c instanceof AuthorizeCallback) { |
| ((AuthorizeCallback) c).setAuthorized(true); |
| } else if (c instanceof RealmCallback) { |
| ((RealmCallback) c).setText(REALM); |
| } else { |
| throw new UnsupportedCallbackException(c); |
| } |
| } |
| } |
| } |
| |
| @Before |
| public void testStartServer() throws Exception { |
| if (server != null) return; |
| server = new SaslSocketServer |
| (new TestResponder(), new InetSocketAddress(0), DIGEST_MD5_MECHANISM, |
| SERVICE, HOST, DIGEST_MD5_PROPS, new TestSaslCallbackHandler()); |
| server.start(); |
| SaslClient saslClient = Sasl.createSaslClient |
| (new String[]{DIGEST_MD5_MECHANISM}, PRINCIPAL, SERVICE, HOST, |
| DIGEST_MD5_PROPS, new TestSaslCallbackHandler()); |
| client = new SaslSocketTransceiver(new InetSocketAddress(server.getPort()), |
| saslClient); |
| requestor = new GenericRequestor(PROTOCOL, client); |
| } |
| |
| @Test(expected=SaslException.class) |
| public void testAnonymousClient() throws Exception { |
| Server s = new SaslSocketServer |
| (new TestResponder(), new InetSocketAddress(0), DIGEST_MD5_MECHANISM, |
| SERVICE, HOST, DIGEST_MD5_PROPS, new TestSaslCallbackHandler()); |
| s.start(); |
| Transceiver c = |
| new SaslSocketTransceiver(new InetSocketAddress(s.getPort())); |
| GenericRequestor requestor = new GenericRequestor(PROTOCOL, c); |
| GenericRecord params = |
| new GenericData.Record(PROTOCOL.getMessages().get("hello").getRequest()); |
| params.put("greeting", "bob"); |
| Utf8 response = (Utf8)requestor.request("hello", params); |
| assertEquals(new Utf8("goodbye"), response); |
| s.close(); |
| c.close(); |
| } |
| |
| |
| private static class WrongPasswordCallbackHandler implements CallbackHandler { |
| @Override |
| public void handle(Callback[] callbacks) |
| throws IOException, UnsupportedCallbackException { |
| for (Callback c : callbacks) { |
| if (c instanceof NameCallback) { |
| ((NameCallback) c).setName(PRINCIPAL); |
| } else if (c instanceof PasswordCallback) { |
| ((PasswordCallback) c).setPassword("wrong".toCharArray()); |
| } else if (c instanceof AuthorizeCallback) { |
| ((AuthorizeCallback) c).setAuthorized(true); |
| } else if (c instanceof RealmCallback) { |
| ((RealmCallback) c).setText(REALM); |
| } else { |
| throw new UnsupportedCallbackException(c); |
| } |
| } |
| } |
| } |
| |
| @Test(expected=SaslException.class) |
| public void testWrongPassword() throws Exception { |
| Server s = new SaslSocketServer |
| (new TestResponder(), new InetSocketAddress(0), DIGEST_MD5_MECHANISM, |
| SERVICE, HOST, DIGEST_MD5_PROPS, new TestSaslCallbackHandler()); |
| s.start(); |
| SaslClient saslClient = Sasl.createSaslClient |
| (new String[]{DIGEST_MD5_MECHANISM}, PRINCIPAL, SERVICE, HOST, |
| DIGEST_MD5_PROPS, new WrongPasswordCallbackHandler()); |
| Transceiver c = new SaslSocketTransceiver |
| (new InetSocketAddress(server.getPort()), saslClient); |
| GenericRequestor requestor = new GenericRequestor(PROTOCOL, c); |
| GenericRecord params = |
| new GenericData.Record(PROTOCOL.getMessages().get("hello").getRequest()); |
| params.put("greeting", "bob"); |
| Utf8 response = (Utf8)requestor.request("hello", params); |
| assertEquals(new Utf8("goodbye"), response); |
| s.close(); |
| c.close(); |
| } |
| |
| @Override public void testHandshake() throws IOException {} |
| |
| } |