private void DoSubscribe(SIPNonInviteTransaction subTx)
        {
            SIPRequest req    = subTx.TransactionRequest;
            string     user   = req.Header.From.FromURI.User;
            string     domain = req.Header.From.FromURI.HostAddress;

            string canonicalDomain = m_sipDomainManager.GetCanonicalDomain(domain);

            if (canonicalDomain == null)
            {
                Logger.LogWarning($"Subscribe Register request for {req.Header.From.FromURI.Host} rejected as no matching domain found.");
                SIPResponse noDomainResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced");
                subTx.SendResponse(noDomainResponse);
            }
            else
            {
                SIPAccount sipAccount = m_sipAccountsDataLayer.GetSIPAccount(user, canonicalDomain).Result;

                if (sipAccount == null)
                {
                    Logger.LogWarning($"SubscriberCore SIP account {user}@{canonicalDomain} does not exist.");
                    SIPResponse forbiddenResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Forbidden, null);
                    subTx.SendResponse(forbiddenResponse);
                }
                else
                {
                    SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator.AuthenticateSIPRequest(req.LocalSIPEndPoint, req.RemoteSIPEndPoint, req, sipAccount);

                    if (!authenticationResult.Authenticated)
                    {
                        // 401 Response with a fresh nonce needs to be sent.
                        SIPResponse authReqdResponse = SIPResponse.GetResponse(req, authenticationResult.ErrorResponse, null);
                        authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader;
                        subTx.SendResponse(authReqdResponse);

                        if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden)
                        {
                            Logger.LogWarning($"Forbidden {sipAccount.AOR} does not exist, received from {req.RemoteSIPEndPoint}, user agent {req.Header.UserAgent}.");
                        }
                    }
                    else
                    {
                        SIPResponse okResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Ok, null);
                        subTx.SendResponse(okResponse);
                        Logger.LogDebug($"Subscription request for {user}@{domain} was successful.");

                        // Give the subscribe response time to be sent.
                        Thread.Sleep(500);

                        if (req.Header.Expires > 0)
                        {
                            SendInitialNotification(req, sipAccount);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        private RegisterResultEnum Register(SIPNonInviteTransaction registerTransaction)
        {
            try
            {
                SIPRequest  sipRequest      = registerTransaction.TransactionRequest;
                SIPURI      registerURI     = sipRequest.URI;
                SIPToHeader toHeader        = sipRequest.Header.To;
                string      toUser          = toHeader.ToURI.User;
                string      canonicalDomain = m_sipDomainManager.GetCanonicalDomain(toHeader.ToURI.HostAddress);
                int         requestedExpiry = GetRequestedExpiry(sipRequest);

                if (canonicalDomain == null)
                {
                    Logger.LogWarning($"Register request for {toHeader.ToURI.HostAddress} rejected as no matching domain found.");
                    SIPResponse noDomainResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced");
                    registerTransaction.SendResponse(noDomainResponse);
                    return(RegisterResultEnum.DomainNotServiced);
                }
                else
                {
                    SIPAccount sipAccount = m_sipAccountsDataLayer.GetSIPAccount(toUser, canonicalDomain).Result;

                    if (sipAccount == null)
                    {
                        Logger.LogWarning($"RegistrarCore SIP account {toUser}@{canonicalDomain} does not exist.");
                        SIPResponse forbiddenResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, null);
                        registerTransaction.SendResponse(forbiddenResponse);
                        return(RegisterResultEnum.Forbidden);
                    }
                    else
                    {
                        SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator.AuthenticateSIPRequest(
                            registerTransaction.TransactionRequest.LocalSIPEndPoint,
                            registerTransaction.TransactionRequest.RemoteSIPEndPoint,
                            sipRequest,
                            sipAccount.ToSIPAccountModel());

                        if (!authenticationResult.Authenticated)
                        {
                            // 401 Response with a fresh nonce needs to be sent.
                            SIPResponse authReqdResponse = SIPResponse.GetResponse(sipRequest, authenticationResult.ErrorResponse, null);
                            authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader;
                            registerTransaction.SendResponse(authReqdResponse);

                            if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden)
                            {
                                Logger.LogWarning($"Forbidden {sipAccount.AOR} does not exist, {sipRequest.Header.ProxyReceivedFrom}, {sipRequest.Header.UserAgent}.");
                                return(RegisterResultEnum.Forbidden);
                            }
                            else
                            {
                                return(RegisterResultEnum.AuthenticationRequired);
                            }
                        }
                        else
                        {
                            if (sipRequest.Header.Contact == null || sipRequest.Header.Contact.Count == 0)
                            {
                                // No contacts header to update bindings with, return a list of the current bindings.
                                //List<SIPRegistrarBinding> bindings = m_registrarBindingsManager.GetBindings(sipAccount.ID);
                                List <SIPRegistrarBinding> bindings = m_sipRegistrarBindingDataLayer.GetForSIPAccount(new Guid(sipAccount.ID)).ToList();
                                //List<SIPContactHeader> contactsList = m_registrarBindingsManager.GetContactHeader(); // registration.GetContactHeader(true, null);
                                if (bindings != null)
                                {
                                    sipRequest.Header.Contact = GetContactHeader(bindings);
                                }

                                SIPResponse okResponse = GetOkResponse(sipRequest);
                                registerTransaction.SendResponse(okResponse);
                                Logger.LogDebug($"Empty registration request successful for {sipAccount.AOR} from {sipRequest.Header.ProxyReceivedFrom}.");
                            }
                            else
                            {
                                SIPEndPoint uacRemoteEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? registerTransaction.TransactionRequest.RemoteSIPEndPoint;
                                SIPEndPoint proxySIPEndPoint  = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn);
                                SIPEndPoint registrarEndPoint = registerTransaction.TransactionRequest.LocalSIPEndPoint;

                                SIPResponseStatusCodesEnum updateResult = SIPResponseStatusCodesEnum.Ok;
                                string updateMessage = null;

                                DateTime startTime = DateTime.Now;

                                List <SIPRegistrarBinding> bindingsList = m_registrarBindingsManager.UpdateBindings(
                                    sipAccount,
                                    proxySIPEndPoint,
                                    uacRemoteEndPoint,
                                    registrarEndPoint,
                                    sipRequest.Header.Contact,
                                    sipRequest.Header.CallId,
                                    sipRequest.Header.CSeq,
                                    sipRequest.Header.Expires,
                                    sipRequest.Header.UserAgent,
                                    out updateResult,
                                    out updateMessage);

                                TimeSpan duration = DateTime.Now.Subtract(startTime);
                                Logger.LogDebug($"Binding update time for {sipAccount.AOR} took {duration.TotalMilliseconds}ms.");

                                if (updateResult == SIPResponseStatusCodesEnum.Ok)
                                {
                                    string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null;

                                    Logger.LogDebug($"Bindings for {sipAccount.AOR}:");
                                    for (int i = 0; i < bindingsList.Count(); i++)
                                    {
                                        var binding = bindingsList[i];
                                        Logger.LogDebug($" {i}: {binding.ContactURI}, expiry {binding.Expiry}s.");
                                    }

                                    sipRequest.Header.Contact = GetContactHeader(bindingsList);
                                    SIPResponse okResponse = GetOkResponse(sipRequest);
                                    registerTransaction.SendResponse(okResponse);
                                }
                                else
                                {
                                    // The binding update failed even though the REGISTER request was authorised. This is probably due to a
                                    // temporary problem connecting to the bindings data store. Send Ok but set the binding expiry to the minimum so
                                    // that the UA will try again as soon as possible.
                                    Logger.LogError($"Registration request successful but binding update failed for {sipAccount.AOR} from {registerTransaction.TransactionRequest.RemoteSIPEndPoint}.");
                                    sipRequest.Header.Contact[0].Expires = m_minimumBindingExpiry;
                                    SIPResponse okResponse = GetOkResponse(sipRequest);
                                    registerTransaction.SendResponse(okResponse);
                                }
                            }

                            return(RegisterResultEnum.Authenticated);
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                string regErrorMessage = "Exception registrarcore registering. " + excp.Message + "\r\n" + registerTransaction.TransactionRequest.ToString();
                Logger.LogError(regErrorMessage);

                SIPResponse errorResponse = SIPResponse.GetResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null);
                registerTransaction.SendResponse(errorResponse);

                return(RegisterResultEnum.Error);
            }
        }