Source Code Cross Referenced for SipSecurityManager.java in  » Net » openfire » org » jivesoftware » openfire » sip » tester » security » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » openfire » org.jivesoftware.openfire.sip.tester.security 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * $RCSfile$
003:         * $Revision: $
004:         * $Date: $
005:         *
006:         * Copyright (C) 2007 Jive Software. All rights reserved.
007:         *
008:         * This software is published under the terms of the GNU Public License (GPL),
009:         * a copy of which is included in this distribution.
010:         */package org.jivesoftware.openfire.sip.tester.security;
011:
012:        import org.jivesoftware.openfire.sip.tester.Log;
013:        import org.jivesoftware.openfire.sip.tester.stack.SIPConfig;
014:        import org.jivesoftware.openfire.sip.tester.stack.SipManager;
015:
016:        import javax.sip.ClientTransaction;
017:        import javax.sip.InvalidArgumentException;
018:        import javax.sip.SipException;
019:        import javax.sip.SipProvider;
020:        import javax.sip.address.Address;
021:        import javax.sip.address.SipURI;
022:        import javax.sip.address.URI;
023:        import javax.sip.header.*;
024:        import javax.sip.message.Request;
025:        import javax.sip.message.Response;
026:        import java.text.ParseException;
027:        import java.util.ListIterator;
028:
029:        /**
030:         * <p/>
031:         * Title: Netsite TudoMais
032:         * </p>
033:         * <p/>
034:         * Description:JAIN-SIP Audio/Video phone application
035:         * </p>
036:         * <p/>
037:         * Copyright: Copyright (c) 2006
038:         * </p>
039:         * <p/>
040:         * Organisation: CTBC Telecom / Netsite
041:         * </p>
042:         *
043:         * @author Thiago Rocha Camargo (thiago@jivesoftware.com)
044:         */
045:
046:        public class SipSecurityManager {
047:            /**
048:             */
049:            private HeaderFactory headerFactory = null;
050:
051:            /**
052:             */
053:            private SipProvider transactionCreator = null;
054:
055:            private SipManager sipManCallback = null;
056:
057:            /**
058:             * Credentials cached so far.
059:             */
060:            CredentialsCache cachedCredentials = new CredentialsCache();
061:
062:            public UserCredentials defaultCredentials = null;
063:
064:            public SipSecurityManager() {
065:
066:            }
067:
068:            public UserCredentials getDefaultCredentials() {
069:                return defaultCredentials;
070:            }
071:
072:            public void setDefaultCredentials(UserCredentials defaultCredentials) {
073:                this .defaultCredentials = defaultCredentials;
074:            }
075:
076:            /**
077:             * set the header factory to be used when creating authorization headers
078:             *
079:             * @uml.property name="headerFactory"
080:             */
081:            public void setHeaderFactory(HeaderFactory headerFactory) {
082:                this .headerFactory = headerFactory;
083:            }
084:
085:            /**
086:             * Verifies whether there are any user credentials registered for the call
087:             * that "request" belongs to and appends corresponding authorization headers
088:             * if that is the case.
089:             *
090:             * @param request the request that needs to be attached credentials.
091:             */
092:            public void appendCredentialsIfNecessary(Request request) {
093:                // TODO IMPLEMENT
094:            }
095:
096:            /**
097:             * Uses securityAuthority to determinie a set of valid user credentials for
098:             * the specified Response (Challenge) and appends it to the challenged
099:             * request so that it could be retransmitted.
100:             * <p/>
101:             * Fredrik Wickstrom reported that dialog cseq counters are not incremented
102:             * when resending requests. He later uncovered additional problems and
103:             * proposed a way to fix them (his proposition was taken into account).
104:             *
105:             * @param challenge             the 401/407 challenge response
106:             * @param challengedTransaction the transaction established by the challenged request
107:             * @return a transaction containing a reoriginated request with the
108:             *         necessary authorization header.
109:             * @throws SipSecurityException
110:             */
111:            public ClientTransaction handleChallenge(Response challenge,
112:                    ClientTransaction challengedTransaction)
113:                    throws SipSecurityException, SipException,
114:                    InvalidArgumentException, ParseException {
115:                try {
116:
117:                    String branchID = challengedTransaction.getBranchId();
118:                    Request challengedRequest = challengedTransaction
119:                            .getRequest();
120:
121:                    Request reoriginatedRequest = (Request) challengedRequest
122:                            .clone();
123:
124:                    ListIterator authHeaders = null;
125:
126:                    if (challenge == null || reoriginatedRequest == null)
127:                        throw new NullPointerException(
128:                                "A null argument was passed to handle challenge.");
129:
130:                    // CallIdHeader callId =
131:                    // (CallIdHeader)challenge.getHeader(CallIdHeader.NAME);
132:
133:                    if (challenge.getStatusCode() == Response.UNAUTHORIZED)
134:                        authHeaders = challenge
135:                                .getHeaders(WWWAuthenticateHeader.NAME);
136:                    else if (challenge.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED)
137:                        authHeaders = challenge
138:                                .getHeaders(ProxyAuthenticateHeader.NAME);
139:
140:                    if (authHeaders == null)
141:                        throw new SecurityException(
142:                                "Could not find WWWAuthenticate or ProxyAuthenticate headers");
143:
144:                    // Remove all authorization headers from the request (we'll re-add
145:                    // them
146:                    // from cache)
147:                    reoriginatedRequest.removeHeader(AuthorizationHeader.NAME);
148:                    reoriginatedRequest
149:                            .removeHeader(ProxyAuthorizationHeader.NAME);
150:
151:                    // rfc 3261 says that the cseq header should be augmented for the
152:                    // new
153:                    // request. do it here so that the new dialog (created together with
154:                    // the new client transaction) takes it into account.
155:                    // Bug report - Fredrik Wickstrom
156:                    CSeqHeader cSeq = (CSeqHeader) reoriginatedRequest
157:                            .getHeader((CSeqHeader.NAME));
158:                    cSeq.setSequenceNumber(cSeq.getSequenceNumber() + 1);
159:
160:                    ClientTransaction retryTran = transactionCreator
161:                            .getNewClientTransaction(reoriginatedRequest);
162:
163:                    WWWAuthenticateHeader authHeader = null;
164:                    CredentialsCacheEntry ccEntry = null;
165:                    while (authHeaders.hasNext()) {
166:                        authHeader = (WWWAuthenticateHeader) authHeaders.next();
167:                        String realm = authHeader.getRealm();
168:
169:                        // Check whether we have cached credentials for authHeader's
170:                        // realm
171:                        // make sure that if such credentials exist they get removed.
172:                        // The
173:                        // challenge means that there's something wrong with them.
174:                        ccEntry = cachedCredentials.remove(realm);
175:
176:                        // Try to guess user name and facilitate user
177:                        UserCredentials defaultCredentials = new UserCredentials();
178:                        FromHeader from = (FromHeader) reoriginatedRequest
179:                                .getHeader(FromHeader.NAME);
180:                        URI uri = from.getAddress().getURI();
181:                        if (uri.isSipURI()) {
182:                            Log.debug("handleChallenge", SIPConfig
183:                                    .getAuthUserName());
184:                            String user = SIPConfig.getAuthUserName() != null ? SIPConfig
185:                                    .getAuthUserName()
186:                                    : ((SipURI) uri).getUser();
187:                            defaultCredentials
188:                                    .setAuthUserName(user == null ? SIPConfig
189:                                            .getUserName() : user);
190:                        }
191:
192:                        boolean ccEntryHasSeenTran = false;
193:
194:                        if (ccEntry != null)
195:                            ccEntryHasSeenTran = ccEntry
196:                                    .processResponse(branchID);
197:
198:                        // get a new pass
199:                        if (ccEntry == null // we don't have credentials for the
200:                                // specified realm
201:                                || ((!authHeader.isStale() && ccEntryHasSeenTran))) {
202:                            if (ccEntry == null) {
203:                                ccEntry = new CredentialsCacheEntry();
204:
205:                                ccEntry.userCredentials = defaultCredentials;
206:
207:                            }
208:                            // put the returned user name in the properties file
209:                            // so that it appears as a default one next time user is
210:                            // prompted for pass
211:                            SIPConfig.setUserName(ccEntry.userCredentials
212:                                    .getUserName());
213:                        }
214:                        // encode and send what we have
215:                        else if (ccEntry != null
216:                                && (!ccEntryHasSeenTran || authHeader.isStale())) {
217:                        }
218:
219:                        // if user canceled or sth else went wrong
220:                        if (ccEntry.userCredentials == null)
221:                            throw new SecurityException(
222:                                    "Unable to authenticate with realm "
223:                                            + realm);
224:
225:                        AuthorizationHeader authorization = this 
226:                                .getAuthorization(
227:                                        reoriginatedRequest.getMethod(),
228:                                        reoriginatedRequest.getRequestURI()
229:                                                .toString(),
230:                                        reoriginatedRequest.getContent() == null ? ""
231:                                                : reoriginatedRequest
232:                                                        .getContent()
233:                                                        .toString(),
234:                                        authHeader, ccEntry.userCredentials);
235:
236:                        ccEntry.processRequest(retryTran.getBranchId());
237:                        cachedCredentials.cacheEntry(realm, ccEntry);
238:
239:                        reoriginatedRequest.addHeader(authorization);
240:
241:                        // if there was trouble with the user - make sure we fix it
242:                        if (uri.isSipURI()) {
243:                            ((SipURI) uri).setUser(ccEntry.userCredentials
244:                                    .getUserName());
245:                            Address add = from.getAddress();
246:                            add.setURI(uri);
247:                            from.setAddress(add);
248:                            reoriginatedRequest.setHeader(from);
249:                            if (challengedRequest.getMethod().equals(
250:                                    Request.REGISTER)) {
251:                                ToHeader to = (ToHeader) reoriginatedRequest
252:                                        .getHeader(ToHeader.NAME);
253:                                add.setURI(uri);
254:                                to.setAddress(add);
255:                                reoriginatedRequest.setHeader(to);
256:
257:                            }
258:
259:                            // very ugly but very necessary
260:
261:                            sipManCallback.setCurrentlyUsedURI(uri.toString());
262:                            Log.debug("URI: " + uri.toString());
263:
264:                        }
265:
266:                        // if this is a register - fix to as well
267:
268:                    }
269:
270:                    return retryTran;
271:                } catch (Exception e) {
272:                    Log.debug("ERRO REG: " + e.toString());
273:                    return null;
274:                }
275:
276:            }
277:
278:            /**
279:             * Generates an authorisation header in response to wwwAuthHeader.
280:             *
281:             * @param method          method of the request being authenticated
282:             * @param uri             digest-uri
283:             * @param authHeader      the challenge that we should respond to
284:             * @param userCredentials username and pass
285:             * @return an authorisation header in response to wwwAuthHeader.
286:             */
287:            private AuthorizationHeader getAuthorization(String method,
288:                    String uri, String requestBody,
289:                    WWWAuthenticateHeader authHeader,
290:                    UserCredentials userCredentials) throws SecurityException {
291:                String response = null;
292:                try {
293:                    Log.debug("getAuthorization", userCredentials
294:                            .getAuthUserName());
295:                    response = MessageDigestAlgorithm.calculateResponse(
296:                            authHeader.getAlgorithm(), userCredentials
297:                                    .getAuthUserName(), authHeader.getRealm(),
298:                            new String(userCredentials.getPassword()),
299:                            authHeader.getNonce(),
300:                            // TODO we should one day implement those two null-s
301:                            null,// nc-value
302:                            null,// cnonce
303:                            method, uri, requestBody, authHeader.getQop());
304:                } catch (NullPointerException exc) {
305:                    throw new SecurityException(
306:                            "The authenticate header was malformatted");
307:                }
308:
309:                AuthorizationHeader authorization = null;
310:                try {
311:                    if (authHeader instanceof  ProxyAuthenticateHeader) {
312:                        authorization = headerFactory
313:                                .createProxyAuthorizationHeader(authHeader
314:                                        .getScheme());
315:                    } else {
316:                        authorization = headerFactory
317:                                .createAuthorizationHeader(authHeader
318:                                        .getScheme());
319:                    }
320:
321:                    authorization
322:                            .setUsername(userCredentials.getAuthUserName());
323:                    authorization.setRealm(authHeader.getRealm());
324:                    authorization.setNonce(authHeader.getNonce());
325:                    authorization.setParameter("uri", uri);
326:                    authorization.setResponse(response);
327:                    if (authHeader.getAlgorithm() != null)
328:                        authorization.setAlgorithm(authHeader.getAlgorithm());
329:                    if (authHeader.getOpaque() != null)
330:                        authorization.setOpaque(authHeader.getOpaque());
331:
332:                    authorization.setResponse(response);
333:                } catch (ParseException ex) {
334:                    throw new SecurityException(
335:                            "Failed to create an authorization header!");
336:                }
337:
338:                return authorization;
339:            }
340:
341:            public void cacheCredentials(String realm,
342:                    UserCredentials credentials) {
343:                CredentialsCacheEntry ccEntry = new CredentialsCacheEntry();
344:                ccEntry.userCredentials = credentials;
345:
346:                this .cachedCredentials.cacheEntry(realm, ccEntry);
347:            }
348:
349:            /**
350:             * Sets a valid SipProvider that would enable the security manager to map
351:             * credentials to transactionsand thus understand when it is suitable to use
352:             * cached passwords and when it should go ask the user.
353:             *
354:             * @param transactionCreator a valid SipProvder instance
355:             * @uml.property name="transactionCreator"
356:             */
357:            public void setTransactionCreator(SipProvider transactionCreator) {
358:                this .transactionCreator = transactionCreator;
359:            }
360:
361:            /**
362:             * If the user name was wrong and the user fixes it here we should als
363:             * notify the sip manager that the currentlyUsedURI it has is not valid.
364:             *
365:             * @param sipManCallback a valid instance of SipMaqnager
366:             * @uml.property name="sipManCallback"
367:             */
368:            public void setSipManCallback(SipManager sipManCallback) {
369:                this.sipManCallback = sipManCallback;
370:            }
371:
372:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.