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;
        }
Beispiel #2
0
        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 " + m_transaction.TransactionRequest.Method + " request 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);
            }
        }
        public Dictionary <Guid, object> LoadAssetsFromXMLRecordSet(XmlDocument dom)
        {
            try
            {
                Dictionary <Guid, object> assets = new Dictionary <Guid, object>();

                DataSet       sipAssetSet = new DataSet();
                XmlTextReader xmlReader   = new XmlTextReader(dom.OuterXml, XmlNodeType.Document, null);
                sipAssetSet.ReadXml(xmlReader);

                if (sipAssetSet != null && sipAssetSet.Tables != null && sipAssetSet.Tables.Count > 0)
                {
                    try
                    {
                        foreach (DataRow row in sipAssetSet.Tables[0].Rows)
                        {
                            SIPAccount sipAsset = new SIPAccount();
                            sipAsset.Load(row);
                            assets.Add(sipAsset.Id, sipAsset);
                        }
                    }
                    catch (Exception excp)
                    {
                        logger.Error("Exception loading SIP asset record in LoadAssetsFromXMLRecordSet (" + (new SIPAccount()).GetType().ToString() + "). " + excp.Message);
                    }

                    logger.Debug(" " + assets.Count + " " + (new SIPAccount()).GetType().ToString() + " assets loaded from XML record set.");
                }
                else
                {
                    //logger.Warn("The XML supplied to LoadAssetsFromXMLRecordSet for asset type " + (new T()).GetType().ToString() + " did not contain any assets.");
                    logger.Debug(" no " + (new SIPAccount()).GetType().ToString() + " assets loaded from XML record set.");
                }

                xmlReader.Close();

                return(assets);
            }
            catch (Exception excp)
            {
                logger.Error("Exception LoadAssetsFromXMLRecordSet. " + excp.Message);
                throw;
            }
        }
        /// <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;
        }
Beispiel #5
0
        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);
        }
        public static string ValidateAndClean(SIPAccount sipAccount)
        {
            if (sipAccount.Owner.IsNullOrBlank())
            {
                return("The owner must be specified when creating a new SIP account.");
            }
            if (sipAccount.SIPUsername.IsNullOrBlank())
            {
                return("The username must be specified when creating a new SIP account.");
            }
            if (sipAccount.SIPDomain.IsNullOrBlank())
            {
                return("The domain must be specified when creating a new SIP account.");
            }
            else if (sipAccount.SIPUsername.Length < USERNAME_MIN_LENGTH)
            {
                return("The username must be at least " + USERNAME_MIN_LENGTH + " characters long.");
            }
            else if (Regex.Match(sipAccount.SIPUsername, BANNED_SIPACCOUNT_NAMES).Success)
            {
                return("The username you have requested is not permitted.");
            }
            else if (Regex.Match(sipAccount.SIPUsername, "[^" + USERNAME_ALLOWED_CHARS + "]").Success)
            {
                return("The username had an invalid character, characters permitted are alpha-numeric and .-_.");
            }
            else if (sipAccount.SIPUsername.Contains(".") &&
                     (sipAccount.SIPUsername.Substring(sipAccount.SIPUsername.LastIndexOf(".") + 1).Trim().Length >= USERNAME_MIN_LENGTH &&
                      sipAccount.SIPUsername.Substring(sipAccount.SIPUsername.LastIndexOf(".") + 1).Trim() != sipAccount.Owner))
            {
                return("You are not permitted to create this username. Only user " + sipAccount.SIPUsername.Substring(sipAccount.SIPUsername.LastIndexOf(".") + 1).Trim() + " can create SIP accounts ending in " + sipAccount.SIPUsername.Substring(sipAccount.SIPUsername.LastIndexOf(".")).Trim() + ".");
            }
            else if (!sipAccount.IsIncomingOnly || !sipAccount.SIPPassword.IsNullOrBlank())
            {
                if (sipAccount.SIPPassword.IsNullOrBlank())
                {
                    return("A password must be specified.");
                }
                else if (sipAccount.SIPPassword.Length < PASSWORD_MIN_LENGTH || sipAccount.SIPPassword.Length > PASSWORD_MAX_LENGTH)
                {
                    return("The password field must be at least " + PASSWORD_MIN_LENGTH + " characters and no more than " + PASSWORD_MAX_LENGTH + " characters.");
                }
                else
                {
                    #region Check the password illegal characters.

                    char[] passwordChars = sipAccount.SIPPassword.ToCharArray();

                    bool illegalCharFound = false;
                    char illegalChar      = ' ';

                    foreach (char passwordChar in passwordChars)
                    {
                        if (Regex.Match(passwordChar.ToString(), "[a-zA-Z0-9]").Success)
                        {
                            continue;
                        }
                        else
                        {
                            bool validChar = false;
                            foreach (char allowedChar in NONAPLPHANUM_ALLOWED_PASSWORD_CHARS)
                            {
                                if (allowedChar == passwordChar)
                                {
                                    validChar = true;
                                    break;
                                }
                            }

                            if (validChar)
                            {
                                continue;
                            }
                            else
                            {
                                illegalCharFound = true;
                                illegalChar      = passwordChar;
                                break;
                            }
                        }
                    }

                    #endregion

                    if (illegalCharFound)
                    {
                        return("Your password has an invalid character " + illegalChar + " it can only contain a to Z, 0 to 9 and characters in this set " + SafeXML.MakeSafeXML(new String(NONAPLPHANUM_ALLOWED_PASSWORD_CHARS)) + ".");
                    }
                }
            }

            sipAccount.Owner       = sipAccount.Owner.Trim();
            sipAccount.SIPUsername = sipAccount.SIPUsername.Trim();
            sipAccount.SIPPassword = (sipAccount.SIPPassword.IsNullOrBlank()) ? null : sipAccount.SIPPassword.Trim();
            sipAccount.SIPDomain   = sipAccount.SIPDomain.Trim();

            return(null);
        }
Beispiel #7
0
        /// <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));
            }
        }