Eggdrop
From SHellium Wiki
Eggdrop is the world's most popular Open Source IRC bot, designed for flexibility and ease of use, and is freely distributable under the GNU General Public License (GPL).
Contents |
Please Remember!
Remember to run the 'myports' command when using any process requiring ports. This command will show you your two (2) assigned ports, and if you are running any ports that do not belong to you. Running any port or ports other than the two assigned to you will lock your account.
Please be aware that running a statistics or 'stats' script on your bot may call open other non-assigned ports, and earn you a 'bad ports' mention. Check your scripts carefully and use the myports command.
What is an IRC bot?
An IRC bot is a program that sits in an IRC channel around the clock, keeping it open 24 hours a day. It looks just like a normal user on the channel, but is usually idle until it's called upon to perform a particular function. A bot can contribute greatly to the stability of a channel by protecting it from takeovers and abusers, and providing a central location for storage of the channel op list and giving ops to those users when they join the channel. It can also perform many other useful functions, such as logging channel events, providing frequently-requested information, hosting trivia games, and so on. IRC bots are particularly important on IRC networks without channel registration services, such as EFnet and IRCnet, and on networks that may prevent your channel being registered due to certain registration requirements, such as Undernet. On these networks, keeping a channel running smoothly without some kind of IRC bot would often be impossible.
There are many types of bots out there, such as Acidblood, ComBot, EnergyMech, IncuBot, HackBot, and so on. Most of these are old and unsupported, leaving only one bot that has survived the test of time - the Eggdrop.
What is an Eggdrop?
Eggdrop is the most advanced, most popular, and best supported IRC bot. If you've never used a bot before, you'll find Eggdrop provides a staggering array of options for channel management, and can easily be expanded further to provide even more functions. The Eggdrop code is free for anyone to download and use. Some of the main features of Eggdrop include:
- Support for multiple channels.
- An advanced, flexible userfile structure.
- The 'party line', a unique feature accessed by DCC chat which allows you to speak to others connected to the bot's party line, and is also used as a console where you can control and use most of Eggdrop's features.
- Botnet support, allowing you to link multiple bots to create a 'botnet' and synchronise userfiles with automatic userfile sharing.
- Multi-language support, with English, German and French included.
- Support for Tcl scripts and modules, allowing you to easily add extra features to the bot.
Eggdrop is not a simple bot, so don't expect it to run inside 100KB of memory. The bot is quite complex and packed with features, making it the Microsoft Office™ (a la resource hog) of IRC bots. If you're after a smaller and tighter but less customisable bot, consider EnergyMech.
Installing an eggdrop on your Shellium.org Shell
Get precompiled 1.6.19 eggdrop ctcp fixed for shellium here: http://www.shellium.org/~brabo/shegg.tar or Eggdrop is already on the shell, you don't have to download the source or install anything. You can use your own config file (the default scripts are in /usr/share/eggdrop/scripts), or make one using the "shegg" command, follow the instructions then, type:
./eggdrop -m <filename.conf>
Eggdrop Configuration
Eggdrop uses a configfile (eggdrop.conf) , you can make this file like you wish and you can edit the file with nano, pico or by using any text editor on your desktop. Alternatively, you can generate a configuration file.
At first onto your Eggdrop config file you will need to set the "modules" section, the help section, hostname, idents... by setting that, your bot will know where to look for the modules.
Example:
set mod-path "/usr/lib/eggdrop/modules" set help-path "/usr/share/eggdrop/help/" set text-path "/usr/share/eggdrop/text/" set my-hostname "127.0.0.1" set protect-telnet 0 set dcc-sanitycheck 0 set ident-timeout 5 set require-p 0 set open-telnets 0 set stealth-telnets 0 set use-telnet-banner 0 set connect-timeout 90 set dcc-flood-thr 3 set telnet-flood 5:60 set paranoid-telnet-flood 1 set resolve-timeout 15 set max-dcc 50 set dcc-portrange 1024:65535 set enable-simul 1 set allow-dk-cmds 1
loadmodule dns loadmodule channels loadmodule server loadmodule ctcp loadmodule irc loadmodule notes set notefile "name.notes" loadmodule console loadmodule transfer loadmodule share checkmodule blowfish
The next step is giving your Eggdrop a name/nickname and an alternative nick, which will be used when its main nick is already in use:
set nick "botname" set altnick "botname-"
Next is to set an administrator (owner) nickname:
Example:
set admin "botownernick"
Some more information about your bot to show on IRC can be done like this.
Example:
set realname "Shellium.org pwnage eggy"
An option is to set a shortnick for your bot. this is sometimes useful in other scripts like (commands.tcl) script.
Example:
set shortnick "afkorting botnaam"
The next line is to set a couple off servers followed by :port for your bot to connect to. You can add multiple servers by using this line but make sure you add the correct ones in there! To make sure, type /map onto the IRC server where you are at now to see which servers are available. But keep in mind, some IRC server don't allow connecting to some off the servers listed into the /map . (If you are unlucky, you will get a message (This command is for network staff only) when using the /map command).
Example:
set servers {
irc.freenode.net:6667
}
Next is to set the channel where your bot will be at all times, to provide information etc. As you can see there are some modes to be set also. These are at the end of each channel line. (channel set #shellium +enforcebans +dynamicbans +userbans). Leave these as they are if you don't know what they do. This will be explained later on into the next wiki section.
Example:
channel add #shellium {
chanmode "+nt"
idle-kick 0
stopnethack-mode 0
}
Example 2:
channel set #shellium +enforcebans +dynamicbans +userbans channel set #shellium +dynamicexempts +userexempts +dynamicinvites +userinvites channel set #shellium -autoop -bitch +protectops +protectfriends +dontkickops channel set #shellium +greet +statuslog channel set #shellium +revenge +autovoice channel set #shellium -secret +shared +cycle channel set #shellium -inactive -seen +nodesynch
Set network type, by choosing the server name with the number 1 to 5. If your network isn't in the list, just use 5 for "others"
- 0 = EFnet
- 1 = IRCnet
- 2 = Undernet
- 3 = DALnet
- 4 = +e/+I/max-modes 20 Hybrid
- 5 = Others
Example:
set net-type 5
Valid ports are typically anything between 1025 and 65535 assuming the port is not already in use. If you would like the bot to listen for users and bots in separate ports, use the following format:
Example:
listen 3333 bots listen 4444 users
If you wish to use only one port, use this format:
Example:
listen 3333 all
Set the list of owners of the bot.
Example:
set owner "Sambali, MrSambali"
Specify here the filename your userfile should be saved as.
Example:
set userfile "botname.user"
Enter here the filename where dynamic channel settings are stored.
Example:
set chanfile "botname.chan"
Set the file where the bot stores its own log:
set temp-path ""
logfile msbxco * "logs/botnaam.log"
logfile jpk #uwkanaal "logs/botnaam.log"
proc evnt:init_server {type} {
global botnick
putquick "MODE $botnick +i6e"
putserv "privmsg nickserv :identify passwordhere"
}
At last, mostly located at the bottom of your config file , the scripts . You will see that there is a path to the scripts folder that needs to be given. When having none like this, your bot wont start or wont work properly. Standard path for the scripts is (/usr/share/eggdrop/scripts on shellium). So add,
Example:
source /usr/share/eggdrop/scripts/alltools.tcl source /usr/share/eggdrop/scripts/action.fix.tcl source /usr/share/eggdrop/scripts/compat.tcl source /usr/share/eggdrop/scripts/userinfo.tcl loadhelp userinfo.help
The example config lines are the most used, there is a lot more to set into your Eggdrop configuration file (eggdrop.conf).
Setting up a Botnet
One of the great features of Eggdrop is bot linking, allowing you to create your own 'botnet'. A botnet can consist of two linked bots to as many as hundreds of linked bots. If you're using an Eggdrop for channel management, the most important feature of linked bots is userfile sharing. With userfile sharing, the bots can keep their user lists, ban lists, and ignore lists in sync with one another. A botnet also has many other possible capabilities, such as allowing bots to op one another securely, and making all bots join a channel with one command.
Linking bots can be a confusing process for first timers, but it's quite simple if you know how. The first thing you need to do is chose a hub bot. The hub is the main bot which all the other bots on the botnet (which will become leaf bots) connect to. Even if you are only using two bots, it's best to use one as a hub bot, and the other as a leaf. The hub bot should be the most reliable bot on your botnet, running on a fast, stable, and secure shell - so keep that in mind when deciding which bot will be the hub.
Once you've decided on the hub, it's time to set up the linking. A typical botnet of just a few bots will have a structure like the one shown in the tree below:
[16:21] <dirty> .vb [16:21] <BigBoy> [05:57] #darkutz# vbottree [16:21] <BigBoy> BigBoy (1.6.18.1) [16:21] <BigBoy> |--Camelback (1.6.18.1) [16:21] <BigBoy> `--Mallard (1.6.18.1) [16:21] <BigBoy> Average hops: 1.0, total bots: 3
The tree above shows a botnet of three linked bots. BigBoy is the hub bot, while Camelback and Mallard are leaf bots. In order to set up a botnet like this, you need to add each bot to each other bot's user file, then set certain flags for each of those bots. In the steps below, I'll refer to the nicknames of the bots above - just substitute your own bot nicks when following these steps.
Note that if you don't wish to set up userfile sharing, just skip the four steps marked with an (s).
1) First up, config file stuff - make sure any channels you want bots to synchronise information about (e.g. user flags, bans, etc.) are set to +shared in each bot's config file, and make sure the share and transfer modules are loaded in the main config file of the eggdrop(loadmodule transfer and loadmodule share). The channel setting +shared is usualy set in the main config file as default setting to all newly added channels but in case you decide not to share all channels by default you can change the channel setting individualy from dcc chat by using .chanset #channel +share
2) On BigBoy (the hub bot), you need to add the leaf bots to the userfile. To add Camelback and Mallard you need to use the command .+bot in the party line and i will show you how this works by giving you a live example from a dcc chat (or partyline as it`s called) but before this first you need to know the telnet address of your bots, which consists of the bot's host and port (the port will be whatever you set in the listen setting in bot's config file).
EX: If Camelback's hostname is camelback@127.0.0.1 and the port is 3001, its telnet address is 127.0.0.1:3001
[16:19] <dirty> .+bot Camelback 127.0.0.1:3001 [16:19] <BigBoy> [05:55] #darkutz# +bot Camelback 127.0.0.1:3001 [16:19] <BigBoy> Added bot 'Camelback' with address '127.0.0.1:3001' and no hostmask. [16:19] <BigBoy> (Added hostmask for Camelback from #RulZ) [16:19] <dirty> .+bot Mallard 127.0.0.2:3002 [16:19] <BigBoy> [05:55] #darkutz# +bot Mallard 127.0.0.2:3002 [16:19] <BigBoy> Added bot 'Mallard' with address '127.0.0.2:3002' and no hostmask. [16:19] <BigBoy> (Added hostmask for Mallard from #RulZ)
3) Set any ordinary user flags for the bots. Generally, bots should be given global f (friend) and o (op) flags.
[16:19] <dirty> .chattr Camelback +fo [16:19] <BigBoy> [05:56] #darkutz# chattr Camelback +fo [16:19] <BigBoy> Global flags for Camelback are now +fo. [16:19] <dirty> .chattr Mallard +fo [16:19] <BigBoy> [05:56] #darkutz# chattr Mallard +fo [16:19] <BigBoy> Global flags for Mallard are now +fo.
4) (s) Give the bots the s bot flag. This makes the hub aggressively share its userfile with the leaf bots.
[16:19] <dirty> .botattr Camelback +s [16:19] <BigBoy> [05:55] #darkutz# botattr Camelback +s [16:19] <BigBoy> Bot flags for Camelback are now +s. [16:19] <dirty> .botattr Mallard +s [16:19] <BigBoy> [05:55] #darkutz# botattr Mallard +s [16:19] <BigBoy> Bot flags for Mallard are now +s.
REMEMBER: You can not change bot flags while they are linked.
[02:49] <dirty> .botattr Mallard +l [02:49] <BigBoy> You may not change the attributes of a directly linked bot.
5) (s) Give the bots the s bot flag for each channel you want to synchronise information about, e.g. if the three bots are on #railroad and #trains, type .botattr Camelback |+s #railroad and .botattr Camelback |+s #trains, then do the same for Mallard. Alternatively, you can use the g flag by typing .botattr Camelback +g, instead of setting the s flag for each channel. The g flag simply makes the bot share information for all channels.
6) Repeat steps 2 to 5 for any other leaf bots to be added to the hub.
7) Now it's time to setup the hub on the leaf bots. Let's start with Camelback, so leave BigBoy for now and switch to Camelback's command console.
[16:19] <dirty> .+bot BigBoy steam.trains.com:11941 [16:19] <Camelback> [05:55] #darkutz# +bot BigBoy steam.trains.com:11941 [16:19] <Camelback> Added bot 'BigBoy' with address 'steam.trains.com:11941' and no hostmask. [16:19] <Camelback> (Added hostmask for BigBoy from #RulZ)
8) Set any ordinary flags for BigBoy, like you did for the leaf bots.
[16:19] <dirty> .chattr BigBoy +fo [16:19] <Camelback> [05:56] #darkutz# chattr BigBoy +fo [16:19] <Camelback> Global flags for BigBoy are now +fo.
9) (s) Give BigBoy the p bot flag. The p flag makes the bot passively share its userfile with the hub bot (i.e. the bot downloads the userfile from BigBoy).
[16:19] <dirty> .botattr BigBoy +p [16:19] <Camelback> [05:55] #darkutz# botattr BigBoy +p [16:19] <Camelback> Bot flags for BigBoy are now +p.
10) (s) Give BigBoy the s bot flag for each channel you want to synchronise user information about, e.g. if the three bots are on #railroad and #trains, type .botattr BigBoy |+s #railroad and .botattr BigBoy |+s #trains. Alternatively, you can use the g flag by typing .botattr BigBoy +g, instead of setting the s flag for each channel. The g flag simply makes the bot share information for all channels.
11) Give BigBoy the h flag by typing .botattr BigBoy +h. The h flag makes the bot try to link to the hub automatically.
12) Within a minute, Camelback should attempt to link to BigBoy and (if you set up sharing flags) download the userfile.
[16:22] <Camelback> [05:58] Telnet connection: steam.trains.com/53420 [16:22] <Camelback> [05:58] Challenging BigBoy... [16:22] <Camelback> [05:58] Linked to BigBoy. [16:22] <Camelback> *** Linked to BigBoy
13) Repeat steps 7 to 11 on any other leaf bots.
If the the hub bot goes down for any reason, leaf bots will automatically relink when returns. Some users may wish to set up an alternate hub, which the leaf bots will connect to if the hub goes down, using the a bot flag. If you wish to try this, as well as gain a better understanding of botnet configuration, refer to the Botnet Sharing and Linking guide that is included with Eggdrop.
Eggdrop Script Archives
A few useful Scripts
- Fishdrop
- Superscript.tcl Superscript based on [1]
- Bseen, seen script
- msg_say, make your bot talk without being in it
- Fishdrop, fishbot for your eggdrop
- Source for several useful scripts such as google, weather, and others
- Quoteit, script for adding quotes to your bot
- Another useful weather script
- Http.tcl
- Rss feed script
- URL Title Grabber - Bot will announce the webpage title for URLS pasted into channel.
- BogusTrivia - one of the more popular trivia scripts with KAOS rounds.
- BogusHTML - addon for trivia script that allows players to see scores on a website and give any question.
- TopicADD by dirty - Lets you add predefined topics to a database and set those topics using a single word.
- StormBot.TCL - Eggdrop/Channel management though public (non dcc) commands. Includes 100+ commands to ensure everyone's needs are met. Script is modular (customizable)
- a&a light Eggdrop script (Also see: a&a light Settings & )a&a light Flags)
Creating an IRC front/back-end from a C# web application
This lengthy howto will show you how to hook up C# to an eggdrop IRC bot. I've taken this approach because it avoids the overhead of managing a fully fledged IRC client in C# whilst still providing 2-way command functionality between IRC and the application.
The app works by:
1. Connecting to the eggdrop 2. Logging in to the eggdrop 3. Sending .say and .topic commands to the eggdrop 4. Providing a web service to which the eggdrop may send a SOAP request to perform specific actions
So, let's get started!
The first part is the main IRC class. The version implemented here comes with a log4net appender implementation so that errors can be logged directly to IRC.
IRC.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Threading;
namespace Logging
{
public class IRCLogger : log4net.Appender.AppenderSkeleton
{
protected override void Append(log4net.Core.LoggingEvent loggingEvent)
{
if (loggingEvent.Level == log4net.Core.Level.Error)
{
if (loggingEvent.ExceptionObject != null)
{
IRC.SendAdminMessage(loggingEvent.MessageObject.ToString() + ": " + loggingEvent.ExceptionObject.Message);
}
else
{
IRC.SendAdminMessage(loggingEvent.MessageObject.ToString());
}
DateTime gmt = DateTime.Now.AddHours(5);
IRC.SetAdminTopic("Last error rececived on " + gmt.ToShortDateString() + " at " + gmt.ToShortTimeString() + " (GMT).");
}
}
}
public class IRC
{
static TcpClient client = null;
static NetworkStream ns = null;
static StreamWriter sw = null;
static StreamReader sr = null;
static bool isConnecting = false;
static bool isSending = false;
static List<string> commands = new List<string>();
private static void GetConnection()
{
bool ret = false;
if (isConnecting) ret = true;
while (isConnecting) { Thread.Sleep(1000); }
if (ret) return;
isConnecting = true;
try
{
NameValueCollection botConfig =
ConfigurationManager.GetSection("ircSetup/botDetails")
as NameValueCollection;
client = new TcpClient(botConfig["host"], int.Parse(botConfig["port"]));
if (client.Connected)
{
ns = client.GetStream();
sw = new StreamWriter(ns);
sr = new StreamReader(ns);
sw.WriteLine(botConfig["username"]);
sr.ReadLine();
sw.WriteLine(botConfig["password"]);
sr.ReadLine();
sw.Flush();
}
}
finally
{
isConnecting = false;
}
}
public static void SetTopic(string topic)
{
commands.Add(".topic #default [-http://mysite.com-] " + topic);
DoSend();
}
public static void SendMessage(string msg)
{
commands.Add(".say #default [-default-] " + msg);
DoSend();
}
public static void SendMessage(string msg, string channel)
{
commands.Add(".say " + channel + " [-default-] " + msg);
DoSend();
}
public static void SetAdminTopic(string topic)
{
commands.Add(".topic #adminchannel [-admin-] " + topic);
DoSend();
}
public static void SendAdminMessage(string msg)
{
commands.Add(".say #adminchannel [-admin-] " + msg);
DoSend();
}
private static void DoSend()
{
ThreadStart pts = new ThreadStart(SendToBot);
Thread t = new Thread(pts);
t.Start();
}
private static void SendToBot()
{
while (isSending) { System.Threading.Thread.Sleep(1000); }
isSending = true;
try
{
while (commands.Count > 0)
{
//Filter the data using safe whitelist
string msg = commands[0].ToString();
string regex = @".*[\r\n].*";
if (System.Text.RegularExpressions.Regex.IsMatch(msg, regex))
return;
int attempts = 0;
if (client == null)
{
GetConnection();
attempts++;
if (attempts > 3) return;
}
while (client == null || !client.Connected)
{
GetConnection();
attempts++;
if (attempts > 3) return;
}
if (client.Connected)
{
sw.WriteLine(msg);
sw.Flush();
sr.ReadLine();
}
while (ns.DataAvailable)
{
sr.ReadLine();
}
commands.RemoveAt(0);
}
}
catch (Exception ex)
{
Logging.Logger.Log.Info("Error sending to IRC: " + ex.Message);
}
finally
{
isSending = false;
}
}
}
}
Then, put the relevant stuff into your web.config file:
<configSections>
<section name="log4net"
type="false"/>
<sectionGroup name="ircSetup">
<section name="botDetails" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<ircSetup>
<botDetails>
<add key="host" value="your.eggdrop.host"/>
<add key="port" value="31337"/>
<add key="username" value="youreggdropusername" />
<add key="password" value="youreggdroppassword" />
</botDetails>
</ircSetup>
<log4net>
<appender name="ircAppender" type="Logging.IRCLogger, Logging">
</log4net>
It should hook up! But what about getting commands from the bot I hear you cry? Well, first of all you'll need to hook up the following TCL to your eggdrop:
package require http 2.7
bind pubm - * webServiceRequest
proc webServiceRequest {nick uhost hand chan text} {
if {[string index $text 0] == "!"} {
set token [::http::geturl "http://www.yoursite.com/webservice.asmx" \
-type "text/xml; charset=utf-8" \
-headers {"SOAPAction" "http://www.yoursite.com/IrcMessage"} \
-query "<?xml version=\"1.0\" encoding=\"utf-8\"?> \
<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> \
<soap:Header> \
<Authentication xmlns=\"http://www.yoursite.com/\"> \
<User>YourUsername</User> \
<Password>YourPassword</Password> \
<Version>Bot_1.0</Version> \
</Authentication> \
</soap:Header> \
<soap:Body> \
<IrcMessage xmlns=\"http://www.yoursite.com/\"> \
<user>$nick</user> \
<hostmark>$uhost</hostmark> \
<channel>$chan</channel> \
<message>$text</message> \
</IrcMessage> \
</soap:Body> \
</soap:Envelope>"]
upvar #0 $token state
if {$state(status) != "ok"} {
putserv "PRIVMSG $chan :ERROR"
}
}
}
Then, the webservice at http://www.yoursite.com/webservice.asmx should expose the following web method:
[WebMethod]
[PrincipalPermissionAttribute(SecurityAction.Demand, Role = "Bot")]
[SoapHeader("authentication")]
public void IrcMessage(string user, string hostmark, string channel, string message)
{
IRC.ParseIrcMessage(user, hostmark, channel, message);
}
With which you can do what you like! The only proviso you might require is the following setup for the authentication SOAP header:
/// <summary>
/// An Authentication class
/// </summary>
public class Authentication : SoapHeader
{
public string User;
public string Password;
public string Version;
}
And the following HttpModule:
using System;
using System.Web;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Text;
using System.Web.Services.Protocols;
using System.Security.Principal;
using System.Web.Security;
using System.Diagnostics;
using Logging;
namespace YourWebService
{
public sealed class WebServiceAuthenticationModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication app)
{
app.AuthenticateRequest += new
EventHandler(this.OnEnter);
}
public string ModuleName
{
get { return "WebServiceAuthentication"; }
}
void OnEnter(Object source, EventArgs eventArgs)
{
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
Stream HttpStream = context.Request.InputStream;
// Save the current position of stream.
long posStream = HttpStream.Position;
// If the request contains an HTTP_SOAPACTION
// header, look at this message.
if (context.Request.ServerVariables["HTTP_SOAPACTION"]
== null)
return;
// Load the body of the HTTP message
// into an XML document.
XmlDocument dom = new XmlDocument();
string soapUser;
string soapPassword;
string soapVersion;
try
{
dom.Load(HttpStream);
// Reset the stream position.
HttpStream.Position = posStream;
// Bind to the Authentication header.
soapUser = dom.GetElementsByTagName("User").Item(0).InnerText;
soapPassword = dom.GetElementsByTagName("Password").Item(0).InnerText;
soapVersion = dom.GetElementsByTagName("Version").Item(0).InnerText;
if (Membership.ValidateUser(soapUser, soapPassword))
{
MembershipUser user = Membership.GetUser(soapUser);
GenericIdentity identity = new GenericIdentity(user.UserName);
RolePrincipal rp = new RolePrincipal(identity);
HttpContext.Current.User = rp;
user.Comment = soapVersion;
Membership.UpdateUser(user);
Logger.Log.Info("Authenticated: " + soapUser + " :: " + soapVersion);
}
else
{
Logger.Log.Info("Failed to login as " + soapUser);
Logging.IRC.SendAdminMessage("Attempt to login as " + soapUser + " with password " + soapPassword + " failed.");
}
}
catch (Exception e)
{
Logging.IRC.SendAdminMessage("Error in SOAP parser: " + e.Message);
// Reset the position of stream.
HttpStream.Position = posStream;
// Throw a SOAP exception.
XmlQualifiedName name = new
XmlQualifiedName("Load");
SoapException soapException = new SoapException(
"Unable to read SOAP request", name, e);
throw soapException;
}
return;
}
}
}
Which, of course, you will need to load in web.config:
<httpModules>
<add name="WebServiceAuthenticationModule" type="YourWebService.WebServiceAuthenticationModule" />
</httpModules>