public void ProcessExtensionAuthentication(PreprocessSipRequestEventArgs e)
        {
            try
            {
                SIPURI fromURI = new SIPURI(e.Request.HeaderFields["From", "f"].FieldValue);

                // Is this coming from an internal extension
                WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, Convert.ToInt32(fromURI.User));

                if (extension != null)
                {
                    if (ProcessRequestAuthorization(e, fromURI, false))
                    {
                        e.Handled = false;
                    }
                    else
                    {
                        e.Handled = true;
                    }
                }
            }
            catch
            {
            }
        }
        private bool ProcessRequestAuthorization(PreprocessSipRequestEventArgs e, SIPURI fromURI, bool requireRegistration)
        {
            try
            {
                switch (e.Request.SIPMethodType)
                {
                    case SIPMethodType.INVITE:
                    case SIPMethodType.REGISTER:

                        //if (Properties.Settings.Default.SIPRegistrarDomain == null || Properties.Settings.Default.SIPRegistrarDomain.Length == 0 || fromURI.Host == ipClient.LocalIPAddress /*|| fromURI.Host == ipClient.Sip*/ || string.Compare(fromURI.Host, Properties.Settings.Default.SIPRegistrarDomain, true) == 0)
                        //{
                            int extensionNumber = Convert.ToInt32(fromURI.User);

                            // Check to see if this is a valid extension
                            WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, extensionNumber);

                            if (extension == null)
                            {
                                ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                                return false;
                            }

                            // Get our PBX password from our database
                            string pbxPassword = "";

                            if (extension.PBXPassword.Length > 0)
                                pbxPassword = WOSI.Utilities.CryptoUtils.Decrypt(extension.PBXPassword, WOSI.CallButler.Data.Constants.EncryptionPassword);

                            if (requireRegistration && !PresenceInfoExists(extensionNumber, e.Request.SentFrom, e.Request.SentFromPort, true))
                            {
                                // If we require registration and the SIP client isn't registered, return a 404 not found
                                ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));

                                return false;
                            }
                            else if (IsRequestAuthorized(e.Request, extensionNumber.ToString(), pbxPassword))
                            {
                                return true;
                            }
                            else
                            {
                                string realmDomain = Properties.Settings.Default.SIPRegistrarDomain;

                                if (realmDomain == null || realmDomain.Length == 0)
                                    realmDomain = ipClient.LocalIPAddress;

                                // Tell the client that we need authorization
                                string authString = string.Format("Digest realm=\"{0}\", domain=\"sip:{1}\", nonce=\"{2}\", algorithm=MD5", realmDomain, realmDomain, Guid.NewGuid().ToString());

                                SipResponse response = e.Request.CreateResponse(401, "Unauthorized");
                                response.HeaderFields.InsertAfter("CSeq", "WWW-Authenticate", authString);
                                ipClient.SendSipResponse(response);

                                return false;
                            }
                        /*}
                        else
                        {
                            ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                            return false;
                        }*/

                        break;

                    default:
                        return true;
                }
            }
            catch
            {
            }

            return false;
        }
        void ProcessRegister(PreprocessSipRequestEventArgs e)
        {
            e.Handled = true;
            bool isNewRegistration = false;

            // Remove the Record-Route field as per RFC-3261 10.3
            if (e.Request.HeaderFields.Contains("Record-Route", null))
                e.Request.HeaderFields.Remove("Record-Route");

            try
            {
                SIPURI addressOfRecord = new SIPURI(e.Request.HeaderFields["To", "t"].FieldValue);

                // Make sure the request is authorized
                if (ProcessRequestAuthorization(e, addressOfRecord, false))
                {
                    int extensionNumber = 0;

                    try
                    {
                        extensionNumber = Convert.ToInt32(addressOfRecord.User);
                    }
                    catch
                    {
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                        return;
                    }

                    PBXPresenceInfo presenceInfo = FindPresenceInfo(extensionNumber, e.Request.SentFrom, e.Request.SentFromPort, true);

                    if (e.Request.HeaderFields.Contains("Contact", "m"))
                    {
                        HeaderField[] contactFields = e.Request.HeaderFields.GetMultiHeaderFields("Contact", "m");

                        bool containsStar = false;

                        foreach (HeaderField contactField in contactFields)
                        {
                            if (contactField.FieldValue == "*")
                            {
                                containsStar = true;
                            }
                        }

                        if (containsStar)
                        {
                            if (contactFields.Length > 1 || !e.Request.HeaderFields.Contains("Expires", null) || e.Request.HeaderFields["Expires", null].FieldValue.Trim() != "0")
                            {
                                ipClient.SendSipResponse(e.Request.CreateResponse(400, "Invalid Request"));
                                return;
                            }
                        }

                        int requestedExpiration = 0;

                        if (contactFields[0].ContainsParameter("Expires"))
                            requestedExpiration = Convert.ToInt32(contactFields[0].Parameters["Expires"]);
                        else if (e.Request.HeaderFields.Contains("Expires", null))
                            requestedExpiration = Convert.ToInt32(e.Request.HeaderFields["Expires", null].FieldValue);
                        else
                            requestedExpiration = Properties.Settings.Default.PresenceTimeout;

                        if (presenceInfo != null)
                        {
                            // Check the Call-ID
                            string callID = e.Request.HeaderFields["Call-ID", "i"].FieldValue;

                            if (callID == presenceInfo.SessionID)
                            {
                                // Parse our CSeq
                                int cSeq = Convert.ToInt32(e.Request.HeaderFields["CSeq", null].FieldValue.Split(' ')[0]);

                                if (cSeq < presenceInfo.CSeq)
                                {
                                    RemovePresenceInfo(presenceInfo);

                                    ipClient.SendSipResponse(e.Request.CreateResponse(400, "Invalid Request"));

                                    return;
                                }
                            }

                            if (requestedExpiration == 0)
                            {
                                RemovePresenceInfo(presenceInfo);
                                ipClient.SendSipResponse(e.Request.CreateResponse(200, "OK"));
                                return;
                            }
                        }
                        else
                        {
                            presenceInfo = new PBXPresenceInfo();
                            isNewRegistration = true;
                        }

                        presenceInfo.AddressOfRecord = new SIPURI(e.Request.HeaderFields["To", "t"].FieldValue).BasicURIStringWithoutParameters;
                        presenceInfo.CSeq = Convert.ToInt32(e.Request.HeaderFields["CSeq", null].FieldValue.Split(' ')[0]);
                        presenceInfo.ExpiresInSeconds = requestedExpiration;
                        presenceInfo.ExtensionNumber = extensionNumber;
                        presenceInfo.LastRegistration = DateTime.Now;
                        presenceInfo.Name = addressOfRecord.DisplayName;
                        presenceInfo.RemoteAddress = e.Request.SentFrom;
                        presenceInfo.RemotePort = e.Request.SentFromPort;
                        presenceInfo.SessionID = e.Request.HeaderFields["Call-ID", "i"].FieldValue;
                        presenceInfo.Status = PBXPresenceStatus.Online;

                        if (isNewRegistration)
                        {
                            lock (presenceDataLock)
                            {
                                presenceData.Add(presenceInfo);
                                LoggingService.AddLogEntry(WOSI.CallButler.ManagementInterface.LogLevel.Extended, "Extension " + presenceInfo.ExtensionNumber + " registered for " + presenceInfo.RemoteAddress, false);

                                UpdateExtensionState(presenceInfo);
                            }
                        }
                    }

                    if (presenceInfo != null)
                    {
                        SipResponse response = e.Request.CreateResponse(200, "OK");

                        response.HeaderFields.InsertAfter("CSeq", e.Request.HeaderFields["Contact", "m"]);
                        response.HeaderFields["Contact", "m"].Parameters["expires"] = presenceInfo.ExpiresInSeconds.ToString();
                        response.HeaderFields.InsertAfter("Contact", "Date", DateTime.Now.ToUniversalTime().ToString("ddd, d MMM yyyy HH:mm:ss G\\MT"));

                        ipClient.SendSipResponse(response);

                        // Send our message waiting notification
                        if(isNewRegistration)
                            SendMessageWaitingNotification(extensionNumber);

                        PerformanceCounterService.PhonesRegistered = presenceData.Count;
                    }
                    else
                    {
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                    }

                    return;
                }
            }
            catch (Exception ex)
            {
                ipClient.SendSipResponse(e.Request.CreateResponse(500, "Server Error"));
                LoggingService.AddLogEntry(WOSI.CallButler.ManagementInterface.LogLevel.ErrorsOnly, Utils.ErrorUtils.FormatErrorString(ex), true);
            }
        }
        public void ProcessExtensionAuthentication(PreprocessSipRequestEventArgs e)
        {
            try
            {
                SIPURI fromURI = new SIPURI(e.Request.HeaderFields["From", "f"].FieldValue);

                // Is this coming from an internal extension
                WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, Convert.ToInt32(fromURI.User));

                if (extension != null)
                {
                    if (ProcessRequestAuthorization(e, fromURI, false))
                        e.Handled = false;
                    else
                        e.Handled = true;
                }
            }
            catch
            {
            }
        }
        private bool ProcessRequestAuthorization(PreprocessSipRequestEventArgs e, SIPURI fromURI, bool requireRegistration)
        {
            try
            {
                switch (e.Request.SIPMethodType)
                {
                case SIPMethodType.INVITE:
                case SIPMethodType.REGISTER:

                    //if (Properties.Settings.Default.SIPRegistrarDomain == null || Properties.Settings.Default.SIPRegistrarDomain.Length == 0 || fromURI.Host == ipClient.LocalIPAddress /*|| fromURI.Host == ipClient.Sip*/ || string.Compare(fromURI.Host, Properties.Settings.Default.SIPRegistrarDomain, true) == 0)
                    //{
                    int extensionNumber = Convert.ToInt32(fromURI.User);

                    // Check to see if this is a valid extension
                    WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension = dataProvider.GetExtensionNumber(Properties.Settings.Default.CustomerID, extensionNumber);

                    if (extension == null)
                    {
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                        return(false);
                    }

                    // Get our PBX password from our database
                    string pbxPassword = "";

                    if (extension.PBXPassword.Length > 0)
                    {
                        pbxPassword = WOSI.Utilities.CryptoUtils.Decrypt(extension.PBXPassword, WOSI.CallButler.Data.Constants.EncryptionPassword);
                    }

                    if (requireRegistration && !PresenceInfoExists(extensionNumber, e.Request.SentFrom, e.Request.SentFromPort, true))
                    {
                        // If we require registration and the SIP client isn't registered, return a 404 not found
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));

                        return(false);
                    }
                    else if (IsRequestAuthorized(e.Request, extensionNumber.ToString(), pbxPassword))
                    {
                        return(true);
                    }
                    else
                    {
                        string realmDomain = Properties.Settings.Default.SIPRegistrarDomain;

                        if (realmDomain == null || realmDomain.Length == 0)
                        {
                            realmDomain = ipClient.LocalIPAddress;
                        }

                        // Tell the client that we need authorization
                        string authString = string.Format("Digest realm=\"{0}\", domain=\"sip:{1}\", nonce=\"{2}\", algorithm=MD5", realmDomain, realmDomain, Guid.NewGuid().ToString());

                        SipResponse response = e.Request.CreateResponse(401, "Unauthorized");
                        response.HeaderFields.InsertAfter("CSeq", "WWW-Authenticate", authString);
                        ipClient.SendSipResponse(response);

                        return(false);
                    }

                    /*}
                     * else
                     * {
                     *  ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                     *  return false;
                     * }*/

                    break;

                default:
                    return(true);
                }
            }
            catch
            {
            }

            return(false);
        }
        void ProcessRegister(PreprocessSipRequestEventArgs e)
        {
            e.Handled = true;
            bool isNewRegistration = false;

            // Remove the Record-Route field as per RFC-3261 10.3
            if (e.Request.HeaderFields.Contains("Record-Route", null))
            {
                e.Request.HeaderFields.Remove("Record-Route");
            }

            try
            {
                SIPURI addressOfRecord = new SIPURI(e.Request.HeaderFields["To", "t"].FieldValue);

                // Make sure the request is authorized
                if (ProcessRequestAuthorization(e, addressOfRecord, false))
                {
                    int extensionNumber = 0;

                    try
                    {
                        extensionNumber = Convert.ToInt32(addressOfRecord.User);
                    }
                    catch
                    {
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                        return;
                    }

                    PBXPresenceInfo presenceInfo = FindPresenceInfo(extensionNumber, e.Request.SentFrom, e.Request.SentFromPort, true);

                    if (e.Request.HeaderFields.Contains("Contact", "m"))
                    {
                        HeaderField[] contactFields = e.Request.HeaderFields.GetMultiHeaderFields("Contact", "m");

                        bool containsStar = false;

                        foreach (HeaderField contactField in contactFields)
                        {
                            if (contactField.FieldValue == "*")
                            {
                                containsStar = true;
                            }
                        }

                        if (containsStar)
                        {
                            if (contactFields.Length > 1 || !e.Request.HeaderFields.Contains("Expires", null) || e.Request.HeaderFields["Expires", null].FieldValue.Trim() != "0")
                            {
                                ipClient.SendSipResponse(e.Request.CreateResponse(400, "Invalid Request"));
                                return;
                            }
                        }

                        int requestedExpiration = 0;

                        if (contactFields[0].ContainsParameter("Expires"))
                        {
                            requestedExpiration = Convert.ToInt32(contactFields[0].Parameters["Expires"]);
                        }
                        else if (e.Request.HeaderFields.Contains("Expires", null))
                        {
                            requestedExpiration = Convert.ToInt32(e.Request.HeaderFields["Expires", null].FieldValue);
                        }
                        else
                        {
                            requestedExpiration = Properties.Settings.Default.PresenceTimeout;
                        }

                        if (presenceInfo != null)
                        {
                            // Check the Call-ID
                            string callID = e.Request.HeaderFields["Call-ID", "i"].FieldValue;

                            if (callID == presenceInfo.SessionID)
                            {
                                // Parse our CSeq
                                int cSeq = Convert.ToInt32(e.Request.HeaderFields["CSeq", null].FieldValue.Split(' ')[0]);

                                if (cSeq < presenceInfo.CSeq)
                                {
                                    RemovePresenceInfo(presenceInfo);

                                    ipClient.SendSipResponse(e.Request.CreateResponse(400, "Invalid Request"));

                                    return;
                                }
                            }

                            if (requestedExpiration == 0)
                            {
                                RemovePresenceInfo(presenceInfo);
                                ipClient.SendSipResponse(e.Request.CreateResponse(200, "OK"));
                                return;
                            }
                        }
                        else
                        {
                            presenceInfo      = new PBXPresenceInfo();
                            isNewRegistration = true;
                        }

                        presenceInfo.AddressOfRecord  = new SIPURI(e.Request.HeaderFields["To", "t"].FieldValue).BasicURIStringWithoutParameters;
                        presenceInfo.CSeq             = Convert.ToInt32(e.Request.HeaderFields["CSeq", null].FieldValue.Split(' ')[0]);
                        presenceInfo.ExpiresInSeconds = requestedExpiration;
                        presenceInfo.ExtensionNumber  = extensionNumber;
                        presenceInfo.LastRegistration = DateTime.Now;
                        presenceInfo.Name             = addressOfRecord.DisplayName;
                        presenceInfo.RemoteAddress    = e.Request.SentFrom;
                        presenceInfo.RemotePort       = e.Request.SentFromPort;
                        presenceInfo.SessionID        = e.Request.HeaderFields["Call-ID", "i"].FieldValue;
                        presenceInfo.Status           = PBXPresenceStatus.Online;

                        if (isNewRegistration)
                        {
                            lock (presenceDataLock)
                            {
                                presenceData.Add(presenceInfo);
                                LoggingService.AddLogEntry(WOSI.CallButler.ManagementInterface.LogLevel.Extended, "Extension " + presenceInfo.ExtensionNumber + " registered for " + presenceInfo.RemoteAddress, false);

                                UpdateExtensionState(presenceInfo);
                            }
                        }
                    }

                    if (presenceInfo != null)
                    {
                        SipResponse response = e.Request.CreateResponse(200, "OK");

                        response.HeaderFields.InsertAfter("CSeq", e.Request.HeaderFields["Contact", "m"]);
                        response.HeaderFields["Contact", "m"].Parameters["expires"] = presenceInfo.ExpiresInSeconds.ToString();
                        response.HeaderFields.InsertAfter("Contact", "Date", DateTime.Now.ToUniversalTime().ToString("ddd, d MMM yyyy HH:mm:ss G\\MT"));

                        ipClient.SendSipResponse(response);

                        // Send our message waiting notification
                        if (isNewRegistration)
                        {
                            SendMessageWaitingNotification(extensionNumber);
                        }

                        PerformanceCounterService.PhonesRegistered = presenceData.Count;
                    }
                    else
                    {
                        ipClient.SendSipResponse(e.Request.CreateResponse(404, "Not Found"));
                    }

                    return;
                }
            }
            catch (Exception ex)
            {
                ipClient.SendSipResponse(e.Request.CreateResponse(500, "Server Error"));
                LoggingService.AddLogEntry(WOSI.CallButler.ManagementInterface.LogLevel.ErrorsOnly, Utils.ErrorUtils.FormatErrorString(ex), true);
            }
        }