From 89a3172d1bb50117417023fad4803f4e707aa88f Mon Sep 17 00:00:00 2001 From: Yana Stamcheva Date: Tue, 8 Jun 2010 19:23:29 +0000 Subject: [PATCH] Fix incorrect sequence number in dialog during file transfer. --- .../sip/security/SipSecurityManager.java | 71 ++++++++++++++----- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/src/net/java/sip/communicator/impl/protocol/sip/security/SipSecurityManager.java b/src/net/java/sip/communicator/impl/protocol/sip/security/SipSecurityManager.java index ae8364dda..7b145a6ba 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/security/SipSecurityManager.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/security/SipSecurityManager.java @@ -121,12 +121,26 @@ public ClientTransaction handleChallenge( Request reoriginatedRequest = cloneReqForAuthentication( challengedRequest, challenge); + //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 + incrementRequestSeqNo(reoriginatedRequest); + ListIterator authHeaders = extractChallenges(challenge); ClientTransaction retryTran = transactionCreator.getNewClientTransaction(reoriginatedRequest); + // We have previously incremented the request sequence number and we + // want to make sure that the dialog (if it exists) has its local + // sequence number also incremented. + Dialog tranDialog = retryTran.getDialog(); + if (tranDialog != null && tranDialog.getLocalSeqNumber() + != getRequestSeqNo(reoriginatedRequest)) + tranDialog.incrementLocalSequenceNumber(); + //obtain authentication credentials for all authentication challenges. while (authHeaders.hasNext()) { @@ -326,14 +340,23 @@ public ClientTransaction handleForbiddenResponse( //request and remove the authorization headers. List realms = removeAuthHeaders(reoriginatedRequest); - //increment cseq (as per 3261) - CSeqHeader cSeq = - (CSeqHeader) reoriginatedRequest.getHeader( (CSeqHeader.NAME)); - cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l); + //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 + incrementRequestSeqNo(reoriginatedRequest); ClientTransaction retryTran = transactionCreator.getNewClientTransaction(reoriginatedRequest); + // We have previously incremented the request sequence number and we + // want to make sure that the dialog (if it exists) has its local + // sequence number also incremented. + Dialog tranDialog = retryTran.getDialog(); + if (tranDialog != null && tranDialog.getLocalSeqNumber() + != getRequestSeqNo(reoriginatedRequest)) + tranDialog.incrementLocalSequenceNumber(); + //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. @@ -414,13 +437,9 @@ else if (header instanceof SIPHeaderList) * * @return the list of authentication challenge headers that we'd need to * reply to. - * - * @throws InvalidArgumentException if we fail to increase the value of the - * cseq header. */ private Request cloneReqForAuthentication( Request challengedRequest, Response challenge) - throws InvalidArgumentException { Request reoriginatedRequest = (Request) challengedRequest.clone(); @@ -440,14 +459,6 @@ else if (challenge.getStatusCode() 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); - cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l); - return reoriginatedRequest; } @@ -718,4 +729,32 @@ public AuthorizationHeader getCachedAuthorizationHeader(String callID) { return this.cachedCredentials.getCachedAuthorizationHeader(callID); } + + /** + * Increments the given request sequence number. + * @param request the Request, which sequence number we would like + * to increment + * + * @throws InvalidArgumentException if we fail to increase the value of the + * cSeq header. + */ + private void incrementRequestSeqNo(Request request) + throws InvalidArgumentException + { + CSeqHeader cSeq = (CSeqHeader) request.getHeader(CSeqHeader.NAME); + + cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l); + } + + /** + * Returns the request sequence number. + * @param request the Request, for which we're returning a sequence + * number + * @return the sequence number of the given request + */ + private long getRequestSeqNo(Request request) + { + CSeqHeader cSeq = (CSeqHeader) request.getHeader(CSeqHeader.NAME); + return cSeq.getSeqNumber(); + } }