Search in sources :

Example 6 with SIPClientTransaction

use of gov.nist.javax.sip.stack.SIPClientTransaction in project XobotOS by xamarin.

the class AuthenticationHelperImpl method handleChallenge.

/*
     * (non-Javadoc)
     *
     * @see gov.nist.javax.sip.clientauthutils.AuthenticationHelper#handleChallenge(javax.sip.message.Response,
     *      javax.sip.ClientTransaction, javax.sip.SipProvider)
     */
public ClientTransaction handleChallenge(Response challenge, ClientTransaction challengedTransaction, SipProvider transactionCreator, int cacheTime) throws SipException, NullPointerException {
    try {
        if (sipStack.isLoggingEnabled()) {
            sipStack.getStackLogger().logDebug("handleChallenge: " + challenge);
        }
        SIPRequest challengedRequest = ((SIPRequest) challengedTransaction.getRequest());
        Request reoriginatedRequest = null;
        /*
             * If the challenged request is part of a Dialog and the
             * Dialog is confirmed the re-originated request should be
             * generated as an in-Dialog request.
             */
        if (challengedRequest.getToTag() != null || challengedTransaction.getDialog() == null || challengedTransaction.getDialog().getState() != DialogState.CONFIRMED) {
            reoriginatedRequest = (Request) challengedRequest.clone();
        } else {
            /*
                 * Re-originate the request by consulting the dialog. In particular
                 * the route set could change between the original request and the 
                 * in-dialog challenge.
                 */
            reoriginatedRequest = challengedTransaction.getDialog().createRequest(challengedRequest.getMethod());
            Iterator<String> headerNames = challengedRequest.getHeaderNames();
            while (headerNames.hasNext()) {
                String headerName = headerNames.next();
                if (reoriginatedRequest.getHeader(headerName) != null) {
                    ListIterator<Header> iterator = reoriginatedRequest.getHeaders(headerName);
                    while (iterator.hasNext()) {
                        reoriginatedRequest.addHeader(iterator.next());
                    }
                }
            }
        }
        // remove the branch id so that we could use the request in a new
        // transaction
        removeBranchID(reoriginatedRequest);
        if (challenge == null || reoriginatedRequest == null) {
            throw new NullPointerException("A null argument was passed to handle challenge.");
        }
        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");
        }
        // Remove all authorization headers from the request (we'll re-add them
        // from cache)
        reoriginatedRequest.removeHeader(AuthorizationHeader.NAME);
        reoriginatedRequest.removeHeader(ProxyAuthorizationHeader.NAME);
        // rfc 3261 says that the cseq header should be augmented for the new
        // request. do it here so that the new dialog (created together with
        // the new client transaction) takes it into account.
        // Bug report - Fredrik Wickstrom
        CSeqHeader cSeq = (CSeqHeader) reoriginatedRequest.getHeader((CSeqHeader.NAME));
        try {
            cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l);
        } catch (InvalidArgumentException ex) {
            throw new SipException("Invalid CSeq -- could not increment : " + cSeq.getSeqNumber());
        }
        /* Resolve this to the next hop based on the previous lookup. If we are not using
             * lose routing (RFC2543) then just attach hop as a maddr param.
             */
        if (challengedRequest.getRouteHeaders() == null) {
            Hop hop = ((SIPClientTransaction) challengedTransaction).getNextHop();
            SipURI sipUri = (SipURI) reoriginatedRequest.getRequestURI();
            // BEGIN android-added
            if (!hop.getHost().equalsIgnoreCase(sipUri.getHost()) && !hop.equals(sipStack.getRouter(challengedRequest).getOutboundProxy()))
                // END android-added
                sipUri.setMAddrParam(hop.getHost());
            if (hop.getPort() != -1)
                sipUri.setPort(hop.getPort());
        }
        ClientTransaction retryTran = transactionCreator.getNewClientTransaction(reoriginatedRequest);
        WWWAuthenticateHeader authHeader = null;
        SipURI requestUri = (SipURI) challengedTransaction.getRequest().getRequestURI();
        while (authHeaders.hasNext()) {
            authHeader = (WWWAuthenticateHeader) authHeaders.next();
            String realm = authHeader.getRealm();
            AuthorizationHeader authorization = null;
            String sipDomain;
            if (this.accountManager instanceof SecureAccountManager) {
                UserCredentialHash credHash = ((SecureAccountManager) this.accountManager).getCredentialHash(challengedTransaction, realm);
                URI uri = reoriginatedRequest.getRequestURI();
                sipDomain = credHash.getSipDomain();
                authorization = this.getAuthorization(reoriginatedRequest.getMethod(), uri.toString(), (reoriginatedRequest.getContent() == null) ? "" : new String(reoriginatedRequest.getRawContent()), authHeader, credHash);
            } else {
                UserCredentials userCreds = ((AccountManager) this.accountManager).getCredentials(challengedTransaction, realm);
                sipDomain = userCreds.getSipDomain();
                if (userCreds == null)
                    throw new SipException("Cannot find user creds for the given user name and realm");
                // we haven't yet authenticated this realm since we were
                // started.
                authorization = this.getAuthorization(reoriginatedRequest.getMethod(), reoriginatedRequest.getRequestURI().toString(), (reoriginatedRequest.getContent() == null) ? "" : new String(reoriginatedRequest.getRawContent()), authHeader, userCreds);
            }
            if (sipStack.isLoggingEnabled())
                sipStack.getStackLogger().logDebug("Created authorization header: " + authorization.toString());
            if (cacheTime != 0)
                cachedCredentials.cacheAuthorizationHeader(sipDomain, authorization, cacheTime);
            reoriginatedRequest.addHeader(authorization);
        }
        if (sipStack.isLoggingEnabled()) {
            sipStack.getStackLogger().logDebug("Returning authorization transaction." + retryTran);
        }
        return retryTran;
    } catch (SipException ex) {
        throw ex;
    } catch (Exception ex) {
        sipStack.getStackLogger().logError("Unexpected exception ", ex);
        throw new SipException("Unexpected exception ", ex);
    }
}
Also used : SIPClientTransaction(gov.nist.javax.sip.stack.SIPClientTransaction) SIPClientTransaction(gov.nist.javax.sip.stack.SIPClientTransaction) ClientTransaction(javax.sip.ClientTransaction) ProxyAuthorizationHeader(javax.sip.header.ProxyAuthorizationHeader) AuthorizationHeader(javax.sip.header.AuthorizationHeader) Request(javax.sip.message.Request) SIPRequest(gov.nist.javax.sip.message.SIPRequest) Hop(javax.sip.address.Hop) WWWAuthenticateHeader(javax.sip.header.WWWAuthenticateHeader) ListIterator(java.util.ListIterator) SipURI(javax.sip.address.SipURI) SIPRequest(gov.nist.javax.sip.message.SIPRequest) URI(javax.sip.address.URI) SipURI(javax.sip.address.SipURI) InvalidArgumentException(javax.sip.InvalidArgumentException) ParseException(java.text.ParseException) SipException(javax.sip.SipException) CSeqHeader(javax.sip.header.CSeqHeader) InvalidArgumentException(javax.sip.InvalidArgumentException) CSeqHeader(javax.sip.header.CSeqHeader) ProxyAuthorizationHeader(javax.sip.header.ProxyAuthorizationHeader) ProxyAuthenticateHeader(javax.sip.header.ProxyAuthenticateHeader) ViaHeader(javax.sip.header.ViaHeader) WWWAuthenticateHeader(javax.sip.header.WWWAuthenticateHeader) AuthorizationHeader(javax.sip.header.AuthorizationHeader) Header(javax.sip.header.Header) SipException(javax.sip.SipException)

Example 7 with SIPClientTransaction

use of gov.nist.javax.sip.stack.SIPClientTransaction in project XobotOS by xamarin.

the class SipProviderImpl method getNewServerTransaction.

/*
     * (non-Javadoc)
     *
     * @see javax.sip.SipProvider#getNewServerTransaction(javax.sip.message.Request)
     */
public ServerTransaction getNewServerTransaction(Request request) throws TransactionAlreadyExistsException, TransactionUnavailableException {
    if (!sipStack.isAlive())
        throw new TransactionUnavailableException("Stack is stopped");
    SIPServerTransaction transaction = null;
    SIPRequest sipRequest = (SIPRequest) request;
    try {
        sipRequest.checkHeaders();
    } catch (ParseException ex) {
        throw new TransactionUnavailableException(ex.getMessage(), ex);
    }
    if (request.getMethod().equals(Request.ACK)) {
        if (sipStack.isLoggingEnabled())
            sipStack.getStackLogger().logError("Creating server transaction for ACK -- makes no sense!");
        throw new TransactionUnavailableException("Cannot create Server transaction for ACK ");
    }
    /*
         * Got a notify.
         */
    if (sipRequest.getMethod().equals(Request.NOTIFY) && sipRequest.getFromTag() != null && sipRequest.getToTag() == null) {
        SIPClientTransaction ct = sipStack.findSubscribeTransaction(sipRequest, (ListeningPointImpl) this.getListeningPoint());
        /* Issue 104 */
        if (ct == null && !sipStack.deliverUnsolicitedNotify) {
            throw new TransactionUnavailableException("Cannot find matching Subscription (and gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY not set)");
        }
    }
    if (!sipStack.acquireSem()) {
        throw new TransactionUnavailableException("Transaction not available -- could not acquire stack lock");
    }
    try {
        if (sipStack.isDialogCreated(sipRequest.getMethod())) {
            if (sipStack.findTransaction((SIPRequest) request, true) != null)
                throw new TransactionAlreadyExistsException("server transaction already exists!");
            transaction = (SIPServerTransaction) ((SIPRequest) request).getTransaction();
            if (transaction == null)
                throw new TransactionUnavailableException("Transaction not available");
            if (transaction.getOriginalRequest() == null)
                transaction.setOriginalRequest(sipRequest);
            try {
                sipStack.addTransaction(transaction);
            } catch (IOException ex) {
                throw new TransactionUnavailableException("Error sending provisional response");
            }
            // So I can handle timeouts.
            transaction.addEventListener(this);
            if (isAutomaticDialogSupportEnabled()) {
                // If automatic dialog support is enabled then
                // this tx gets his own dialog.
                String dialogId = sipRequest.getDialogId(true);
                SIPDialog dialog = sipStack.getDialog(dialogId);
                if (dialog == null) {
                    dialog = sipStack.createDialog(transaction);
                }
                transaction.setDialog(dialog, sipRequest.getDialogId(true));
                if (sipRequest.getMethod().equals(Request.INVITE) && this.isDialogErrorsAutomaticallyHandled()) {
                    sipStack.putInMergeTable(transaction, sipRequest);
                }
                dialog.addRoute(sipRequest);
                if (dialog.getRemoteTag() != null && dialog.getLocalTag() != null) {
                    this.sipStack.putDialog(dialog);
                }
            }
        } else {
            if (isAutomaticDialogSupportEnabled()) {
                /*
                     * Under automatic dialog support, dialog is tied into a transaction. You cannot
                     * create a server tx except for dialog creating transactions. After that, all
                     * subsequent transactions are created for you by the stack.
                     */
                transaction = (SIPServerTransaction) sipStack.findTransaction((SIPRequest) request, true);
                if (transaction != null)
                    throw new TransactionAlreadyExistsException("Transaction exists! ");
                transaction = (SIPServerTransaction) ((SIPRequest) request).getTransaction();
                if (transaction == null)
                    throw new TransactionUnavailableException("Transaction not available!");
                if (transaction.getOriginalRequest() == null)
                    transaction.setOriginalRequest(sipRequest);
                // Map the transaction.
                try {
                    sipStack.addTransaction(transaction);
                } catch (IOException ex) {
                    throw new TransactionUnavailableException("Could not send back provisional response!");
                }
                // If there is a dialog already assigned then just update the
                // dialog state.
                String dialogId = sipRequest.getDialogId(true);
                SIPDialog dialog = sipStack.getDialog(dialogId);
                if (dialog != null) {
                    dialog.addTransaction(transaction);
                    dialog.addRoute(sipRequest);
                    transaction.setDialog(dialog, sipRequest.getDialogId(true));
                }
            } else {
                transaction = (SIPServerTransaction) sipStack.findTransaction((SIPRequest) request, true);
                if (transaction != null)
                    throw new TransactionAlreadyExistsException("Transaction exists! ");
                transaction = (SIPServerTransaction) ((SIPRequest) request).getTransaction();
                if (transaction != null) {
                    if (transaction.getOriginalRequest() == null)
                        transaction.setOriginalRequest(sipRequest);
                    // Map the transaction.
                    sipStack.mapTransaction(transaction);
                    // If there is a dialog already assigned then just
                    // assign the dialog to the transaction.
                    String dialogId = sipRequest.getDialogId(true);
                    SIPDialog dialog = sipStack.getDialog(dialogId);
                    if (dialog != null) {
                        dialog.addTransaction(transaction);
                        dialog.addRoute(sipRequest);
                        transaction.setDialog(dialog, sipRequest.getDialogId(true));
                    }
                    return transaction;
                } else {
                    // tx does not exist so create the tx.
                    MessageChannel mc = (MessageChannel) sipRequest.getMessageChannel();
                    transaction = sipStack.createServerTransaction(mc);
                    if (transaction == null)
                        throw new TransactionUnavailableException("Transaction unavailable -- too many servrer transactions");
                    transaction.setOriginalRequest(sipRequest);
                    sipStack.mapTransaction(transaction);
                    // If there is a dialog already assigned then just
                    // assign the dialog to the transaction.
                    String dialogId = sipRequest.getDialogId(true);
                    SIPDialog dialog = sipStack.getDialog(dialogId);
                    if (dialog != null) {
                        dialog.addTransaction(transaction);
                        dialog.addRoute(sipRequest);
                        transaction.setDialog(dialog, sipRequest.getDialogId(true));
                    }
                    return transaction;
                }
            }
        }
        return transaction;
    } finally {
        sipStack.releaseSem();
    }
}
Also used : SIPClientTransaction(gov.nist.javax.sip.stack.SIPClientTransaction) MessageChannel(gov.nist.javax.sip.stack.MessageChannel) SIPDialog(gov.nist.javax.sip.stack.SIPDialog) TransactionAlreadyExistsException(javax.sip.TransactionAlreadyExistsException) TransactionUnavailableException(javax.sip.TransactionUnavailableException) ParseException(java.text.ParseException) IOException(java.io.IOException) SIPServerTransaction(gov.nist.javax.sip.stack.SIPServerTransaction) SIPRequest(gov.nist.javax.sip.message.SIPRequest)

Example 8 with SIPClientTransaction

use of gov.nist.javax.sip.stack.SIPClientTransaction in project XobotOS by xamarin.

the class SipProviderImpl method transactionErrorEvent.

/**
     * Invoked when an error has ocurred with a transaction. Propagate up to the
     * listeners.
     *
     * @param transactionErrorEvent
     *            Error event.
     */
public void transactionErrorEvent(SIPTransactionErrorEvent transactionErrorEvent) {
    SIPTransaction transaction = (SIPTransaction) transactionErrorEvent.getSource();
    if (transactionErrorEvent.getErrorID() == SIPTransactionErrorEvent.TRANSPORT_ERROR) {
        // There must be a way to inform the TU here!!
        if (sipStack.isLoggingEnabled()) {
            sipStack.getStackLogger().logDebug("TransportError occured on " + transaction);
        }
        // Treat this like a timeout event. (Suggestion from Christophe).
        Object errorObject = transactionErrorEvent.getSource();
        Timeout timeout = Timeout.TRANSACTION;
        TimeoutEvent ev = null;
        if (errorObject instanceof SIPServerTransaction) {
            ev = new TimeoutEvent(this, (ServerTransaction) errorObject, timeout);
        } else {
            SIPClientTransaction clientTx = (SIPClientTransaction) errorObject;
            Hop hop = clientTx.getNextHop();
            if (sipStack.getRouter() instanceof RouterExt) {
                ((RouterExt) sipStack.getRouter()).transactionTimeout(hop);
            }
            ev = new TimeoutEvent(this, (ClientTransaction) errorObject, timeout);
        }
        // Handling transport error like timeout
        this.handleEvent(ev, (SIPTransaction) errorObject);
    } else if (transactionErrorEvent.getErrorID() == SIPTransactionErrorEvent.TIMEOUT_ERROR) {
        // This is a timeout event.
        Object errorObject = transactionErrorEvent.getSource();
        Timeout timeout = Timeout.TRANSACTION;
        TimeoutEvent ev = null;
        if (errorObject instanceof SIPServerTransaction) {
            ev = new TimeoutEvent(this, (ServerTransaction) errorObject, timeout);
        } else {
            SIPClientTransaction clientTx = (SIPClientTransaction) errorObject;
            Hop hop = clientTx.getNextHop();
            if (sipStack.getRouter() instanceof RouterExt) {
                ((RouterExt) sipStack.getRouter()).transactionTimeout(hop);
            }
            ev = new TimeoutEvent(this, (ClientTransaction) errorObject, timeout);
        }
        this.handleEvent(ev, (SIPTransaction) errorObject);
    } else if (transactionErrorEvent.getErrorID() == SIPTransactionErrorEvent.TIMEOUT_RETRANSMIT) {
        // This is a timeout retransmit event.
        // We should never get this if retransmit filter is
        // enabled (ie. in that case the stack should handle.
        // all retransmits.
        Object errorObject = transactionErrorEvent.getSource();
        Transaction tx = (Transaction) errorObject;
        if (tx.getDialog() != null)
            InternalErrorHandler.handleException("Unexpected event !", this.sipStack.getStackLogger());
        Timeout timeout = Timeout.RETRANSMIT;
        TimeoutEvent ev = null;
        if (errorObject instanceof SIPServerTransaction) {
            ev = new TimeoutEvent(this, (ServerTransaction) errorObject, timeout);
        } else {
            ev = new TimeoutEvent(this, (ClientTransaction) errorObject, timeout);
        }
        this.handleEvent(ev, (SIPTransaction) errorObject);
    }
}
Also used : SIPClientTransaction(gov.nist.javax.sip.stack.SIPClientTransaction) TimeoutEvent(javax.sip.TimeoutEvent) ServerTransaction(javax.sip.ServerTransaction) Transaction(javax.sip.Transaction) SIPServerTransaction(gov.nist.javax.sip.stack.SIPServerTransaction) SIPClientTransaction(gov.nist.javax.sip.stack.SIPClientTransaction) SIPTransaction(gov.nist.javax.sip.stack.SIPTransaction) ClientTransaction(javax.sip.ClientTransaction) RouterExt(gov.nist.javax.sip.address.RouterExt) Timeout(javax.sip.Timeout) SIPTransaction(gov.nist.javax.sip.stack.SIPTransaction) SIPClientTransaction(gov.nist.javax.sip.stack.SIPClientTransaction) ClientTransaction(javax.sip.ClientTransaction) Hop(javax.sip.address.Hop) EventObject(java.util.EventObject) ServerTransaction(javax.sip.ServerTransaction) SIPServerTransaction(gov.nist.javax.sip.stack.SIPServerTransaction) SIPServerTransaction(gov.nist.javax.sip.stack.SIPServerTransaction)

Aggregations

SIPClientTransaction (gov.nist.javax.sip.stack.SIPClientTransaction)8 SIPRequest (gov.nist.javax.sip.message.SIPRequest)6 SipException (javax.sip.SipException)6 SIPDialog (gov.nist.javax.sip.stack.SIPDialog)5 SIPServerTransaction (gov.nist.javax.sip.stack.SIPServerTransaction)4 SIPTransaction (gov.nist.javax.sip.stack.SIPTransaction)4 IOException (java.io.IOException)4 ClientTransaction (javax.sip.ClientTransaction)4 InvalidArgumentException (javax.sip.InvalidArgumentException)4 SIPResponse (gov.nist.javax.sip.message.SIPResponse)3 ParseException (java.text.ParseException)3 ServerTransaction (javax.sip.ServerTransaction)3 Hop (javax.sip.address.Hop)3 Request (javax.sip.message.Request)3 Response (javax.sip.message.Response)3 ObjectInUseException (javax.sip.ObjectInUseException)2 TransactionUnavailableException (javax.sip.TransactionUnavailableException)2 RouterExt (gov.nist.javax.sip.address.RouterExt)1 SipUri (gov.nist.javax.sip.address.SipUri)1 Contact (gov.nist.javax.sip.header.Contact)1