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); } } } } }
private RegisterResultEnum Register(SIPTransaction registerTransaction) { try { SIPRequest sipRequest = registerTransaction.TransactionRequest; SIPURI registerURI = sipRequest.URI; SIPToHeader toHeader = sipRequest.Header.To; string toUser = toHeader.ToURI.User; string canonicalDomain = toHeader.ToURI.Host; int requestedExpiry = GetRequestedExpiry(sipRequest); if (canonicalDomain == null) { SIPResponse noDomainResponse = GetErrorResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); registerTransaction.SendFinalResponse(noDomainResponse); return(RegisterResultEnum.DomainNotServiced); } SIPAccount sipAccount = new SIPAccount { Id = Guid.NewGuid(), Owner = "admin", SIPUsername = toUser, SIPDomain = canonicalDomain }; SIPRequestAuthenticationResult authenticationResult = _sipRequestAuthenticator_External?.Invoke(registerTransaction.LocalSIPEndPoint, registerTransaction.RemoteEndPoint, sipRequest, sipAccount); if (!_needAuthentication) { SIPResponse okRes = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okRes); if (requestedExpiry > 0) { CacheDeviceItem(sipRequest); RegisterReceived?.Invoke(sipRequest, _localSipAccount); } if (requestedExpiry == 0) { RemoveDeviceItem(sipRequest); UnRegisterReceived?.Invoke(sipRequest, _localSipAccount); } return(RegisterResultEnum.AuthenticationRequired); } if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; registerTransaction.SendFinalResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { return(RegisterResultEnum.Forbidden); } else { return(RegisterResultEnum.AuthenticationRequired); } } else { if (sipRequest.Header.Contact == null || sipRequest.Header.Contact.Count == 0) { SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); if (requestedExpiry > 0) { CacheDeviceItem(sipRequest); RegisterReceived?.Invoke(sipRequest, _localSipAccount); } if (requestedExpiry == 0) { RemoveDeviceItem(sipRequest); UnRegisterReceived?.Invoke(sipRequest, _localSipAccount); } } else { SIPEndPoint uacRemoteEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? registerTransaction.RemoteEndPoint; SIPEndPoint proxySIPEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn); SIPEndPoint registrarEndPoint = registerTransaction.LocalSIPEndPoint; SIPResponseStatusCodesEnum updateResult = SIPResponseStatusCodesEnum.Ok; DateTime startTime = DateTime.Now; TimeSpan duration = DateTime.Now.Subtract(startTime); if (updateResult == SIPResponseStatusCodesEnum.Ok) { string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null; SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); if (requestedExpiry > 0) { CacheDeviceItem(sipRequest); RegisterReceived?.Invoke(sipRequest, _localSipAccount); } if (requestedExpiry == 0) { RemoveDeviceItem(sipRequest); UnRegisterReceived?.Invoke(sipRequest, _localSipAccount); } } else { sipRequest.Header.Contact[0].Expires = m_minimumBindingExpiry; SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); } } return(RegisterResultEnum.Authenticated); } } catch (Exception excp) { string regErrorMessage = "Exception registrarcore registering. ->" + excp.Message + "->" + registerTransaction.TransactionRequest.ToString(); Logger.Logger.Error(regErrorMessage); try { SIPResponse errorResponse = GetErrorResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); registerTransaction.SendFinalResponse(errorResponse); } catch { } return(RegisterResultEnum.Error); } }
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); } }
public bool AuthenticateCall() { m_isAuthenticated = false; try { if (SIPAuthenticateRequest_External == null) { // No point trying to authenticate if we haven't been given an authentication delegate. Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } else if (GetSIPAccount_External == null) { // No point trying to authenticate if we haven't been given a delegate to load the SIP account. Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } else { m_sipAccount = GetSIPAccount_External(s => s.SIPUsername == m_sipUsername && s.SIPDomain == m_sipDomain); if (m_sipAccount == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Rejecting authentication required " + m_transaction.TransactionRequest.Method + " for " + m_sipUsername + "@" + m_sipDomain + ", SIP account not found.", null)); Reject(SIPResponseStatusCodesEnum.Forbidden, null, null); } else { SIPRequest sipRequest = m_transaction.TransactionRequest; SIPEndPoint localSIPEndPoint = (!sipRequest.Header.ProxyReceivedOn.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedOn) : sipRequest.LocalSIPEndPoint; SIPEndPoint remoteEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : sipRequest.RemoteSIPEndPoint; SIPRequestAuthenticationResult authenticationResult = SIPAuthenticateRequest_External(localSIPEndPoint, remoteEndPoint, sipRequest, m_sipAccount, Log_External); if (authenticationResult.Authenticated) { if (authenticationResult.WasAuthenticatedByIP) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, m_transaction.TransactionRequest.Method + " request from " + remoteEndPoint.ToString() + " successfully authenticated by IP address.", m_sipAccount.Owner)); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, m_transaction.TransactionRequest.Method + " request from " + remoteEndPoint.ToString() + " successfully authenticated by digest.", m_sipAccount.Owner)); } SetOwner(m_sipAccount.Owner, m_sipAccount.AdminMemberId); m_isAuthenticated = true; } else { // Send authorisation failure or required response SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, m_transaction.TransactionRequest.Method + " request not authenticated for " + m_sipUsername + "@" + m_sipDomain + ", responding with " + authenticationResult.ErrorResponse + ".", null)); m_transaction.SendFinalResponse(authReqdResponse); } } } } catch (Exception excp) { logger.Error("Exception SIPNonInviteUserAgent AuthenticateCall. " + excp.Message); Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } return(m_isAuthenticated); }
private void Subscribe(SIPTransaction subscribeTransaction) { try { SIPRequest sipRequest = subscribeTransaction.TransactionRequest; string fromUser = sipRequest.Header.From.FromURI.User; string fromHost = sipRequest.Header.From.FromURI.Host; string canonicalDomain = GetCanonicalDomain_External(fromHost, true); if (canonicalDomain == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request for " + fromHost + " rejected as no matching domain found.", null)); SIPResponse noDomainResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); subscribeTransaction.SendFinalResponse(noDomainResponse); return; } SIPAccount sipAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == fromUser && s.SIPDomain == canonicalDomain); SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(subscribeTransaction.LocalSIPEndPoint, subscribeTransaction.RemoteEndPoint, sipRequest, sipAccount, FireProxyLogEvent); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; subscribeTransaction.SendFinalResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Forbidden " + fromUser + "@" + canonicalDomain + " does not exist, " + sipRequest.Header.ProxyReceivedFrom.ToString() + ", " + sipRequest.Header.UserAgent + ".", null)); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Authentication required for " + fromUser + "@" + canonicalDomain + " from " + subscribeTransaction.RemoteEndPoint + ".", sipAccount.Owner)); } return; } else { if (sipRequest.Header.To.ToTag != null) { // Request is to renew an existing subscription. SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None; string errorResponseReason = null; string sessionID = m_subscriptionsManager.RenewSubscription(sipRequest, out errorResponse, out errorResponseReason); if (errorResponse != SIPResponseStatusCodesEnum.None) { // A subscription renewal attempt failed SIPResponse renewalErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason); subscribeTransaction.SendFinalResponse(renewalErrorResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription renewal failed for event type " + sipRequest.Header.Event + " " + sipRequest.URI.ToString() + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner)); } else if (sipRequest.Header.Expires == 0) { // Existing subscription was closed. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); subscribeTransaction.SendFinalResponse(okResponse); } else { // Existing subscription was found. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); subscribeTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeRenew, "Subscription renewal for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner)); m_subscriptionsManager.SendFullStateNotify(sessionID); } } else { // Authenticated but the this is a new subscription request and authorisation to subscribe to the requested resource also needs to be checked. SIPURI canonicalResourceURI = sipRequest.URI.CopyOf(); string resourceCanonicalDomain = GetCanonicalDomain_External(canonicalResourceURI.Host, true); canonicalResourceURI.Host = resourceCanonicalDomain; SIPAccount resourceSIPAccount = null; if (resourceCanonicalDomain == null) { SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain " + resourceCanonicalDomain + " not serviced"); subscribeTransaction.SendFinalResponse(notFoundResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", domain not serviced.", sipAccount.Owner)); return; } if (canonicalResourceURI.User != m_wildcardUser) { resourceSIPAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == canonicalResourceURI.User && s.SIPDomain == canonicalResourceURI.Host); if (resourceSIPAccount == null) { SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Requested resource does not exist"); subscribeTransaction.SendFinalResponse(notFoundResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", SIP account does not exist.", sipAccount.Owner)); return; } } // Check the owner permissions on the requesting and subscribed resources. bool authorised = false; string adminID = null; if (canonicalResourceURI.User == m_wildcardUser || sipAccount.Owner == resourceSIPAccount.Owner) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to common owner.", sipAccount.Owner)); } else { // Lookup the customer record for the requestor and check the administrative level on it. Customer requestingCustomer = GetCustomer_External(c => c.CustomerUsername == sipAccount.Owner); adminID = requestingCustomer.AdminId; if (!resourceSIPAccount.AdminMemberId.IsNullOrBlank() && requestingCustomer.AdminId == resourceSIPAccount.AdminMemberId) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor admin permissions for domain " + resourceSIPAccount.AdminMemberId + ".", sipAccount.Owner)); } else if (requestingCustomer.AdminId == m_topLevelAdminID) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor having top level admin permissions.", sipAccount.Owner)); } } if (authorised) { // Request is to create a new subscription. SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None; string errorResponseReason = null; string toTag = CallProperties.CreateNewTag(); string sessionID = m_subscriptionsManager.SubscribeClient(sipAccount.Owner, adminID, sipRequest, toTag, canonicalResourceURI, out errorResponse, out errorResponseReason); if (errorResponse != SIPResponseStatusCodesEnum.None) { SIPResponse subscribeErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason); subscribeTransaction.SendFinalResponse(subscribeErrorResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner)); } else { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.To.ToTag = toTag; okResponse.Header.Expires = sipRequest.Header.Expires; okResponse.Header.Contact = new List <SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, subscribeTransaction.LocalSIPEndPoint)) }; subscribeTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription accepted for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner)); if (sessionID != null) { m_subscriptionsManager.SendFullStateNotify(sessionID); } } } else { SIPResponse forbiddenResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Requested resource not authorised"); subscribeTransaction.SendFinalResponse(forbiddenResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", requesting account " + sipAccount.Owner + " was not authorised.", sipAccount.Owner)); } } } } catch (Exception excp) { logger.Error("Exception notifiercore subscribing. " + excp.Message + "\r\n" + subscribeTransaction.TransactionRequest.ToString()); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Error, "Exception notifiercore subscribing. " + excp.Message, null)); SIPResponse errorResponse = SIPTransport.GetResponse(subscribeTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); subscribeTransaction.SendFinalResponse(errorResponse); } }
public bool AuthenticateCall() { m_isAuthenticated = false; try { if (SIPAuthenticateRequest_External == null) { // No point trying to authenticate if we haven't been given an authentication delegate. Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } else if (GetSIPAccount_External == null) { // No point trying to authenticate if we haven't been given a delegate to load the SIP account. Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } else { m_sipAccount = GetSIPAccount_External(s => s.SIPUsername == m_sipUsername && s.SIPDomain == m_sipDomain); if (m_sipAccount == null) { Reject(SIPResponseStatusCodesEnum.Forbidden, null, null); } else { SIPRequest sipRequest = m_uasTransaction.TransactionRequest; SIPEndPoint localSIPEndPoint = (!sipRequest.Header.ProxyReceivedOn.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedOn) : sipRequest.LocalSIPEndPoint; SIPEndPoint remoteEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : sipRequest.RemoteSIPEndPoint; SIPRequestAuthenticationResult authenticationResult = SIPAuthenticateRequest_External(localSIPEndPoint, remoteEndPoint, sipRequest, m_sipAccount); if (authenticationResult.Authenticated) { if (authenticationResult.WasAuthenticatedByIP) { } else { } SetOwner(m_sipAccount.Owner, m_sipAccount.AdminMemberId); m_isAuthenticated = true; } else { // Send authorisation failure or required response SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; m_uasTransaction.SendFinalResponse(authReqdResponse); } } } } catch (Exception excp) { Logger.Logger.Error("Exception SIPServerUserAgent AuthenticateCall. ->" + excp.Message); Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } return(m_isAuthenticated); }
private RegisterResultEnum Register(SIPTransaction registerTransaction) { try { SIPRequest sipRequest = registerTransaction.TransactionRequest; SIPURI registerURI = sipRequest.URI; SIPToHeader toHeader = sipRequest.Header.To; string toUser = toHeader.ToURI.User; string canonicalDomain = (m_strictRealmHandling) ? GetCanonicalDomain_External(toHeader.ToURI.Host, true) : toHeader.ToURI.Host; int requestedExpiry = GetRequestedExpiry(sipRequest); if (canonicalDomain == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Warn, "Register request for " + toHeader.ToURI.Host + " rejected as no matching domain found.", null)); SIPResponse noDomainResponse = GetErrorResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); registerTransaction.SendFinalResponse(noDomainResponse); return(RegisterResultEnum.DomainNotServiced); } SIPAccountAsset sipAccountAsset = GetSIPAccount_External(s => s.SIPUsername == toUser && s.SIPDomain == canonicalDomain); SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(registerTransaction.LocalSIPEndPoint, registerTransaction.RemoteEndPoint, sipRequest, sipAccountAsset.SIPAccount, FireProxyLogEvent); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; registerTransaction.SendFinalResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Warn, "Forbidden " + toUser + "@" + canonicalDomain + " does not exist, " + sipRequest.Header.ProxyReceivedFrom + ", " + sipRequest.Header.UserAgent + ".", null)); return(RegisterResultEnum.Forbidden); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Registrar, "Authentication required for " + toUser + "@" + canonicalDomain + " from " + sipRequest.Header.ProxyReceivedFrom + ".", toUser)); return(RegisterResultEnum.AuthenticationRequired); } } else { // Authenticated. //if (!sipRequest.Header.UserAgent.IsNullOrBlank() && !m_switchboarduserAgentPrefix.IsNullOrBlank() && sipRequest.Header.UserAgent.StartsWith(m_switchboarduserAgentPrefix)) //{ // // Check that the switchboard user is authorised. // var customer = CustomerPersistor_External.Get(x => x.CustomerUsername == sipAccount.Owner); // if (!(customer.ServiceLevel == CustomerServiceLevels.Switchboard.ToString() || customer.ServiceLevel == CustomerServiceLevels.Gold.ToString())) // { // FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Warn, "Register request for switchboard from " + toHeader.ToURI.Host + " rejected as not correct service level.", sipAccount.Owner)); // SIPResponse payReqdResponse = GetErrorResponse(sipRequest, SIPResponseStatusCodesEnum.PaymentRequired, "You need to purchase a Switchboard service"); // registerTransaction.SendFinalResponse(payReqdResponse); // return RegisterResultEnum.SwitchboardPaymentRequired; // } //} 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(sipAccountAsset.Id); //List<SIPContactHeader> contactsList = m_registrarBindingsManager.GetContactHeader(); // registration.GetContactHeader(true, null); if (bindings != null) { sipRequest.Header.Contact = GetContactHeader(bindings); } SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegisterSuccess, "Empty registration request successful for " + toUser + "@" + canonicalDomain + " from " + sipRequest.Header.ProxyReceivedFrom + ".", toUser)); } else { SIPEndPoint uacRemoteEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? registerTransaction.RemoteEndPoint; SIPEndPoint proxySIPEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn); SIPEndPoint registrarEndPoint = registerTransaction.LocalSIPEndPoint; SIPResponseStatusCodesEnum updateResult = SIPResponseStatusCodesEnum.Ok; string updateMessage = null; DateTime startTime = DateTime.Now; List <SIPRegistrarBinding> bindingsList = m_registrarBindingsManager.UpdateBindings( sipAccountAsset.SIPAccount, proxySIPEndPoint, uacRemoteEndPoint, registrarEndPoint, //sipRequest.Header.Contact[0].ContactURI.CopyOf(), sipRequest.Header.Contact, sipRequest.Header.CallId, sipRequest.Header.CSeq, //sipRequest.Header.Contact[0].Expires, sipRequest.Header.Expires, sipRequest.Header.UserAgent, out updateResult, out updateMessage); //int bindingExpiry = GetBindingExpiry(bindingsList, sipRequest.Header.Contact[0].ContactURI.ToString()); TimeSpan duration = DateTime.Now.Subtract(startTime); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegistrarTiming, "Binding update time for " + toUser + "@" + canonicalDomain + " took " + duration.TotalMilliseconds + "ms.", null)); if (updateResult == SIPResponseStatusCodesEnum.Ok) { string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null; int bindingCount = 1; foreach (SIPRegistrarBinding binding in bindingsList) { string bindingIndex = (bindingsList.Count == 1) ? String.Empty : " (" + bindingCount + ")"; //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegisterSuccess, "Registration successful for " + toUser + "@" + canonicalDomain + " from " + uacRemoteEndPoint + proxySocketStr + ", binding " + binding.ContactSIPURI.ToParameterlessString() + ";expiry=" + binding.Expiry + bindingIndex + ".", toUser)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegisterSuccess, "Registration successful for " + toUser + "@" + canonicalDomain + " from " + uacRemoteEndPoint + ", binding " + binding.ContactSIPURI.ToParameterlessString() + ";expiry=" + binding.Expiry + bindingIndex + ".", toUser)); //FireProxyLogEvent(new SIPMonitorMachineEvent(SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingUpdate, toUser, uacRemoteEndPoint, sipAccount.Id.ToString())); bindingCount++; } // The standard states that the Ok response should contain the list of current bindings but that breaks some UAs. As a // compromise the list is returned with the Contact that UAC sent as the first one in the list. bool contactListSupported = m_userAgentConfigs.GetUserAgentContactListSupport(sipRequest.Header.UserAgent); if (contactListSupported) { sipRequest.Header.Contact = GetContactHeader(bindingsList); } else { // Some user agents can't match the contact header if the expiry is added to it. sipRequest.Header.Contact[0].Expires = GetBindingExpiry(bindingsList, sipRequest.Header.Contact[0].ContactURI.ToString());; } SIPResponse okResponse = GetOkResponse(sipRequest); // If a request was made for a switchboard token and a certificate is available to sign the tokens then generate it. //if (sipRequest.Header.SwitchboardTokenRequest > 0 && m_switchbboardRSAProvider != null) //{ // SwitchboardToken token = new SwitchboardToken(sipRequest.Header.SwitchboardTokenRequest, sipAccount.Owner, uacRemoteEndPoint.Address.ToString()); // lock (m_switchbboardRSAProvider) // { // token.SignedHash = Convert.ToBase64String(m_switchbboardRSAProvider.SignHash(Crypto.GetSHAHash(token.GetHashString()), null)); // } // string tokenXML = token.ToXML(true); // logger.Debug("Switchboard token set for " + sipAccount.Owner + " with expiry of " + token.Expiry + "s."); // okResponse.Header.SwitchboardToken = Crypto.SymmetricEncrypt(sipAccount.SIPPassword, sipRequest.Header.AuthenticationHeader.SIPDigest.Nonce, tokenXML); //} registerTransaction.SendFinalResponse(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. FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Error, "Registration request successful but binding update failed for " + toUser + "@" + canonicalDomain + " from " + registerTransaction.RemoteEndPoint + ".", toUser)); sipRequest.Header.Contact[0].Expires = m_minimumBindingExpiry; SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); } } return(RegisterResultEnum.Authenticated); } } catch (Exception excp) { string regErrorMessage = "Exception registrarcore registering. " + excp.Message + "\r\n" + registerTransaction.TransactionRequest.ToString(); logger.Error(regErrorMessage); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Error, regErrorMessage, null)); try { SIPResponse errorResponse = GetErrorResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); registerTransaction.SendFinalResponse(errorResponse); } catch { } return(RegisterResultEnum.Error); } }