FS-3588 --resolve thanks drk

This commit is contained in:
Jeff Lenk 2014-02-23 23:47:49 -06:00
parent 5e0b3fa077
commit aa7800690d
10 changed files with 974 additions and 0 deletions

View File

@ -604,6 +604,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_opus", "src\mod\codecs\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_t43_gray_code_tables", "libs\spandsp\src\msvc\make_t43_gray_code_tables.2012.vcxproj", "{EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "winFailToBan", "src\mod\languages\mod_managed\managed\examples\winFailToBan\winFailToBan.csproj", "{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -4056,6 +4058,18 @@ Global
{EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.Release|x64.Build.0 = All|Win32
{EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.Release|x64 Setup.ActiveCfg = All|Win32
{EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.Release|x86 Setup.ActiveCfg = All|Win32
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.All|Win32.ActiveCfg = Release|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.All|x64.ActiveCfg = Release|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.All|x64 Setup.ActiveCfg = Release|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.All|x86 Setup.ActiveCfg = Release|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Debug|Win32.ActiveCfg = Debug|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Debug|x64.ActiveCfg = Debug|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Debug|x64 Setup.ActiveCfg = Debug|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Debug|x86 Setup.ActiveCfg = Debug|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Release|Win32.ActiveCfg = Release|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Release|x64.ActiveCfg = Release|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Release|x64 Setup.ActiveCfg = Release|Any CPU
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}.Release|x86 Setup.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -4188,6 +4202,7 @@ Global
{7B077E7F-1BE7-4291-AB86-55E527B25CAC} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{7B42BDA1-72C0-4378-A9B6-5C530F8CD61E} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{692F6330-4D87-4C82-81DF-40DB5892636E} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}
{2286DA73-9FC5-45BC-A508-85994C3317AB} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}
{66444AEE-554C-11DD-A9F0-8C5D56D89593} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}

View File

@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FreeSWITCH;
using FreeSWITCH.Native;
namespace winFailToBan
{
public static class BanTracker
{
public static int MaxFails = 3;
public static int FailMinutes = 1;
public static int BanMinutes = 1;
public static String BanApi = @"system netsh adv fire add rule name={0} dir=in action=block remoteip={1}";
public static String UnBanApi = @"system netsh adv fire delete rule name={0}";
// Tracker object
public static Dictionary<String, List<DateTime>> MainTracker =
new Dictionary<string, List<DateTime>>();
// Active Ban list Key=IP val=baninfo
public static Dictionary<String, BanInfo> ActiveBans =
new Dictionary<string, BanInfo>();
public static void Startup()
{
LoadSettings();
}
private static void LoadSettings()
{
using (var a = new Api(null))
{
var setting = a.ExecuteString("global_getvar ban_maxfails");
if (!String.IsNullOrEmpty(setting))
MaxFails = int.Parse(setting);
setting = a.ExecuteString("global_getvar ban_failminutes");
if (!String.IsNullOrEmpty(setting))
FailMinutes = int.Parse(setting);
setting = a.ExecuteString("global_getvar ban_banminutes");
if (!String.IsNullOrEmpty(setting))
BanMinutes = int.Parse(setting);
}
}
private static void CleanOld(List<DateTime> l)
{
var expiretime = DateTime.Now.Subtract(new TimeSpan(0, FailMinutes, 0));
var expired = l.Where(x => x < expiretime).ToList();
expired.ForEach(x => l.Remove(x));
}
public static void CleanUp()
{
var templist = new List<String>();
foreach (var kvp in MainTracker)
{
CleanOld(kvp.Value);
if (kvp.Value.Count == 0)
templist.Add(kvp.Key);
}
templist.ForEach(i =>
{
MainTracker.Remove(i);
Log.WriteLine(LogLevel.Critical, "FTB: Removed tracker entry for {0}", i);
}); // remove all the dictinoary entries that are old
templist.Clear();
// now unban the expired bans
templist.AddRange(from kvp in ActiveBans where kvp.Value.Expires < DateTime.Now select kvp.Key);
templist.ForEach(Unban);
}
public static void TrackFailure(String ipAddress)
{
LoadSettings(); // just in case they've changed...
if (ActiveBans.ContainsKey(ipAddress))
return; // don't process again, some delay may happen between the ban, and it taking effect by external system
if (!MainTracker.ContainsKey(ipAddress))
MainTracker.Add(ipAddress, new List<DateTime>());
var l = MainTracker[ipAddress];
CleanOld(l); // clean out the old ones
l.Add(DateTime.Now); // add the failure to the list
Log.WriteLine(LogLevel.Critical, "Fail to ban logging attempt from {0} count is {1}", ipAddress, l.Count);
if (l.Count > MaxFails)
{
// do the ban here
l.Clear();
MainTracker.Remove(ipAddress);
Ban(ipAddress);
}
}
public static void Ban(String ipAddress)
{
Log.WriteLine(LogLevel.Critical, "FTP Banning IP Address {0}", ipAddress);
if (ActiveBans.ContainsKey(ipAddress))
return; // it's already banned so f-it
var bi = new BanInfo();
ActiveBans.Add(ipAddress, bi);
// Execute the ban API callback here
var acmd = String.Format(BanApi, bi.FirewallRuleName, ipAddress);
Log.WriteLine(LogLevel.Critical, "FTB: api command: {0}", acmd);
using (var a = new Api(null))
a.ExecuteString(acmd);
}
public static void Unban(String ipAddress)
{
Log.WriteLine(LogLevel.Critical, "FTB: Unbanning ip address {0}", ipAddress);
if (!ActiveBans.ContainsKey(ipAddress))
return; // nothing to do, it's not banned
var bi = ActiveBans[ipAddress]; // get the ban info
// Execute the unban API
var acmd = String.Format(UnBanApi, bi.FirewallRuleName);
Log.WriteLine(LogLevel.Critical, "FTB: api command: {0}", acmd);
using (var a = new Api(null))
a.ExecuteString(acmd);
ActiveBans.Remove(ipAddress);
}
}
public class BanInfo
{
public String FirewallRuleName { get; set; }
public DateTime Expires { get; set; }
public BanInfo()
{
FirewallRuleName = "ftb-" + Guid.NewGuid().ToString("N");
Expires = DateTime.Now.AddMinutes(BanTracker.BanMinutes);
}
}
}

View File

@ -0,0 +1,87 @@
using System;
using System.Threading;
using FreeSWITCH.Native;
using winFailToBan.Internal;
using FreeSWITCH;
namespace winFailToBan
{
public static class EventLoop
{
public static Boolean Running = true;
private static Thread _eventThread;
public static void StartEvents()
{
if (_eventThread != null)
return;
_eventThread = new Thread(EventMainLoop);
Running = true;
_eventThread.Start();
}
public static void StopEvents()
{
Running = false;
}
public static void EventMainLoop()
{
EventConsumer ec = null;
try
{
ec = new EventConsumer("CUSTOM", "sofia::register_attempt", 100);
ec.bind("SHUTDOWN", String.Empty);
ec.bind("HEARTBEAT", String.Empty);
while (Running)
{
var evt = ec.pop(0, 0);
if (evt == null)
continue;
var en = evt.InternalEvent.GetValueOfHeader("Event-Name");
if (en == "CUSTOM")
en = evt.InternalEvent.GetValueOfHeader("Event-SubClass");
switch (en)
{
case @"sofia::register_attempt":
{
var iev = evt.InternalEvent;
var ar = iev.GetValueOfHeader("auth-result"); // get the value of the result to see if it's the case we want
var ip = iev.GetValueOfHeader("network-ip"); // and the ip address the register came from
if (ar == "FORBIDDEN")
{
BanTracker.TrackFailure(ip);
}
}
break;
case "SHUTDOWN":
Log.WriteLine(LogLevel.Critical,"FTB: Processing Shutdown event");
Running = false;
break;
case "HEARTBEAT":
BanTracker.CleanUp();
break;
default:
break;
}
}
}
catch (Exception exx)
{
Log.WriteLine(LogLevel.Critical, "FailToBan -- Exception in event loop {0}", exx.Message);
}
finally
{
if(ec != null)
ec.Dispose();
_eventThread = null;
}
}
}
}

View File

@ -0,0 +1,45 @@
using FreeSWITCH;
namespace winFailToBan
{
public class Fail2Ban : IApiPlugin , ILoadNotificationPlugin
{
public void Execute(ApiContext context)
{
var cmds = context.Arguments.Split(" ".ToCharArray());
var cmd = cmds[0].ToLower();
switch (cmd)
{
case "shutdown":
Shutdown();
break;
default:
context.Stream.Write("\n\nInvalid Command\n\n");
break;
}
}
public void ExecuteBackground(ApiBackgroundContext context)
{
return;
}
public static void Startup()
{
BanTracker.Startup();
EventLoop.StartEvents();
}
public static void Shutdown()
{
EventLoop.StopEvents();
}
public bool Load()
{
Startup();
return true;
}
}
}

View File

@ -0,0 +1,83 @@
using System;
using FreeSWITCH;
using FreeSWITCH.Native;
namespace winFailToBan.Internal
{
public class ConfigurationEventArgs : EventArgs
{
public SwitchXmlSearchBinding.XmlBindingArgs FsArgs { get; private set; }
public fsConfigDocument Result { get; set; }
public Boolean DontProcess { get; set; }
public ConfigurationEventArgs(SwitchXmlSearchBinding.XmlBindingArgs args)
{
DontProcess = false;
FsArgs = args;
Result = null;
}
}
// Bind XML search function turned into CLR events for ease use
public class ConfigHandler : IDisposable
{
public event EventHandler<ConfigurationEventArgs> DirectoryRequest;
public event EventHandler<ConfigurationEventArgs> DialPlanRequest;
private IDisposable _binder; // object to bind to
public void Dispose()
{
if(_binder != null)
_binder.Dispose();
_binder = null;
}
public String XmlCallback(SwitchXmlSearchBinding.XmlBindingArgs args)
{
String rv = null; // return value
switch (args.Section.ToLower())
{
case "directory":
var dargs = new ConfigurationEventArgs(args);
if (DirectoryRequest != null)
{
var temp = DirectoryRequest;
temp(this, dargs);
if (dargs.DontProcess)
return null;
if (dargs.Result != null)
rv = dargs.Result.ToXMLString();
}
break;
case "dialplan":
var dialargs = new ConfigurationEventArgs(args);
if(DialPlanRequest != null)
{
var temp = DialPlanRequest;
temp(this, dialargs);
if (dialargs.Result != null)
rv = dialargs.Result.ToXMLString();
}
break;
}
return rv ?? new fsNotFoundDocument().ToXMLString();
}
~ConfigHandler()
{
Dispose();
}
public ConfigHandler()
{
_binder = SwitchXmlSearchBinding.Bind(XmlCallback,
switch_xml_section_enum_t.SWITCH_XML_SECTION_DIRECTORY |
switch_xml_section_enum_t.SWITCH_XML_SECTION_DIALPLAN);
}
}
}

View File

@ -0,0 +1,327 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using FreeSWITCH.Native;
using Stream = System.IO.Stream;
namespace winFailToBan.Internal
{
public abstract class fsConfigDocument
{
public XElement xmldoc;
public XElement main;
protected fsConfigDocument(String SectionName)
{
main = new XElement("wtf",
new XElement("document",
new XAttribute("type", "freeswitch/xml"),
new XElement("section",
new XAttribute("name", SectionName),
new XAttribute("description", "Auto generated")
)));
xmldoc = main.Descendants("document").Single();
}
public Int64 Length()
{
return xmldoc.ToString().Length + 2;
}
public String ToXMLString()
{
return xmldoc.ToString();
}
public Int64 WriteXML(Stream outStream)
{
var wr = new StreamWriter(outStream);
wr.WriteLine(xmldoc.ToString());
wr.Flush();
return xmldoc.ToString().Length + 2;
}
public void WriteXML(TextWriter outText)
{
outText.Write(xmldoc.ToString());
}
protected void SectionChild(XElement Node)
{
// ReSharper disable PossibleNullReferenceException
if (xmldoc != null) xmldoc.Element("section").Add(Node);
// ReSharper restore PossibleNullReferenceException
}
}
public class fsNotFoundDocument : fsConfigDocument
{
public fsNotFoundDocument()
: base("result")
{
SectionChild(new XElement("result",
new XAttribute("status", "not found")));
}
}
public class fsDomainGatewayDirectoryDocument : fsConfigDocument
{
public fsDomainGatewayDirectoryDocument(Dictionary<String, Dictionary<String, Dictionary<String, String>>> domainGatewayList)
: base("directory")
{
if (xmldoc == null)
return;
foreach (var v in
(from d in domainGatewayList
select new XElement("domain",
new XAttribute("name", d.Key),
new XElement("user",
new XAttribute("id", "gatewaydummyser"),
new XElement("gateways",
from g in d.Value
select new XElement("gateway",
new XAttribute("name", g.Key),
from p in g.Value
select new XElement("param",
new XAttribute(
"name", p.Key),
new XAttribute(
"value", p.Value))))))))
xmldoc.Element("section").Add(v);
}
}
public class fsDirectoryDocument : fsConfigDocument
{
public fsDirectoryDocument(String Domain, String User, String Password)
: base("directory")
{
SectionChild(new XElement("domain",
new XAttribute("name", Domain),
new XElement("user",
new XAttribute("id", User),
new XElement("params",
new XElement("param",
new XAttribute("name", "password"),
new XAttribute("value", Password)
)
)
)
));
}
public fsDirectoryDocument(String Domain, String User, String Password, Dictionary<String, String> Params)
: this(Domain, User, Password)
{
if (Params == null)
return;
// ReSharper disable PossibleNullReferenceException
xmldoc.Element("section").Element("domain").Element("user").Element("params").Add(
// ReSharper restore PossibleNullReferenceException
from par in Params
select new XElement("param",
new XAttribute("name", par.Key),
new XAttribute("value", par.Value)));
}
public fsDirectoryDocument(String Domain, String User, String Password, Dictionary<String, String> Params, Dictionary<String, String> Variables)
: this(Domain, User, Password, Params)
{
if (Variables == null)
return;
// ReSharper disable PossibleNullReferenceException
xmldoc.Element("section").Element("domain").Element("user").Add(
// ReSharper restore PossibleNullReferenceException
new XElement("variables", from v in Variables
select new XElement("variable",
new XAttribute("name", v.Key),
new XAttribute("value", v.Value))));
}
}
public class fsDialPlanDocument : fsConfigDocument
{
private static XElement MakeActionNode(String ActionString)
{
var p = ActionString.Split(",".ToCharArray(), 2);
var rv = new XElement("action",
new XAttribute("application", p[0]));
if (p.Length > 1)
rv.Add(new XAttribute("data", p[1]));
return rv;
}
public fsDialPlanDocument(String Context, IEnumerable<String> Actions)
: base("dialplan")
{
SectionChild(new XElement("context",
new XAttribute("name", Context),
new XElement("extension",
new XAttribute("name", "extension"),
new XElement("condition",
from act in Actions
select MakeActionNode(act)))));
}
}
public static class ConfigExtensions
{
public static switch_event_header GetHeader(this switch_event e, String HeaderName)
{
for (var x = e.headers; x != null; x = x.next)
{
if (HeaderName.ToLower() == x.name.ToLower())
return x;
}
return null;
}
public static String GetValueOfHeader(this switch_event e, String headerName, String defaultValue = "")
{
var head = e.GetHeader(headerName);
return (head == null ? defaultValue : head.value);
}
public static Boolean GetBooleanHeader(this switch_event e, String headerName)
{
var hv = e.GetValueOfHeader(headerName);
hv = (String.IsNullOrEmpty(hv) ? "false" : hv);
Boolean rv = false;
Boolean.TryParse(hv, out rv);
return rv;
}
public static Guid GetUUID(this Event e)
{
var idfld = e.GetHeader("Unique-ID");
return String.IsNullOrEmpty(idfld) ? Guid.Empty : new Guid(idfld);
}
public static void ForEach(this switch_event e, Action<String, String> action)
{
for (var x = e.headers; x != null; x = x.next)
{
action(x.name, x.value);
}
}
public static Guid GetGuid(this switch_event e)
{
return e.GetHeader("Unique-ID") == null ? Guid.Empty : Guid.Parse(e.GetHeader("Unique-ID").value);
}
public static void Dump(this switch_event e)
{
e.ForEach((n, v) => Console.WriteLine("{0}={1}", n, v));
}
public static Dictionary<String, String> ExtractVars(this switch_event e)
{
var r = new Dictionary<String, String>();
for (var x = e.headers; x != null; x = x.next)
{
if (x.name.StartsWith("variable_"))
{
r.Add(x.name.ToLower().Replace("variable_", String.Empty),
x.value);
}
}
return r;
}
public static String ModDigits(this String Orig, int qdel, String Prefix)
{
var rv = Orig;
rv = qdel > Orig.Length ? String.Empty : rv.Substring(qdel);
if (!String.IsNullOrEmpty(Prefix))
rv = Prefix + rv;
return rv;
}
//public static String RoutingReplace(this String Orig, String Orignal, String Modified)
//{
// var rv = Orig;
// rv = rv.Replace("%d", Modified);
// rv = rv.Replace("%o", Orignal);
// return rv;
//}
public static void MergeFrom<TKey, TValue>(
this Dictionary<TKey, TValue> dict,
Dictionary<TKey, TValue> src
)
{
foreach (var entry in src)
{
if (!dict.ContainsKey(entry.Key))
dict.Add(entry.Key, entry.Value);
}
}
public static void RemoveKeysIn<TKey, TValue>(
this Dictionary<TKey, TValue> dict,
IEnumerable<TKey> keys
)
{
foreach (var k in keys)
if (dict.ContainsKey(k))
dict.Remove(k);
}
public static void AddVariableTextList(this Dictionary<String, String> d, String varslist)
{
if (d == null || String.IsNullOrEmpty(varslist))
return;
foreach (var vardef in varslist.Split(",".ToCharArray()))
{
var args = vardef.Split("=".ToCharArray(), 2);
if (!d.ContainsKey(args[0]))
{
d.Add(args[0], args[1]);
}
else
{
d[args[0]] = args[1];
}
}
}
public static String ToParamString(this Dictionary<String, String> d)
{
var firstPart = new List<String>();
foreach (var e in d)
{
firstPart.Add(String.Format("{0}={1}", e.Key, e.Value));
}
var rv = String.Join(",", firstPart.ToArray());
return rv;
}
public static String ToChannelVars(this Dictionary<String, String> d, Boolean bLocal)
{
if (d == null || d.Count == 0)
return String.Empty;
String fmt;
if (bLocal)
fmt = "[{0}]";
else
fmt = "{{{0}}}";
return String.Format(fmt, d.ToParamString());
}
public static void AddActions(this List<String> l, params String[] strings)
{
String seperator = "^";
foreach (var s in strings)
{
if (String.IsNullOrEmpty(s))
continue;
l.AddRange(s.Split(seperator.ToCharArray()));
}
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("winFailToBan")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("winFailToBan")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a171cab9-d773-4070-9993-26a581c6f243")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FreeSWITCHManaged.LibCS" version="1.0.1.10" targetFramework="net40" />
</packages>

View File

@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FreeSWITCH;
using winFailToBan.Internal;
namespace winFailToBan
{
public class SampleApp : IAppPlugin
{
// example class for a dialplan APP just implment the run method
public void Run(AppContext context)
{
var s = context.Session;
var args = context.Arguments;
// Do something with them here
}
}
// Example class to implment an API command
public class SampleApi : IApiPlugin
{
public void Execute(ApiContext context)
{
throw new NotImplementedException();
}
public void ExecuteBackground(ApiBackgroundContext context)
{
throw new NotImplementedException();
}
}
// This examle class can be used to handle XML config lookups for dialplan and directory
public class SampleConfigHandler : ILoadNotificationPlugin
{
private static ConfigHandler MyConfigHandler;
static void HandleDirectoryLookups(Object sender, ConfigurationEventArgs e)
{
e.Result = null; // not found example just return after this
// return; // uncomment to just return not-fouond
// return a directory object that will work
var evt = e.FsArgs.Parameters; // Get the raw event that generated the userDir lookup
var eventName = evt.GetHeader("Event-Name").value; // Find the event name
// If your module handles voicemail authorization then implment the following
// to update the voicemail password, when they change their voicemail password using TUI
if (eventName == "CUSTOM")
{
var subClass = evt.GetValueOfHeader("Event-Subclass");
if (subClass == "vm::maintenance")
{
var vmaction = evt.GetValueOfHeader("VM-Actoun");
var username = evt.GetValueOfHeader("VM-User");
var newPassword = evt.GetValueOfHeader("VM-User-Password");
if (vmaction == "change-password" && !string.IsNullOrEmpty(username) &&
!String.IsNullOrEmpty(newPassword))
{
// implment your code to update the users vm password in your database
return; // No more processing we don't actually do an auth just a notification
}
}
}
// to make sure we don't have some future events messing us up...
if (eventName != "REQUEST_PARAMS" && eventName != "GENERAL")
return;
// implment the following if you want to handle gateway lookup from directory when a profile loads
if (evt.GetValueOfHeader("purpose") == "gateways")
{
var profileName = evt.GetValueOfHeader("profile");
// implment your gateway lookup
//e.Result = new fsDomainGatewayDirectoryDocument(myGwStructure);
return;
}
var action = evt.GetValueOfHeader("action", "none"); // get the action
// If you want to handle ESL Logins implment the following
if (action == "event_socket_auth")
{
// preform your stuff here
// e.result = ...
return;
}
// Normal lookup processing
if (evt.GetHeader("user") == null || evt.GetHeader("domain") == null)
return; // does't have required fields
var method = evt.GetValueOfHeader("sip_auth_method", "unknown");
var user = evt.GetValueOfHeader("user");
var domain = evt.GetValueOfHeader("domain");
// Some variables to return the params and variables section of the user record
var variables = new Dictionary<String, String>();
var uparams = new Dictionary<String, String>();
// if you're implmenting reverse-auth of devices
if (action == "reverse-auth-lookup")
{
// lookup stuff in your db
uparams.Add("reverse-auth-user", "device uername");
uparams.Add("reverse-auth-pass", "device password");
}
// if you handle voicemail passwords ...
if (true /*check for voicemail box */)
{
uparams.Add("vm-password", "theirvmpassword");
// the following is optional
uparams.Add("MWI-Account", "registrationstring");
}
// add more parameters here
uparams.Add("anyotherparameters", "value");
// add variables here for example
variables.Add("user_context", "theuserscontext");
e.Result = new fsDirectoryDocument(
domain,
user,
"theirpassword",
uparams,
variables);
return;
}
// Example dialplan handler
static void HandleDialPlanRequest(object sender, ConfigurationEventArgs e)
{
var evt = e.FsArgs.Parameters; // get the native event that caused this dialplan lookup
// extract the minimum variables you will need
var context = evt.GetValueOfHeader("Hunt-Context"); // the context
var destination = evt.GetValueOfHeader("Hunt-Destination-Number"); // the dialed number or "DID"
var ani = evt.GetValueOfHeader("Hunt-ANI"); // The ANI/CallerID number
// A place to return the dialplan actions you want
var actions = new List<String>(); // format is "app,data"
// add the actions for your code they shouldn't be static this is just an example
actions.Add("set,continue_on_fail=true");
actions.Add("brige,sofia/mygateway/" + destination);
actions.Add("transfer,fialedDest XML failedcontext");
e.Result = new fsDialPlanDocument(context, actions);
return; // Isn't this easy?
}
public bool Load()
{
// Start any threads doing event consumer loops
MyConfigHandler = new ConfigHandler(); // init a config handler
MyConfigHandler.DirectoryRequest += HandleDirectoryLookups;
MyConfigHandler.DialPlanRequest += HandleDialPlanRequest;
return true;
}
}
}

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5BA0D5BD-330D-4EE2-B959-CAFEA04E50E0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>winFailToBan</RootNamespace>
<AssemblyName>winFailToBan</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BanTracker.cs" />
<Compile Include="EventLoop.cs" />
<Compile Include="Fail2Ban.cs" />
<Compile Include="Internal\ConfigHandler.cs" />
<Compile Include="Internal\ConfigHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<None Include="skel.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\FreeSWITCH.Managed.2012.csproj">
<Project>{834e2b2f-5483-4b80-8fe3-fe48ff76e5c0}</Project>
<Name>FreeSWITCH.Managed.2012</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>