Course 2 / Lecture 2

How to build a VoIP PBX in C#

How to register and authenticaticate your VoIP PBX

In order to implement VoIP PBX registration and authentication functions in your SIP PBX your best choice is Ozeki VoIP SIP SDK. Ozeki SIP SDK ensures you all the necessary tools and background to develop a powerful and reliable SIP PBX. This guide explains with source codes how to achieve VoIP PBX registration and authentication with Ozeki SIP SDK.

Download: custom-auth.zip

This example program is based on the simple PBX implementation that is introduced in the "Default VoIP PBX Functionality" article. The following sections will show how you need to extend that program for user authentication purposes.

Introduction

Please be informed that PBX development support is available in Ozeki VoIP SIP SDK from version 10.0. You can download the latest Ozeki SIP SDK version from the download page.

A Private Branch Exchange (PBX) is the main tool for establishing communication lines in between communication end points. The phone line establishment is done through SIP authentication. This authentication can be automatic or can be restricted by special rules.

The example program in this article shows how you can define authentication rules for the PBX extensions' registration. Ozeki VoIP SIP SDK provides the basic PBX functionalities but you can redefine any behavior by overriding the provided methods. In this example code, the registration authentication method is redefined for only accepting the registration of SIP accounts of a certain range.

The following program code uses the background support of Ozeki VoIP SIP SDK, therefore you will need to download and install Ozeki SIP SDK on your computer before starting to use the program code. You will also need to have Visual Studio 2010 or compatible IDE and .NET Framework installed on your system, as the program code below is written in C# language.

The user authentication is a basic feature of a PBX system. The standard implementation Ozeki VoIP SIP SDK provides does not contain restrictions for the extension that want to register to the PBX. In this example, you will find how you can implement rules for the authentication in order to set which SIP accounts your PBX will accept for registration.

The registration data needs to be stored in some data structures. This example program uses two helping classes for this purpose. The user data are stored in the UserInfo class shown in Code 1. This class only stores the user name and password for the extensions that will be able to register to the PBX.

class UserInfo
{
        public UserInfo(string userName, string password)
        {
            UserName = userName;
            Password = password;
        }

        public string UserName { get; private set; }
        public string Password { get; private set; }
}
Code 1 - A simple data structure for user data

The user data (name and password) need to be stored somehow. In this case a simple container class is defined for this purpose. Code 2 shows the UserInfoContainer class that only handles a generic Dictionary that will store the extension data for the registration.

The allowed user data can be added to the user info container and the class can check if a certain data set is in the allowed Dictionary. This is the base of the authentication process.

class UserInfoContainer
{
        Dictionary<string, UserInfo> allowedUsers;

        public UserInfoContainer()
        {
            allowedUsers = new Dictionary<string, UserInfo>();
        }

        public void AddUserInfo(UserInfo userInfo)
        {
            if(allowedUsers.ContainsKey(userInfo.UserName))
                throw new InvalidOperationException("User already configured");

            allowedUsers.Add(userInfo.UserName, userInfo);
        }

        public bool TryGetUserInfo(string userName, out UserInfo userInfo)
        {
            return allowedUsers.TryGetValue(userName, out userInfo);
        }
}
Code 2 - A simple container class for user data handling

The PBX class of this example program is a bit extended version of the previous one. The example program has a method for setting the allowed extension user names and passwords shown in Code 3.

In this simple example the PBX will allow the registration of the extensions with the names from the range 100 to 109 with the same password as the user name. You can, of course set more restricted rules for the allowed extensions.

private void SetUserInfos()
{
    userInfoContainer = new UserInfoContainer();

    for (int i = 0; i < 10; i++)
    {
        var userName = string.Format("10{0}", i);
        var password = userName;

        userInfoContainer.AddUserInfo(new UserInfo(userName, password));
    }
}
Code 3 - Setting the user data that are allowed for registration

The allowed user data needs to be actually set in the constructor of the PBX (Code 4). The PBX class has a property of the UserInfoContainer class that will be filled up with the allowed data. The container is filled by the SetUserInfos(); instruction.

The constructor does not contain any other additional functionality, it basically prints the log information on the console as in the previous case, and all the other behaviors are the same as in the Ozeki VoIP SIP SDK implementation.

string localAddress;
UserInfoContainer userInfoContainer;

public MyPBX(string localAddress, int minPortRange, int maxPortRange) : base(minPortRange, maxPortRange)
{
	this.localAddress = localAddress;
	Console.WriteLine("PBX starting...");
	Console.WriteLine("Local address: " + localAddress);

	SetUserInfos();
}
Code 4 - Extended constructor for authentication

The actual authentication process needs to be implemented in the OnAuthenticationRequest method. This method is implemented with a standard (no authentication) behavior in the Ozeki SDK, but in this case, you need to override it (Code 5).

The authentication process works with checking the user name and password the extension sends during the registration process. The PBX checks if the name-password pair is a valid one and if so, the registration will be allowed or it will be denied otherwise.

The actual checking means that the PBX tries to look for the user name and password in the user info container. In case the user info container includes the user name and password, the registration will be allowed.

		protected override AuthenticationResult OnAuthenticationRequest(ISIPExtension extension, RequestAuthenticationInfo authInfo)
        {
            Console.WriteLine("Authentication request received from: " + extension.ExtensionID);

            AuthenticationResult result = new AuthenticationResult();

            UserInfo userInfo;
            if (userInfoContainer.TryGetUserInfo(extension.ExtensionID, out userInfo))
            {
                result = extension.CheckPassword(userInfo.UserName, userInfo.Password, authInfo);
            }
            else
            {
                Console.WriteLine("Cannot find extension. UserName: " + extension.ExtensionID);
            }

            if (result.AuthenticationAccepted)
            {
                Console.WriteLine("Authentication accepted. UserName: " + extension.ExtensionID);
            }
            else
            {
                Console.WriteLine("Authentication failed. UserName: " + extension.ExtensionID);
            }

            return result;
        }
Code 5 - The authentication process

By this time you are familiar with the basic concepts of the extension authentication in a PBX. The example program will be your absolute help during development. After reading this article, you will be able to write your own authentication rules in your PBX solution.

If you have any questions or need assistance, please contact us at info@voip-sip-sdk.com

You can select an Ozeki VoIP SIP SDK license for building your PBX on licensing information page

Related Pages

More information