1

I want to constract a telephone-caller inside my java application. For this pupose I used a JAIN-SIP library. After the first INVITE the system needs Proxy-Authentication. The second invite is conscructed with the help of "AuthenticationHelperImpl.class":https://gitorious.org/0xdroid/external_nist-sip/source/1e0f37693341071f316852c8e05a08deef2b7fc4:java/gov/nist/javax/sip/clientauthutils/AuthenticationHelperImpl.java#L311, includes Proxy-Authentication header and lloks like:

INVITE sip:+11111111111@fpbx.de;maddr=fpbx.de SIP/2.0
Call-ID: 1c609509a43b721ab11c396c1e6ea9e7@192.168.17.107
CSeq: 2 INVITE
From: "77735hk6iu" <sip:77735hk6iu@fpbx.de>
To: "+111111111111111" <sip:+11111111111@fpbx.de>
Via: SIP/2.0/UDP 192.168.17.107:34567;rport;branch=z9hG4bK-383337-5bc4fd6b7a616843fce9eaa243bcb10e
Max-Forwards: 70
Contact: <sip:77735hk6iu@192.168.17.107:5060>
Content-Type: application/sdp
Proxy-Authorization: Digest       username="77735hk6iu",realm="fpbx.de",nonce="VLaIxVS2h5muPS30F2zLdXHjup6ELyen",uri="sip:+111111111111@fpbx.de:5060;maddr=fpbx.de",response="47ea578c6b01c99fd3ed2b41c60983df"
Content-Length: 61

v=0
o=- 130565705777141827 1 IN IP4 192.168.17.107
s=call

After that I receive at the beginning code 100 message ("your call is very important for us") followed with 408 code message ("Request Timeout").

What I did to imporve the situation:

  1. tried different phone number formats: 004930208488480, 04930208488480, 049, 0049, sdfhajfkhsk. For all these numbers I become the same combination on messages.

  2. tried to use port in request uri

  3. tried to remove maddr from request uri.

  4. tried to fullfill the message body with codek settings.

  5. to set and remove rport from via header

If you now what I'm doing wrong, please, help me. Thank you in advance.

4

3 回答 3

2

我想,也许你的 Proxy-Authorization 标头是错误的。可能你算错了。我想分享我的决心。

authUser 是您的电话号码。(例如: 77735hk6iu ) authPass 是您的用户密码。msg 是您的邀请请求。(标题!)

AccountManagerImpl accountManagerImp = new AccountManagerImpl(authUser, AuthPass);
        AuthenticationHelperImpl authenticationHelperImpl = new AuthenticationHelperImpl(accountManagerImp);

        try {
           this.authentication = authenticationHelperImpl.handleChallenge(msg, (SIPClientTransaction)trans);

AuthenticationHelperImple.java 类:

   public AuthorizationHeader handleChallenge(Response challenge, ClientTransaction challengedTransaction) throws SipException {


  SIPRequest challengedRequest = ((SIPRequest) challengedTransaction.getRequest());

  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");
  }

  WWWAuthenticateHeader authHeader = null;
  while (authHeaders.hasNext()) {
     authHeader = (WWWAuthenticateHeader) authHeaders.next();
     String realm = authHeader.getRealm();

     this.uri = challengedRequest.getRequestURI();

     this.requestMethod = challengedRequest.getMethod();
     this.requestBody = (challengedRequest.getContent() == null) ? "" : new String(challengedRequest.getRawContent());

     if (this.accountManager instanceof SecureAccountManager) {
        UserCredentialHash credHash = ((SecureAccountManager) this.accountManager).getCredentialHash(challengedTransaction,
                                                                                                     realm);
        if (credHash == null) {
           logger.logDebug("Could not find creds");
           throw new SipException("Cannot find user creds for the given user name and realm");
        }

        this.authorizationHeader = this.getAuthorization(requestMethod, uri.toString(), requestBody, 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.

       this.authorizationHeader = this.getAuthorization(requestMethod, uri.toString(), requestBody, authHeader, userCreds);
     }
  }

  return this.authorizationHeader;

}

获取授权功能:

 public AuthorizationHeader getAuthorization(String method,
                                           String uri,
                                           String requestBody,
                                           WWWAuthenticateHeader authHeader,
                                           UserCredentials userCredentials) throws SecurityException {
  String response = null;
  String qopList = authHeader.getQop();
  String qop = (qopList != null) ? "auth" : null;
  String nc_value = "00000001";
  String cnonce = "xyz";

  try {
     response = MessageDigestAlgorithm.calculateResponse(authHeader.getAlgorithm(),
                                                        userCredentials.getUserName(), authHeader.getRealm(),userCredentials.getPassword(), authHeader.getNonce(), nc_value, // JvB added
                                                 cnonce, // JvB added
                                                 method, uri, requestBody, qop,logger);
  }
  catch (NullPointerException exc) {
     throw new SecurityException("The received authenticate header was malformatted: " + exc.getMessage());
  }

  AuthorizationHeader authorization = null;
  try {
      if (authHeader instanceof ProxyAuthenticateHeader) {
         if (this.headerFactory != null) {
            authorization = headerFactory.createProxyAuthorizationHeader(authHeader.getScheme());
         }
         else {
            authorization = new ProxyAuthorization();
            authorization.setScheme(authHeader.getScheme()); 
         }
      } 
      else {
         if (this.headerFactory != null) {
            authorization = headerFactory.createAuthorizationHeader(authHeader.getScheme());
         }
         else {
            authorization = new Authorization();
            authorization.setScheme(authHeader.getScheme());
         }
      }

      authorization.setUsername(userCredentials.getUserName());
      authorization.setRealm(authHeader.getRealm());
      authorization.setNonce(authHeader.getNonce());
      authorization.setParameter("uri", uri);
      authorization.setResponse(response);
      if (authHeader.getAlgorithm() != null) {
          authorization.setAlgorithm(authHeader.getAlgorithm());
      }

      if (authHeader.getOpaque() != null) {
          authorization.setOpaque(authHeader.getOpaque());
      }

      // jvb added
      if (qop != null) {
          authorization.setQop(qop);
          authorization.setCNonce(cnonce);
          authorization.setNonceCount(Integer.parseInt(nc_value));
      }

      authorization.setResponse(response);

  } catch (ParseException ex) {
      throw new RuntimeException("Failed to create an authorization header!");
  }

  return authorization;

}

最后,您的 this.authentication 变量是 ProxyAuthorizationHeader。您必须将 this.authentication 放入您的 INVITE 消息中。并且您将从事务或对话发送 SipMessage 到 JAIN-SIP 堆栈。

祝你好运 !

于 2015-01-15T13:37:02.777 回答
0

当从请求 URI 和代理身份验证中删除“maddr=fpbx.de”时,问题部分解决了。乌里

fpr 这是一个使用过的带有布尔参数的 handleCahllenge 方法:

inviteTid = authenticationHelper.handleChallenge(response, tid, sipProvider, 15, **true**);

但我仍然不知道如何获得自发电话号码。

于 2015-01-15T15:38:59.427 回答
0

100消息是逐跳的,也就是说它只是意味着下一跳得到了你的请求。其他消息通常是端到端的(因此,如果您收到 180 Ringing,这通常意味着被调用的端点发送了 180)。当其中一个跃点发送 INVITE 但从未得到响应时,通常会显示 408(并且您的 SIP 堆栈可能会在内部生成它,因为它在合理的时间范围内没有得到临时响应 - 通常约为 32 秒,默认值SIP 定时器)。

我不知道您的网络设置,但该消息中有几个私有 IP(属于 192.168.xx 种类)。如果我不得不猜测,您的第一个跃点是将 100 发送回它接收它的 IP/端口,但下一个响应是遵循 Via 标头(应该如此),并且在您不尊重 rport 之后的跃点参数,所以响应会丢失。或者,您的 NAT 配置不当,并且过快地关闭了它为 INVITE 创建的漏洞。

如果您的网络边缘有一个代理发送此消息,则它要么在消息上放置了错误的 Via 标头(可能使用内部 IP 而不是外部 IP),要么将 INVITE 发送到错误的地方(导致它永远不会得到响应),并且 408 来自它。

于 2015-02-01T05:10:23.383 回答