//--------------------------------------------------------------------- // Static members /// <summary> /// Reads the RADIUS server settings from the application's configuration /// using the specified key prefix. /// </summary> /// <param name="keyPrefix">The application configuration key prefix.</param> /// <returns>The server settings.</returns> /// <remarks> /// <para> /// The RADIUS server settings are loaded from the application /// configuration, under the specified key prefix. The following /// settings are recognized by the class: /// </para> /// <div class="tablediv"> /// <table class="dtTABLE" cellspacing="0" ID="Table1"> /// <tr valign="top"> /// <th width="1">Setting</th> /// <th width="1">Default</th> /// <th width="90%">Description</th> /// </tr> /// <tr valign="top"> /// <td>NetworkBinding</td> /// <td>ANY:RADIUS</td> /// <td> /// Specifies the network binding for the server expressed as an IP address and port. /// An IP address of 0.0.0.0 specifies that the server is bound to all network interfaces. /// </td> /// </tr> /// <tr valign="top"> /// <td>SocketBuffer</td> /// <td>128K</td> /// <td> /// Byte size of the server socket's send and receive buffers. /// </td> /// </tr> /// <tr valign="top"> /// <td>DnsRefreshInterval</td> /// <td>15m</td> /// <td> /// Specifies the interval at which Network Access Service (NAS) DNS host /// names will be requeried to resolve to the IP addresses used to /// identify the NAS device. /// </td> /// </tr> /// <tr valign="top"> /// <td>BkTaskInterval</td> /// <td>1m</td> /// <td> /// Specifies the interval at which the server will process background tasks. /// </td> /// </tr> /// <tr valign="top"> /// <td>Devices[#]</td> /// <td>(none)</td> /// <td> /// <para> /// An optional array of entries describing the known NAS devices. The format for /// each entry is: /// </para> /// <code lang="none"> /// <host name or IP address> ";" <shared secret> /// </code> /// <para> /// which maps the devices host name or IP address to the shared secret (aka the password). /// </para> /// </td> /// </tr> /// <tr valign="top"> /// <td>DefaultSecret</td> /// <td>(none)</td> /// <td> /// <para> /// This setting, if present specifies a default NAS shared secret. This secret /// will be used to attempt to decrypt passwords from RADIUS packets received /// from NAS devices that we're not specifically listed in the <b>Devices[#]</b> /// setting array. This is a convenient feature for IT operations but its /// use will reduce the security of the service a bit. /// </para> /// </td> /// </tr> /// <tr valign="top"> /// <td>RealmFormat</td> /// <td>Email</td> /// <td> /// Specifies how the <b>realm</b> and <b>account</b> components are /// to be parsed from a user name. See <see cref="LillTek.Common.RealmFormat" /> /// for more information. The possible values are: <b>Slash</b> and <b>Email</b>. /// </td> /// </tr> /// </table> /// </div> /// </remarks> public static RadiusServerSettings LoadConfig(string keyPrefix) { var config = new Config(keyPrefix); var settings = new RadiusServerSettings(); string[] devices; settings.NetworkBinding = config.Get("NetworkBinding", settings.NetworkBinding); settings.SocketBuffer = config.Get("SocketBuffer", settings.SocketBuffer); settings.DnsRefreshInterval = config.Get("DnsRefreshInterval", settings.DnsRefreshInterval); settings.BkTaskInterval = config.Get("BkTaskInterval", settings.BkTaskInterval); settings.DefaultSecret = config.Get("DefaultSecret", settings.DefaultSecret); settings.RealmFormat = config.Get <RealmFormat>("RealmFormat", settings.RealmFormat); if (settings.NetworkBinding.IsHost) { throw new RadiusException("[{0}] is not a valid RADIUS server network binding.", settings.NetworkBinding); } // Load the NAS device information devices = config.GetArray("Devices", new string[0]); for (int i = 0; i < devices.Length; i++) { string host; IPAddress address; string password; int pos; pos = devices[i].IndexOf(';'); if (pos == -1) { throw new RadiusException("{0}Devices[{1}] configuration setting missing a ':'.", config.KeyPrefix, i); } host = devices[i].Substring(0, pos).Trim(); password = devices[i].Substring(pos + 1).Trim(); if (host == string.Empty) { throw new RadiusException("{0}Devices[{1}] configuration setting has an invalid device host name or IP address.", config.KeyPrefix, i); } if (Helper.TryParseIPAddress(host, out address)) { settings.Devices.Add(new RadiusNasInfo(address, password)); } else { settings.Devices.Add(new RadiusNasInfo(host, password)); } } return(settings); }
/// <summary> /// Starts the server using the settings passed. /// </summary> /// <param name="settings">The server settings.</param> /// <remarks> /// <note> /// All successful calls to <b>Start()</b> must eventually be matched /// with a call to <see cref="Stop" /> so that system resources will be /// released promptly. /// </note> /// </remarks> public void Start(RadiusServerSettings settings) { using (TimedLock.Lock(this)) { if (isRunning) { throw new RadiusException("RADIUS server has already started."); } this.sock = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); this.sock.Bind(settings.NetworkBinding); this.sock.SendBufferSize = settings.SocketBuffer; this.sock.ReceiveBufferSize = settings.SocketBuffer; this.isRunning = true; this.defSecret = settings.DefaultSecret; this.networkBinding = settings.NetworkBinding; this.dnsRefreshInterval = settings.DnsRefreshInterval; this.nextDnsRefresh = SysTime.Now + dnsRefreshInterval; this.bkTimer = new GatedTimer(new TimerCallback(OnBkTask), null, settings.BkTaskInterval, settings.BkTaskInterval); this.recvBuf = new byte[TcpConst.MTU]; this.Devices = settings.Devices; this.onReceive = new AsyncCallback(OnReceive); this.remoteEP = new IPEndPoint(IPAddress.Any, 0); this.realmFormat = settings.RealmFormat; if (networkBinding.Address.Equals(IPAddress.Any)) { actualEndPoint = new IPEndPoint(NetHelper.GetActiveAdapter(), ((IPEndPoint)sock.LocalEndPoint).Port); } else { actualEndPoint = new IPEndPoint(networkBinding.Address, ((IPEndPoint)sock.LocalEndPoint).Port); } this.sock.BeginReceiveFrom(recvBuf, 0, recvBuf.Length, SocketFlags.None, ref remoteEP, onReceive, null); } }
/// <summary> /// Starts the server using settings gathered from the application /// configuration. /// </summary> /// <param name="keyPrefix"> /// The key prefix to use when loading server settings from the /// application configuration. /// </param> /// <remarks> /// <para> /// The RADIUS server settings are loaded from the application /// configuration, using the specified key prefix. See /// <see cref="RadiusServerSettings.LoadConfig" /> for a description /// of the server application configuration settings. /// </para> /// <note> /// All successful calls to <b>Start()</b> must eventually be matched /// with a call to <see cref="Stop" /> so that system resources will be /// released promptly. /// </note> /// </remarks> public void Start(string keyPrefix) { Start(RadiusServerSettings.LoadConfig(keyPrefix)); }