无法从 Asterisk 服务器获取 200 OK

问题描述 投票:0回答:1

我正在 Eclipse 中开发 SIP 客户端应用程序。我正在尝试注册到 Asterisk Server,但每次我都会收到 401 Unauthorized。在收到第一条 401 消息后,我还添加了授权标头。

REGISTER sip:xx.xx.xx.xx SIP/2.0
Call-ID: [email protected]
CSeq: 1 REGISTER
From: <sip:[email protected]>;tag=textclientv1.0
To: <sip:[email protected]>
Via: SIP/2.0/UDP 192.168.0.6:5060
Max-Forwards: 70
Expires: 180
Content-Length: 0


SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.0.6:5060;branch=z9hG4bK-363031-07183c4bdcc67d2a427747d132335a51;received=115.187.33.88;rport=5060
From: <sip:[email protected]>;tag=textclientv1.0
To: <sip:[email protected]>;tag=as7fe2c61e
Call-ID: [email protected]
CSeq: 1 REGISTER
Server: Asterisk PBX 16.7.0
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH,MESSAGE
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="asterisk",nonce="75a0c702"
Content-Length: 0


REGISTER sip:xx.xx.xx.xx SIP/2.0
Call-ID: [email protected]
CSeq: 1 REGISTER
From: <sip:[email protected]>;tag=textclientv1.0
To: <sip:[email protected]>
Via: SIP/2.0/UDP 192.168.0.6:5060
Max-Forwards: 70
Expires: 180
Authorization: Digest realm="asterisk",nonce="75a0c702",username="Santanu",uri="sip:xx.xx.xx.xx",algorithm=MD5,response="34c55995ca5bd9e5a1df9d21d1c8bd9e",cnonce="0a4f113b",nc=00000001,qop=auth
Content-Length: 0


SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.0.6:5060;branch=z9hG4bK-363031-d081e9dc17d5bdaf73ecd2da30763b51;received=115.187.33.88;rport=5060
From: <sip:[email protected]>;tag=textclientv1.0
To: <sip:[email protected]>;tag=as2d43d078
Call-ID: [email protected]
CSeq: 1 REGISTER
Server: Asterisk PBX 16.7.0
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH,MESSAGE
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="asterisk",nonce="788c190c"
Content-Length: 0


REGISTER sip:xx.xx.xx.xx SIP/2.0
Call-ID: [email protected]
CSeq: 1 REGISTER
From: <sip:[email protected]>;tag=textclientv1.0
To: <sip:[email protected]>
Via: SIP/2.0/UDP 192.168.0.6:5060
Max-Forwards: 70
Expires: 180
Authorization: Digest realm="asterisk",nonce="788c190c",username="Santanu",uri="sip:xx.xx.xx.xx",algorithm=MD5,response="6e1abc053061344d38dfb25211e4af49",cnonce="0a4f113b",nc=00000001,qop=auth
Content-Length: 0


SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.0.6:5060;branch=z9hG4bK-363031-e1b94f1f52aa39e35c662fc3ae261d16;received=115.187.33.88;rport=5060
From: <sip:[email protected]>;tag=textclientv1.0
To: <sip:[email protected]>;tag=as58c8d6ed
Call-ID: [email protected]
CSeq: 1 REGISTER
Server: Asterisk PBX 16.7.0
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH,MESSAGE
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="asterisk",nonce="33185dc4"
Content-Length: 0

我的代码如下:

public class SipInit implements SipListener {


    private String ip;
    private SipFactory sipFactory;
    private Properties properties;
    private SipStack sipStack;
    @SuppressWarnings("unused")
    private MessageFactory messageFactory;
    private HeaderFactory headerFactory;
    private AddressFactory addressFactory;
    private ListeningPoint listeningPoint;
    private int port;
    private String protocol;
    private SipProvider sipProvider;
    private String username1;
    private String username2;
    private Address contactAddress;
    @SuppressWarnings("unused")
    private ContactHeader contactHeader;
    private String server;
    private char[] tag;
    private Request request;
    private String password;
    private ClientTransaction inviteTid;
    private Dialog dialog;
    private Response resp;
    int cseq = 0;

    public void init() throws ParseException {
        try {
            // Get the local IP address.
            this.ip = "192.168.0.6";//InetAddress.getLocalHost().getHostAddress();
            //this.tag=" ".toCharArray();
            // Create the SIP factory and set the path name.
            this.sipFactory = SipFactory.getInstance();
            this.port=5060;
            this.protocol="udp";
            this.server="178.63.254.99";
            this.username1="Santanu";
            this.username2="Arijit";
            this.password="voip123";
            
            this.sipFactory.setPathName("gov.nist");
            // Create and set the SIP stack properties.
            this.properties = new Properties();
            this.properties.setProperty("javax.sip.STACK_NAME", "stack");
            this.properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");



            this.properties.setProperty(
                    "gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
            this.properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
                    "mss-jsip-debuglog.txt");
            this.properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
                    "mss-jsip-messages.xml");
            // Create the SIP stack.
            this.sipStack = this.sipFactory.createSipStack(this.properties);
            // Create the SIP message factory.
            this.messageFactory = this.sipFactory.createMessageFactory();
            // Create the SIP header factory.
            this.headerFactory = this.sipFactory.createHeaderFactory();
            // Create the SIP address factory.
            this.addressFactory = this.sipFactory.createAddressFactory();
            // Create the SIP listening point and bind it to the local IP
            // address, port and protocol.
            this.listeningPoint = this.sipStack.createListeningPoint(this.ip,
                    this.port, this.protocol);
            // Create the SIP provider.
            this.sipProvider = this.sipStack
                    .createSipProvider(this.listeningPoint);
            // Add our application as a SIP listener.
            this.sipProvider.addSipListener(this);
            // Create the contact address used for all SIP messages.
            this.contactAddress = this.addressFactory.createAddress("sip:" + this.username1 + "@"
                    + this.ip + ";transport=udp");
            // Create the contact header used for all SIP messages.
            this.contactHeader = this.headerFactory
                    .createContactHeader(contactAddress);
            // 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);
        }
        
        
        //r.setStatusCode(200);
        register();
    }


    public void register() throws NullPointerException{
        
        Object logger;
        try {
        
        cseq++;
        
        ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
        ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip,
        this.port, "udp", "abcd");
        viaHeaders.add(viaHeader);
        // The "Max-Forwards" header.
        MaxForwardsHeader maxForwardsHeader = this.headerFactory
        .createMaxForwardsHeader(70);
        // The "Call-Id" header.
        CallIdHeader callIdHeader = this.sipProvider.getNewCallId();
        // The "CSeq" header.
        @SuppressWarnings("deprecation")
        CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(cseq,
        "REGISTER");

        Address fromAddress = addressFactory.createAddress("sip:"
        + username1 + '@' + server);

        FromHeader fromHeader = this.headerFactory.createFromHeader(
        fromAddress, "textclientv1.0");//String.valueOf(this.tag)//Integer.toString(hashCode())
        // The "To" header.
        ToHeader toHeader = this.headerFactory.createToHeader(fromAddress,
        null);

        // this.contactHeader = this.headerFactory
        // .createContactHeader(contactAddress);

        request = this.messageFactory.createRequest("REGISTER sip:"
        + server + " SIP/2.0\r\n\r\n");
        
        request.addHeader(viaHeader);
        request.addHeader(maxForwardsHeader);
        request.addHeader(fromHeader);
        request.addHeader(toHeader);
        request.addHeader(callIdHeader);
        request.addHeader(cSeqHeader);
        
        request.addHeader(contactHeader);
        /*URI requestURI = addressFactory.createURI("sip:" + server);
        
        Request request = messageFactory.createRequest(requestURI,
                Request.REGISTER, callIdHeader, cSeqHeader, fromHeader,
                toHeader, viaHeaders, maxForwardsHeader);
        request.addHeader(contactHeader);*/
        /*Request request = messageFactory.createRequest(requestURI,
                Request.REGISTER, callIdHeader, cSeqHeader, fromHeader,
                toHeader, viaHeaders, maxForwardsHeader);*/
        
        
        //Response response=this.messageFactory.createResponse(200, request);
        HeaderFactory header=this.sipFactory.createHeaderFactory();
        ExpiresHeader eh = header.createExpiresHeader(3060);
        request.addHeader(eh);
        
        if (resp != null) {
        boolean retry = true;
        AuthorizationHeader authHeader = makeAuthHeader(headerFactory, resp,
        request, username1, password);
        request.addHeader(authHeader);
        }
        System.out.println(""+ request);
        inviteTid = sipProvider.getNewClientTransaction(request);
        // send the request out.
        inviteTid.sendRequest();
        this.dialog = inviteTid.getDialog();
        // Send the request statelessly through the SIP provider.
//                  this.sipProvider.sendRequest(request);

        // Display the message in the text area.
        //debug("Request sent:\n" + request.toString() + "\n\n");
        } catch (Exception e) {
        // If an error occurred, display the error.
        e.printStackTrace();
        //debug("Request sent failed: " + e.getMessage() + "\n");
        }
        }

    @Override
    public void processDialogTerminated(DialogTerminatedEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void processIOException(IOExceptionEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void processRequest(RequestEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void processResponse(ResponseEvent arg0) {
        // TODO Auto-generated method stub
        resp=arg0.getResponse();
        //CSeqHeader cseq = (CSeqHeader) resp.getHeader(CSeqHeader.NAME);  
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(resp);
        //if(cseq<=2)
            register();
    }

    @Override
    public void processTimeout(TimeoutEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void processTransactionTerminated(TransactionTerminatedEvent arg0) {
        // TODO Auto-generated method stub

    }
    
    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 = username2 + ":" + realm + ":" + password2;
            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(username2);
            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;

    }

    private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    
    static String toHexString(byte b[]) {
        int pos = 0;
        char[] c = new char[b.length * 2];
        for (int i = 0; i < b.length; i++) {
            c[pos++] = toHex[(b[i] >> 4) & 0x0F];
            c[pos++] = toHex[b[i] & 0x0f];
        }
        return new String(c);
    }
}

请指教。

java eclipse sip jain-sip
1个回答
0
投票

你好

第一个 401 在“WWW-Authenticate:”中用“nonce”来回答,客户端必须在下一次注册时用“Authorization:”中的正确“响应”来回答

找出服务器不接受“响应”的原因。 ( 密码错误? ) 第二个具有有效“响应”的 REGISTER 看起来像......

[Jul 16 14:54:48] REGISTER sip:osmc SIP/2.0
[Jul 16 14:54:48] Via: SIP/2.0/UDP 192.168.178.1:5060;rport;branch=z9hG4bK0F70B6BAE0059522
[Jul 16 14:54:48] Route: <sip:192.168.178.22:5070;lr>
[Jul 16 14:54:48] From: <sip:1001@osmc>;tag=2183661807
[Jul 16 14:54:48] To: <sip:1001@osmc>
[Jul 16 14:54:48] Call-ID: [email protected]
[Jul 16 14:54:48] CSeq: 1704 REGISTER
[Jul 16 14:54:48] Contact: <sip:[email protected];uniq=0FA6428E93F9F1194B723E54CA22B>
[Jul 16 14:54:48] Authorization: Digest username="1001", realm="asterisk", nonce="4b2486f6", uri="sip:osmc", response="00c53b8da7d68da98a56bcd00f153f33", algorithm=MD5
[Jul 16 14:54:48] Max-Forwards: 70
[Jul 16 14:54:48] Expires: 1800
[Jul 16 14:54:48] User-Agent: AVM FRITZ!Box 7560 149.07.12 (Jul 3 2019)
[Jul 16 14:54:48] Supported: 100rel,replaces
[Jul 16 14:54:48] Allow-Events: telephone-event,refer,reg
[Jul 16 14:54:48] Allow: INVITE,ACK,OPTIONS,CANCEL,BYE,UPDATE,PRACK,INFO,SUBSCRIBE,NOTIFY,REFER,MESSAGE,PUBLISH
[Jul 16 14:54:48] Accept: application/sdp, multipart/mixed
[Jul 16 14:54:48] Accept-Encoding: identity
[Jul 16 14:54:48] Content-Length: 0
[Jul 16 14:54:48]
[Jul 16 14:54:48] <------------->
[Jul 16 14:54:48] --- (18 headers 0 lines) ---
[Jul 16 14:54:48] Sending to 192.168.178.1:5060 (no NAT)
[Jul 16 14:54:48]
[Jul 16 14:54:48] <--- Transmitting (no NAT) to 192.168.178.1:5060 --->
[Jul 16 14:54:48] SIP/2.0 200 OK
[Jul 16 14:54:48] Via: SIP/2.0/UDP 192.168.178.1:5060;branch=z9hG4bK0F70B6BAE0059522;received=192.168.178.1;rport=5060
[Jul 16 14:54:48] From: <sip:1001@osmc>;tag=2183661807
[Jul 16 14:54:48] To: <sip:1001@osmc>;tag=as793919e9
[Jul 16 14:54:48] Call-ID: [email protected]
[Jul 16 14:54:48] CSeq: 1704 REGISTER
[Jul 16 14:54:48] Server: PiBX
[Jul 16 14:54:48] Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
[Jul 16 14:54:48] Supported: replaces, timer
[Jul 16 14:54:48] Expires: 1800
[Jul 16 14:54:48] Contact: <sip:[email protected];uniq=0FA6428E93F9F1194B723E54CA22B>;expires=1800
[Jul 16 14:54:48] Date: Thu, 16 Jul 2020 12:54:48 GMT
[Jul 16 14:54:48] Content-Length: 0

编辑 - 我认为你忘记了联系方式:* 完全采用并用

;expires=1800
扩展它,例如客户必须遵循。不管客户有什么要求。服务器有关于到期的最后消息。不合规矩:来自客户的
Expires: 0
意味着:取消我的注册

© www.soinside.com 2019 - 2024. All rights reserved.