public Request processAuthChallenge(Response response, Request req_msg, String username,
      String password) {
    initErrorInfo();

    ListIterator<?> challenges = null;
    if (response.getStatusCode() == Response.UNAUTHORIZED) {
      challenges = response.getHeaders(WWWAuthenticateHeader.NAME);
    } else if (response.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED) {
      challenges = response.getHeaders(ProxyAuthenticateHeader.NAME);
    }

    if (challenges == null) {
      setReturnCode(ERROR_OF_UNKNOWN_ORIGIN);
      setErrorMessage(
          "Improper use of processAuthChallenge() or response auth challenge header is missing");
      return null;
    }

    // find the list of cached AuthorizationHeaders for this call (Call-ID)
    String call_id = ((CallIdHeader) req_msg.getHeader(CallIdHeader.NAME)).getCallId();
    Map<String, AuthorizationHeader> authorization_list =
        getAuthorizations().get(call_id);

    if (authorization_list == null) {
      // it should have been created already when sent or received 1st
      // request for the
      // call ID
      setReturnCode(ERROR_OF_UNKNOWN_ORIGIN);
      setErrorMessage(
          "Invalid Call-ID header in request or the call's authorization list wasn't created");
      return null;
    }

    Request msg;
    try {
      msg = (Request) req_msg.clone();
      msg.setMethod(req_msg.getMethod());
    } catch (Exception ex) {
      setReturnCode(EXCEPTION_ENCOUNTERED);
      setErrorMessage(
          "Exception while cloning request: " + ex.getClass().getName() + ": " + ex.getMessage());
      setException(ex);
      return null;
    }

    int content_length = 0;
    if (req_msg.getContentLength() != null) {
      content_length = req_msg.getContentLength().getContentLength();
    }
    String req_body = null;
    if (content_length > 0) {
      req_body = new String(req_msg.getRawContent());
    }

    // loop through the challenges received and create an
    // authorization for each one
    while (challenges.hasNext()) {
      WWWAuthenticateHeader authenticate_header = (WWWAuthenticateHeader) challenges.next();

      String realm = authenticate_header.getRealm();
      String uname = username;
      String passwd = password;

      // check credentials list for this realm entry
      Credential credential = (Credential) credentials.get(realm);

      if (credential != null) {
        uname = credential.getUser();
        passwd = credential.getPassword();
      } else if (uname == null) {
        setReturnCode(MISSING_CREDENTIAL);
        setErrorMessage("Could not find credentials for realm: " + realm);
        return null;
      }

      try {
        AuthorizationHeader authorization = getAuthorization(msg.getMethod(),
            msg.getRequestURI().toString(), req_body, authenticate_header, uname, passwd);

        // what was wrong with req_body = msg.getContent() == null ? ""
        // : msg.getContent()
        // .toString() ?

        // save the auth header for use later, overwriting old one if
        // there

        if (credential != null) {
          authorization_list.put(realm, authorization);
        }

        // Add/replace this authorization header in the message

        // should we be replacing? or just add to it. Looks like you can
        // have lots
        // of auth headers for a given realm and call-ID. TODO - confirm
        // and change
        // authorizations to hold more than one auth header per realm
        // per call-ID

        msg.setHeader(authorization);

        /*
         * here's replace code
         *
         * ListIterator msg_headers; if (authorization instanceof ProxyAuthorizationHeader) {
         * msg_headers = msg.getHeaders(ProxyAuthorizationHeader.NAME); } else { msg_headers =
         * msg.getHeaders(AuthorizationHeader.NAME); }
         *
         * boolean replaced = false;
         *
         *
         * while (msg_headers.hasNext()) { AuthorizationHeader msg_hdr = (AuthorizationHeader)
         * msg_headers .next(); if (msg_hdr.getRealm().equals(realm)) {
         * msg_headers.set(authorization); replaced = true; break; } }
         *
         *
         * if (replaced == false) { msg.addHeader(authorization); // how to bubble auth up - //
         * check 1.2 API }
         */
      } catch (Exception ex) {
        setReturnCode(EXCEPTION_ENCOUNTERED);
        setErrorMessage("Exception while creating AuthorizationHeader(s): "
            + ex.getClass().getName() + ": " + ex.getMessage());
        setException(ex);
        return null;
      }
    }

    // do we need to compare new reqmsg auth headers to old reqmsg auth
    // headers - if
    // same, return null

    return msg;

  }
public Request processAuthChallenge ( Response response , Request req_msg , String username , String password ) { initErrorInfo ( ) ; ListIterator < ? > challenges = null ; if ( response . getStatusCode ( ) == Response . UNAUTHORIZED ) { challenges = response . getHeaders ( WWWAuthenticateHeader . NAME ) ; } else if ( response . getStatusCode ( ) == Response . PROXY_AUTHENTICATION_REQUIRED ) { challenges = response . getHeaders ( ProxyAuthenticateHeader . NAME ) ; } if ( challenges == null ) { setReturnCode ( ERROR_OF_UNKNOWN_ORIGIN ) ; setErrorMessage ( "Improper use of processAuthChallenge() or response auth challenge header is missing" ) ; return null ; } String call_id = ( ( CallIdHeader ) req_msg . getHeader ( CallIdHeader . NAME ) ) . getCallId ( ) ; Map < String , AuthorizationHeader > authorization_list = getAuthorizations ( ) . get ( call_id ) ; if ( authorization_list == null ) { setReturnCode ( ERROR_OF_UNKNOWN_ORIGIN ) ; setErrorMessage ( "Invalid Call-ID header in request or the call's authorization list wasn't created" ) ; return null ; } Request msg ; try { msg = ( Request ) req_msg . clone ( ) ; msg . setMethod ( req_msg . getMethod ( ) ) ; } catch ( Exception ex ) { setReturnCode ( EXCEPTION_ENCOUNTERED ) ; setErrorMessage ( "Exception while cloning request: " + ex . getClass ( ) . getName ( ) + ": " + ex . getMessage ( ) ) ; setException ( ex ) ; return null ; } int content_length = 0 ; if ( req_msg . getContentLength ( ) != null ) { content_length = req_msg . getContentLength ( ) . getContentLength ( ) ; } String req_body = null ; if ( content_length > 0 ) { req_body = new String ( req_msg . getRawContent ( ) ) ; } while ( challenges . hasNext ( ) ) { WWWAuthenticateHeader authenticate_header = ( WWWAuthenticateHeader ) challenges . next ( ) ; String realm = authenticate_header . getRealm ( ) ; String uname = username ; String passwd = password ; Credential credential = ( Credential ) credentials . get ( realm ) ; if ( credential != null ) { uname = credential . getUser ( ) ; passwd = credential . getPassword ( ) ; } else if ( uname == null ) { setReturnCode ( MISSING_CREDENTIAL ) ; setErrorMessage ( "Could not find credentials for realm: " + realm ) ; return null ; } try { AuthorizationHeader authorization = getAuthorization ( msg . getMethod ( ) , msg . getRequestURI ( ) . toString ( ) , req_body , authenticate_header , uname , passwd ) ; if ( credential != null ) { authorization_list . put ( realm , authorization ) ; } msg . setHeader ( authorization ) ; } catch ( Exception ex ) { setReturnCode ( EXCEPTION_ENCOUNTERED ) ; setErrorMessage ( "Exception while creating AuthorizationHeader(s): " + ex . getClass ( ) . getName ( ) + ": " + ex . getMessage ( ) ) ; setException ( ex ) ; return null ; } } return msg ; }
This method is public for test purposes and for use when using low level SipSession methods for
sending/receiving messages. A test program using high level SipUnit doesn't need to call this
method.

<p>
This method modifies the given request to include the authorization header(s) required by the
given response. It may cache in SipPhone's authorizations list the AuthorizationHeader(s)
created here for use later. The modified Request object is returned, or null in case of error
or unresolved challenge.

<p>
For each received challenge present in the response message: SipPhone's credentials list is
checked first, for the realm entry. If it is not found there, the username parameter passed
into this method is checked. If null, this method returns null. If not null, the passed in
username and password values are used to respond to the received challenge. In this case an
entry is NOT added to the credentials list associating these values with the challenging realm
and the authorization created here is NOT saved for later re-use. If the credentials list
contains an entry for the challenging realm, then the authorization created here is saved in
the authorizations list for later re-use.

@param response the challenge that was received
@param req_msg the request originally sent (that was challenged)
@param username see above
@param password see above
@return the original request with the authorization header(s) added, or null if username and
password weren't passed in and the SipPhone's credentials list doesn't have an entry
for the realm.