Fixes handling of 403 responses during authentication in a way that guarantees that the user would be re-asked for a password.

cusax-fix
Emil Ivov 17 years ago
parent a00c0a4d12
commit 353d53d75e

@ -38,6 +38,12 @@ public class ActiveCallsRepository
private Hashtable<String, CallSipImpl> activeCalls
= new Hashtable<String, CallSipImpl>();
/**
* Creates a new instance of this repository.
*
* @param opSet a reference to the
* <tt>OperationSetBasicTelephonySipImpl</tt> that craeted us.
*/
public ActiveCallsRepository(OperationSetBasicTelephonySipImpl opSet)
{
this.parentOperationSet = opSet;

@ -107,7 +107,6 @@ public CallPeerSipImpl(Address peerAddress,
{
this.peerAddress = peerAddress;
this.call = owningCall;
call.addCallPeer(this);
//create the uid
this.peerID = String.valueOf( System.currentTimeMillis())

@ -53,17 +53,31 @@ public class CallSipImpl
*/
private final SipMessageFactory messageFactory;
/**
* A reference to the <tt>OperationSetBasicTelephonySipImpl</tt> that
* created us;
*/
private final OperationSetBasicTelephonySipImpl parentOpSet;
/**
* Crates a CallSipImpl instance belonging to <tt>sourceProvider</tt> and
* initiated by <tt>CallCreator</tt>.
*
* @param sourceProvider the ProtocolProviderServiceSipImpl instance in the
* context of which this call has been created.
* context of which this call has been created.
* @param parentOpSet a reference to the operation set that's creating us
* and that we would be able to use for even dispatching.
*/
protected CallSipImpl(ProtocolProviderServiceSipImpl sourceProvider)
protected CallSipImpl(ProtocolProviderServiceSipImpl sourceProvider,
OperationSetBasicTelephonySipImpl parentOpSet)
{
super(sourceProvider);
this.messageFactory = sourceProvider.getMessageFactory();
this.parentOpSet = parentOpSet;
//let's add ourselves to the calls repo. we are doing it ourselves just
//to make sure that no one ever forgets.
parentOpSet.getActiveCallsRepository().addCall(this);
}
/**
@ -73,7 +87,7 @@ protected CallSipImpl(ProtocolProviderServiceSipImpl sourceProvider)
*
* @param callPeer the new <tt>CallPeer</tt>
*/
public void addCallPeer(CallPeerSipImpl callPeer)
private void addCallPeer(CallPeerSipImpl callPeer)
{
if (callPeers.contains(callPeer))
return;
@ -431,8 +445,7 @@ private void attachSdpOffer(Request invite, CallPeerSipImpl callPeer)
/**
* Creates an SDP description that could be sent to <tt>peer</tt> and adds
* it to
* <tt>response</tt>. Provides a hook for this instance to take last
* it to <tt>response</tt>. Provides a hook for this instance to take last
* configuration steps on a specific <tt>Response</tt> before it is sent to
* a specific <tt>CallPeer</tt> as part of the execution of.
*
@ -442,7 +455,7 @@ private void attachSdpOffer(Request invite, CallPeerSipImpl callPeer)
* @throws OperationFailedException if we fail parsing call peer's media.
* @throws ParseException if we try to attach invalid SDP to response.
*/
private void attachSDPAnswer(Response response, CallPeerSipImpl peer)
private void attachSdpHoldAnswer(Response response, CallPeerSipImpl peer)
throws OperationFailedException, ParseException
{
/*
@ -450,8 +463,7 @@ private void attachSDPAnswer(Response response, CallPeerSipImpl peer)
* response to a call-hold invite is to be sent.
*/
CallSession callSession =
((CallSipImpl) peer.getCall()).getMediaCallSession();
CallSession callSession = peer.getCall().getMediaCallSession();
String sdpAnswer = null;
try
@ -487,8 +499,11 @@ private CallPeerSipImpl createCallPeerFor(
{
CallPeerSipImpl callPeer = new CallPeerSipImpl(
containingTransaction.getDialog().getRemoteParty(), this);
addCallPeer(callPeer);
callPeer.setState( (containingTransaction instanceof ServerTransaction)
boolean incomingCall
= (containingTransaction instanceof ServerTransaction);
callPeer.setState( incomingCall
? CallPeerState.INCOMING_CALL
: CallPeerState.INITIATING_CALL);
@ -496,6 +511,12 @@ private CallPeerSipImpl createCallPeerFor(
callPeer.setFirstTransaction(containingTransaction);
callPeer.setJainSipProvider(sourceProvider);
// notify everyone
parentOpSet.fireCallEvent( (incomingCall
? CallEvent.CALL_RECEIVED
: CallEvent.CALL_INITIATED),
this);
return callPeer;
}
@ -825,9 +846,9 @@ public synchronized void answerCallPeer(CallPeerSipImpl callPeer)
throws OperationFailedException
{
Transaction transaction = callPeer.getFirstTransaction();
Dialog dialog = callPeer.getDialog();
if (transaction == null || !dialog.isServer())
if (transaction == null ||
!(transaction instanceof ServerTransaction))
{
callPeer.setState(CallPeerState.DISCONNECTED);
throw new OperationFailedException(

@ -164,14 +164,10 @@ private synchronized CallSipImpl createOutgoingCall(Address calleeAddress,
{
assertRegistered();
CallSipImpl call = new CallSipImpl(protocolProvider);
CallSipImpl call = new CallSipImpl(protocolProvider, this);
activeCallsRepository.addCall(call);
call.invite(calleeAddress, cause);
// notify everyone
fireCallEvent( CallEvent.CALL_INITIATED, call);
return call;
}
@ -185,6 +181,18 @@ public Iterator<CallSipImpl> getActiveCalls()
return activeCallsRepository.getActiveCalls();
}
/**
* Returns a reference to the {@link ActiveCallsRepository} that we are
* currently using.
*
* @return a reference to the {@link ActiveCallsRepository} that we are
* currently using.
*/
protected ActiveCallsRepository getActiveCallsRepository()
{
return activeCallsRepository;
}
/**
* Resumes communication with a call peer previously put on hold.
*
@ -1161,7 +1169,7 @@ private void processInvite(SipProvider sourceProvider,
if (replacesHeader == null)
{
//this is a brand new call (not a transfered one)
callSipImpl = new CallSipImpl(protocolProvider);
callSipImpl = new CallSipImpl(protocolProvider, this);
callSipImpl.processInvite(sourceProvider, serverTransaction);
}
else
@ -1879,47 +1887,6 @@ public synchronized void answerCallPeer(CallPeer peer)
}
/**
* Creates a new call and call peer associated with
* <tt>containingTransaction</tt>
*
* @param containingTransaction the transaction that created the call.
* @param sourceProvider the provider that the containingTransaction belongs
* to.
*
* @return a new instance of a <tt>CallPeerSipImpl</tt> corresponding
* to the <tt>containingTransaction</tt>.
*/
private CallPeerSipImpl createCallPeerFor(
Transaction containingTransaction, SipProvider sourceProvider)
{
CallSipImpl call = new CallSipImpl(protocolProvider);
CallPeerSipImpl callPeer =
new CallPeerSipImpl(
containingTransaction.getDialog().getRemoteParty(),
call);
boolean incomingCall =
(containingTransaction instanceof ServerTransaction);
callPeer.setState(
incomingCall ?
CallPeerState.INCOMING_CALL :
CallPeerState.INITIATING_CALL);
callPeer.setDialog(containingTransaction.getDialog());
callPeer.setFirstTransaction(containingTransaction);
callPeer.setJainSipProvider(sourceProvider);
activeCallsRepository.addCall(call);
// notify everyone
fireCallEvent(
incomingCall ? CallEvent.CALL_RECEIVED : CallEvent.CALL_INITIATED,
call);
return callPeer;
}
/**
* Returns a string representation of this OperationSetBasicTelephony
* instance including information that would permit to distinguish it among

@ -8,6 +8,7 @@
import gov.nist.javax.sip.header.*;
import gov.nist.javax.sip.header.extensions.*;
import gov.nist.javax.sip.message.*;
import java.text.*;
import java.util.*;
@ -201,6 +202,7 @@ public Response createResponse(int statusCode, Request request,
{
Response response = this.wrappedFactory.createResponse(statusCode,
request, contentType, content);
extractAndApplyDialogToTag((SIPRequest)request, response);
return (Response)attachScSpecifics(response);
}
@ -216,6 +218,7 @@ public Response createResponse(int statusCode, Request request,
{
Response response = this.wrappedFactory.createResponse(statusCode,
request, contentType, content);
extractAndApplyDialogToTag((SIPRequest)request, response);
return (Response)attachScSpecifics(response);
}
@ -230,6 +233,7 @@ public Response createResponse(int statusCode, Request request)
{
Response response
= this.wrappedFactory.createResponse(statusCode, request);
extractAndApplyDialogToTag((SIPRequest)request, response);
return (Response)attachScSpecifics(response);
}
@ -246,6 +250,51 @@ public Response createResponse(String responseParam)
return (Response)attachScSpecifics(response);
}
/**
* It appears that when the JAIN-SIP message factory creates responses it
* does not add the dialog to tag (if it exists) to the response. We
* therefore try some heavy-weight JAIN-SIP hacking in order to do this
* ourselves.
*
* @param request the <tt>SIPRequest</tt> that we are constructing a
* response to.
* @param response the <tt>Response</tt> that we have just constructed
* and that we'd like to patch with a To tag.
*/
private void extractAndApplyDialogToTag(
SIPRequest request, Response response)
{
ServerTransaction tran = (ServerTransaction)request.getTransaction();
//be extra cautious
if(tran == null)
return;
Dialog dialog = tran.getDialog();
if(dialog == null)
return;
String localDialogTag = dialog.getLocalTag();
ToHeader to = (ToHeader) response.getHeader(ToHeader.NAME);
if( to == null)
return;
try
{
to.setTag(localDialogTag);
}
catch (ParseException e)
{
//we just extracted the tag from a Dialog. This is therefore
//very unlikely to happen and we are going to just log it.
logger.debug("Failed to attach a to tag", e);
}
}
/**
* Attaches to <tt>message</tt> headers and object params that we'd like to
* be present in absolutely all messages we create (like for example the
@ -253,7 +302,7 @@ public Response createResponse(String responseParam)
* tag).
*
* @param message the message that we'd like to tag
* @return
* @return returns a reference to <tt>message</tt> for convenience reasons.
*/
private Message attachScSpecifics(Message message)
{
@ -269,7 +318,7 @@ private Message attachScSpecifics(Message message)
Response response = (Response)message;
//if there's a from tag and this is a non-failure response,
//then we are adding a to tag.
//that still doesn't have a To tag, then we are adding a to tag.
if(fromTag != null && fromTag.trim().length() > 0
&& response.getStatusCode() > 100
&& response.getStatusCode() < 300)
@ -660,6 +709,8 @@ private void reflectCauseOnEffect(javax.sip.message.Message cause,
* @return a <tt>Header</tt> which represents the Replaces header contained
* in the <tt>URI</tt> of the specified <tt>address</tt>; <tt>null</tt> if
* no such header is present
*
* @throws OperationFailedException if we can't parse the replaces header.
*/
private Header stripReplacesHeader( Address address )
throws OperationFailedException
@ -710,7 +761,6 @@ private Header stripReplacesHeader( Address address )
* effect if the <tt>Call-ID</tt> has not been seen by our security manager.
*
* @param request the request that we'd like to try pre-authenticating.
* @param service the provider where the request originated.
*/
public void preAuthenticateRequest( Request request )
{

@ -928,25 +928,18 @@ else if (response.getStatusCode() == Response.NOT_IMPLEMENTED) {
else if (response.getStatusCode() == Response.TRYING) {
//do nothing
}
//401 UNAUTHORIZED
//401 UNAUTHORIZED,
//407 PROXY_AUTHENTICATION_REQUIRED,
//403 FORBIDDEN
else if (response.getStatusCode() == Response.UNAUTHORIZED
|| response.getStatusCode()
== Response.PROXY_AUTHENTICATION_REQUIRED)
{
processAuthenticationChallenge(clientTransaction
, response
, sourceProvider);
processed = true;
}
//403 FORBIDDEN
else if (response.getStatusCode() == Response.FORBIDDEN)
== Response.PROXY_AUTHENTICATION_REQUIRED
|| response.getStatusCode() == Response.FORBIDDEN)
{
processForbidden(clientTransaction
, response
, sourceProvider);
processAuthenticationChallenge(
clientTransaction, response, sourceProvider);
processed = true;
}
//errors
else if ( response.getStatusCode() >= 400 )
{
logger.error("Received an error response.");
@ -982,11 +975,24 @@ private void processAuthenticationChallenge(
{
logger.debug("Authenticating a Register request.");
ClientTransaction retryTran
= sipProvider.getSipSecurityManager().handleChallenge(
response,
clientTransaction,
jainSipProvider);
ClientTransaction retryTran;
if( response.getStatusCode() == Response.UNAUTHORIZED
|| response.getStatusCode()
== Response.PROXY_AUTHENTICATION_REQUIRED)
{
//respond to the challenge
retryTran = sipProvider.getSipSecurityManager().handleChallenge(
response, clientTransaction, jainSipProvider);
}
else
{
//we got a BAD PASSWD reply. send a new credential-less request
//in order to trigger a new challenge and rerequest a password.
retryTran = sipProvider.getSipSecurityManager()
.handleForbiddenResponse(
response, clientTransaction, jainSipProvider);
}
if(retryTran == null)
{
@ -1035,36 +1041,6 @@ private void processAuthenticationChallenge(
}
}
/**
* Makes sure that the last password used is removed from the cache, and
* notifies the user of the authentication failure..
*
* @param clientTransaction the corresponding transaction
* @param response the challenge
* @param jainSipProvider the provider that received the challenge
*/
private void processForbidden(
ClientTransaction clientTransaction,
Response response,
SipProvider jainSipProvider)
{
logger.debug("Authenticating a Register request.");
sipProvider.getSipSecurityManager().handleForbiddenResponse(
response
, clientTransaction
, jainSipProvider);
//tell the others we couldn't register
this.setRegistrationState(
RegistrationState.AUTHENTICATION_FAILED
, RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED
, "Received a "+Response.FORBIDDEN+" FORBIDDEN response while "
+"authenticating. Server returned error:"
+ response.getReasonPhrase());
}
/**
* Processes a Request received on a SipProvider upon which this SipListener
* is registered.

@ -7,6 +7,7 @@
package net.java.sip.communicator.impl.protocol.sip.security;
import java.util.*;
import java.util.Map.*;
import javax.sip.header.*;
@ -60,6 +61,33 @@ CredentialsCacheEntry get(String realm)
return this.authenticatedRealms.get(realm);
}
/**
* Returns the list of realms that <tt>branchID</tt> has been used to
* authenticate against.
*
* @param branchID the transaction branchID that we are looking for.
*
* @return the list of realms that <tt>branchID</tt> has been used to
* authenticate against.
*/
List<String> getRealms(String branchID)
{
List<String> realms = new LinkedList<String>();
Iterator<Entry<String, CredentialsCacheEntry>> credentials =
authenticatedRealms.entrySet().iterator();
while ( credentials.hasNext())
{
Entry<String, CredentialsCacheEntry> entry = credentials.next();
if (entry.getValue().containsBranchID(branchID))
realms.add(entry.getKey());
}
return realms;
}
/**
* Returns the credentials corresponding to the specified realm
* or null if none could be found and removes the entry from the cache.
@ -89,7 +117,7 @@ void clear()
* belongs to.
* @param authorization the authorization header that we'd like to cache.
*/
void cacheAuthorizationHeader(String callid,
void cacheAuthorizationHeader(String callid,
AuthorizationHeader authorization)
{
authenticatedCalls.put(callid, authorization);
@ -108,5 +136,4 @@ AuthorizationHeader getCachedAuthorizationHeader(String callid)
{
return this.authenticatedCalls.get(callid);
}
}

@ -25,8 +25,8 @@ class CredentialsCacheEntry
/**
* The transactionHistory list contains transactions where the entry
* has been and that had not yet been responded to (or at least the response
* has not reached this class). The transactionHistory's elements are Strings
* corresponding to branch ids.
* has not reached this class). The transactionHistory's elements are
* <tt>String</tt>s corresponding to branch id-s.
*/
private Vector<String> transactionHistory = new Vector<String>();
@ -35,7 +35,7 @@ class CredentialsCacheEntry
* know that we've seen it and don't try to authenticate with the same
* credentials if we get an unauthorized response for it.
*
* @param requestBranchID the id to add to the list of uncofirmed
* @param requestBranchID the id to add to the list of unconfirmed
* transactions.
*/
void pushBranchID(String requestBranchID)
@ -50,11 +50,25 @@ void pushBranchID(String requestBranchID)
* there is no point in keeping it. We can't get an unauthorized response
* more than once in the same transaction.
*
* @param responseBranchID the branchi id of the response to process.
* @return true if this entry hase been used for the transaction.
* @param responseBranchID the branch id of the response to process.
* @return true if this entry has been used for the transaction.
*/
boolean popBranchID(String responseBranchID)
{
return transactionHistory.remove(responseBranchID);
}
/**
* Determines whether these credentials have been used for the specified
* transaction.
*
* @param branchID the branch id of the transaction that we are looking for.
*
* @return <tt>true</tt> if this entry has been used for the transaction
* and <tt>false</tt> otherwise.
*/
boolean containsBranchID(String branchID)
{
return transactionHistory.contains(branchID);
}
}

@ -6,6 +6,9 @@
*/
package net.java.sip.communicator.impl.protocol.sip.security;
import gov.nist.javax.sip.header.*;
import gov.nist.javax.sip.message.*;
import java.text.*;
import java.util.*;
@ -16,6 +19,7 @@
import net.java.sip.communicator.impl.protocol.sip.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
import net.kano.joscar.snaccmd.ssi.*;
/**
* The class handles authentication challenges, caches user credentials and
@ -97,8 +101,6 @@ public void setHeaderFactory(HeaderFactory headerFactory)
* new transaction
* @throws InvalidArgumentException if we fail to create a new header
* containing user credentials.
* @throws ParseException if we fail to create a new header containing user
* credentials.
* @throws NullPointerException if an argument or a header is null.
* @throws OperationFailedException if we fail to acquire a password from
* our security authority.
@ -109,7 +111,6 @@ public ClientTransaction handleChallenge(
SipProvider transactionCreator)
throws SipException,
InvalidArgumentException,
ParseException,
OperationFailedException,
NullPointerException
{
@ -124,34 +125,24 @@ public ClientTransaction handleChallenge(
ListIterator authHeaders = null;
if (challenge == null || reoriginatedRequest == null)
{
throw new NullPointerException(
"A null argument was passed to handle challenge.");
}
if (challenge.getStatusCode() == Response.UNAUTHORIZED)
{
authHeaders = challenge.getHeaders(WWWAuthenticateHeader.NAME);
// Remove all authorization headers from the request (we'll re-add
// them from cache)
reoriginatedRequest.removeHeader(AuthorizationHeader.NAME);
}
else if (challenge.getStatusCode()
== Response.PROXY_AUTHENTICATION_REQUIRED)
{
authHeaders = challenge.getHeaders(ProxyAuthenticateHeader.NAME);
reoriginatedRequest.removeHeader(ProxyAuthorizationHeader.NAME);
}
if (authHeaders == null)
{
throw new NullPointerException(
"Could not find WWWAuthenticate or ProxyAuthenticate headers");
// Remove all authorization headers from the request (we'll re-add
// them from cache)
reoriginatedRequest.removeHeader(ProxyAuthorizationHeader.NAME);
}
//Remove all authorization headers from the request (we'll re-add them
//from cache)
//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.
@ -216,7 +207,7 @@ else if (challenge.getStatusCode()
{
//this is the transaction that created the cc entry. if we
//need to authenticate the same transaction then the
//credentials we supplied the first time we wrong.
//credentials we supplied the first time were wrong.
//remove password and ask user again.
SipActivator.getProtocolProviderFactory().storePassword(
accountID, null);
@ -317,25 +308,132 @@ public SecurityAuthority getSecurityAuthority()
}
/**
* Makes sure that the password that was used for this forbidden response,
* is removed from the local cache and is not stored for future use.
* Handles a 403 Forbidden response. Contrary to the
* <tt>handleChallenge</tt> method this one would not attach an \
* authentication header to the request since there was no challenge in
* the response.As a result the use of this method would result in sending
* one more request and receiving one more failure response. Not quite
* efficient ... but what do you want ... life is tough.
*
* @param forbidden the 401/407 challenge response
* @param endedTransaction the transaction established by the challenged
* request
* @param transactionCreator the JAIN SipProvider that we should use to
* create the new transaction.
*
* @return the client transaction that can be used to try and reregister.
*
* @throws InvalidArgumentException if we fail to create a new header
* containing user credentials.
* @throws TransactionUnavailableException if we get an exception white
* creating the new transaction
*/
public void handleForbiddenResponse(
public ClientTransaction handleForbiddenResponse(
Response forbidden,
ClientTransaction endedTransaction,
SipProvider transactionCreator)
throws InvalidArgumentException,
TransactionUnavailableException
{
//a request that we previously sent was mal-authenticated. empty the
//credentials cache so that we don't use the same credentials once more.
//now empty the cache because the request we previously sent was
//mal-authenticated.
cachedCredentials.clear();
//also remove the stored password:
SipActivator.getProtocolProviderFactory().storePassword(
accountID, null);
//now recreate a transaction so that we could start all over again.
Request challengedRequest = endedTransaction.getRequest();
Request reoriginatedRequest = (Request) challengedRequest.clone();
//remove the branch id so that we could use the request in a new
//transaction
removeBranchID(reoriginatedRequest);
//extract the realms that we tried to authenticate with the previous
//request and remove the authorization headers.
List<String> realms = removeAuthHeaders(reoriginatedRequest);
//increment cseq (as per 3261)
CSeqHeader cSeq =
(CSeqHeader) reoriginatedRequest.getHeader( (CSeqHeader.NAME));
cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l);
ClientTransaction retryTran =
transactionCreator.getNewClientTransaction(reoriginatedRequest);
//create a credentials entry with an empty password so that we can
//store the transaction and when we get the next challenge notify the
//user that their password was wrong.
Iterator<String> realmsIter = realms.iterator();
while(realmsIter.hasNext())
{
CredentialsCacheEntry ccEntry = createCcEntryWithStoredPassword("");
ccEntry.pushBranchID(retryTran.getBranchId());
cachedCredentials.cacheEntry(realmsIter.next(), ccEntry);
}
logger.debug("Returning authorization transaction.");
return retryTran;
}
/**
* Removes all authorization (and proxy authorization) headers from
* <tt>request</tt> and returns the list of realms that they were about.
*
* @param request the request that we'd like to clear of all authorization
* headers.
* @return the <tt>List</tt> of realms that this request was supposed to
* authenticate against.
*/
private List<String> removeAuthHeaders(Request request)
{
List<String> realms = new LinkedList<String>();
Iterator<SIPHeader> headers = ((SIPRequest)request).getHeaders();
removeAuthHeaders(headers, realms);
request.removeHeader(AuthorizationHeader.NAME);
request.removeHeader(ProxyAuthorizationHeader.NAME);
return realms;
}
/**
* Adds realms from all authorization headers in the <tt>headers</tt> list
* into the realms list (for use from <tt>removeAuthHeaders(Request)</tt>
* only). The method also handles header lists and is recursive.
*
* @param headers the list of headers that we need to analyze.
* @param realms the list that we should fill with the realmswe encounter
* in all kinds of authorization headers.
*/
@SuppressWarnings("unchecked") //no way around it
private void removeAuthHeaders(Iterator<SIPHeader> headers,
List<String> realms)
{
while(headers.hasNext())
{
SIPHeader header = headers.next();
if(header instanceof AuthorizationHeader)
{
realms.add(((AuthorizationHeader)header).getRealm());
}
//expand header lists
else if (header instanceof SIPHeaderList)
{
Iterator<SIPHeader> hdrListIter
= ((SIPHeaderList<SIPHeader>)header).iterator();
removeAuthHeaders(hdrListIter, realms);
}
}
}
/**
* Generates an authorisation header in response to wwwAuthHeader.
@ -458,26 +556,30 @@ public void cacheCredentials(String realm, UserCredentials credentials)
* new one, equal to the one that was top most.
*
* @param request the Request whose branchID we'd like to remove.
*
* @throws ParseException in case the host port or transport in the original
* request were malformed
* @throws InvalidArgumentException if the port in the original via header
* was invalid.
*/
private void removeBranchID(Request request)
throws ParseException, InvalidArgumentException
{
ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
request.removeHeader(ViaHeader.NAME);
ViaHeader newViaHeader = headerFactory.createViaHeader(
viaHeader.getHost()
, viaHeader.getPort()
, viaHeader.getTransport()
, null);
request.setHeader(newViaHeader);
ViaHeader newViaHeader;
try
{
newViaHeader = headerFactory.createViaHeader(
viaHeader.getHost()
, viaHeader.getPort()
, viaHeader.getTransport()
, null);
request.setHeader(newViaHeader);
}
catch (Exception exc)
{
// we are using the host port and transport of an existing Via
// header so it would be quite weird to get this exception.
logger.debug("failed to reset a Via header");
}
}
/**
@ -486,13 +588,14 @@ private void removeBranchID(Request request)
*
* @param realm the realm that we'd like to obtain a
* <tt>CredentialsCacheEntry</tt> for.
* @param reasonCode one of the fields defined in this class that indicate
* the reason for asking the user to enter a password.
*
* @return a newly created <tt>CredentialsCacheEntry</tt> corresponding to
* the specified <tt>realm</tt>.
*/
private CredentialsCacheEntry createCcEntryWithNewCredentials(
String realm,
int reasonCode)
String realm, int reasonCode)
{
CredentialsCacheEntry ccEntry = new CredentialsCacheEntry();
@ -505,11 +608,8 @@ private CredentialsCacheEntry createCcEntryWithNewCredentials(
else
defaultCredentials.setUserName(accountID.getUserID());
UserCredentials newCredentials =
getSecurityAuthority().obtainCredentials(
realm,
defaultCredentials,
reasonCode);
UserCredentials newCredentials = getSecurityAuthority()
.obtainCredentials( realm, defaultCredentials, reasonCode);
// in case user has canceled the login window
if(newCredentials == null)

Loading…
Cancel
Save