耆那教 SIP 未经授权的响应



我正在日食环境中使用JAIN SIP库开发SIP客户端。

我在获得授权时遇到问题。我还实施了 MD5 挑战,并将授权添加到第二个注册功能中。

授权凭据也是正确的,因为我使用可用的 SIP 应用程序检查了它们。我能够注册并用它拨打电话。

这是初始化和注册的代码

String username = "username";
String server = "10.99.00.00";
String password = "password";
String realm = null ;
private String nonce = null;
// Objects used to communicate to the JAIN SIP API.
SipFactory sipFactory;          // Used to access the SIP API.
SipStack sipStack;              // The SIP stack.
SipProvider sipProvider;        // Used to send SIP messages.
MessageFactory messageFactory;  // Used to create SIP message factory.
HeaderFactory headerFactory;    // Used to create SIP headers.
AddressFactory addressFactory;  // Used to create SIP URIs.
ListeningPoint listeningPoint;  // SIP listening IP address/port.
Properties properties;          // Other properties.
ClientTransaction inviteTid;
Request request;
Response response;
// Objects keeping local configuration.
String proxy = null;
String sipIP="10.99.00.00"; 
String localIP= null;
// The local IP address.
int sipport = 5060;                // The local port.
int rport = 52216;
String protocol = "UDP";        // The local protocol (UDP).
int tag = (new Random()).nextInt(); // The local tag.
Address contactAddress;         // The contact address.
ContactHeader contactHeader;    // The contact header.
private Dialog dialog;
private Logger logger;
private String current_process;
public test() throws NoSuchAlgorithmException, ParseException{
    init();
    Response response = null;
    register(response);
}
public void init() {
    try {
    // Get the local IP address.
    localIP = InetAddress.getLocalHost().getHostAddress();
    // Create the SIP factory and set the path name.
    sipFactory = SipFactory.getInstance();
    sipFactory.setPathName("gov.nist");
    // Create and set the SIP stack properties.
    properties = new Properties();
    properties.setProperty("javax.sip.STACK_NAME", "stack");
    properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
    if(proxy != null) {
    properties.setProperty("javax.sip.OUTBOUND_PROXY", sipIP + ':' + sipport + '/' + protocol);
    }
    properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
    properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",  "mss-jsip-debuglog.txt");
    properties.setProperty("gov.nist.javax.sip.SERVER_LOG","mss-jsip-messages.xml");
    // Create the SIP stack.
    sipStack = sipFactory.createSipStack(this.properties);
    // Create the SIP message factory.
    messageFactory = sipFactory.createMessageFactory();
    // Create the SIP header factory.
    headerFactory = sipFactory.createHeaderFactory();
    // Create the SIP address factory.
    addressFactory = sipFactory.createAddressFactory();
    // Create the SIP listening point and bind it to the local IP
    // address, port and protocol.
    listeningPoint = sipStack.createListeningPoint(localIP, rport, protocol);
    // Create the SIP provider.
    sipProvider = sipStack.createSipProvider(listeningPoint);
    // Add our application as a SIP listener.
    sipProvider.addSipListener(this);

    // Display the local IP address and port in the text area.
    } catch (Exception e) {
    e.printStackTrace();
    // If an error occurs, display an error message box and exit.
    System.exit(-1);
    }
    }
    int cseq;
public void register(Response response) {
    try {
    cseq++;
    current_process = cseq + "REGISTER";
    ArrayList viaHeaders = new ArrayList();
    ViaHeader viaHeader = headerFactory.createViaHeader(localIP,
    rport, "udp", null);
    viaHeader.setRPort();
    viaHeaders.add(viaHeader);
    // The "Max-Forwards" header.
    MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);
    // The "Call-Id" header.
    CallIdHeader callIdHeader = sipProvider.getNewCallId();
    // The "CSeq" header.
    @SuppressWarnings("deprecation")
    CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L,Request.REGISTER);
    Address fromAddress = addressFactory.createAddress("sip:"
    + "username" + '@' + server);
    FromHeader fromHeader = headerFactory.createFromHeader(
    fromAddress, String.valueOf(this.tag));
    // The "To" header.
    ToHeader toHeader = headerFactory.createToHeader(fromAddress , null);
    // Create the contact address used for all SIP messages.
    contactAddress = addressFactory.createAddress("sip:" + username + "@"+ localIP +":"+rport+ ";"+ "transport=UDP");
    // Create the contact header used for all SIP messages.
    contactHeader = headerFactory.createContactHeader(contactAddress);
    URI requestURI = addressFactory.createURI("sip:" + server);
    request = messageFactory.createRequest(requestURI, Request.REGISTER,callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwardsHeader);
    request.addHeader(contactHeader);

//      System.out.println(request.toString());
    if (response != null) {
    AuthorizationHeader authHeader = makeAuthHeader(headerFactory, response, request, username, password);
    request.addHeader(authHeader);
    }
    inviteTid = sipProvider.getNewClientTransaction(request);
    // send the request out.
    inviteTid.sendRequest();
//      dialog = inviteTid.getDialog();
    System.out.println(request.toString());
    // Send the request statelessly through the SIP provider.
//          this.sipProvider.sendRequest(request);
    // Display the message in the text area.
//      logger.debug("Request sent:n" + request.toString() + "nn");
    } catch (Exception e) {
    // If an error occurred, display the error.
    e.printStackTrace();
//      logger.debug("Request sent failed: " + e.getMessage() + "n");
    }
    }
private AuthorizationHeader makeAuthHeader(HeaderFactory headerFactory2,  Response response, Request request, String username2,
        String password2) throws ParseException {
    // TODO Auto-generated method stub
    // Authenticate header with challenge we need to reply to
    WWWAuthenticateHeader ah_c =  (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
    // Authorization header we will build with response to challenge
    AuthorizationHeader ah_r =    headerFactory.createAuthorizationHeader(ah_c.getScheme());
    // assemble data we need to create response string
    URI request_uri = request.getRequestURI();
    String request_method = request.getMethod();
    String nonce  = ah_c.getNonce();
    String algrm  = ah_c.getAlgorithm();
    String realm  = ah_c.getRealm();
    MessageDigest mdigest;
    try {
        mdigest = MessageDigest.getInstance(algrm);
         // A1
        String A1 = username + ":" + realm + ":" + password;
        String HA1 = toHexString(mdigest.digest(A1.getBytes()));
        // A2
        String A2 = request_method.toUpperCase() + ":" + request_uri ;
        String HA2 = toHexString(mdigest.digest(A2.getBytes()));
        // KD
        String KD = HA1 + ":" + nonce + ":" + HA2;
        String responsenew = toHexString(mdigest.digest(KD.getBytes()));
        ah_r.setUsername(username);
        ah_r.setRealm(realm);
        ah_r.setNonce(nonce);
        ah_r.setURI(request_uri);
        ah_r.setAlgorithm(algrm);
        ah_r.setResponse(responsenew);

    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return ah_r;
}

这是我发送的请求和收到的响应。

REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bK-   363430-38c329167b2d9108d20c996fec776b29
Max-Forwards: 70
To: <sip:tusername7@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=421569181
Call-ID: 37cd8463e628a6960f62267027cf0720@10.99.00.00
CSeq: 1 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>
Content-Length: 0
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bK- 363430-38c329167b2d9108d20c996fec776b29;received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=421569181
To: <sip:username@10.99.00.00>;tag=as64c39fdc
Call-ID: 37cd8463e628a6960f62267027cf0720@10.99.00.00
CSeq: 1 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="13250a39"
Content-Length: 0

REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bK-  363430-19fd7f5d12dc78762617b26d61129919
Max-Forwards: 70
To: <sip:username@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=421569181
Call-ID: 68bd42d26ac8f9f90729927434eb5ad3@10.99.70.106
CSeq: 2 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>
Authorization: Digest   username="username",realm="xyz.com",nonce="13250a39",uri="sip:10.99.00.00",algorithm=MD5,response="f525cda4442d7388e6ea4a737e46b639"
Content-Length: 0

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bK-     363430-19fd7f5d12dc78762617b26d61129919;received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=421569181
To: <sip:username@10.99.00.00>;tag=as3b3b0796
Call-ID: 68bd42d26ac8f9f90729927434eb5ad3@10.99.00.00
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="22cbe904"
Content-Length: 0

当我使用具有相同凭据的 SIP 应用程序时,我收到了此请求和响应

2015-04-22 11:55:42,794 SENT to 10.99.00.00/5060 [AWT-EventQueue-0]
REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bKcABnbdE6G
Max-Forwards: 70
To: <sip:username@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 1 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>

2015-04-22 11:55:42,795 RECEIVED from 10.99.00.00/5060 [TransportManager 0]
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bKcABnbdE6G;    received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
To: <sip:username@10.99.00.00>;tag=as7c9471aa
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 1 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
Supported: replaces, timer
WWW-Authenticate: Digest algorithm=MD5, realm="xyz.com",     nonce="7d0754cc"
Content-Length: 0

2015-04-22 11:55:43,637 SENT to 10.99.00.00/5060 [TransportManager 0]
REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bK3Oe6XIIh8
Max-Forwards: 70
To: <sip:username@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 2 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>
Authorization: Digest username="username", realm="xyz.com", nonce="7d0754cc", uri="sip:10.99.00.00", response="4150b8392729806ff601eb6d67da7c19"

2015-04-22 11:55:43,638 RECEIVED from 10.99.00.00/5060 [TransportManager 0]
OPTIONS sip:username@10.99.00.00:52016;transport=UDP SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:5060;branch=z9hG4bK21f59b09
Max-Forwards: 70
From: "asterisk" <sip:asterisk@10.99.00.00>;tag=as2093e268
To: <sip:username@10.99.00.00:52016;transport=UDP>
Contact: <sip:asterisk@10.99.00.00:5060>
Call-ID: 77805e3c524799632da223b942a4e8f1@10.99.00.00:5060
CSeq: 102 OPTIONS
User-Agent: Asterisk PBX 10.5.1
Date: Wed, 22 Apr 2015 09:55:43 GMT
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
Supported: replaces, timer
Content-Length: 0

2015-04-22 11:55:43,660 RECEIVED from 10.99.00.00/5060 [TransportManager 0]
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bK3Oe6XIIh8;received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
To: <sip:username@10.99.00.00>;tag=as7c9471aa
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
Supported: replaces, timer
Expires: 240
Contact: <sip:username@10.99.00.00:52016;transport=UDP>;expires=240
Date: Wed, 22 Apr 2015 09:55:43 GMT
Content-Length: 0

我比较了两个数据包,没有发现任何差异。我不明白为什么我没有授权。在这种情况下,本地IP和SIPIP也是不同的。

我认为问题可能出在端口上,但我在网上没有找到任何用于分配 rport 和 sipport 的帮助:5060。我还想获得更多关于它的信息。

两个寄存器 CSeq 1 和 CSeq 2 上的调用 ID 应该相同。在您的情况下,它们是不同的。

最新更新