sipStack.getStackLogger().logDebug("handleChallenge: " + challenge);
SIPRequest challengedRequest = ((SIPRequest) challengedTransaction.getRequest());
Request reoriginatedRequest = null;
/*
* If the challenged request is part of a Dialog and the
* Dialog is confirmed the re-originated request should be
* generated as an in-Dialog request.
*/
if ( challengedRequest.getToTag() != null ||
challengedTransaction.getDialog() == null ||
challengedTransaction.getDialog().getState() != DialogState.CONFIRMED) {
reoriginatedRequest = (Request) challengedRequest.clone();
} else {
/*
* Re-originate the request by consulting the dialog. In particular
* the route set could change between the original request and the
* in-dialog challenge.
*/
reoriginatedRequest =
challengedTransaction.getDialog().createRequest(challengedRequest.getMethod());
Iterator<String> headerNames = challengedRequest.getHeaderNames();
while (headerNames.hasNext()) {
String headerName = headerNames.next();
if ( reoriginatedRequest.getHeader(headerName) != null) {
ListIterator<Header> iterator = reoriginatedRequest.getHeaders(headerName);
while (iterator.hasNext()) {
reoriginatedRequest.addHeader(iterator.next());
}
}
}
}
// remove the branch id so that we could use the request in a new
// transaction
removeBranchID(reoriginatedRequest);
if (challenge == null || reoriginatedRequest == null) {
throw new NullPointerException("A null argument was passed to handle challenge.");
}
ListIterator authHeaders = null;
if (challenge.getStatusCode() == Response.UNAUTHORIZED) {
authHeaders = challenge.getHeaders(WWWAuthenticateHeader.NAME);
} else if (challenge.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED) {
authHeaders = challenge.getHeaders(ProxyAuthenticateHeader.NAME);
} else {
throw new IllegalArgumentException("Unexpected status code ");
}
if (authHeaders == null) {
throw new IllegalArgumentException(
"Could not find WWWAuthenticate or ProxyAuthenticate headers");
}
// Remove all authorization headers from the request (we'll re-add them
// from cache)
reoriginatedRequest.removeHeader(AuthorizationHeader.NAME);
reoriginatedRequest.removeHeader(ProxyAuthorizationHeader.NAME);
// rfc 3261 says that the cseq header should be augmented for the new
// request. do it here so that the new dialog (created together with
// the new client transaction) takes it into account.
// Bug report - Fredrik Wickstrom
CSeqHeader cSeq = (CSeqHeader) reoriginatedRequest.getHeader((CSeqHeader.NAME));
try {
cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l);
} catch (InvalidArgumentException ex) {
throw new SipException("Invalid CSeq -- could not increment : "
+ cSeq.getSeqNumber());
}
/* Resolve this to the next hop based on the previous lookup. If we are not using
* lose routing (RFC2543) then just attach hop as a maddr param.
*/
if ( challengedRequest.getRouteHeaders() == null ) {
Hop hop = ((SIPClientTransaction) challengedTransaction).getNextHop();
SipURI sipUri = (SipURI) reoriginatedRequest.getRequestURI();
sipUri.setMAddrParam(hop.getHost());
if ( hop.getPort() != -1 ) sipUri.setPort(hop.getPort());
}
ClientTransaction retryTran = transactionCreator
.getNewClientTransaction(reoriginatedRequest);
WWWAuthenticateHeader authHeader = null;
SipURI requestUri = (SipURI) challengedTransaction.getRequest().getRequestURI();
while (authHeaders.hasNext()) {
authHeader = (WWWAuthenticateHeader) authHeaders.next();
String realm = authHeader.getRealm();
AuthorizationHeader authorization = null;
String sipDomain;
if ( this.accountManager instanceof SecureAccountManager ) {
UserCredentialHash credHash =
((SecureAccountManager)this.accountManager).getCredentialHash(challengedTransaction,realm);
if ( credHash == null ) {
sipStack.getStackLogger().logDebug("Could not find creds");
throw new SipException(
"Cannot find user creds for the given user name and realm");
}
URI uri = reoriginatedRequest.getRequestURI();
sipDomain = credHash.getSipDomain();
authorization = this.getAuthorization(reoriginatedRequest
.getMethod(), uri.toString(),
(reoriginatedRequest.getContent() == null) ? "" : new String(
reoriginatedRequest.getRawContent()), authHeader, credHash);
} else {
UserCredentials userCreds = ((AccountManager) this.accountManager).getCredentials(challengedTransaction, realm);
if (userCreds == null) {
throw new SipException(
"Cannot find user creds for the given user name and realm");
}
sipDomain = userCreds.getSipDomain();
// we haven't yet authenticated this realm since we were
// started.
authorization = this.getAuthorization(reoriginatedRequest
.getMethod(), reoriginatedRequest.getRequestURI().toString(),
(reoriginatedRequest.getContent() == null) ? "" : new String(
reoriginatedRequest.getRawContent()), authHeader, userCreds);
}
if ( sipStack.getStackLogger().isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
sipStack.getStackLogger().logDebug(
"Created authorization header: " + authorization.toString());
}
if (cacheTime != 0) {
String callId = challengedRequest.getCallId().getCallId();
cachedCredentials.cacheAuthorizationHeader(callId,
authorization, cacheTime);
}
reoriginatedRequest.addHeader(authorization);
}
if ( sipStack.getStackLogger().isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
sipStack.getStackLogger().logDebug(