public ManualResetEvent DelayMRE; // If the call needs to be delayed DelaySeconds this MRE will be used. /// <summary> /// /// </summary> /// <param name="toSIPAccount"></param> /// <param name="uri">The uri can be different to the to SIP account if a dotted notation is used. For /// example [email protected].</param> /// <param name="fromHeader"></param> /// <param name="contentType"></param> /// <param name="content"></param> public SIPCallDescriptor(SIPAccount toSIPAccount, string uri, string fromHeader, string contentType, string content) { ToSIPAccount = toSIPAccount; Uri = uri ?? toSIPAccount.SIPUsername + "@" + toSIPAccount.SIPDomain; From = fromHeader; ContentType = contentType; Content = content; }
public bool LoadSIPAccountForIncomingCall() { try { bool loaded = false; 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) { // A full lookup failed. Now try a partial lookup if the incoming username is in a dotted domain name format. if (m_sipUsername.Contains(".")) { string sipUsernameSuffix = m_sipUsername.Substring(m_sipUsername.LastIndexOf(".") + 1); m_sipAccount = GetSIPAccount_External(s => s.SIPUsername == sipUsernameSuffix && s.SIPDomain == m_sipDomain); } if (m_sipAccount == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Rejecting public call for " + m_sipUsername + "@" + m_sipDomain + ", SIP account not found.", null)); Reject(SIPResponseStatusCodesEnum.NotFound, null, null); } else { loaded = true; } } else { loaded = true; } } if (loaded) { SetOwner(m_sipAccount.Owner, m_sipAccount.AdminMemberId); } return(loaded); } catch (Exception excp) { logger.Error("Exception LoadSIPAccountForIncomingCall. " + excp.Message); Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); return(false); } }
/// <summary></summary> /// <param name="uacRecvdEndPoint">If this is non-null it indicates the contact header should be mangled based on the public socket the register request was demmed /// to have originated from rather then relying on the contact value recieved from the uac.</param> public SIPRegistrarBinding( SIPAccount sipAccount, SIPURI bindingURI, string callId, int cseq, string userAgent, SIPEndPoint remoteSIPEndPoint, SIPEndPoint proxySIPEndPoint, SIPEndPoint registrarSIPEndPoint, int expiry) { Id = Guid.NewGuid(); LastUpdate = DateTime.UtcNow; SIPAccountId = sipAccount.Id; SIPAccountName = sipAccount.SIPUsername + "@" + sipAccount.SIPDomain; Owner = sipAccount.Owner; AdminMemberId = sipAccount.AdminMemberId; m_contactURI = bindingURI.CopyOf(); m_mangledContactURI = m_contactURI.CopyOf(); CallId = callId; CSeq = cseq; UserAgent = userAgent; RemoteSIPEndPoint = remoteSIPEndPoint; m_proxySIPEndPoint = proxySIPEndPoint; m_registrarSIPEndPoint = registrarSIPEndPoint; //if (SIPTransport.IsPrivateAddress(sipRequest.Header.Contact[0].ContactURI.Host) && m_mangleUACContact) if (!sipAccount.DontMangleEnabled && Regex.Match(m_mangledContactURI.Host, @"(\d+\.){3}\d+").Success) { // The Contact URI Host is used by registrars as the contact socket for the user so it needs to be changed to reflect the socket // the intial request was received on in order to work around NAT. It's no good just relying on private addresses as a lot of User Agents // determine their public IP but NOT their public port so they send the wrong port in the Contact header. //logger.Debug("Mangling contact header from " + m_mangledContactURI.Host + " to " + IPSocket.GetSocketString(uacRecvdEndPoint) + "."); m_mangledContactURI.Host = remoteSIPEndPoint.GetIPEndPoint().ToString(); } m_expiry = expiry; }
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 call for " + m_sipUsername + "@" + m_sipDomain + ", SIP account not found.", 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, Log_External); if (authenticationResult.Authenticated) { if (authenticationResult.WasAuthenticatedByIP) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "New call from " + remoteEndPoint.ToString() + " successfully authenticated by IP address.", m_sipAccount.Owner)); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "New call 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, "Call not authenticated for " + m_sipUsername + "@" + m_sipDomain + ", responding with " + authenticationResult.ErrorResponse + ".", null)); m_uasTransaction.SendFinalResponse(authReqdResponse); } } } } catch (Exception excp) { logger.Error("Exception SIPServerUserAgent AuthenticateCall. " + excp.Message); Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } return(m_isAuthenticated); }
/// <summary> /// Authenticates a SIP request. /// </summary> public static SIPRequestAuthenticationResult AuthenticateSIPRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest, SIPAccount sipAccount, SIPMonitorLogDelegate logSIPMonitorEvent) { try { if (sipAccount == null) { return(new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Forbidden, null)); } else if (sipAccount.IsDisabled) { logSIPMonitorEvent?.Invoke(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.DialPlan, "SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " is disabled for " + sipRequest.Method + ".", sipAccount.Owner)); return(new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Forbidden, null)); } else { SIPAuthenticationHeader reqAuthHeader = sipRequest.Header.AuthenticationHeader; if (reqAuthHeader == null) { // Check for IP address authentication. if (!sipAccount.IPAddressACL.IsNullOrBlank()) { SIPEndPoint uaEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : remoteEndPoint; if (Regex.Match(uaEndPoint.GetIPEndPoint().ToString(), sipAccount.IPAddressACL).Success) { // Successfully authenticated return(new SIPRequestAuthenticationResult(true, true)); } } SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce()); return(new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader)); } else { return(new SIPRequestAuthenticationResult(true, false)); //// Check for IP address authentication. //if (!sipAccount.IPAddressACL.IsNullOrBlank()) //{ // SIPEndPoint uaEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : remoteEndPoint; // if (Regex.Match(uaEndPoint.GetIPEndPoint().ToString(), sipAccount.IPAddressACL).Success) // { // // Successfully authenticated // return new SIPRequestAuthenticationResult(true, true); // } //} //string requestNonce = reqAuthHeader.SIPDigest.Nonce; //string uri = reqAuthHeader.SIPDigest.URI; //string response = reqAuthHeader.SIPDigest.Response; //// Check for stale nonces. //if (IsNonceStale(requestNonce)) //{ // if (logSIPMonitorEvent != null) // { // logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Warn, "Authentication failed stale nonce for realm=" + sipAccount.SIPDomain + ", username="******", uri=" + uri + ", nonce=" + requestNonce + ", method=" + sipRequest.Method + ".", null)); // } // SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce()); // return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader); //} //else //{ // SIPAuthorisationDigest checkAuthReq = reqAuthHeader.SIPDigest; // checkAuthReq.SetCredentials(sipAccount.SIPUsername, sipAccount.SIPPassword, uri, sipRequest.Method.ToString()); // string digest = checkAuthReq.Digest; // if (digest == response) // { // // Successfully authenticated // return new SIPRequestAuthenticationResult(true, false); // } // else // { // if (logSIPMonitorEvent != null) // { // logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Warn, "Authentication token check failed for realm=" + sipAccount.SIPDomain + ", username="******", uri=" + uri + ", nonce=" + requestNonce + ", method=" + sipRequest.Method + ".", sipAccount.Owner)); // } // SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce()); // return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader); // } //} } } } catch (Exception excp) { logSIPMonitorEvent?.Invoke(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Error, "Exception AuthoriseSIPRequest. " + excp.Message, null)); return(new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.InternalServerError, null)); } }