Files
Hermes/TorControlLibrary/ExitPolicy.cs
2022-06-11 16:42:18 -04:00

119 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
namespace TorControlLibrary
{
public class ExitPolicy
{
public ExitPolicy() { }
public ExitPolicy(String policy)
{
ParsePolicy(policy);
}
public void ParsePolicy(String policy)
{
int count = 0;
StringReader sr = new StringReader(policy);
while (true)
{
String line = sr.ReadLine();
if (String.IsNullOrEmpty(line))
break;
Policy.Add(count++, new PolicyLine(line));
}
}
public Boolean IsAcceptableDestination(IPEndPoint destination)
{
return checkAddress((UInt32)System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(destination.Address.GetAddressBytes(), 0)), (UInt16)destination.Port);
}
public Boolean IsAcceptableDestination(IPAddress address, UInt16 port)
{
return checkAddress((UInt32)System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(address.GetAddressBytes(), 0)), port);
}
private Boolean checkAddress(UInt32 address, UInt16 port)
{
//the first match dictates the appropriate action
for (int i = 0; i < Policy.Count; i++)
{
if (Policy[i].AddressRangeStart <= address &&
Policy[i].AddressRangeEnd >= address)
if (Policy[i].PortRangeStart <= port &&
Policy[i].PortRangeEnd >= port)
return Policy[i].Action.Equals("accept");
}
return false;
}
private SortedList<Int32, PolicyLine> Policy = new SortedList<int,PolicyLine>();
class PolicyLine
{
public PolicyLine(String line)
{
Int32 ptr = line.IndexOf(' ');
Action = line.Substring(0, ptr);
ptr++;
//Address
String address = line.Substring(ptr, line.IndexOf(':') - ptr);
if (address.Equals("*"))
{
AddressRangeStart = UInt32.MinValue;
AddressRangeEnd = UInt32.MaxValue;
}
else
{
if (address.Contains("/"))
{ //range
String[] rangeParts = address.Split('/');
System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse(rangeParts[0]);
UInt32 mask = ((UInt32)0xFFFFFFFF << (32 - Int32.Parse(rangeParts[1])));
AddressRangeStart = BitConverter.ToUInt32(ipAddress.GetAddressBytes(), 0);
//Cast to int to avoid long overload
AddressRangeStart = (UInt32)System.Net.IPAddress.HostToNetworkOrder((int)AddressRangeStart);
AddressRangeEnd = AddressRangeStart | ~(UInt32)mask;
}
else
{ //Single IP
System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse(address);
AddressRangeStart = BitConverter.ToUInt32(ipAddress.GetAddressBytes(),0);
AddressRangeEnd = BitConverter.ToUInt32(ipAddress.GetAddressBytes(), 0);
}
}
//Port
ptr = line.IndexOf(':') + 1;
String port = line.Substring(ptr);
if (port.Equals("*"))
{
PortRangeStart = UInt16.MinValue;
PortRangeEnd = UInt16.MaxValue;
}
else
{
if (port.Contains("-"))
{ //range
String[] portParts = port.Split('-');
PortRangeStart = UInt16.Parse(portParts[0]);
PortRangeEnd = UInt16.Parse(portParts[1]);
}
else
{
PortRangeStart = UInt16.Parse(port);
PortRangeEnd = UInt16.Parse(port);
}
}
}
public String Action { get; set; }
public UInt32 AddressRangeStart { get; set; }
public UInt32 AddressRangeEnd { get; set; }
public UInt16 PortRangeStart { get; set; }
public UInt16 PortRangeEnd { get; set; }
}
}
}