您的位置:首页 > 产品设计 > UI/UE

为 Serv-U 编写插件 (Building an Add-on for Serv-U)

2006-08-08 14:57 453 查看
需要对服务器上的 ftp server 作扩展,ftp server 采用的是 Serv-U 6.0。看了一些插件,有免费的,有商业的,都无法达到我们需求的功能,于是决定自己为 Serv-U 编写插件。查看帮助文件中的 Extending Serv-U 部分,大概了解了 Serv-U 插件的基本情况。

由于我们只需要控制存取信息所以我们只关注和介绍一下 Access Verification DLLs 部分,还有 Event Notification DLLs 基本和前者相似。现有的多数插件都是 Access Verificatin DLLs,这部分的内容比较多些,比如 用户登陆,密码更改,执行权限,配额,等等,一些 ftp 与论坛挂接的插件都是基于这部分写的。这个 DLL 必须导出一个函数:

extern "C" int __declspec( dllexport ) cdecl HandleClientEvent(RClientEventStr* pEventStruc);

插件的工作原理就是,Serv-U 服务器根据初始化文件的内容装载插件 DLL, 然后用 GetProcessAddress() 获得这个导出函数的地址,当有事件发生时,服务器就会调用这个函数并将相关信息通过参数 RClientEventStr* pEventStruc 传递给我们,RClientEventStr 结构定义如下:

// event structure for communications with external DLL's
struct RClientEventStr {
int Event; // event code
int Flag; // flag, meaning depends on event
//char User[151];//this member upgraded to 151 since v6.0 // user name
char User[40]; // it is 40 byte before 5.0
char Aux[512]; // auxiliary area, usage depends on event
char HostIP[16]; // IP number of host that client is connected to
unsigned long SessionID; // client session ID
int DomainID; // unique ID for the domain the client connected to
int DomainPort; // server port number the client connected to
};

这里有一点需要注意的是 User 成员在 6.0 以前是 40 个元素,从 6.0 开始变成 150 个元素,最近又因为修整一个Null Terminater 符号越界的 bug 又被定义成了 151 个元素,所以大家需要关注一下插件将在哪个版本的 Serv-U 上工作,否则我们的程序就会发生错误,甚至会使 Serv-U 崩溃。

Event 成员是事件 ID, 相关定义如下:

// event definitions, for usage by external DLL's
#define SRVU_LoginMesFile 1 // get login message file
#define SRVU_HomeDir 2 // get home dir
#define SRVU_Password 3 // verify password
#define SRVU_IPAccess 4 // verify IP access
#define SRVU_WriteFile 5 // verify write access
#define SRVU_ReadFile 6 // verify read access
#define SRVU_ModifyFile 7 // verify mod./del. file access
#define SRVU_ExecProg 8 // verify execute access

#define SRVU_ListDir 9 // verify dir listing access
#define SRVU_ChangeDir 10 // verify dir change access
#define SRVU_DeleteDir 11 // verify dir delete access
#define SRVU_CreateDir 12 // verify dir create access
#define SRVU_HideHidden 13 // get setting for 'hide hidden files'
#define SRVU_RelPaths 14 // get setting for 'relative paths'
#define SRVU_RatioType 15 // get setting for type of ratios

#define SRVU_RatioDown 16 // get setting for download ratio
#define SRVU_RatioUp 17 // get setting for upload ratio
#define SRVU_RatioCredit 18 // get/adjust ratio credit setting
#define SRVU_RatioFree 19 // verify if file is free for ratios
#define SRVU_QuotaEnable 20 // verify if disk quota is enabled
#define SRVU_QuotaChange 21 // change in disk quota

#define SRVU_QuotaMax 22 // maximum disk quota
#define SRVU_AlwaysLogin 23 // always allow login
#define SRVU_OneLoginPerIP 24 // allow one login per user/IP pair
#define SRVU_LogClientIP 25 // log client from this IP address
#define SRVU_SpeedLimit 26 // maximum transfer speed
#define SRVU_PassChange 27 // change user's password
#define SRVU_TimeOut 28 // get user time-out value

#define SRVU_MaxUsers 29 // max. no. of users for account
#define SRVU_PassChallenge 30 // get password challenge if needed
#define SRVU_Connect 31 // information only: client connected
#define SRVU_Close 32 // information only: client disconnected
#define SRVU_MaxLoginPerIP 33 // max. no. of logins from same IP for user
#define SRVU_VerifyPasswd 34 // verify old password before changing it

#define SRVU_AppendFile 35 // verify append file access
#define SRVU_SignOnMes 36 // get signon message file
#define SRVU_SignOffMes 37 // get signoff message file

#define SRVU_Maintenance 38 // switch to maintenance mode
#define SRVU_SessionTimeOut 39 // session time-out
#define SRVU_SecureOnly 40 // only allow login over secure connection
#define SRVU_PassExpired 41 // verify if password is expired
这里是最新版本所包含的 41 个事件, 较早的版本没有这么多事件,这里也请大家注意查阅相关版本的资料。

所有的扩展功能就看这个导出函数 HandleClientEvent 了,我们只需要在里面实现一个 switch...case..多路分枝语句就可以根据需要处理事件了。

举个例子说明一下大致的编写方法,如果我们需要让论坛或其他系统用户用他们在论坛或其他系统里的帐户密码登陆 ftp 我们可以处理 SRVU_Password 事件:

int __declspec( dllexport ) cdecl HandleClientEvent(RClientEventStr* pEventStruc)
// ******
// Event handler.
// ******
{
int Ret=0; // default return value -> not handling event

switch (pEventStruc->Event) {
case SRVU_Password:
if( CheckForumUser(pEventStruc->User, pEventStruc->Aux) )
{
pEventStruc->Flag = 1;
}
Ret = 1; // Don’t forget return 1 to Serv-U
break;
}

return(Ret);
}
当我们确认用户有效以后就将 Flag 置 1 (true),同时也要 return Ret=1;

Aux 是综合数据成员,不同事件时存储不同的信息,在这个事件中 Aux 中是用户的密码!

巧妙的处理这些事件便可以随心所欲的扩展我们的 Serv-U 了。

使 Serv-U 加载我们的插件的方法是在 ServUDaemon.ini 的 [EXTERNAL] 片段加入如下变量
ClientCheckDLL1=MyAddon1.dll

ClientCheckDLL2=MyAddon2.dll

以此类推。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐