Exemple #1
0
  /**
   * Checks for certain params existence in the value, and replace them with real values obtained
   * from <tt>request</tt>.
   *
   * @param value the value of the header param
   * @param request the request we are processing
   * @return the value with replaced params
   */
  private static String processParams(String value, Request request) {
    if (value.indexOf("${from.address}") != -1) {
      FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);

      if (fromHeader != null) {
        value = value.replace("${from.address}", fromHeader.getAddress().getURI().toString());
      }
    }

    if (value.indexOf("${from.userID}") != -1) {
      FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);

      if (fromHeader != null) {
        URI fromURI = fromHeader.getAddress().getURI();
        String fromAddr = fromURI.toString();

        // strips sip: or sips:
        if (fromURI.isSipURI()) {
          fromAddr = fromAddr.replaceFirst(fromURI.getScheme() + ":", "");
        }

        // take the userID part
        int index = fromAddr.indexOf('@');
        if (index > -1) fromAddr = fromAddr.substring(0, index);

        value = value.replace("${from.userID}", fromAddr);
      }
    }

    if (value.indexOf("${to.address}") != -1) {
      ToHeader toHeader = (ToHeader) request.getHeader(ToHeader.NAME);

      if (toHeader != null) {
        value = value.replace("${to.address}", toHeader.getAddress().getURI().toString());
      }
    }

    if (value.indexOf("${to.userID}") != -1) {
      ToHeader toHeader = (ToHeader) request.getHeader(ToHeader.NAME);

      if (toHeader != null) {
        URI toURI = toHeader.getAddress().getURI();
        String toAddr = toURI.toString();

        // strips sip: or sips:
        if (toURI.isSipURI()) {
          toAddr = toAddr.replaceFirst(toURI.getScheme() + ":", "");
        }

        // take the userID part
        int index = toAddr.indexOf('@');
        if (index > -1) toAddr = toAddr.substring(0, index);

        value = value.replace("${to.userID}", toAddr);
      }
    }

    return value;
  }
  /**
   * Check the response and answer true if authentication succeeds. We are making simplifying
   * assumptions here and assuming that the password is available to us for computation of the MD5
   * hash. We also dont cache authentications so that the user has to authenticate on each
   * registration.
   *
   * @param user is the username
   * @param authHeader is the Authroization header from the SIP request.
   * @param requestLine is the SIP Request line from the SIP request.
   * @exception SIPAuthenticationException is thrown when authentication fails or message is bad
   */
  public boolean doAuthenticate(String user, AuthorizationHeader authHeader, Request request) {
    String realm = authHeader.getRealm();
    String username = authHeader.getUsername();
    URI requestURI = request.getRequestURI();

    if (username == null) {
      ProxyDebug.println(
          "DEBUG, DigestAuthenticateMethod, doAuthenticate(): "
              + "WARNING: userName parameter not set in the header received!!!");
      username = user;
    }
    if (realm == null) {
      ProxyDebug.println(
          "DEBUG, DigestAuthenticateMethod, doAuthenticate(): "
              + "WARNING: realm parameter not set in the header received!!! WE use the default one");
      realm = DEFAULT_REALM;
    }

    ProxyDebug.println(
        "DEBUG, DigestAuthenticateMethod, doAuthenticate(): "
            + "Trying to authenticate user: "******" for "
            + " the realm: "
            + realm);

    String password = (String) passwordTable.get(username + "@" + realm);
    if (password == null) {
      ProxyDebug.println(
          "DEBUG, DigestAuthenticateMethod, doAuthenticate(): "
              + "ERROR: password not found for the user: "******"@"
              + realm);
      return false;
    }

    String nonce = authHeader.getNonce();
    // If there is a URI parameter in the Authorization header,
    // then use it.
    URI uri = authHeader.getURI();
    // There must be a URI parameter in the authorization header.
    if (uri == null) {
      ProxyDebug.println(
          "DEBUG, DigestAuthenticateMethod, doAuthenticate(): "
              + "ERROR: uri paramater not set in the header received!");
      return false;
    }

    ProxyDebug.println(
        "DEBUG, DigestAuthenticationMethod, doAuthenticate(), username:"******"!");
    ProxyDebug.println("DEBUG, DigestAuthenticationMethod, doAuthenticate(), realm:" + realm + "!");
    ProxyDebug.println(
        "DEBUG, DigestAuthenticationMethod, doAuthenticate(), password:"******"!");
    ProxyDebug.println("DEBUG, DigestAuthenticationMethod, doAuthenticate(), uri:" + uri + "!");
    ProxyDebug.println("DEBUG, DigestAuthenticationMethod, doAuthenticate(), nonce:" + nonce + "!");
    ProxyDebug.println(
        "DEBUG, DigestAuthenticationMethod, doAuthenticate(), method:" + request.getMethod() + "!");

    String A1 = username + ":" + realm + ":" + password;
    String A2 = request.getMethod().toUpperCase() + ":" + uri.toString();
    byte mdbytes[] = messageDigest.digest(A1.getBytes());
    String HA1 = ProxyUtilities.toHexString(mdbytes);

    ProxyDebug.println("DEBUG, DigestAuthenticationMethod, doAuthenticate(), HA1:" + HA1 + "!");
    mdbytes = messageDigest.digest(A2.getBytes());
    String HA2 = ProxyUtilities.toHexString(mdbytes);
    ProxyDebug.println("DEBUG, DigestAuthenticationMethod, doAuthenticate(), HA2:" + HA2 + "!");
    String cnonce = authHeader.getCNonce();
    String KD = HA1 + ":" + nonce;
    if (cnonce != null) {
      KD += ":" + cnonce;
    }
    KD += ":" + HA2;
    mdbytes = messageDigest.digest(KD.getBytes());
    String mdString = ProxyUtilities.toHexString(mdbytes);
    String response = authHeader.getResponse();
    ProxyDebug.println(
        "DEBUG, DigestAuthenticateMethod, doAuthenticate(): "
            + "we have to compare his response: "
            + response
            + " with our computed"
            + " response: "
            + mdString);

    int res = (mdString.compareTo(response));
    if (res == 0) {
      ProxyDebug.println(
          "DEBUG, DigestAuthenticateMethod, doAuthenticate(): " + "User authenticated...");
    } else {
      ProxyDebug.println(
          "DEBUG, DigestAuthenticateMethod, doAuthenticate(): " + "User not authenticated...");
    }

    return res == 0;
  }
  /**
   * Find the <tt>ProtocolProviderServiceSipImpl</tt> (one of our "candidate recipient" listeners)
   * which this <tt>request</tt> should be dispatched to. The strategy is to look first at the
   * request URI, and then at the To field to find a matching candidate for dispatching. Note that
   * this method takes a <tt>Request</tt> as param, and not a <tt>ServerTransaction</tt>, because
   * sometimes <tt>RequestEvent</tt>s have no associated <tt>ServerTransaction</tt>.
   *
   * @param request the <tt>Request</tt> to find a recipient for.
   * @return a suitable <tt>ProtocolProviderServiceSipImpl</tt>.
   */
  private ProtocolProviderServiceSipImpl findTargetFor(Request request) {
    if (request == null) {
      logger.error("request shouldn't be null.");
      return null;
    }

    List<ProtocolProviderServiceSipImpl> currentListenersCopy =
        new ArrayList<ProtocolProviderServiceSipImpl>(this.getSipListeners());

    // Let's first narrow down candidate choice by comparing
    // addresses and ports (no point in delivering to a provider with a
    // non matching IP address  since they will reject it anyway).
    filterByAddress(currentListenersCopy, request);

    if (currentListenersCopy.size() == 0) {
      logger.error("no listeners");
      return null;
    }

    URI requestURI = request.getRequestURI();

    if (requestURI.isSipURI()) {
      String requestUser = ((SipURI) requestURI).getUser();

      List<ProtocolProviderServiceSipImpl> candidates =
          new ArrayList<ProtocolProviderServiceSipImpl>();

      // check if the Request-URI username is
      // one of ours usernames
      for (ProtocolProviderServiceSipImpl listener : currentListenersCopy) {
        String ourUserID = listener.getAccountID().getUserID();
        // logger.trace(ourUserID + " *** " + requestUser);
        if (ourUserID.equals(requestUser)) {
          if (logger.isTraceEnabled())
            logger.trace("suitable candidate found: " + listener.getAccountID());
          candidates.add(listener);
        }
      }

      // the perfect match
      // every other case is approximation
      if (candidates.size() == 1) {
        ProtocolProviderServiceSipImpl perfectMatch = candidates.get(0);

        if (logger.isTraceEnabled())
          logger.trace("Will dispatch to \"" + perfectMatch.getAccountID() + "\"");
        return perfectMatch;
      }

      // more than one account match
      if (candidates.size() > 1) {
        // check if a custom param exists in the contact
        // address (set for registrar accounts)
        for (ProtocolProviderServiceSipImpl candidate : candidates) {
          String hostValue =
              ((SipURI) requestURI).getParameter(SipStackSharing.CONTACT_ADDRESS_CUSTOM_PARAM_NAME);
          if (hostValue == null) continue;
          if (hostValue.equals(candidate.getContactAddressCustomParamValue())) {
            if (logger.isTraceEnabled())
              logger.trace(
                  "Will dispatch to \""
                      + candidate.getAccountID()
                      + "\" because "
                      + "\" the custom param was set");
            return candidate;
          }
        }

        // Past this point, our guess is not reliable. We try to find
        // the "least worst" match based on parameters like the To field

        // check if the To header field host part
        // matches any of our SIP hosts
        for (ProtocolProviderServiceSipImpl candidate : candidates) {
          URI fromURI = ((FromHeader) request.getHeader(FromHeader.NAME)).getAddress().getURI();
          if (fromURI.isSipURI() == false) continue;
          SipURI ourURI = (SipURI) candidate.getOurSipAddress((SipURI) fromURI).getURI();
          String ourHost = ourURI.getHost();

          URI toURI = ((ToHeader) request.getHeader(ToHeader.NAME)).getAddress().getURI();
          if (toURI.isSipURI() == false) continue;
          String toHost = ((SipURI) toURI).getHost();

          // logger.trace(toHost + "***" + ourHost);
          if (toHost.equals(ourHost)) {
            if (logger.isTraceEnabled())
              logger.trace(
                  "Will dispatch to \""
                      + candidate.getAccountID()
                      + "\" because "
                      + "host in the To: is the same as in our AOR");
            return candidate;
          }
        }

        // fallback on the first candidate
        ProtocolProviderServiceSipImpl target = candidates.iterator().next();
        logger.info(
            "Will randomly dispatch to \""
                + target.getAccountID()
                + "\" because there is ambiguity on the username from"
                + " the Request-URI");
        if (logger.isTraceEnabled()) logger.trace("\n" + request);
        return target;
      }

      // fallback on any account
      ProtocolProviderServiceSipImpl target = currentListenersCopy.iterator().next();
      if (logger.isDebugEnabled())
        logger.debug(
            "Will randomly dispatch to \""
                + target.getAccountID()
                + "\" because the username in the Request-URI "
                + "is unknown or empty");
      if (logger.isTraceEnabled()) logger.trace("\n" + request);
      return target;
    } else {
      logger.error("Request-URI is not a SIP URI, dropping");
    }
    return null;
  }