四、08年3月04日
作者:青青子衿
email:[email protected]
1、 class CMac : public CCommandHandler 類的分析 該類主要用於用戶什麼的檢查
爲 CCommandHandler 的子類
在類定義之前定義了一些結構體,註釋都很明白,就不多解釋了
typedef struct func_s
{
CString sFuncname ; // Function name
} func ;
typedef struct user_s
{
CString sUsername ; // Username
CString sPassword ; // Password
CString sHost ; // Host
CString sIdentd ; // Identd
list < func *> lDeny ; // Functions to deny 拒絕
} user ;
typedef struct login_s
{
user * pUser ; // Pointer to the user of this login
CString sUsername ; // Username
CString sIRCUsername ; // Username in IRC
CString sHost ; // Host
CString sIdentd ; // Identd
} login ;
兩個私有成員變量,分別是:
list < user *> luStart ;
list < login *> llStart ;
兩個公有成員變量,分別是:
command m_cmdLogin , m_cmdLogout ;
23個成員函數
(1) 、構造函數和析構函數,將兩個列表變量清0
CMac :: CMac ()
{
luStart . clear ();
llStart . clear ();
}
CMac ::~ CMac ()
{
luStart . clear ();
llStart . clear ();
}
(2) 、 void CMac :: Init () 初始化函數
void CMac :: Init ()
{
//增加login登錄,和mac.logout登出兩個命令
g_cMainCtrl . m_cCommands . RegisterCommand (& m_cmdLogout , "mac.logout" , "logs the user out" , this );
g_cMainCtrl . m_cCommands . RegisterCommand (& m_cmdLogin , "login" , "logs the user in" , this );
}
(3)、 FindLogin ( CString sIRCUsername ) 函數
//////////////////////////////////////////////////////////////////
//
//函數功能:尋找指定的用戶名對應的login結構體
//參數: CString sIRCUsername IRC用戶名稱
//返回值: login *類型的變量,如果找到返回對應的login 結構體的指針
// 否則返回NULL
//
///////////////////////////////////////////////////////////////////
login * CMac :: FindLogin ( CString sIRCUsername )
{
if (! sIRCUsername . CStr ()) //如果要查找的用戶名爲空,函數返回
{
return NULL ;
}
list < login *>:: iterator il ;
for ( il = llStart . begin (); il != llStart . end (); ++ il )
{
if (!(* il )-> sIRCUsername . Compare ( sIRCUsername ))
{
return (* il ); //找到對應的結構體元素,返回該指針
}
}
return NULL ;
}
(4) 、 FindUser ( CString sUsername ) 函數, 還沒有完全弄明白具體的實現過程
//////////////////////////////////////////////////////////////////
//
//函數功能:尋找指定的用戶名對應 的user *結 構體
//參數: CString sUsername 用戶名稱
//返回值: user *類型的變量,如果找到返回對應的user 結構體的指針
// 否則返回NULL
//
///////////////////////////////////////////////////////////////////
user * CMac :: FindUser ( CString sUsername )
{
if (! sUsername . CStr ()) //判斷用戶名字符串是否是NULL
{
return NULL ;
}
list < user *>:: iterator iu ;
for ( iu = luStart . begin (); iu != luStart . end (); ++ iu )
{
user * pUser =(* iu ); //定義一個user類型的變量,並保存luStart列表的當前位置
login * pLogin = FindLogin ( sUsername ); //在login類型列表llStart中,找到與sUsername相匹配的login元素。找到是sIRCUsername
if ( pLogin ) //如果找到了
{
pUser = pLogin -> pUser ; //將login類型變量中的pLogin->pUser變量,賦值給pUser
}
if (! pUser -> sUsername . Compare ( sUsername ) || pLogin )
{
return pUser ;
}
}
return NULL ;
}
(5) 、 FindFunc ( CString sFuncname , list < func *> lStart )
//////////////////////////////////////////////////////////
//
//函數功能:尋找相應的func 結構體變量
//參數: CString sFuncname 名稱
// list<func*> lStart 函數結構體列表
//返回值: func *變量
//
//
/////////////////////////////////////////////////////////
func * CMac :: FindFunc ( CString sFuncname , list < func *> lStart )
{
if (! sFuncname . CStr ()) //保證函數名稱不等於空
{
return NULL ;
}
list < func *>:: iterator i ;
for ( i = lStart . begin (); i != lStart . end (); ++ i ) //在func*列表中進行查找,與sFuncname名字相匹配的元素
{
if (!(* i )-> sFuncname . Compare ( sFuncname ))
{
return (* i ); //將給元素返回
}
}
return NULL ;
}
(6)、 CheckPassword 函數用來校驗密碼
/////////////////////////////////////////////////////////
//
//函數功能:檢測密碼
//參數: CString sPassword 密碼字符串
// user *pUser 指向用戶結構體變量的指針
//返回值: 通過檢測返回true, 否則返回false
//
///////////////////////////////////////////////////////
bool CMac :: CheckPassword ( CString sPassword , user * pUser )
{
if (! sPassword . CStr ()) //密碼字符串不爲空
{
return false ;
}
/*
#define MD5_CBLOCK 64
#define MD5_LBLOCK (MD5_CBLOCK/4)
#define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st
{
MD5_LONG A,B,C,D;
MD5_LONG Nl,Nh;
MD5_LONG data[MD5_LBLOCK];
int num;
} MD5_CTX;
*/
MD5_CTX md5 ; //申請一個MD5類型的結構體
MD5_Init (& md5 );
unsigned char szMD5 [16];
CString sMD5 ;
sMD5 . Assign ( "" );
MD5_Update (& md5 , ( unsigned char *) sPassword . Str (), sPassword . GetLength ()); //第二個參數爲需要做md5計算的字符串,第三個參數是該字符串的長度
MD5_Final ( szMD5 , & md5 ); //szMD5爲生成的0x10位的md5值
for ( int i =0; i <16; i ++) //將計算出來的MD5值,保存到MD5中
{
CString sTemp ;
sTemp . Format ( "%2.2X" , szMD5 [ i ]);
sMD5 . Append ( sTemp );
}
if (! pUser -> sPassword . Compare ( sMD5 )) //用計算出來的MD5值,與pUser結構體中保存的密碼比較如果相等返回true,否則返回false。
{
return true ;
}
return false ;
}
(7)、 CheckBadFunc ( CString sFuncname , CString sUsername ) 函數, 檢查特定用戶是否有操作特定函數的權限
////////////////////////////////////////////////////////////////////
//
//函數功能:檢查特定用戶是否有操作特定函數的權限
//參數: CString sFuncname 所需要驗證函數的名稱
// CString sUsername 所需要驗證的用戶的名稱
//返回值: 如果有權限返回true,否則返回false
//
////////////////////////////////////////////////////////////////////
bool CMac :: CheckBadFunc ( CString sFuncname , CString sUsername )
{
user * pUser = FindUser ( sUsername ); //判斷該用戶是否存在
if (! pUser ) return false ; //如果不存在,返回false
if ( FindFunc ( sFuncname , pUser -> lDeny )) //調用函數在用戶的函數列表中尋找,指定的函數名稱
{
return true ; //如果找到返回true
}
return false ; //否則返回false
}
(8) 、 AddBadFunc ( CString sFuncname , user * pUser ) 函數
////////////////////////////////////////////////////////
//
//函數功能:爲特定用戶添加使用指定函數的權限
//參數: CString sFuncname 函數名稱
// user *pUser 指向特定用戶結構體變量的指針
//返回值:爲空
//
/////////////////////////////////////////////////////////
void CMac :: AddBadFunc ( CString sFuncname , user * pUser )
{
if (! pUser || ! sFuncname . CStr ()) //如果函數名稱爲空,或用戶結構體指針爲空,返回
{
return ;
}
int iToken =0;
while ( sFuncname . Token ( iToken , ":" ). Compare ( "" )) //如果sFuncname字符串的":"後邊的子字符串不爲空,執行循環裏邊的代碼,
{
func * pFunc = new func ;
pFunc -> sFuncname = sFuncname . Token ( iToken , ":" ); //獲得":"號後邊的子字符串,放到申請的func類型變量中
pUser -> lDeny . push_back ( pFunc ); //將賦值後的pFunc變量,添加到user類型變量的鏈表中。
iToken ++;
}
}
(9)、 AddLogin 函數
///////////////////////////////////////////////////////////////////////////
//
//函數功能:添加登錄賬號
//參數: CString sUsername 用戶名稱
// CString sPassword 用戶密碼
// CString sIRCUsername IRC的用戶名稱
// CString sHost 主機名信息
// CString sIdentd 或許是用戶的ID吧,不確定
//返回值: bool 添加成功返回true,否則返回false
//
/////////////////////////////////////////////////////////////////////////////
bool CMac :: AddLogin ( CString sUsername , CString sPassword , CString sIRCUsername , CString sHost , CString sIdentd )
{
if ( FindLogin ( sIRCUsername )) //尋找IRC用戶名(或許是頻道名),有人登錄
{
return false ; //如果找到返回false
}
user * pUser = FindUser ( sUsername ); //尋找sUsername名稱對應的用戶結構體變量
if (! pUser ) //如果沒有找到返回false
{
return false ;
}
if ( pUser ) //找到該用戶執行下面操作
if ( CheckPassword ( sPassword , pUser )) //檢查密碼的合法性
{ //如果合法
if ( pUser -> sHost . Compare ( "" )) //判斷sHost是否爲空
{ //如果不爲空
if (! strstr ( sHost . CStr (), pUser -> sHost . CStr ())) //用戶結構體變量中的主機名,是否是參數主機名字符串的字串
{ //如果不是返回false
return false ;
}
}
login * pLogin = new login ; //申請一塊login結構體大小的空間
pLogin -> pUser = pUser ; //將用戶結構體指針,加入login結構體變量
pLogin -> sUsername = sUsername ; //添加用戶名
pLogin -> sIRCUsername = sIRCUsername ; //添加IRC用戶名
llStart . push_back ( pLogin ); //將申請的pLogin變量,加入llStart列表中
return true ; //返回添加成功
}
return false ;
}
(10) 、 ClearLogins () 函數清除所有登錄賬號
/////////////////////////////////////////////////////////////////////////////
//
//函數功能:清除用戶登錄信息列表
//參數: 無
//返回值: void
//
/////////////////////////////////////////////////////////////////////////////
void CMac :: ClearLogins ()
{
llStart . clear ();
}
(11) 、 AddUser ( CString sUsername , CString sPassword , CString sHost , CString sIdentd ) 添加用戶函數
/////////////////////////////////////////////////////////////////////////////
//
//函數功能:添加用戶
//參數: CString sUsername 用戶名
// CString sPassword 密碼
// CString sHost 主機名
// CString sIdentd 用戶的ID
//返回值: void
//
/////////////////////////////////////////////////////////////////////////////
void CMac :: AddUser ( CString sUsername , CString sPassword , CString sHost , CString sIdentd )
{
user * pUser = new user ; //申請user類型的變量空間
pUser -> sUsername = sUsername ;
pUser -> sPassword = sPassword ;
pUser -> sHost = sHost ;
pUser -> sIdentd = sIdentd ;
luStart . push_back ( pUser ); //加入用戶列表
}
(12) 、 DelBadFunc_int 函數 刪除指定用戶某個函數功能調用的權限
////////////////////////////////////////////////////////////////////
//
//函數功能:刪除指定用戶某個函數功能調用的權限
//參數: CString sFuncname 功能函數的名稱
// user *pUser 用戶結構體指針
//返回值: bool 調用成功返回true,否則返回false
//
///////////////////////////////////////////////////////////////////
bool CMac :: DelBadFunc_int ( CString sFuncname , user * pUser )
{
func * pRemove = NULL ;
list < func *>:: iterator i ;
for ( i = pUser -> lDeny . begin (); i != pUser -> lDeny . end (); ++ i ) //在指定用戶的func列表中查找
{
if (!(* i )-> sFuncname . Compare ( sFuncname )) pRemove =(* i ); //如果找到一個與參數中的函數名稱相同的func結構體元素,將該原始結構體指針賦值給pRemove指針變量中
}
if ( pRemove ) //如果pRemove不爲空,將pRemove所指的元素從pUser->lDeny列表中刪除。
{
pUser -> lDeny . remove ( pRemove );
delete pRemove ;
return true ; //刪除成功返回true
}
return false ; //否則返回false
}
(13) 、 DelBadFunc 函數
////////////////////////////////////////////////////////////////////
//
//函數功能:刪除指定用戶的多個函數功能調用的權限,各函數用:分隔
//參數: CString sFuncname 功能函數的名稱
// user *pUser 用戶結構體指針
//返回值: bool 調用成功返回true,否則返回false
//
///////////////////////////////////////////////////////////////////
bool CMac :: DelBadFunc ( CString sFuncname , user * pUser )
{
bool bRetVal = true ;
int iToken =0;
while ( sFuncname . Token ( iToken , ":" ). Compare ( "" )) //循環提取出函數功能名,分別調用DelBadFunc_int函數
{
if (! DelBadFunc_int ( sFuncname . Token ( iToken , ":" ), pUser ))
{
bRetVal = false ;
}
iToken ++;
}
return bRetVal ;
}
(14) 、 DelUser ( CString sUsername ) 函數,刪除指定的用戶
///////////////////////////////////////////////////////////////////
//
//函數功能:刪除用戶記錄
//參數: CString sUsername 要用戶名稱
//返回值: bool 刪除成功返回true,否則返回false
//
///////////////////////////////////////////////////////////////////
bool CMac :: DelUser ( CString sUsername )
{
if (! sUsername . CStr ()) //保證用戶名字符串不爲空,否則函數返回false
{
return false ;
}
user * pRemove = NULL ;
list < user *>:: iterator i ;
for ( i = luStart . begin (); i != luStart . end (); ++ i ) //從列表中檢索要刪除的用戶名
{
if (!(* i )-> sUsername . Compare ( sUsername ))
{
pRemove =(* i ); //如果找到,將保存該用戶名信息的結構體變量的指針的值賦值給pRemove
}
}
if ( pRemove )
{
luStart . remove ( pRemove ); //刪除列表中該元素。
delete pRemove ;
return true ;
}
return false ;
}
(15) HandleCommand ( CMessage * pMsg ) 消息處理函數
////////////////////////////////////////////////////////////////////
//
//函數功能:處理與該類相關的消息
//參數: CMessage *pMsg 消息變量
//返回值: bool 調用成功返回true,否則false
//
///////////////////////////////////////////////////////////////////////
bool CMac :: HandleCommand ( CMessage * pMsg )
{
if (! pMsg -> sCmd . Compare ( "login" )) //處理login消息
{
if ( g_cMainCtrl . m_cMac . AddLogin ( pMsg -> sChatString . Token (1, " " , true ), pMsg -> sChatString . Token (2, " " , true ), pMsg -> sSrc , pMsg -> sHost , pMsg -> sIdentd ))
{
CString sReply ;
sReply . Format ( "Password accepted." );
g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent , pMsg -> bNotice , sReply . Str (), pMsg -> sReplyTo . Str ());
return true ;
}
else return false ;
}
else if (! pMsg -> sCmd . Compare ( "mac.logout" )) //處理mac.logout 消息
{
if ( g_cMainCtrl . m_cMac . DelLogin ( CString ( "" ), pMsg -> sSrc ))
{
CString sReply ;
sReply . Format ( "User %s logged out." , pMsg -> sSrc . CStr ());
g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent , pMsg -> bNotice , sReply . Str (), pMsg -> sReplyTo . Str ());
return true ;
}
else return false ;
}
return false ;
}