package gov.nist.javax.sip.clientauthutils; import gov.nist.javax.sip.stack.SIPStackTimerTask; import gov.nist.javax.sip.stack.timers.SipTimer; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import javax.sip.header.AuthorizationHeader; /** * A cache of authorization headers to be used for subsequent processing when we * set up calls. We cache credentials on a per proxy domain per user basis. * */ class CredentialsCache { /** * The key for this map is the proxy domain name. A given proxy authorizes a * user for a number of domains. The Hashtable value of the mapping is a * mapping of user names to AuthorizationHeader list for that proxy domain. */ private ConcurrentHashMap<String, List<AuthorizationHeader>> authorizationHeaders = new ConcurrentHashMap<String, List<AuthorizationHeader>>(); private SipTimer timer; class TimeoutTask extends SIPStackTimerTask { String callId; String userName; public TimeoutTask(String userName, String callId) { this.callId = callId; this.userName = userName; } public void runTask() { authorizationHeaders.remove(callId); } } CredentialsCache (SipTimer timer) { this.timer = timer; } /** * Cache the bindings of proxyDomain and authorization header. * * @param callid * the id of the call that the <tt>authorization</tt> header * belongs to. * @param authorization * the authorization header that we'd like to cache. */ void cacheAuthorizationHeader(String callId, AuthorizationHeader authorization, int cacheTime) { String user = authorization.getUsername(); if ( callId == null) throw new NullPointerException("Call ID is null!"); if ( authorization == null) throw new NullPointerException("Null authorization domain"); List<AuthorizationHeader> authHeaders = authorizationHeaders.get(callId); if (authHeaders == null) { authHeaders = new LinkedList<AuthorizationHeader>(); authorizationHeaders.put(callId, authHeaders); } else { String realm = authorization.getRealm(); for (ListIterator<AuthorizationHeader> li = authHeaders.listIterator(); li.hasNext();) { AuthorizationHeader authHeader = (AuthorizationHeader) li.next(); if ( realm.equals(authHeader.getRealm()) ) { li.remove(); } } } authHeaders.add(authorization); TimeoutTask timeoutTask = new TimeoutTask( callId,user); if ( cacheTime != -1) this.timer.schedule(timeoutTask, cacheTime*1000); } /** * Returns an authorization header cached for the specified call id and null * if no authorization header has been previously cached for this call. * * @param callid * the call id that we'd like to retrive a cached authorization * header for. * * @return authorization header corresponding to that user for the given * proxy domain. */ Collection<AuthorizationHeader> getCachedAuthorizationHeaders( String callid) { if (callid == null) throw new NullPointerException("Null arg!"); return this.authorizationHeaders.get(callid); } /** * Remove a cached authorization header. * * @param callId */ public void removeAuthenticationHeader(String callId) { this.authorizationHeaders.remove(callId); } }