Skip to content

Commit 0b5231a

Browse files
committed
1 parent e8f8155 commit 0b5231a

File tree

10 files changed

+225
-10
lines changed

10 files changed

+225
-10
lines changed

activemq-broker/src/main/java/org/apache/activemq/network/LdapNetworkConnector.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,16 @@ public void start() throws Exception {
210210
env.put(Context.SECURITY_AUTHENTICATION, "none");
211211
} else {
212212
LOG.debug(" login credentials [{}:******]", user);
213-
env.put(Context.SECURITY_PRINCIPAL, user);
214-
env.put(Context.SECURITY_CREDENTIALS, password);
213+
if (user != null && !"".equals(user)) {
214+
env.put(Context.SECURITY_PRINCIPAL, user);
215+
} else {
216+
throw new Exception("Empty username is not allowed");
217+
}
218+
if (password != null && !"".equals(password)) {
219+
env.put(Context.SECURITY_CREDENTIALS, password);
220+
} else {
221+
throw new Exception("Empty password is not allowed");
222+
}
215223
}
216224
boolean isConnected = false;
217225
while (!isConnected) {

activemq-broker/src/main/java/org/apache/activemq/security/LDAPAuthorizationMap.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,11 +469,15 @@ protected DirContext open() throws NamingException {
469469
try {
470470
Hashtable<String, String> env = new Hashtable<String, String>();
471471
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
472-
if (connectionUsername != null || !"".equals(connectionUsername)) {
472+
if (connectionUsername != null && !"".equals(connectionUsername)) {
473473
env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
474+
} else {
475+
throw new NamingException("Empty username is not allowed");
474476
}
475-
if (connectionPassword != null || !"".equals(connectionPassword)) {
477+
if (connectionPassword != null && !"".equals(connectionPassword)) {
476478
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
479+
} else {
480+
throw new NamingException("Empty password is not allowed");
477481
}
478482
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
479483
env.put(Context.PROVIDER_URL, connectionURL);

activemq-broker/src/main/java/org/apache/activemq/security/SimpleCachedLDAPAuthorizationMap.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,15 @@ public Thread newThread(Runnable r) {
125125
protected DirContext createContext() throws NamingException {
126126
Hashtable<String, String> env = new Hashtable<String, String>();
127127
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
128-
if (connectionUsername != null || !"".equals(connectionUsername)) {
128+
if (connectionUsername != null && !"".equals(connectionUsername)) {
129129
env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
130+
} else {
131+
throw new NamingException("Empty username is not allowed");
130132
}
131-
if (connectionPassword != null || !"".equals(connectionPassword)) {
133+
if (connectionPassword != null && !"".equals(connectionPassword)) {
132134
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
135+
} else {
136+
throw new NamingException("Empty password is not allowed");
133137
}
134138
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
135139
env.put(Context.PROVIDER_URL, connectionURL);

activemq-jaas/src/main/java/org/apache/activemq/jaas/LDAPLoginModule.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ protected boolean authenticate(String username, String password) throws LoginExc
190190
try {
191191

192192
String filter = userSearchMatchingFormat.format(new String[] {
193-
username
193+
doRFC2254Encoding(username)
194194
});
195195
SearchControls constraints = new SearchControls();
196196
if (userSearchSubtreeBool) {
@@ -319,7 +319,7 @@ protected List<String> getRoles(DirContext context, String dn, String username,
319319
return list;
320320
}
321321
String filter = roleSearchMatchingFormat.format(new String[] {
322-
doRFC2254Encoding(dn), username
322+
doRFC2254Encoding(dn), doRFC2254Encoding(username)
323323
});
324324

325325
SearchControls constraints = new SearchControls();
@@ -459,9 +459,14 @@ protected DirContext open() throws NamingException {
459459
env.put(Context.INITIAL_CONTEXT_FACTORY, getLDAPPropertyValue(INITIAL_CONTEXT_FACTORY));
460460
if (isLoginPropertySet(CONNECTION_USERNAME)) {
461461
env.put(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
462+
} else {
463+
throw new NamingException("Empty username is not allowed");
462464
}
465+
463466
if (isLoginPropertySet(CONNECTION_PASSWORD)) {
464467
env.put(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
468+
} else {
469+
throw new NamingException("Empty password is not allowed");
465470
}
466471
env.put(Context.SECURITY_PROTOCOL, getLDAPPropertyValue(CONNECTION_PROTOCOL));
467472
env.put(Context.PROVIDER_URL, getLDAPPropertyValue(CONNECTION_URL));
@@ -484,7 +489,7 @@ private String getLDAPPropertyValue (String propertyName){
484489

485490
private boolean isLoginPropertySet(String propertyName) {
486491
for (int i=0; i < config.length; i++ ) {
487-
if (config[i].getPropertyName() == propertyName && config[i].getPropertyValue() != null)
492+
if (config[i].getPropertyName() == propertyName && (config[i].getPropertyValue() != null && !"".equals(config[i].getPropertyValue())))
488493
return true;
489494
}
490495
return false;

activemq-jaas/src/test/java/org/apache/activemq/jaas/LDAPLoginModuleTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@
4141
import java.util.HashSet;
4242
import java.util.Hashtable;
4343

44+
import static org.junit.Assert.assertEquals;
4445
import static org.junit.Assert.assertTrue;
46+
import static org.junit.Assert.fail;
4547

4648
@RunWith ( FrameworkRunner.class )
4749
@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port=1024)})
@@ -121,4 +123,29 @@ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallback
121123
context.logout();
122124
}
123125

126+
@Test
127+
public void testUnauthenticated() throws LoginException {
128+
LoginContext context = new LoginContext("UnAuthenticatedLDAPLogin", new CallbackHandler() {
129+
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
130+
for (int i = 0; i < callbacks.length; i++) {
131+
if (callbacks[i] instanceof NameCallback) {
132+
((NameCallback) callbacks[i]).setName("first");
133+
} else if (callbacks[i] instanceof PasswordCallback) {
134+
((PasswordCallback) callbacks[i]).setPassword("secret".toCharArray());
135+
} else {
136+
throw new UnsupportedCallbackException(callbacks[i]);
137+
}
138+
}
139+
}
140+
});
141+
try {
142+
context.login();
143+
} catch (LoginException le) {
144+
assertEquals(le.getCause().getMessage(), "Empty password is not allowed");
145+
return;
146+
}
147+
fail("Should have failed authenticating");
148+
}
149+
150+
124151
}

activemq-jaas/src/test/resources/login.config

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ LDAPLogin {
4040
;
4141
};
4242

43+
UnAuthenticatedLDAPLogin {
44+
org.apache.activemq.jaas.LDAPLoginModule required
45+
debug=true
46+
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
47+
connectionURL="ldap://localhost:1024"
48+
connectionUsername="uid=admin,ou=system"
49+
connectionPassword=""
50+
connectionProtocol=s
51+
authentication=simple
52+
userBase="ou=system"
53+
userSearchMatching="(uid={0})"
54+
userSearchSubtree=false
55+
roleBase="ou=system"
56+
roleName=dummyRoleName
57+
roleSearchMatching="(uid={1})"
58+
roleSearchSubtree=false
59+
;
60+
};
61+
4362
ExpandedLDAPLogin {
4463
org.apache.activemq.jaas.LDAPLoginModule required
4564
debug=true
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.activemq.security;
18+
import static org.junit.Assert.assertNotNull;
19+
import static org.junit.Assert.fail;
20+
21+
import javax.jms.Connection;
22+
import javax.jms.Destination;
23+
import javax.jms.JMSException;
24+
import javax.jms.Message;
25+
import javax.jms.MessageConsumer;
26+
import javax.jms.MessageProducer;
27+
import javax.jms.Queue;
28+
import javax.jms.Session;
29+
30+
import org.apache.activemq.ActiveMQConnectionFactory;
31+
import org.apache.activemq.broker.BrokerFactory;
32+
import org.apache.activemq.broker.BrokerService;
33+
import org.apache.directory.server.annotations.CreateLdapServer;
34+
import org.apache.directory.server.annotations.CreateTransport;
35+
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
36+
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
37+
import org.apache.directory.server.core.integ.FrameworkRunner;
38+
import org.apache.directory.server.ldap.LdapServer;
39+
import org.junit.After;
40+
import org.junit.Before;
41+
import org.junit.Test;
42+
import org.junit.runner.RunWith;
43+
44+
45+
@RunWith( FrameworkRunner.class )
46+
@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port=1024)})
47+
@ApplyLdifFiles(
48+
"org/apache/activemq/security/activemq.ldif"
49+
)
50+
public class LDAPAuthenticationTest extends AbstractLdapTestUnit {
51+
52+
public BrokerService broker;
53+
54+
public static LdapServer ldapServer;
55+
56+
@Before
57+
public void setup() throws Exception {
58+
System.setProperty("ldapPort", String.valueOf(getLdapServer().getPort()));
59+
60+
broker = BrokerFactory.createBroker("xbean:org/apache/activemq/security/activemq-ldap-auth.xml");
61+
broker.start();
62+
broker.waitUntilStarted();
63+
}
64+
65+
@After
66+
public void shutdown() throws Exception {
67+
broker.stop();
68+
broker.waitUntilStopped();
69+
}
70+
71+
@Test
72+
public void testWildcard() throws Exception {
73+
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
74+
Connection conn = factory.createQueueConnection("*", "sunflower");
75+
try {
76+
conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
77+
} catch (Exception e) {
78+
e.printStackTrace();
79+
return;
80+
}
81+
fail("Should have failed connecting");
82+
}
83+
}

activemq-unit-tests/src/test/java/org/apache/activemq/security/LDAPSecurityTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545

4646
@RunWith( FrameworkRunner.class )
47-
@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")})
47+
@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port=1024)})
4848
@ApplyLdifFiles(
4949
"org/apache/activemq/security/activemq.ldif"
5050
)

activemq-unit-tests/src/test/resources/login.config

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,23 @@ broker2 {
6565
debug=true
6666
org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users2.properties"
6767
org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
68+
};
69+
70+
LDAPLogin {
71+
org.apache.activemq.jaas.LDAPLoginModule required
72+
debug=true
73+
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
74+
connectionURL="ldap://localhost:1024"
75+
connectionUsername="uid=admin,ou=system"
76+
connectionPassword=secret
77+
connectionProtocol=s
78+
authentication=simple
79+
userBase="ou=User,ou=ActiveMQ,ou=system"
80+
userSearchMatching="(uid={0})"
81+
userSearchSubtree=false
82+
roleBase="ou=Group,ou=ActiveMQ,ou=system"
83+
roleName=cn
84+
roleSearchMatching="(uid={1})"
85+
roleSearchSubtree=true
86+
;
6887
};
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one or more
4+
contributor license agreements. See the NOTICE file distributed with
5+
this work for additional information regarding copyright ownership.
6+
The ASF licenses this file to You under the Apache License, Version 2.0
7+
(the "License"); you may not use this file except in compliance with
8+
the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-->
18+
<!-- START SNIPPET: xbean -->
19+
<beans
20+
xmlns="http://www.springframework.org/schema/beans"
21+
xmlns:amq="http://activemq.apache.org/schema/core"
22+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23+
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
24+
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
25+
26+
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
27+
28+
<broker useJmx="false" xmlns="http://activemq.apache.org/schema/core" persistent="false">
29+
30+
<destinations>
31+
<queue physicalName="ADMIN.FOO" />
32+
</destinations>
33+
34+
<plugins>
35+
<jaasAuthenticationPlugin configuration="LDAPLogin"/>
36+
</plugins>
37+
38+
39+
<transportConnectors>
40+
<transportConnector uri="tcp://localhost:61616"/>
41+
</transportConnectors>
42+
43+
</broker>
44+
45+
</beans>
46+
<!-- END SNIPPET: xbean -->

0 commit comments

Comments
 (0)