1package gov.nist.javax.sip.clientauthutils;
2
3import java.util.*;
4import java.util.concurrent.ConcurrentHashMap;
5
6import javax.sip.*;
7import javax.sip.header.*;
8import javax.sip.address.*;
9import javax.sip.message.*;
10
11/**
12 * A cache of authorization headers to be used for subsequent processing when we
13 * set up calls. We cache credentials on a per proxy domain per user basis.
14 *
15 */
16
17class CredentialsCache {
18
19
20    /**
21     * The key for this map is the proxy domain name. A given proxy authorizes a
22     * user for a number of domains. The Hashtable value of the mapping is a
23     * mapping of user names to AuthorizationHeader list for that proxy domain.
24     */
25    private ConcurrentHashMap<String, List<AuthorizationHeader>> authorizationHeaders =
26            new ConcurrentHashMap<String, List<AuthorizationHeader>>();
27    private Timer timer;
28
29    class TimeoutTask extends TimerTask {
30        String callId;
31        String userName;
32
33        public TimeoutTask(String userName, String proxyDomain) {
34            this.callId = proxyDomain;
35            this.userName = userName;
36        }
37
38        @Override
39        public void run() {
40            authorizationHeaders.remove(callId);
41
42        }
43
44    }
45
46
47
48    CredentialsCache (Timer timer) {
49        this.timer = timer;
50    }
51
52    /**
53     * Cache the bindings of proxyDomain and authorization header.
54     *
55     * @param callid
56     *            the id of the call that the <tt>authorization</tt> header
57     *            belongs to.
58     * @param authorization
59     *            the authorization header that we'd like to cache.
60     */
61    void cacheAuthorizationHeader(String callId,
62            AuthorizationHeader authorization, int cacheTime) {
63        String user = authorization.getUsername();
64        if ( callId == null) throw new NullPointerException("Call ID is null!");
65        if ( authorization == null) throw new NullPointerException("Null authorization domain");
66
67        List<AuthorizationHeader> authHeaders = authorizationHeaders.get(callId);
68        if (authHeaders == null) {
69            authHeaders = new LinkedList<AuthorizationHeader>();
70            authorizationHeaders.put(callId, authHeaders);
71        } else {
72            String realm = authorization.getRealm();
73            for (ListIterator<AuthorizationHeader> li = authHeaders.listIterator(); li.hasNext();) {
74                AuthorizationHeader authHeader = (AuthorizationHeader) li.next();
75                if ( realm.equals(authHeader.getRealm()) ) {
76                    li.remove();
77                }
78            }
79        }
80
81        authHeaders.add(authorization);
82
83        TimeoutTask timeoutTask  = new TimeoutTask( callId,user);
84        if ( cacheTime != -1)
85            this.timer.schedule(timeoutTask, cacheTime*1000);
86
87
88    }
89
90    /**
91     * Returns an authorization header cached for the specified call id and null
92     * if no authorization header has been previously cached for this call.
93     *
94     * @param callid
95     *            the call id that we'd like to retrive a cached authorization
96     *            header for.
97     *
98     * @return authorization header corresponding to that user for the given
99     *         proxy domain.
100     */
101    Collection<AuthorizationHeader> getCachedAuthorizationHeaders(
102            String callid) {
103        if (callid == null)
104            throw new NullPointerException("Null arg!");
105        return this.authorizationHeaders.get(callid);
106
107    }
108
109    /**
110     * Remove a cached authorization header.
111     *
112     * @param callId
113     */
114    public void removeAuthenticationHeader(String callId) {
115        this.authorizationHeaders.remove(callId);
116
117    }
118
119}
120