org.ice4j.security.CredentialsManager Maven / Gradle / Ivy
/*
* ice4j, the OpenSource Java Solution for NAT and Firewall Traversal.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ice4j.security;
import java.util.*;
/**
* The CredentialsManager allows an application to handle verification
* of incoming MessageIntegrityAttributes by registering a
* {@link CredentialsAuthority} implementation. The point of this mechanism
* is to allow use in both applications that would handle large numbers of
* possible users (such as STUN/TURN servers) or others that would only work
* with a few, like for example an ICE implementation.
*
* TODO: just throwing a user name at the manager and expecting it to find
* an authority that knows about it may lead to ambiguities so we may need
* to add other parameters in here that would allow us to better select an
* authority.
*
* @author Emil Ivov
* @author Lyubomir Marinov
*/
public class CredentialsManager
{
/**
* The list of CredentialsAuthoritys registered with this manager
* as being able to provide credentials.
*/
private final List authorities = new LinkedList<>();
/**
* The list of CredentialsAuthoritys registered with this manager
* as being able to provide credentials. If non-null, represents
* an unmodifiable view of {@link #authorities}. The field was introduced in
* order to reduce the scopes of the synchronization blocks of
* CredentialsManager and to thus reduce the risks of deadlocks.
*/
private CredentialsAuthority[] unmodifiableAuthorities;
/**
* Verifies whether username is currently known to any of the
* {@link CredentialsAuthority}s registered with this manager and
* and returns true if so. Returns false otherwise.
*
* @param username the user name whose validity we'd like to check.
*
* @return true if username is known to any of the
* CredentialsAuthoritys registered here and false
* otherwise.
*/
public boolean checkLocalUserName(String username)
{
for (CredentialsAuthority auth : getAuthorities())
{
if (auth.checkLocalUserName(username))
return true;
}
return false;
}
/**
* Gets the list of CredentialsAuthoritys registered with this
* manager as being able to provide credentials. Warning: the
* returned value is an internal state of this instance and is to be
* considered unmodifiable.
*
* @return the list of CredentialsAuthoritys registered with this
* manager as being able to provide credentials. Warning: the
* returned value is an internal state of this instance and is to be
* considered unmodifiable.
*/
private CredentialsAuthority[] getAuthorities()
{
synchronized (authorities)
{
if (unmodifiableAuthorities == null)
{
unmodifiableAuthorities
= authorities.toArray(
new CredentialsAuthority[authorities.size()]);
}
return unmodifiableAuthorities;
}
}
/**
* Queries all currently registered {@link CredentialsAuthority}s for a
* password corresponding to the specified local username or user
* frag and returns the first non-null one.
*
* @param username a local user name or user frag whose credentials we'd
* like to obtain.
*
* @return null if username was not a recognized local user name
* for none of the currently registered CredentialsAuthoritys or
* a byte array containing the first non-null password
* that one of them returned.
*/
public byte[] getLocalKey(String username)
{
for (CredentialsAuthority auth : getAuthorities())
{
byte[] passwd = auth.getLocalKey(username);
if (passwd != null)
return passwd;
}
return null;
}
/**
* Queries all currently registered {@link CredentialsAuthority}s for a
* password corresponding to the specified remote username or user
* frag and returns the first non-null one.
*
* @param username a remote user name or user frag whose credentials we'd
* like to obtain.
* @param media the media name that we want to get remote key.
*
* @return null if username was not a recognized remote user name
* for none of the currently registered CredentialsAuthoritys or
* a byte array containing the first non-null password
* that one of them returned.
*/
public byte[] getRemoteKey(String username, String media)
{
for (CredentialsAuthority auth : getAuthorities())
{
byte[] passwd = auth.getRemoteKey(username, media);
if (passwd != null)
{
/** @todo: we should probably add SASLprep here.*/
return passwd;
}
}
return null;
}
/**
* Adds authority to the list of {@link CredentialsAuthority}s
* registered with this manager.
*
* @param authority the {@link CredentialsAuthority} to add to this manager.
*/
public void registerAuthority(CredentialsAuthority authority)
{
synchronized (authorities)
{
if (!authorities.contains(authority) && authorities.add(authority))
unmodifiableAuthorities = null;
}
}
/**
* Removes authority from the list of {@link CredentialsAuthority}s
* registered with this manager.
*
* @param authority the {@link CredentialsAuthority} to remove from this
* manager.
*/
public void unregisterAuthority(CredentialsAuthority authority)
{
synchronized (authorities)
{
if (authorities.remove(authority))
unmodifiableAuthorities = null;
}
}
}