119 lines
4.5 KiB
C#
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; }
|
|
}
|
|
}
|
|
}
|