String method = req.getMethod();
if ((method.equals(Request.ACK) == true)
|| (method.equals(Request.CANCEL) == true))
{
// do not send a challenge for ACK and CANCEL messages
return new Pair(null, null);
}
Pair p = null;
synchronized (jipletMap)
{
p = (Pair) jipletMap.get(jiplet);
if (p == null)
{
// the jiplet does not have any security constraint
return new Pair(null, null);
}
}
Realm realm = (Realm) p.getFirst();
String[] roles = (String[]) p.getSecond();
String realm_name = null;
try
{
Thread.currentThread().setContextClassLoader(
realm.getClass().getClassLoader());
realm_name = realm.getRealmName();
}
finally
{
Thread.currentThread().setContextClassLoader(cl);
}
// check if the request message contains an Authorization Header that
// belongs to this realm
String header_name = method.equals(Request.REGISTER) == true ? AuthorizationHeader.NAME
: ProxyAuthorizationHeader.NAME;
ListIterator iter = req.getHeaders(header_name);
boolean found = false;
while (iter.hasNext() == true)
{
found = true;
AuthorizationHeader header = (AuthorizationHeader) iter.next();
String call_id = ((CallIdHeader) req.getHeader(CallIdHeader.NAME))
.getCallId();
if (JipletLogger.isDebugEnabled() == true)
{
JipletLogger.debug("Found an authentication entry for call-id"
+ call_id + " for realm " + header.getRealm());
}
// check if the user has already been authenticated
String[] uroles = authorizations.findEntry(header.getRealm(),
call_id, header.getNonce(), header.getResponse());
if (uroles != null)
{
if (JipletLogger.isDebugEnabled() == true)
{
JipletLogger.debug("Authenticated call-id " + call_id
+ " from cached authentications");
}
// update the cached information with the new time-stamp
AuthorizationInfo ainfo = new AuthorizationInfo();
ainfo.setRealm(realm_name);
ainfo.setResponse(header.getResponse());
ainfo.setCallId(call_id);
ainfo.setNonce(header.getNonce());
authorizations.addEntry(ainfo, new Date());
// the user has a prior authentication for this realm, check if
// the user has proper authority
if (hasAuthorization(roles, uroles) == true)
{
return new Pair(new JipletPrincipal(header.getUsername()),
uroles);
}
else
{
// send a FORBIDDEN response
sendResponse(jiplet, event, Response.FORBIDDEN,
"You are not authorized to use this service", null);
return null;
}
}
else
{
// the user either does not prior authentication or the auth
// failed. Check if the authentication info that the user has
// sent can
// be authenticated.
try
{
// set the context class loader to that of the realm.
Thread.currentThread().setContextClassLoader(
realm.getClass().getClassLoader());
uroles = realm.authenticate(req.getMethod(), header);
}
finally
{
Thread.currentThread().setContextClassLoader(cl);
}
if (uroles != null)
{
// add the information to the cached authorizations
AuthorizationInfo ainfo = new AuthorizationInfo();
ainfo.setRealm(realm_name);
ainfo.setResponse(header.getResponse());
ainfo.setCallId(call_id);
ainfo.setNonce(header.getNonce());
authorizations.addEntry(ainfo, new Date());
// the user has proper authentication for this realm, check
// if the user has proper authority
if (hasAuthorization(roles, uroles) == true)
{
return new Pair(new JipletPrincipal(header
.getUsername()), uroles);
}
else
{
// send a FORBIDDEN response
sendResponse(jiplet, event, Response.FORBIDDEN,
"You are not authorized to use this service",
null);
return null;
}
}
}
} // end while
if (found == false)
{
if (JipletLogger.isDebugEnabled() == true)
{
JipletLogger
.debug("Received a SIP request with no authentication header");
}
if (authOnLogout == false)
{
if (method.equals(Request.REGISTER) == true)
{
// get the expires header
ExpiresHeader expires = (ExpiresHeader) req
.getHeader(ExpiresHeader.NAME);
if ((expires != null) && (expires.getExpires() == 0))
{
FromHeader from = (FromHeader) req
.getHeader(FromHeader.NAME);
String name = ((SipURI) from.getAddress().getURI())
.getUser();
return new Pair(new JipletPrincipal(name), null);
}
}
}
}